diff --git a/AndroidManifest.xml b/AndroidManifest.xml index c8e3040..7eb1bf3 100755 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -1,8 +1,8 @@ + android:versionCode="57" + android:versionName="1.1RC0" > @@ -11,8 +11,8 @@ @@ -27,6 +27,7 @@ On project folder: To build: $ mm external/nativeMethods + $ cp /nativeMethods/lib/* /res/raw -------------- Compile GUI------- ------------------- diff --git a/bin/droid-VNC-server.apk b/bin/droid-VNC-server.apk index bfa55f7..fefcc08 100644 Binary files a/bin/droid-VNC-server.apk and b/bin/droid-VNC-server.apk differ diff --git a/jni/vnc/.droidvncserver.c.swp b/jni/vnc/.droidvncserver.c.swp new file mode 100644 index 0000000..1413ed4 Binary files /dev/null and b/jni/vnc/.droidvncserver.c.swp differ diff --git a/jni/vnc/Android.mk b/jni/vnc/Android.mk index e8785fb..99ec57a 100755 --- a/jni/vnc/Android.mk +++ b/jni/vnc/Android.mk @@ -71,6 +71,6 @@ LOCAL_C_INCLUDES += \ LOCAL_STATIC_LIBRARIES := libjpeg libpng libssl_static libcrypto_static -LOCAL_MODULE:= androidvncserver +LOCAL_MODULE := androidvncserver include $(BUILD_EXECUTABLE) diff --git a/jni/vnc/LibVNCServer-0.9.9/rfb/rfbconfig.h b/jni/vnc/LibVNCServer-0.9.9/rfb/rfbconfig.h index 337181a..0b3be1a 100644 --- a/jni/vnc/LibVNCServer-0.9.9/rfb/rfbconfig.h +++ b/jni/vnc/LibVNCServer-0.9.9/rfb/rfbconfig.h @@ -437,9 +437,9 @@ /* #undef LIBVNCSERVER_HAVE_XTESTGRABCONTROL */ /* Enable IPv6 support */ -#ifndef LIBVNCSERVER_IPv6 +/*#ifndef LIBVNCSERVER_IPv6 #define LIBVNCSERVER_IPv6 1 -#endif +#endif*/ /* Define to 1 if `lstat' dereferences a symlink specified with a trailing slash. */ diff --git a/jni/vnc/droidvncserver.c b/jni/vnc/droidvncserver.c index fc70d78..e68a7fe 100755 --- a/jni/vnc/droidvncserver.c +++ b/jni/vnc/droidvncserver.c @@ -47,9 +47,10 @@ unsigned int *vncbuf; static rfbScreenInfoPtr vncscr; uint32_t idle = 0; -uint32_t standby = 0; +uint32_t standby = 1; uint16_t rotation = 0; uint16_t scaling = 100; +uint8_t display_rotate_180 = 0; //reverse connection char *rhost = NULL; @@ -80,11 +81,6 @@ inline int getCurrentRotation() return rotation; } -inline int isIdle() -{ - return idle; -} - void setIdle(int i) { idle=i; @@ -175,8 +171,9 @@ void initVncServer(int argc, char **argv) vncscr->passwordCheck = rfbCheckPasswordByList; } - vncscr->httpDir="/data/data/org.onaips.vnc/files/"; - vncscr->sslcertfile="self.pem"; + vncscr->httpDir = "webclients/"; +// vncscr->httpEnableProxyConnect = TRUE; + vncscr->sslcertfile = "self.pem"; vncscr->serverFormat.redShift = screenformat.redShift; vncscr->serverFormat.greenShift = screenformat.greenShift; @@ -206,7 +203,8 @@ void initVncServer(int argc, char **argv) vncscr->serverFormat.bitsPerPixel); sendMsgToGui("~SHOW|Unsupported pixel depth, please send bug report.\n"); - return; + close_app(); + exit(-1); } /* Mark as dirty since we haven't sent any updates at all yet. */ @@ -218,7 +216,7 @@ void initVncServer(int argc, char **argv) void rotate(int value) { - L("rotate()"); + L("rotate()\n"); if (value == -1 || ((value == 90 || value == 270) && (rotation == 0 || rotation == 180)) || @@ -302,16 +300,22 @@ void initGrabberMethod() method = GRALLOC; else if (initFB() != -1) { method = FRAMEBUFFER; - } else if (initADB() != -1) { + } + #if 0 + else if (initADB() != -1) { method = ADB; readBufferADB(); } + #endif } else if (method == FRAMEBUFFER) initFB(); + #if 0 else if (method == ADB) { initADB(); readBufferADB(); - } else if (method == GRALLOC) + } + #endif + else if (method == GRALLOC) initGralloc(); else if (method == FLINGER) initFlinger(); @@ -326,7 +330,8 @@ void printUsage(char **argv) "-p \t- Password to access server\n" "-r \t- Screen rotation (degrees) (0,90,180,270)\n" "-R \t- Host for reverse connection\n" - "-s \t- Scale percentage (20,30,50,100,150)\n\n" ); + "-s \t- Scale percentage (20,30,50,100,150)\n" + "-z\t- Rotate display 180º (for zte compatibility)\n\n"); } @@ -336,6 +341,7 @@ int main(int argc, char **argv) signal(SIGINT, close_app); signal(SIGKILL, close_app); signal(SIGILL, close_app); + long usec; if(argc > 1) { int i=1; @@ -355,6 +361,10 @@ int main(int argc, char **argv) i++; FB_setDevice(argv[i]); break; + case 'z': + i++; + display_rotate_180=1; + break; case 'P': i++; VNC_PORT=atoi(argv[i]); @@ -396,12 +406,12 @@ int main(int argc, char **argv) } else { L("Grab method \"%s\" not found, sticking with auto-detection.\n",argv[i]); } -break; -} -} -i++; -} -} + break; + } + } + i++; + } + } L("Initializing grabber method...\n"); initGrabberMethod(); @@ -440,20 +450,23 @@ i++; } } - rfbRunEventLoop(vncscr,-1,TRUE); - while (1) { - usleep(300000*(standby/2.0)); - + usec=vncscr->deferUpdateTime*2000*standby; + rfbProcessEvents(vncscr,usec); + if (idle) - standby++; + standby++; else - standby=2; - + standby=2; + if (vncscr->clientHead == NULL) - continue; + { + idle=1; + standby=50; + continue; + } update_screen(); } close_app(); - } +} diff --git a/jni/vnc/gui.c b/jni/vnc/gui.c index 9ca5a3e..78e5b71 100755 --- a/jni/vnc/gui.c +++ b/jni/vnc/gui.c @@ -105,7 +105,7 @@ void *handle_connections() n = recvfrom(hServerSocket,pBuffer,BUFFER_SIZE,0,(struct sockaddr *)&from,&fromlen); if (n < 0) perror("recvfrom"); - L("Recebido: %s\n",pBuffer); + //L("Recebido: %s\n",pBuffer); if (strstr(pBuffer,"~PING|")!=NULL) { diff --git a/jni/vnc/screenMethods/flinger.c b/jni/vnc/screenMethods/flinger.c index 2d787b7..87b9972 100644 --- a/jni/vnc/screenMethods/flinger.c +++ b/jni/vnc/screenMethods/flinger.c @@ -31,11 +31,21 @@ getscreenformat_fn_type getscreenformat_flinger = NULL; int initFlinger(void) { L("--Loading flinger native lib--\n"); + int i,len; + char lib_name[64]; - flinger_lib = dlopen("/data/libdvnc_flinger_sdk14.so", RTLD_NOW); - if(flinger_lib == NULL) { - L("Couldnt load library! Error string: %s\n",dlerror()); - return -1; + len=ARR_LEN(compiled_sdks); + for (i=0;iupdate(); - if (errno != NO_ERROR) { - L("screen capture failed: %s\n", strerror(-errno)); + screenshotClient = new ScreenshotClient(); + errno = screenshotClient->update(); + if (!screenshotClient->getPixels()) + return -1; + + if (errno != NO_ERROR) { return -1; } - return 0; } diff --git a/nativeMethods/flinger/flinger.h b/nativeMethods/flinger/flinger.h index 0581091..c602fab 100755 --- a/nativeMethods/flinger/flinger.h +++ b/nativeMethods/flinger/flinger.h @@ -26,8 +26,8 @@ extern "C" { #endif - unsigned int * readfb_flinger(); - int init_flinger(); + unsigned int * readfb_flinger(); + int init_flinger(); void close_flinger(); #ifdef __cplusplus } diff --git a/nativeMethods/lib/libdvnc_flinger_sdk14.so b/nativeMethods/lib/libdvnc_flinger_sdk14.so new file mode 100755 index 0000000..033caa9 Binary files /dev/null and b/nativeMethods/lib/libdvnc_flinger_sdk14.so differ diff --git a/res/anim/animation.xml b/res/anim/animation.xml index 47f326b..5e23075 100644 --- a/res/anim/animation.xml +++ b/res/anim/animation.xml @@ -1,13 +1,10 @@ - + android:fromAlpha="0.0" + android:toAlpha="1.0" + android:duration="500" + android:repeatMode="reverse" + android:repeatCount="infinite" /> diff --git a/res/drawable/btnstart_normal.png b/res/drawable/btnstart_normal.png index ccad8e1..52ac41d 100755 Binary files a/res/drawable/btnstart_normal.png and b/res/drawable/btnstart_normal.png differ diff --git a/res/drawable/btnstart_normal1.png b/res/drawable/btnstart_normal1.png deleted file mode 100755 index 52ac41d..0000000 Binary files a/res/drawable/btnstart_normal1.png and /dev/null differ diff --git a/res/drawable/btnstart_pressed.9.png b/res/drawable/btnstart_pressed.9.png deleted file mode 100755 index 9a87fdb..0000000 Binary files a/res/drawable/btnstart_pressed.9.png and /dev/null differ diff --git a/res/drawable/btnstop_normal.png b/res/drawable/btnstop_normal.png index b683d8d..9391853 100755 Binary files a/res/drawable/btnstop_normal.png and b/res/drawable/btnstop_normal.png differ diff --git a/res/drawable/btnstop_normal1.png b/res/drawable/btnstop_normal1.png deleted file mode 100755 index 9391853..0000000 Binary files a/res/drawable/btnstop_normal1.png and /dev/null differ diff --git a/res/drawable/btnstop_pressed.9.png b/res/drawable/btnstop_pressed.9.png deleted file mode 100755 index eb3d611..0000000 Binary files a/res/drawable/btnstop_pressed.9.png and /dev/null differ diff --git a/res/layout-land/main.xml b/res/layout-land/main.xml index 85f442d..934109c 100755 --- a/res/layout-land/main.xml +++ b/res/layout-land/main.xml @@ -1,32 +1,94 @@ - - - - - - - - - - - - - - + - - + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/res/raw/androidvncserver_froyo b/res/raw/androidvncserver_froyo deleted file mode 100755 index e7b002c..0000000 Binary files a/res/raw/androidvncserver_froyo and /dev/null differ diff --git a/res/raw/androidvncserver_gingerup b/res/raw/androidvncserver_gingerup deleted file mode 100755 index 75a59ed..0000000 Binary files a/res/raw/androidvncserver_gingerup and /dev/null differ diff --git a/res/raw/base64.js b/res/raw/base64.js deleted file mode 100755 index c68b33a..0000000 --- a/res/raw/base64.js +++ /dev/null @@ -1,147 +0,0 @@ -/* - * Modified from: - * http://lxr.mozilla.org/mozilla/source/extensions/xml-rpc/src/nsXmlRpcClient.js#956 - */ - -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla XML-RPC Client component. - * - * The Initial Developer of the Original Code is - * Digital Creations 2, Inc. - * Portions created by the Initial Developer are Copyright (C) 2000 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Martijn Pieters (original author) - * Samuel Sieb - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -/*jslint white: false, bitwise: false, plusplus: false */ -/*global console */ - -var Base64 = { - -/* Convert data (an array of integers) to a Base64 string. */ -toBase64Table : 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/', -base64Pad : '=', - -encode: function (data) { - "use strict"; - var result = '', - chrTable = Base64.toBase64Table.split(''), - pad = Base64.base64Pad, - length = data.length, - i; - // Convert every three bytes to 4 ascii characters. - for (i = 0; i < (length - 2); i += 3) { - result += chrTable[data[i] >> 2]; - result += chrTable[((data[i] & 0x03) << 4) + (data[i+1] >> 4)]; - result += chrTable[((data[i+1] & 0x0f) << 2) + (data[i+2] >> 6)]; - result += chrTable[data[i+2] & 0x3f]; - } - - // Convert the remaining 1 or 2 bytes, pad out to 4 characters. - if (length%3) { - i = length - (length%3); - result += chrTable[data[i] >> 2]; - if ((length%3) === 2) { - result += chrTable[((data[i] & 0x03) << 4) + (data[i+1] >> 4)]; - result += chrTable[(data[i+1] & 0x0f) << 2]; - result += pad; - } else { - result += chrTable[(data[i] & 0x03) << 4]; - result += pad + pad; - } - } - - return result; -}, - -/* Convert Base64 data to a string */ -toBinaryTable : [ - -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, - -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, - -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,62, -1,-1,-1,63, - 52,53,54,55, 56,57,58,59, 60,61,-1,-1, -1, 0,-1,-1, - -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 11,12,13,14, - 15,16,17,18, 19,20,21,22, 23,24,25,-1, -1,-1,-1,-1, - -1,26,27,28, 29,30,31,32, 33,34,35,36, 37,38,39,40, - 41,42,43,44, 45,46,47,48, 49,50,51,-1, -1,-1,-1,-1 -], - -decode: function (data, offset) { - "use strict"; - offset = typeof(offset) !== 'undefined' ? offset : 0; - var binTable = Base64.toBinaryTable, - pad = Base64.base64Pad, - result, result_length, idx, i, c, padding, - leftbits = 0, // number of bits decoded, but yet to be appended - leftdata = 0, // bits decoded, but yet to be appended - data_length = data.indexOf('=') - offset; - - if (data_length < 0) { data_length = data.length - offset; } - - /* Every four characters is 3 resulting numbers */ - result_length = (data_length >> 2) * 3 + Math.floor((data_length%4)/1.5); - result = new Array(result_length); - - // Convert one by one. - for (idx = 0, i = offset; i < data.length; i++) { - c = binTable[data.charCodeAt(i) & 0x7f]; - padding = (data.charAt(i) === pad); - // Skip illegal characters and whitespace - if (c === -1) { - console.error("Illegal character '" + data.charCodeAt(i) + "'"); - continue; - } - - // Collect data into leftdata, update bitcount - leftdata = (leftdata << 6) | c; - leftbits += 6; - - // If we have 8 or more bits, append 8 bits to the result - if (leftbits >= 8) { - leftbits -= 8; - // Append if not padding. - if (!padding) { - result[idx++] = (leftdata >> leftbits) & 0xff; - } - leftdata &= (1 << leftbits) - 1; - } - } - - // If there are any bits left, the base64 string was corrupted - if (leftbits) { - throw {name: 'Base64-Error', - message: 'Corrupted base64 string'}; - } - - return result; -} - -}; /* End of Base64 namespace */ diff --git a/res/raw/black.css b/res/raw/black.css deleted file mode 100755 index 3f95b88..0000000 --- a/res/raw/black.css +++ /dev/null @@ -1,124 +0,0 @@ -body { - margin: 0px; - font-size: 13px; - color: #111; - font-family: "Helvetica"; -} - -#VNC_controls { - background: #111; - line-height: 1em; - color: #FFF; - overflow: hidden; - padding: 4px 24px; -} - -#VNC_controls ul { - list-style:none; - list-style-position: outside; - margin: 0px; - padding: 0px; -} -#VNC_controls li { - margin-right: 15px; - padding: 2px 0px; - float: left; -} -#VNC_controls li input[type=text], -#VNC_controls li input[type=password] { - border: 2px solid #333; -} - -#VNC_host { - width: 100px; -} -#VNC_port { - width: 50px; -} -#VNC_password { - width: 80px; -} -#VNC_encrypt { -} -#VNC_connect_button { - width: 100px; -} - -#VNC_status_bar td { - padding: 0px; - margin: 0px; -} -#VNC_status_bar div { - font-size: 12px; - font-weight: bold; - text-align: center; - margin: 0px; - padding: 1em; -} -.VNC_status_button { - font-size: 10px; - margin: 0px; - padding: 0px; -} -#VNC_status { - text-align: center; -} -#VNC_settings_menu { - display: none; - position: absolute; - width: 13em; - border: 1px solid #888; - color: #111; - font-weight: normal; - background-color: #f0f2f6; - padding: 5px; margin: 3px; - z-index: 100; opacity: 1; - text-align: left; white-space: normal; -} -#VNC_settings_menu ul { - list-style: none; - margin: 0px; - padding: 0px; -} - -.VNC_buttons_right { - text-align: right; -} -.VNC_buttons_left { - text-align: left; -} -.VNC_status_normal { - background: #111; - color: #fff; -} -.VNC_status_error { - background: #111; - color: #f44; -} -.VNC_status_warn { - background: #111; - color: #ff4; -} - -#VNC_screen { - -webkit-border-radius: 10px; - -moz-border-radius: 10px; - border-radius: 10px; - background: #111; - padding: 20px; - margin: 0 auto; - color: #FFF; - margin-top: 20px; - text-align: center; - - /* This causes the width of the outer div(#screen) honor the size of the inner (#vnc) div */ - display: table; - table-layout: auto; -} -#VNC_canvas { - background: #111; - margin: 0 auto; -} -#VNC_clipboard { - display: none; -} diff --git a/res/raw/des.js b/res/raw/des.js deleted file mode 100755 index 1f95285..0000000 --- a/res/raw/des.js +++ /dev/null @@ -1,273 +0,0 @@ -/* - * Ported from Flashlight VNC ActionScript implementation: - * http://www.wizhelp.com/flashlight-vnc/ - * - * Full attribution follows: - * - * ------------------------------------------------------------------------- - * - * This DES class has been extracted from package Acme.Crypto for use in VNC. - * The unnecessary odd parity code has been removed. - * - * These changes are: - * Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. - * - * This software 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. - * - - * DesCipher - the DES encryption method - * - * The meat of this code is by Dave Zimmerman , and is: - * - * Copyright (c) 1996 Widget Workshop, Inc. All Rights Reserved. - * - * Permission to use, copy, modify, and distribute this software - * and its documentation for NON-COMMERCIAL or COMMERCIAL purposes and - * without fee is hereby granted, provided that this copyright notice is kept - * intact. - * - * WIDGET WORKSHOP MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY - * OF THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED - * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A - * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. WIDGET WORKSHOP SHALL NOT BE LIABLE - * FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR - * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. - * - * THIS SOFTWARE IS NOT DESIGNED OR INTENDED FOR USE OR RESALE AS ON-LINE - * CONTROL EQUIPMENT IN HAZARDOUS ENVIRONMENTS REQUIRING FAIL-SAFE - * PERFORMANCE, SUCH AS IN THE OPERATION OF NUCLEAR FACILITIES, AIRCRAFT - * NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL, DIRECT LIFE - * SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH THE FAILURE OF THE - * SOFTWARE COULD LEAD DIRECTLY TO DEATH, PERSONAL INJURY, OR SEVERE - * PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH RISK ACTIVITIES"). WIDGET WORKSHOP - * SPECIFICALLY DISCLAIMS ANY EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR - * HIGH RISK ACTIVITIES. - * - * - * The rest is: - * - * Copyright (C) 1996 by Jef Poskanzer . All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * Visit the ACME Labs Java page for up-to-date versions of this and other - * fine Java utilities: http://www.acme.com/java/ - */ - -"use strict"; -/*jslint white: false, bitwise: false, plusplus: false */ - -function DES(passwd) { - -// Tables, permutations, S-boxes, etc. -var PC2 = [13,16,10,23, 0, 4, 2,27,14, 5,20, 9,22,18,11, 3, - 25, 7,15, 6,26,19,12, 1,40,51,30,36,46,54,29,39, - 50,44,32,47,43,48,38,55,33,52,45,41,49,35,28,31 ], - totrot = [ 1, 2, 4, 6, 8,10,12,14,15,17,19,21,23,25,27,28], - z = 0x0, a,b,c,d,e,f, SP1,SP2,SP3,SP4,SP5,SP6,SP7,SP8, - keys = []; - -a=1<<16; b=1<<24; c=a|b; d=1<<2; e=1<<10; f=d|e; -SP1 = [c|e,z|z,a|z,c|f,c|d,a|f,z|d,a|z,z|e,c|e,c|f,z|e,b|f,c|d,b|z,z|d, - z|f,b|e,b|e,a|e,a|e,c|z,c|z,b|f,a|d,b|d,b|d,a|d,z|z,z|f,a|f,b|z, - a|z,c|f,z|d,c|z,c|e,b|z,b|z,z|e,c|d,a|z,a|e,b|d,z|e,z|d,b|f,a|f, - c|f,a|d,c|z,b|f,b|d,z|f,a|f,c|e,z|f,b|e,b|e,z|z,a|d,a|e,z|z,c|d]; -a=1<<20; b=1<<31; c=a|b; d=1<<5; e=1<<15; f=d|e; -SP2 = [c|f,b|e,z|e,a|f,a|z,z|d,c|d,b|f,b|d,c|f,c|e,b|z,b|e,a|z,z|d,c|d, - a|e,a|d,b|f,z|z,b|z,z|e,a|f,c|z,a|d,b|d,z|z,a|e,z|f,c|e,c|z,z|f, - z|z,a|f,c|d,a|z,b|f,c|z,c|e,z|e,c|z,b|e,z|d,c|f,a|f,z|d,z|e,b|z, - z|f,c|e,a|z,b|d,a|d,b|f,b|d,a|d,a|e,z|z,b|e,z|f,b|z,c|d,c|f,a|e]; -a=1<<17; b=1<<27; c=a|b; d=1<<3; e=1<<9; f=d|e; -SP3 = [z|f,c|e,z|z,c|d,b|e,z|z,a|f,b|e,a|d,b|d,b|d,a|z,c|f,a|d,c|z,z|f, - b|z,z|d,c|e,z|e,a|e,c|z,c|d,a|f,b|f,a|e,a|z,b|f,z|d,c|f,z|e,b|z, - c|e,b|z,a|d,z|f,a|z,c|e,b|e,z|z,z|e,a|d,c|f,b|e,b|d,z|e,z|z,c|d, - b|f,a|z,b|z,c|f,z|d,a|f,a|e,b|d,c|z,b|f,z|f,c|z,a|f,z|d,c|d,a|e]; -a=1<<13; b=1<<23; c=a|b; d=1<<0; e=1<<7; f=d|e; -SP4 = [c|d,a|f,a|f,z|e,c|e,b|f,b|d,a|d,z|z,c|z,c|z,c|f,z|f,z|z,b|e,b|d, - z|d,a|z,b|z,c|d,z|e,b|z,a|d,a|e,b|f,z|d,a|e,b|e,a|z,c|e,c|f,z|f, - b|e,b|d,c|z,c|f,z|f,z|z,z|z,c|z,a|e,b|e,b|f,z|d,c|d,a|f,a|f,z|e, - c|f,z|f,z|d,a|z,b|d,a|d,c|e,b|f,a|d,a|e,b|z,c|d,z|e,b|z,a|z,c|e]; -a=1<<25; b=1<<30; c=a|b; d=1<<8; e=1<<19; f=d|e; -SP5 = [z|d,a|f,a|e,c|d,z|e,z|d,b|z,a|e,b|f,z|e,a|d,b|f,c|d,c|e,z|f,b|z, - a|z,b|e,b|e,z|z,b|d,c|f,c|f,a|d,c|e,b|d,z|z,c|z,a|f,a|z,c|z,z|f, - z|e,c|d,z|d,a|z,b|z,a|e,c|d,b|f,a|d,b|z,c|e,a|f,b|f,z|d,a|z,c|e, - c|f,z|f,c|z,c|f,a|e,z|z,b|e,c|z,z|f,a|d,b|d,z|e,z|z,b|e,a|f,b|d]; -a=1<<22; b=1<<29; c=a|b; d=1<<4; e=1<<14; f=d|e; -SP6 = [b|d,c|z,z|e,c|f,c|z,z|d,c|f,a|z,b|e,a|f,a|z,b|d,a|d,b|e,b|z,z|f, - z|z,a|d,b|f,z|e,a|e,b|f,z|d,c|d,c|d,z|z,a|f,c|e,z|f,a|e,c|e,b|z, - b|e,z|d,c|d,a|e,c|f,a|z,z|f,b|d,a|z,b|e,b|z,z|f,b|d,c|f,a|e,c|z, - a|f,c|e,z|z,c|d,z|d,z|e,c|z,a|f,z|e,a|d,b|f,z|z,c|e,b|z,a|d,b|f]; -a=1<<21; b=1<<26; c=a|b; d=1<<1; e=1<<11; f=d|e; -SP7 = [a|z,c|d,b|f,z|z,z|e,b|f,a|f,c|e,c|f,a|z,z|z,b|d,z|d,b|z,c|d,z|f, - b|e,a|f,a|d,b|e,b|d,c|z,c|e,a|d,c|z,z|e,z|f,c|f,a|e,z|d,b|z,a|e, - b|z,a|e,a|z,b|f,b|f,c|d,c|d,z|d,a|d,b|z,b|e,a|z,c|e,z|f,a|f,c|e, - z|f,b|d,c|f,c|z,a|e,z|z,z|d,c|f,z|z,a|f,c|z,z|e,b|d,b|e,z|e,a|d]; -a=1<<18; b=1<<28; c=a|b; d=1<<6; e=1<<12; f=d|e; -SP8 = [b|f,z|e,a|z,c|f,b|z,b|f,z|d,b|z,a|d,c|z,c|f,a|e,c|e,a|f,z|e,z|d, - c|z,b|d,b|e,z|f,a|e,a|d,c|d,c|e,z|f,z|z,z|z,c|d,b|d,b|e,a|f,a|z, - a|f,a|z,c|e,z|e,z|d,c|d,z|e,a|f,b|e,z|d,b|d,c|z,c|d,b|z,a|z,b|f, - z|z,c|f,a|d,b|d,c|z,b|e,b|f,z|z,c|f,a|e,a|e,z|f,z|f,a|d,b|z,c|e]; - -// Set the key. -function setKeys(keyBlock) { - var i, j, l, m, n, o, pc1m = [], pcr = [], kn = [], - raw0, raw1, rawi, KnLi; - - for (j = 0, l = 56; j < 56; ++j, l-=8) { - l += l<-5 ? 65 : l<-3 ? 31 : l<-1 ? 63 : l===27 ? 35 : 0; // PC1 - m = l & 0x7; - pc1m[j] = ((keyBlock[l >>> 3] & (1<>> 10; - keys[KnLi] |= (raw1 & 0x00000fc0) >>> 6; - ++KnLi; - keys[KnLi] = (raw0 & 0x0003f000) << 12; - keys[KnLi] |= (raw0 & 0x0000003f) << 16; - keys[KnLi] |= (raw1 & 0x0003f000) >>> 4; - keys[KnLi] |= (raw1 & 0x0000003f); - ++KnLi; - } -} - -// Encrypt 8 bytes of text -function enc8(text) { - var i = 0, b = text.slice(), fval, keysi = 0, - l, r, x; // left, right, accumulator - - // Squash 8 bytes to 2 ints - l = b[i++]<<24 | b[i++]<<16 | b[i++]<<8 | b[i++]; - r = b[i++]<<24 | b[i++]<<16 | b[i++]<<8 | b[i++]; - - x = ((l >>> 4) ^ r) & 0x0f0f0f0f; - r ^= x; - l ^= (x << 4); - x = ((l >>> 16) ^ r) & 0x0000ffff; - r ^= x; - l ^= (x << 16); - x = ((r >>> 2) ^ l) & 0x33333333; - l ^= x; - r ^= (x << 2); - x = ((r >>> 8) ^ l) & 0x00ff00ff; - l ^= x; - r ^= (x << 8); - r = (r << 1) | ((r >>> 31) & 1); - x = (l ^ r) & 0xaaaaaaaa; - l ^= x; - r ^= x; - l = (l << 1) | ((l >>> 31) & 1); - - for (i = 0; i < 8; ++i) { - x = (r << 28) | (r >>> 4); - x ^= keys[keysi++]; - fval = SP7[x & 0x3f]; - fval |= SP5[(x >>> 8) & 0x3f]; - fval |= SP3[(x >>> 16) & 0x3f]; - fval |= SP1[(x >>> 24) & 0x3f]; - x = r ^ keys[keysi++]; - fval |= SP8[x & 0x3f]; - fval |= SP6[(x >>> 8) & 0x3f]; - fval |= SP4[(x >>> 16) & 0x3f]; - fval |= SP2[(x >>> 24) & 0x3f]; - l ^= fval; - x = (l << 28) | (l >>> 4); - x ^= keys[keysi++]; - fval = SP7[x & 0x3f]; - fval |= SP5[(x >>> 8) & 0x3f]; - fval |= SP3[(x >>> 16) & 0x3f]; - fval |= SP1[(x >>> 24) & 0x3f]; - x = l ^ keys[keysi++]; - fval |= SP8[x & 0x0000003f]; - fval |= SP6[(x >>> 8) & 0x3f]; - fval |= SP4[(x >>> 16) & 0x3f]; - fval |= SP2[(x >>> 24) & 0x3f]; - r ^= fval; - } - - r = (r << 31) | (r >>> 1); - x = (l ^ r) & 0xaaaaaaaa; - l ^= x; - r ^= x; - l = (l << 31) | (l >>> 1); - x = ((l >>> 8) ^ r) & 0x00ff00ff; - r ^= x; - l ^= (x << 8); - x = ((l >>> 2) ^ r) & 0x33333333; - r ^= x; - l ^= (x << 2); - x = ((r >>> 16) ^ l) & 0x0000ffff; - l ^= x; - r ^= (x << 16); - x = ((r >>> 4) ^ l) & 0x0f0f0f0f; - l ^= x; - r ^= (x << 4); - - // Spread ints to bytes - x = [r, l]; - for (i = 0; i < 8; i++) { - b[i] = (x[i>>>2] >>> (8*(3 - (i%4)))) % 256; - if (b[i] < 0) { b[i] += 256; } // unsigned - } - return b; -} - -// Encrypt 16 bytes of text using passwd as key -function encrypt(t) { - return enc8(t.slice(0,8)).concat(enc8(t.slice(8,16))); -} - -setKeys(passwd); // Setup keys -return {'encrypt': encrypt}; // Public interface - -} // function DES diff --git a/res/raw/display.js b/res/raw/display.js deleted file mode 100755 index d7aa43f..0000000 --- a/res/raw/display.js +++ /dev/null @@ -1,568 +0,0 @@ -/* - * noVNC: HTML5 VNC client - * Copyright (C) 2011 Joel Martin - * Licensed under LGPL-3 (see LICENSE.txt) - * - * See README.md for usage and integration instructions. - */ - -/*jslint browser: true, white: false, bitwise: false */ -/*global Util, Base64, changeCursor */ - -function Display(defaults) { -"use strict"; - -var that = {}, // Public API methods - conf = {}, // Configuration attributes - - // Private Display namespace variables - c_ctx = null, - c_forceCanvas = false, - - c_imageData, c_rgbxImage, c_cmapImage, - - // Predefine function variables (jslint) - imageDataCreate, imageDataGet, rgbxImageData, cmapImageData, - rgbxImageFill, cmapImageFill, setFillColor, rescale, flush, - - c_width = 0, - c_height = 0, - - c_prevStyle = "", - - c_webkit_bug = false, - c_flush_timer = null; - -// Configuration attributes -Util.conf_defaults(conf, that, defaults, [ - ['target', 'wo', 'dom', null, 'Canvas element for rendering'], - ['context', 'ro', 'raw', null, 'Canvas 2D context for rendering (read-only)'], - ['logo', 'rw', 'raw', null, 'Logo to display when cleared: {"width": width, "height": height, "data": data}'], - ['true_color', 'rw', 'bool', true, 'Use true-color pixel data'], - ['colourMap', 'rw', 'arr', [], 'Colour map array (when not true-color)'], - ['scale', 'rw', 'float', 1.0, 'Display area scale factor 0.0 - 1.0'], - ['width', 'rw', 'int', null, 'Display area width'], - ['height', 'rw', 'int', null, 'Display area height'], - - ['render_mode', 'ro', 'str', '', 'Canvas rendering mode (read-only)'], - - ['prefer_js', 'rw', 'str', null, 'Prefer Javascript over canvas methods'], - ['cursor_uri', 'rw', 'raw', null, 'Can we render cursor using data URI'] - ]); - -// Override some specific getters/setters -that.get_context = function () { return c_ctx; }; - -that.set_scale = function(scale) { rescale(scale); }; - -that.set_width = function (val) { that.resize(val, c_height); }; -that.get_width = function() { return c_width; }; - -that.set_height = function (val) { that.resize(c_width, val); }; -that.get_height = function() { return c_height; }; - -that.set_prefer_js = function(val) { - if (val && c_forceCanvas) { - Util.Warn("Preferring Javascript to Canvas ops is not supported"); - return false; - } - conf.prefer_js = val; - return true; -}; - - - -// -// Private functions -// - -// Create the public API interface -function constructor() { - Util.Debug(">> Display.constructor"); - - var c, func, imgTest, tval, i, curDat, curSave, - has_imageData = false, UE = Util.Engine; - - if (! conf.target) { throw("target must be set"); } - - if (typeof conf.target === 'string') { - throw("target must be a DOM element"); - } - - c = conf.target; - - if (! c.getContext) { throw("no getContext method"); } - - if (! c_ctx) { c_ctx = c.getContext('2d'); } - - Util.Debug("User Agent: " + navigator.userAgent); - if (UE.gecko) { Util.Debug("Browser: gecko " + UE.gecko); } - if (UE.webkit) { Util.Debug("Browser: webkit " + UE.webkit); } - if (UE.trident) { Util.Debug("Browser: trident " + UE.trident); } - if (UE.presto) { Util.Debug("Browser: presto " + UE.presto); } - - that.clear(); - - /* - * Determine browser Canvas feature support - * and select fastest rendering methods - */ - tval = 0; - try { - imgTest = c_ctx.getImageData(0, 0, 1,1); - imgTest.data[0] = 123; - imgTest.data[3] = 255; - c_ctx.putImageData(imgTest, 0, 0); - tval = c_ctx.getImageData(0, 0, 1, 1).data[0]; - if (tval === 123) { - has_imageData = true; - } - } catch (exc1) {} - - if (has_imageData) { - Util.Info("Canvas supports imageData"); - c_forceCanvas = false; - if (c_ctx.createImageData) { - // If it's there, it's faster - Util.Info("Using Canvas createImageData"); - conf.render_mode = "createImageData rendering"; - c_imageData = imageDataCreate; - } else if (c_ctx.getImageData) { - // I think this is mostly just Opera - Util.Info("Using Canvas getImageData"); - conf.render_mode = "getImageData rendering"; - c_imageData = imageDataGet; - } - Util.Info("Prefering javascript operations"); - if (conf.prefer_js === null) { - conf.prefer_js = true; - } - c_rgbxImage = rgbxImageData; - c_cmapImage = cmapImageData; - } else { - Util.Warn("Canvas lacks imageData, using fillRect (slow)"); - conf.render_mode = "fillRect rendering (slow)"; - c_forceCanvas = true; - conf.prefer_js = false; - c_rgbxImage = rgbxImageFill; - c_cmapImage = cmapImageFill; - } - - if (UE.webkit && UE.webkit >= 534.7 && UE.webkit <= 534.9) { - // Workaround WebKit canvas rendering bug #46319 - conf.render_mode += ", webkit bug workaround"; - Util.Debug("Working around WebKit bug #46319"); - c_webkit_bug = true; - for (func in {"fillRect":1, "copyImage":1, "rgbxImage":1, - "cmapImage":1, "blitStringImage":1}) { - that[func] = (function() { - var myfunc = that[func]; // Save original function - //Util.Debug("Wrapping " + func); - return function() { - myfunc.apply(this, arguments); - if (!c_flush_timer) { - c_flush_timer = setTimeout(flush, 100); - } - }; - }()); - } - } - - /* - * Determine browser support for setting the cursor via data URI - * scheme - */ - curDat = []; - for (i=0; i < 8 * 8 * 4; i += 1) { - curDat.push(255); - } - try { - curSave = c.style.cursor; - changeCursor(conf.target, curDat, curDat, 2, 2, 8, 8); - if (c.style.cursor) { - if (conf.cursor_uri === null) { - conf.cursor_uri = true; - } - Util.Info("Data URI scheme cursor supported"); - } else { - if (conf.cursor_uri === null) { - conf.cursor_uri = false; - } - Util.Warn("Data URI scheme cursor not supported"); - } - c.style.cursor = curSave; - } catch (exc2) { - Util.Error("Data URI scheme cursor test exception: " + exc2); - conf.cursor_uri = false; - } - - Util.Debug("<< Display.constructor"); - return that ; -} - -rescale = function(factor) { - var c, tp, x, y, - properties = ['transform', 'WebkitTransform', 'MozTransform', null]; - c = conf.target; - tp = properties.shift(); - while (tp) { - if (typeof c.style[tp] !== 'undefined') { - break; - } - tp = properties.shift(); - } - - if (tp === null) { - Util.Debug("No scaling support"); - return; - } - - if (factor > 1.0) { - factor = 1.0; - } else if (factor < 0.1) { - factor = 0.1; - } - - if (conf.scale === factor) { - //Util.Debug("Display already scaled to '" + factor + "'"); - return; - } - - conf.scale = factor; - x = c.width - c.width * factor; - y = c.height - c.height * factor; - c.style[tp] = "scale(" + conf.scale + ") translate(-" + x + "px, -" + y + "px)"; -}; - -// Force canvas redraw (for webkit bug #46319 workaround) -flush = function() { - var old_val; - //Util.Debug(">> flush"); - old_val = conf.target.style.marginRight; - conf.target.style.marginRight = "1px"; - c_flush_timer = null; - setTimeout(function () { - conf.target.style.marginRight = old_val; - }, 1); -}; - -setFillColor = function(color) { - var rgb, newStyle; - if (conf.true_color) { - rgb = color; - } else { - rgb = conf.colourMap[color[0]]; - } - newStyle = "rgb(" + rgb[0] + "," + rgb[1] + "," + rgb[2] + ")"; - if (newStyle !== c_prevStyle) { - c_ctx.fillStyle = newStyle; - c_prevStyle = newStyle; - } -}; - - -// -// Public API interface functions -// - -that.resize = function(width, height) { - var c = conf.target; - - c_prevStyle = ""; - - c.width = width; - c.height = height; - - c_width = c.offsetWidth; - c_height = c.offsetHeight; - - rescale(conf.scale); -}; - -that.clear = function() { - - if (conf.logo) { - that.resize(conf.logo.width, conf.logo.height); - that.blitStringImage(conf.logo.data, 0, 0); - } else { - that.resize(640, 20); - c_ctx.clearRect(0, 0, c_width, c_height); - } - - // No benefit over default ("source-over") in Chrome and firefox - //c_ctx.globalCompositeOperation = "copy"; -}; - -that.fillRect = function(x, y, width, height, color) { - setFillColor(color); - c_ctx.fillRect(x, y, width, height); -}; - -that.copyImage = function(old_x, old_y, new_x, new_y, width, height) { - c_ctx.drawImage(conf.target, old_x, old_y, width, height, - new_x, new_y, width, height); -}; - -/* - * Tile rendering functions optimized for rendering engines. - * - * - In Chrome/webkit, Javascript image data array manipulations are - * faster than direct Canvas fillStyle, fillRect rendering. In - * gecko, Javascript array handling is much slower. - */ -that.getTile = function(x, y, width, height, color) { - var img, data = [], rgb, red, green, blue, i; - img = {'x': x, 'y': y, 'width': width, 'height': height, - 'data': data}; - if (conf.prefer_js) { - if (conf.true_color) { - rgb = color; - } else { - rgb = conf.colourMap[color[0]]; - } - red = rgb[0]; - green = rgb[1]; - blue = rgb[2]; - for (i = 0; i < (width * height * 4); i+=4) { - data[i ] = red; - data[i + 1] = green; - data[i + 2] = blue; - } - } else { - that.fillRect(x, y, width, height, color); - } - return img; -}; - -that.setSubTile = function(img, x, y, w, h, color) { - var data, p, rgb, red, green, blue, width, j, i, xend, yend; - if (conf.prefer_js) { - data = img.data; - width = img.width; - if (conf.true_color) { - rgb = color; - } else { - rgb = conf.colourMap[color[0]]; - } - red = rgb[0]; - green = rgb[1]; - blue = rgb[2]; - xend = x + w; - yend = y + h; - for (j = y; j < yend; j += 1) { - for (i = x; i < xend; i += 1) { - p = (i + (j * width) ) * 4; - data[p ] = red; - data[p + 1] = green; - data[p + 2] = blue; - } - } - } else { - that.fillRect(img.x + x, img.y + y, w, h, color); - } -}; - -that.putTile = function(img) { - if (conf.prefer_js) { - c_rgbxImage(img.x, img.y, img.width, img.height, img.data, 0); - } - // else: No-op, under gecko already done by setSubTile -}; - -imageDataGet = function(width, height) { - return c_ctx.getImageData(0, 0, width, height); -}; -imageDataCreate = function(width, height) { - return c_ctx.createImageData(width, height); -}; - -rgbxImageData = function(x, y, width, height, arr, offset) { - var img, i, j, data; - img = c_imageData(width, height); - data = img.data; - for (i=0, j=offset; i < (width * height * 4); i=i+4, j=j+4) { - data[i ] = arr[j ]; - data[i + 1] = arr[j + 1]; - data[i + 2] = arr[j + 2]; - data[i + 3] = 255; // Set Alpha - } - c_ctx.putImageData(img, x, y); -}; - -// really slow fallback if we don't have imageData -rgbxImageFill = function(x, y, width, height, arr, offset) { - var i, j, sx = 0, sy = 0; - for (i=0, j=offset; i < (width * height); i+=1, j+=4) { - that.fillRect(x+sx, y+sy, 1, 1, [arr[j], arr[j+1], arr[j+2]]); - sx += 1; - if ((sx % width) === 0) { - sx = 0; - sy += 1; - } - } -}; - -cmapImageData = function(x, y, width, height, arr, offset) { - var img, i, j, data, rgb, cmap; - img = c_imageData(width, height); - data = img.data; - cmap = conf.colourMap; - for (i=0, j=offset; i < (width * height * 4); i+=4, j+=1) { - rgb = cmap[arr[j]]; - data[i ] = rgb[0]; - data[i + 1] = rgb[1]; - data[i + 2] = rgb[2]; - data[i + 3] = 255; // Set Alpha - } - c_ctx.putImageData(img, x, y); -}; - -cmapImageFill = function(x, y, width, height, arr, offset) { - var i, j, sx = 0, sy = 0, cmap; - cmap = conf.colourMap; - for (i=0, j=offset; i < (width * height); i+=1, j+=1) { - that.fillRect(x+sx, y+sy, 1, 1, [arr[j]]); - sx += 1; - if ((sx % width) === 0) { - sx = 0; - sy += 1; - } - } -}; - - -that.blitImage = function(x, y, width, height, arr, offset) { - if (conf.true_color) { - c_rgbxImage(x, y, width, height, arr, offset); - } else { - c_cmapImage(x, y, width, height, arr, offset); - } -}; - -that.blitStringImage = function(str, x, y) { - var img = new Image(); - img.onload = function () { c_ctx.drawImage(img, x, y); }; - img.src = str; -}; - -that.changeCursor = function(pixels, mask, hotx, hoty, w, h) { - if (conf.cursor_uri === false) { - Util.Warn("changeCursor called but no cursor data URI support"); - return; - } - - if (conf.true_color) { - changeCursor(conf.target, pixels, mask, hotx, hoty, w, h); - } else { - changeCursor(conf.target, pixels, mask, hotx, hoty, w, h, conf.colourMap); - } -}; - -that.defaultCursor = function() { - conf.target.style.cursor = "default"; -}; - -return constructor(); // Return the public API interface - -} // End of Display() - - -/* Set CSS cursor property using data URI encoded cursor file */ -function changeCursor(target, pixels, mask, hotx, hoty, w, h, cmap) { - "use strict"; - var cur = [], rgb, IHDRsz, RGBsz, ANDsz, XORsz, url, idx, alpha, x, y; - //Util.Debug(">> changeCursor, x: " + hotx + ", y: " + hoty + ", w: " + w + ", h: " + h); - - // Push multi-byte little-endian values - cur.push16le = function (num) { - this.push((num ) & 0xFF, - (num >> 8) & 0xFF ); - }; - cur.push32le = function (num) { - this.push((num ) & 0xFF, - (num >> 8) & 0xFF, - (num >> 16) & 0xFF, - (num >> 24) & 0xFF ); - }; - - IHDRsz = 40; - RGBsz = w * h * 4; - XORsz = Math.ceil( (w * h) / 8.0 ); - ANDsz = Math.ceil( (w * h) / 8.0 ); - - // Main header - cur.push16le(0); // 0: Reserved - cur.push16le(2); // 2: .CUR type - cur.push16le(1); // 4: Number of images, 1 for non-animated ico - - // Cursor #1 header (ICONDIRENTRY) - cur.push(w); // 6: width - cur.push(h); // 7: height - cur.push(0); // 8: colors, 0 -> true-color - cur.push(0); // 9: reserved - cur.push16le(hotx); // 10: hotspot x coordinate - cur.push16le(hoty); // 12: hotspot y coordinate - cur.push32le(IHDRsz + RGBsz + XORsz + ANDsz); - // 14: cursor data byte size - cur.push32le(22); // 18: offset of cursor data in the file - - - // Cursor #1 InfoHeader (ICONIMAGE/BITMAPINFO) - cur.push32le(IHDRsz); // 22: Infoheader size - cur.push32le(w); // 26: Cursor width - cur.push32le(h*2); // 30: XOR+AND height - cur.push16le(1); // 34: number of planes - cur.push16le(32); // 36: bits per pixel - cur.push32le(0); // 38: Type of compression - - cur.push32le(XORsz + ANDsz); // 43: Size of Image - // Gimp leaves this as 0 - - cur.push32le(0); // 46: reserved - cur.push32le(0); // 50: reserved - cur.push32le(0); // 54: reserved - cur.push32le(0); // 58: reserved - - // 62: color data (RGBQUAD icColors[]) - for (y = h-1; y >= 0; y -= 1) { - for (x = 0; x < w; x += 1) { - idx = y * Math.ceil(w / 8) + Math.floor(x/8); - alpha = (mask[idx] << (x % 8)) & 0x80 ? 255 : 0; - - if (cmap) { - idx = (w * y) + x; - rgb = cmap[pixels[idx]]; - cur.push(rgb[2]); // blue - cur.push(rgb[1]); // green - cur.push(rgb[0]); // red - cur.push(alpha); // alpha - } else { - idx = ((w * y) + x) * 4; - cur.push(pixels[idx + 2]); // blue - cur.push(pixels[idx + 1]); // green - cur.push(pixels[idx ]); // red - cur.push(alpha); // alpha - } - } - } - - // XOR/bitmask data (BYTE icXOR[]) - // (ignored, just needs to be right size) - for (y = 0; y < h; y += 1) { - for (x = 0; x < Math.ceil(w / 8); x += 1) { - cur.push(0x00); - } - } - - // AND/bitmask data (BYTE icAND[]) - // (ignored, just needs to be right size) - for (y = 0; y < h; y += 1) { - for (x = 0; x < Math.ceil(w / 8); x += 1) { - cur.push(0x00); - } - } - - url = "data:image/x-icon;base64," + Base64.encode(cur); - target.style.cursor = "url(" + url + ") " + hotx + " " + hoty + ", default"; - //Util.Debug("<< changeCursor, cur.length: " + cur.length); -} diff --git a/res/raw/index.vnc b/res/raw/index.vnc deleted file mode 100755 index 79aafa7..0000000 --- a/res/raw/index.vnc +++ /dev/null @@ -1,21 +0,0 @@ - - - - -$USER's $DESKTOP desktop ($DISPLAY) - - - - - -
-Further help:
-noVNC version (better)
-oNaiPs Blog
-www.TightVNC.com - diff --git a/res/raw/input.js b/res/raw/input.js deleted file mode 100755 index 47b6d77..0000000 --- a/res/raw/input.js +++ /dev/null @@ -1,1865 +0,0 @@ -/* - * noVNC: HTML5 VNC client - * Copyright (C) 2011 Joel Martin - * Licensed under LGPL-2 or any later version (see LICENSE.txt) - */ - -/*jslint browser: true, white: false, bitwise: false */ -/*global window, Util */ - - -// -// Keyboard event handler -// - -function Keyboard(defaults) { -"use strict"; - -var that = {}, // Public API methods - conf = {}, // Configuration attributes - - keyDownList = []; // List of depressed keys - // (even if they are happy) - -// Configuration attributes -Util.conf_defaults(conf, that, defaults, [ - ['target', 'wo', 'dom', document, 'DOM element that captures keyboard input'], - ['focused', 'rw', 'bool', true, 'Capture and send key events'], - - ['onKeyPress', 'rw', 'func', null, 'Handler for key press/release'] - ]); - - -// -// Private functions -// - -// From the event keyCode return the keysym value for keys that need -// to be suppressed otherwise they may trigger unintended browser -// actions -function getKeysymSpecial(evt) { - var keysym = null; - - switch ( evt.keyCode ) { - // These generate a keyDown and keyPress in Firefox and Opera - case 8 : keysym = 0xFF08; break; // BACKSPACE - case 13 : keysym = 0xFF0D; break; // ENTER - - // This generates a keyDown and keyPress in Opera - case 9 : keysym = 0xFF09; break; // TAB - default : break; - } - - if (evt.type === 'keydown') { - switch ( evt.keyCode ) { - case 27 : keysym = 0xFF1B; break; // ESCAPE - case 46 : keysym = 0xFFFF; break; // DELETE - - case 36 : keysym = 0xFF50; break; // HOME - case 35 : keysym = 0xFF57; break; // END - case 33 : keysym = 0xFF55; break; // PAGE_UP - case 34 : keysym = 0xFF56; break; // PAGE_DOWN - case 45 : keysym = 0xFF63; break; // INSERT - // '-' during keyPress - case 37 : keysym = 0xFF51; break; // LEFT - case 38 : keysym = 0xFF52; break; // UP - case 39 : keysym = 0xFF53; break; // RIGHT - case 40 : keysym = 0xFF54; break; // DOWN - case 16 : keysym = 0xFFE1; break; // SHIFT - case 17 : keysym = 0xFFE3; break; // CONTROL - //case 18 : keysym = 0xFFE7; break; // Left Meta (Mac Option) - case 18 : keysym = 0xFFE9; break; // Left ALT (Mac Command) - - case 112 : keysym = 0xFFBE; break; // F1 - case 113 : keysym = 0xFFBF; break; // F2 - case 114 : keysym = 0xFFC0; break; // F3 - case 115 : keysym = 0xFFC1; break; // F4 - case 116 : keysym = 0xFFC2; break; // F5 - case 117 : keysym = 0xFFC3; break; // F6 - case 118 : keysym = 0xFFC4; break; // F7 - case 119 : keysym = 0xFFC5; break; // F8 - case 120 : keysym = 0xFFC6; break; // F9 - case 121 : keysym = 0xFFC7; break; // F10 - case 122 : keysym = 0xFFC8; break; // F11 - case 123 : keysym = 0xFFC9; break; // F12 - - default : break; - } - } - - if ((!keysym) && (evt.ctrlKey || evt.altKey)) { - if ((typeof(evt.which) !== "undefined") && (evt.which > 0)) { - keysym = evt.which; - } else { - // IE9 always - // Firefox and Opera when ctrl/alt + special - Util.Warn("which not set, using keyCode"); - keysym = evt.keyCode; - } - - /* Remap symbols */ - switch (keysym) { - case 186 : keysym = 59; break; // ; (IE) - case 187 : keysym = 61; break; // = (IE) - case 188 : keysym = 44; break; // , (Mozilla, IE) - case 109 : // - (Mozilla, Opera) - if (Util.Engine.gecko || Util.Engine.presto) { - keysym = 45; } - break; - case 189 : keysym = 45; break; // - (IE) - case 190 : keysym = 46; break; // . (Mozilla, IE) - case 191 : keysym = 47; break; // / (Mozilla, IE) - case 192 : keysym = 96; break; // ` (Mozilla, IE) - case 219 : keysym = 91; break; // [ (Mozilla, IE) - case 220 : keysym = 92; break; // \ (Mozilla, IE) - case 221 : keysym = 93; break; // ] (Mozilla, IE) - case 222 : keysym = 39; break; // ' (Mozilla, IE) - } - - /* Remap shifted and unshifted keys */ - if (!!evt.shiftKey) { - switch (keysym) { - case 48 : keysym = 41 ; break; // ) (shifted 0) - case 49 : keysym = 33 ; break; // ! (shifted 1) - case 50 : keysym = 64 ; break; // @ (shifted 2) - case 51 : keysym = 35 ; break; // # (shifted 3) - case 52 : keysym = 36 ; break; // $ (shifted 4) - case 53 : keysym = 37 ; break; // % (shifted 5) - case 54 : keysym = 94 ; break; // ^ (shifted 6) - case 55 : keysym = 38 ; break; // & (shifted 7) - case 56 : keysym = 42 ; break; // * (shifted 8) - case 57 : keysym = 40 ; break; // ( (shifted 9) - - case 59 : keysym = 58 ; break; // : (shifted `) - case 61 : keysym = 43 ; break; // + (shifted ;) - case 44 : keysym = 60 ; break; // < (shifted ,) - case 45 : keysym = 95 ; break; // _ (shifted -) - case 46 : keysym = 62 ; break; // > (shifted .) - case 47 : keysym = 63 ; break; // ? (shifted /) - case 96 : keysym = 126; break; // ~ (shifted `) - case 91 : keysym = 123; break; // { (shifted [) - case 92 : keysym = 124; break; // | (shifted \) - case 93 : keysym = 125; break; // } (shifted ]) - case 39 : keysym = 34 ; break; // " (shifted ') - } - } else if ((keysym >= 65) && (keysym <=90)) { - /* Remap unshifted A-Z */ - keysym += 32; - } else if (evt.keyLocation === 3) { - // numpad keys - switch (keysym) { - case 96 : keysym = 48; break; // 0 - case 97 : keysym = 49; break; // 1 - case 98 : keysym = 50; break; // 2 - case 99 : keysym = 51; break; // 3 - case 100: keysym = 52; break; // 4 - case 101: keysym = 53; break; // 5 - case 102: keysym = 54; break; // 6 - case 103: keysym = 55; break; // 7 - case 104: keysym = 56; break; // 8 - case 105: keysym = 57; break; // 9 - case 109: keysym = 45; break; // - - case 110: keysym = 46; break; // . - case 111: keysym = 47; break; // / - } - } - } - - return keysym; -} - -/* Translate DOM keyPress event to keysym value */ -function getKeysym(evt) { - var keysym, msg; - - if (typeof(evt.which) !== "undefined") { - // WebKit, Firefox, Opera - keysym = evt.which; - } else { - // IE9 - Util.Warn("which not set, using keyCode"); - keysym = evt.keyCode; - } - - if ((keysym > 255) && (keysym < 0xFF00)) { - msg = "Mapping character code " + keysym; - // Map Unicode outside Latin 1 to X11 keysyms - keysym = unicodeTable[keysym]; - if (typeof(keysym) === 'undefined') { - keysym = 0; - } - Util.Debug(msg + " to " + keysym); - } - - return keysym; -} - -function show_keyDownList(kind) { - var c; - var msg = "keyDownList (" + kind + "):\n"; - for (c = 0; c < keyDownList.length; c++) { - msg = msg + " " + c + " - keyCode: " + keyDownList[c].keyCode + - " - which: " + keyDownList[c].which + "\n"; - } - Util.Debug(msg); -} - -function copyKeyEvent(evt) { - var members = ['type', 'keyCode', 'charCode', 'which', - 'altKey', 'ctrlKey', 'shiftKey', - 'keyLocation', 'keyIdentifier'], i, obj = {}; - for (i = 0; i < members.length; i++) { - if (typeof(evt[members[i]]) !== "undefined") { - obj[members[i]] = evt[members[i]]; - } - } - return obj; -} - -function pushKeyEvent(fevt) { - keyDownList.push(fevt); -} - -function getKeyEvent(keyCode, pop) { - var i, fevt = null; - for (i = keyDownList.length-1; i >= 0; i--) { - if (keyDownList[i].keyCode === keyCode) { - if ((typeof(pop) !== "undefined") && (pop)) { - fevt = keyDownList.splice(i, 1)[0]; - } else { - fevt = keyDownList[i]; - } - break; - } - } - return fevt; -} - -function ignoreKeyEvent(evt) { - // Blarg. Some keys have a different keyCode on keyDown vs keyUp - if (evt.keyCode === 229) { - // French AZERTY keyboard dead key. - // Lame thing is that the respective keyUp is 219 so we can't - // properly ignore the keyUp event - return true; - } - return false; -} - - -// -// Key Event Handling: -// -// There are several challenges when dealing with key events: -// - The meaning and use of keyCode, charCode and which depends on -// both the browser and the event type (keyDown/Up vs keyPress). -// - We cannot automatically determine the keyboard layout -// - The keyDown and keyUp events have a keyCode value that has not -// been translated by modifier keys. -// - The keyPress event has a translated (for layout and modifiers) -// character code but the attribute containing it differs. keyCode -// contains the translated value in WebKit (Chrome/Safari), Opera -// 11 and IE9. charCode contains the value in WebKit and Firefox. -// The which attribute contains the value on WebKit, Firefox and -// Opera 11. -// - The keyDown/Up keyCode value indicates (sort of) the physical -// key was pressed but only for standard US layout. On a US -// keyboard, the '-' and '_' characters are on the same key and -// generate a keyCode value of 189. But on an AZERTY keyboard even -// though they are different physical keys they both still -// generate a keyCode of 189! -// - To prevent a key event from propagating to the browser and -// causing unwanted default actions (such as closing a tab, -// opening a menu, shifting focus, etc) we must suppress this -// event in both keyDown and keyPress because not all key strokes -// generate on a keyPress event. Also, in WebKit and IE9 -// suppressing the keyDown prevents a keyPress but other browsers -// still generated a keyPress even if keyDown is suppressed. -// -// For safe key events, we wait until the keyPress event before -// reporting a key down event. For unsafe key events, we report a key -// down event when the keyDown event fires and we suppress any further -// actions (including keyPress). -// -// In order to report a key up event that matches what we reported -// for the key down event, we keep a list of keys that are currently -// down. When the keyDown event happens, we add the key event to the -// list. If it is a safe key event, then we update the which attribute -// in the most recent item on the list when we received a keyPress -// event (keyPress should immediately follow keyDown). When we -// received a keyUp event we search for the event on the list with -// a matching keyCode and we report the character code using the value -// in the 'which' attribute that was stored with that key. -// - -function onKeyDown(e) { - if (! conf.focused) { - return true; - } - var fevt = null, evt = (e ? e : window.event), - keysym = null, suppress = false; - //Util.Debug("onKeyDown kC:" + evt.keyCode + " cC:" + evt.charCode + " w:" + evt.which); - - fevt = copyKeyEvent(evt); - - keysym = getKeysymSpecial(evt); - // Save keysym decoding for use in keyUp - fevt.keysym = keysym; - if (keysym) { - // If it is a key or key combination that might trigger - // browser behaviors or it has no corresponding keyPress - // event, then send it immediately - if (conf.onKeyPress && !ignoreKeyEvent(evt)) { - Util.Debug("onKeyPress down, keysym: " + keysym + - " (onKeyDown key: " + evt.keyCode + - ", which: " + evt.which + ")"); - conf.onKeyPress(keysym, 1, evt); - } - suppress = true; - } - - if (! ignoreKeyEvent(evt)) { - // Add it to the list of depressed keys - pushKeyEvent(fevt); - //show_keyDownList('down'); - } - - if (suppress) { - // Suppress bubbling/default actions - Util.stopEvent(e); - return false; - } else { - // Allow the event to bubble and become a keyPress event which - // will have the character code translated - return true; - } -} - -function onKeyPress(e) { - if (! conf.focused) { - return true; - } - var evt = (e ? e : window.event), - kdlen = keyDownList.length, keysym = null; - //Util.Debug("onKeyPress kC:" + evt.keyCode + " cC:" + evt.charCode + " w:" + evt.which); - - if (((evt.which !== "undefined") && (evt.which === 0)) || - (getKeysymSpecial(evt))) { - // Firefox and Opera generate a keyPress event even if keyDown - // is suppressed. But the keys we want to suppress will have - // either: - // - the which attribute set to 0 - // - getKeysymSpecial() will identify it - Util.Debug("Ignoring special key in keyPress"); - Util.stopEvent(e); - return false; - } - - keysym = getKeysym(evt); - - // Modify the the which attribute in the depressed keys list so - // that the keyUp event will be able to have the character code - // translation available. - if (kdlen > 0) { - keyDownList[kdlen-1].keysym = keysym; - } else { - Util.Warn("keyDownList empty when keyPress triggered"); - } - - //show_keyDownList('press'); - - // Send the translated keysym - if (conf.onKeyPress && (keysym > 0)) { - Util.Debug("onKeyPress down, keysym: " + keysym + - " (onKeyPress key: " + evt.keyCode + - ", which: " + evt.which + ")"); - conf.onKeyPress(keysym, 1, evt); - } - - // Stop keypress events just in case - Util.stopEvent(e); - return false; -} - -function onKeyUp(e) { - if (! conf.focused) { - return true; - } - var fevt = null, evt = (e ? e : window.event), keysym; - //Util.Debug("onKeyUp kC:" + evt.keyCode + " cC:" + evt.charCode + " w:" + evt.which); - - fevt = getKeyEvent(evt.keyCode, true); - - if (fevt) { - keysym = fevt.keysym; - } else { - Util.Warn("Key event (keyCode = " + evt.keyCode + - ") not found on keyDownList"); - keysym = 0; - } - - //show_keyDownList('up'); - - if (conf.onKeyPress && (keysym > 0)) { - //Util.Debug("keyPress up, keysym: " + keysym + - // " (key: " + evt.keyCode + ", which: " + evt.which + ")"); - Util.Debug("onKeyPress up, keysym: " + keysym + - " (onKeyPress key: " + evt.keyCode + - ", which: " + evt.which + ")"); - conf.onKeyPress(keysym, 0, evt); - } - Util.stopEvent(e); - return false; -} - -// -// Public API interface functions -// - -that.grab = function() { - //Util.Debug(">> Keyboard.grab"); - var c = conf.target; - - Util.addEvent(c, 'keydown', onKeyDown); - Util.addEvent(c, 'keyup', onKeyUp); - Util.addEvent(c, 'keypress', onKeyPress); - - //Util.Debug("<< Keyboard.grab"); -}; - -that.ungrab = function() { - //Util.Debug(">> Keyboard.ungrab"); - var c = conf.target; - - Util.removeEvent(c, 'keydown', onKeyDown); - Util.removeEvent(c, 'keyup', onKeyUp); - Util.removeEvent(c, 'keypress', onKeyPress); - - //Util.Debug(">> Keyboard.ungrab"); -}; - -return that; // Return the public API interface - -} // End of Keyboard() - - -// -// Mouse event handler -// - -function Mouse(defaults) { -"use strict"; - -var that = {}, // Public API methods - conf = {}; // Configuration attributes - -// Configuration attributes -Util.conf_defaults(conf, that, defaults, [ - ['target', 'ro', 'dom', document, 'DOM element that captures mouse input'], - ['focused', 'rw', 'bool', true, 'Capture and send mouse clicks/movement'], - ['scale', 'rw', 'float', 1.0, 'Viewport scale factor 0.0 - 1.0'], - - ['onMouseButton', 'rw', 'func', null, 'Handler for mouse button click/release'], - ['onMouseMove', 'rw', 'func', null, 'Handler for mouse movement'] - ]); - - -// -// Private functions -// - -function onMouseButton(e, down) { - var evt, pos, bmask; - if (! conf.focused) { - return true; - } - evt = (e ? e : window.event); - pos = Util.getEventPosition(e, conf.target, conf.scale); - if (evt.which) { - /* everything except IE */ - bmask = 1 << evt.button; - } else { - /* IE including 9 */ - bmask = (evt.button & 0x1) + // Left - (evt.button & 0x2) * 2 + // Right - (evt.button & 0x4) / 2; // Middle - } - //Util.Debug("mouse " + pos.x + "," + pos.y + " down: " + down + - // " bmask: " + bmask + "(evt.button: " + evt.button + ")"); - if (conf.onMouseButton) { - Util.Debug("onMouseButton " + (down ? "down" : "up") + - ", x: " + pos.x + ", y: " + pos.y + ", bmask: " + bmask); - conf.onMouseButton(pos.x, pos.y, down, bmask); - } - Util.stopEvent(e); - return false; -} - -function onMouseDown(e) { - onMouseButton(e, 1); -} - -function onMouseUp(e) { - onMouseButton(e, 0); -} - -function onMouseWheel(e) { - var evt, pos, bmask, wheelData; - if (! conf.focused) { - return true; - } - evt = (e ? e : window.event); - pos = Util.getEventPosition(e, conf.target, conf.scale); - wheelData = evt.detail ? evt.detail * -1 : evt.wheelDelta / 40; - if (wheelData > 0) { - bmask = 1 << 3; - } else { - bmask = 1 << 4; - } - //Util.Debug('mouse scroll by ' + wheelData + ':' + pos.x + "," + pos.y); - if (conf.onMouseButton) { - conf.onMouseButton(pos.x, pos.y, 1, bmask); - conf.onMouseButton(pos.x, pos.y, 0, bmask); - } - Util.stopEvent(e); - return false; -} - -function onMouseMove(e) { - var evt, pos; - if (! conf.focused) { - return true; - } - evt = (e ? e : window.event); - pos = Util.getEventPosition(e, conf.target, conf.scale); - //Util.Debug('mouse ' + evt.which + '/' + evt.button + ' up:' + pos.x + "," + pos.y); - if (conf.onMouseMove) { - conf.onMouseMove(pos.x, pos.y); - } -} - -function onMouseDisable(e) { - var evt, pos; - if (! conf.focused) { - return true; - } - evt = (e ? e : window.event); - pos = Util.getEventPosition(e, conf.target, conf.scale); - /* Stop propagation if inside canvas area */ - if ((pos.x >= 0) && (pos.y >= 0) && - (pos.x < conf.target.offsetWidth) && - (pos.y < conf.target.offsetHeight)) { - //Util.Debug("mouse event disabled"); - Util.stopEvent(e); - return false; - } - //Util.Debug("mouse event not disabled"); - return true; -} - -// -// Public API interface functions -// - -that.grab = function() { - //Util.Debug(">> Mouse.grab"); - var c = conf.target; - - Util.addEvent(c, 'mousedown', onMouseDown); - Util.addEvent(c, 'mouseup', onMouseUp); - Util.addEvent(c, 'mousemove', onMouseMove); - Util.addEvent(c, (Util.Engine.gecko) ? 'DOMMouseScroll' : 'mousewheel', - onMouseWheel); - - /* Work around right and middle click browser behaviors */ - Util.addEvent(document, 'click', onMouseDisable); - Util.addEvent(document.body, 'contextmenu', onMouseDisable); - - //Util.Debug("<< Mouse.grab"); -}; - -that.ungrab = function() { - //Util.Debug(">> Mouse.ungrab"); - var c = conf.target; - - Util.removeEvent(c, 'mousedown', onMouseDown); - Util.removeEvent(c, 'mouseup', onMouseUp); - Util.removeEvent(c, 'mousemove', onMouseMove); - Util.removeEvent(c, (Util.Engine.gecko) ? 'DOMMouseScroll' : 'mousewheel', - onMouseWheel); - - /* Work around right and middle click browser behaviors */ - Util.removeEvent(document, 'click', onMouseDisable); - Util.removeEvent(document.body, 'contextmenu', onMouseDisable); - - //Util.Debug(">> Mouse.ungrab"); -}; - -return that; // Return the public API interface - -} // End of Mouse() - - -/* - * Browser keypress to X11 keysym for Unicode characters > U+00FF - */ -unicodeTable = { - 0x0104 : 0x01a1, - 0x02D8 : 0x01a2, - 0x0141 : 0x01a3, - 0x013D : 0x01a5, - 0x015A : 0x01a6, - 0x0160 : 0x01a9, - 0x015E : 0x01aa, - 0x0164 : 0x01ab, - 0x0179 : 0x01ac, - 0x017D : 0x01ae, - 0x017B : 0x01af, - 0x0105 : 0x01b1, - 0x02DB : 0x01b2, - 0x0142 : 0x01b3, - 0x013E : 0x01b5, - 0x015B : 0x01b6, - 0x02C7 : 0x01b7, - 0x0161 : 0x01b9, - 0x015F : 0x01ba, - 0x0165 : 0x01bb, - 0x017A : 0x01bc, - 0x02DD : 0x01bd, - 0x017E : 0x01be, - 0x017C : 0x01bf, - 0x0154 : 0x01c0, - 0x0102 : 0x01c3, - 0x0139 : 0x01c5, - 0x0106 : 0x01c6, - 0x010C : 0x01c8, - 0x0118 : 0x01ca, - 0x011A : 0x01cc, - 0x010E : 0x01cf, - 0x0110 : 0x01d0, - 0x0143 : 0x01d1, - 0x0147 : 0x01d2, - 0x0150 : 0x01d5, - 0x0158 : 0x01d8, - 0x016E : 0x01d9, - 0x0170 : 0x01db, - 0x0162 : 0x01de, - 0x0155 : 0x01e0, - 0x0103 : 0x01e3, - 0x013A : 0x01e5, - 0x0107 : 0x01e6, - 0x010D : 0x01e8, - 0x0119 : 0x01ea, - 0x011B : 0x01ec, - 0x010F : 0x01ef, - 0x0111 : 0x01f0, - 0x0144 : 0x01f1, - 0x0148 : 0x01f2, - 0x0151 : 0x01f5, - 0x0171 : 0x01fb, - 0x0159 : 0x01f8, - 0x016F : 0x01f9, - 0x0163 : 0x01fe, - 0x02D9 : 0x01ff, - 0x0126 : 0x02a1, - 0x0124 : 0x02a6, - 0x0130 : 0x02a9, - 0x011E : 0x02ab, - 0x0134 : 0x02ac, - 0x0127 : 0x02b1, - 0x0125 : 0x02b6, - 0x0131 : 0x02b9, - 0x011F : 0x02bb, - 0x0135 : 0x02bc, - 0x010A : 0x02c5, - 0x0108 : 0x02c6, - 0x0120 : 0x02d5, - 0x011C : 0x02d8, - 0x016C : 0x02dd, - 0x015C : 0x02de, - 0x010B : 0x02e5, - 0x0109 : 0x02e6, - 0x0121 : 0x02f5, - 0x011D : 0x02f8, - 0x016D : 0x02fd, - 0x015D : 0x02fe, - 0x0138 : 0x03a2, - 0x0156 : 0x03a3, - 0x0128 : 0x03a5, - 0x013B : 0x03a6, - 0x0112 : 0x03aa, - 0x0122 : 0x03ab, - 0x0166 : 0x03ac, - 0x0157 : 0x03b3, - 0x0129 : 0x03b5, - 0x013C : 0x03b6, - 0x0113 : 0x03ba, - 0x0123 : 0x03bb, - 0x0167 : 0x03bc, - 0x014A : 0x03bd, - 0x014B : 0x03bf, - 0x0100 : 0x03c0, - 0x012E : 0x03c7, - 0x0116 : 0x03cc, - 0x012A : 0x03cf, - 0x0145 : 0x03d1, - 0x014C : 0x03d2, - 0x0136 : 0x03d3, - 0x0172 : 0x03d9, - 0x0168 : 0x03dd, - 0x016A : 0x03de, - 0x0101 : 0x03e0, - 0x012F : 0x03e7, - 0x0117 : 0x03ec, - 0x012B : 0x03ef, - 0x0146 : 0x03f1, - 0x014D : 0x03f2, - 0x0137 : 0x03f3, - 0x0173 : 0x03f9, - 0x0169 : 0x03fd, - 0x016B : 0x03fe, - 0x1E02 : 0x1001e02, - 0x1E03 : 0x1001e03, - 0x1E0A : 0x1001e0a, - 0x1E80 : 0x1001e80, - 0x1E82 : 0x1001e82, - 0x1E0B : 0x1001e0b, - 0x1EF2 : 0x1001ef2, - 0x1E1E : 0x1001e1e, - 0x1E1F : 0x1001e1f, - 0x1E40 : 0x1001e40, - 0x1E41 : 0x1001e41, - 0x1E56 : 0x1001e56, - 0x1E81 : 0x1001e81, - 0x1E57 : 0x1001e57, - 0x1E83 : 0x1001e83, - 0x1E60 : 0x1001e60, - 0x1EF3 : 0x1001ef3, - 0x1E84 : 0x1001e84, - 0x1E85 : 0x1001e85, - 0x1E61 : 0x1001e61, - 0x0174 : 0x1000174, - 0x1E6A : 0x1001e6a, - 0x0176 : 0x1000176, - 0x0175 : 0x1000175, - 0x1E6B : 0x1001e6b, - 0x0177 : 0x1000177, - 0x0152 : 0x13bc, - 0x0153 : 0x13bd, - 0x0178 : 0x13be, - 0x203E : 0x047e, - 0x3002 : 0x04a1, - 0x300C : 0x04a2, - 0x300D : 0x04a3, - 0x3001 : 0x04a4, - 0x30FB : 0x04a5, - 0x30F2 : 0x04a6, - 0x30A1 : 0x04a7, - 0x30A3 : 0x04a8, - 0x30A5 : 0x04a9, - 0x30A7 : 0x04aa, - 0x30A9 : 0x04ab, - 0x30E3 : 0x04ac, - 0x30E5 : 0x04ad, - 0x30E7 : 0x04ae, - 0x30C3 : 0x04af, - 0x30FC : 0x04b0, - 0x30A2 : 0x04b1, - 0x30A4 : 0x04b2, - 0x30A6 : 0x04b3, - 0x30A8 : 0x04b4, - 0x30AA : 0x04b5, - 0x30AB : 0x04b6, - 0x30AD : 0x04b7, - 0x30AF : 0x04b8, - 0x30B1 : 0x04b9, - 0x30B3 : 0x04ba, - 0x30B5 : 0x04bb, - 0x30B7 : 0x04bc, - 0x30B9 : 0x04bd, - 0x30BB : 0x04be, - 0x30BD : 0x04bf, - 0x30BF : 0x04c0, - 0x30C1 : 0x04c1, - 0x30C4 : 0x04c2, - 0x30C6 : 0x04c3, - 0x30C8 : 0x04c4, - 0x30CA : 0x04c5, - 0x30CB : 0x04c6, - 0x30CC : 0x04c7, - 0x30CD : 0x04c8, - 0x30CE : 0x04c9, - 0x30CF : 0x04ca, - 0x30D2 : 0x04cb, - 0x30D5 : 0x04cc, - 0x30D8 : 0x04cd, - 0x30DB : 0x04ce, - 0x30DE : 0x04cf, - 0x30DF : 0x04d0, - 0x30E0 : 0x04d1, - 0x30E1 : 0x04d2, - 0x30E2 : 0x04d3, - 0x30E4 : 0x04d4, - 0x30E6 : 0x04d5, - 0x30E8 : 0x04d6, - 0x30E9 : 0x04d7, - 0x30EA : 0x04d8, - 0x30EB : 0x04d9, - 0x30EC : 0x04da, - 0x30ED : 0x04db, - 0x30EF : 0x04dc, - 0x30F3 : 0x04dd, - 0x309B : 0x04de, - 0x309C : 0x04df, - 0x06F0 : 0x10006f0, - 0x06F1 : 0x10006f1, - 0x06F2 : 0x10006f2, - 0x06F3 : 0x10006f3, - 0x06F4 : 0x10006f4, - 0x06F5 : 0x10006f5, - 0x06F6 : 0x10006f6, - 0x06F7 : 0x10006f7, - 0x06F8 : 0x10006f8, - 0x06F9 : 0x10006f9, - 0x066A : 0x100066a, - 0x0670 : 0x1000670, - 0x0679 : 0x1000679, - 0x067E : 0x100067e, - 0x0686 : 0x1000686, - 0x0688 : 0x1000688, - 0x0691 : 0x1000691, - 0x060C : 0x05ac, - 0x06D4 : 0x10006d4, - 0x0660 : 0x1000660, - 0x0661 : 0x1000661, - 0x0662 : 0x1000662, - 0x0663 : 0x1000663, - 0x0664 : 0x1000664, - 0x0665 : 0x1000665, - 0x0666 : 0x1000666, - 0x0667 : 0x1000667, - 0x0668 : 0x1000668, - 0x0669 : 0x1000669, - 0x061B : 0x05bb, - 0x061F : 0x05bf, - 0x0621 : 0x05c1, - 0x0622 : 0x05c2, - 0x0623 : 0x05c3, - 0x0624 : 0x05c4, - 0x0625 : 0x05c5, - 0x0626 : 0x05c6, - 0x0627 : 0x05c7, - 0x0628 : 0x05c8, - 0x0629 : 0x05c9, - 0x062A : 0x05ca, - 0x062B : 0x05cb, - 0x062C : 0x05cc, - 0x062D : 0x05cd, - 0x062E : 0x05ce, - 0x062F : 0x05cf, - 0x0630 : 0x05d0, - 0x0631 : 0x05d1, - 0x0632 : 0x05d2, - 0x0633 : 0x05d3, - 0x0634 : 0x05d4, - 0x0635 : 0x05d5, - 0x0636 : 0x05d6, - 0x0637 : 0x05d7, - 0x0638 : 0x05d8, - 0x0639 : 0x05d9, - 0x063A : 0x05da, - 0x0640 : 0x05e0, - 0x0641 : 0x05e1, - 0x0642 : 0x05e2, - 0x0643 : 0x05e3, - 0x0644 : 0x05e4, - 0x0645 : 0x05e5, - 0x0646 : 0x05e6, - 0x0647 : 0x05e7, - 0x0648 : 0x05e8, - 0x0649 : 0x05e9, - 0x064A : 0x05ea, - 0x064B : 0x05eb, - 0x064C : 0x05ec, - 0x064D : 0x05ed, - 0x064E : 0x05ee, - 0x064F : 0x05ef, - 0x0650 : 0x05f0, - 0x0651 : 0x05f1, - 0x0652 : 0x05f2, - 0x0653 : 0x1000653, - 0x0654 : 0x1000654, - 0x0655 : 0x1000655, - 0x0698 : 0x1000698, - 0x06A4 : 0x10006a4, - 0x06A9 : 0x10006a9, - 0x06AF : 0x10006af, - 0x06BA : 0x10006ba, - 0x06BE : 0x10006be, - 0x06CC : 0x10006cc, - 0x06D2 : 0x10006d2, - 0x06C1 : 0x10006c1, - 0x0492 : 0x1000492, - 0x0493 : 0x1000493, - 0x0496 : 0x1000496, - 0x0497 : 0x1000497, - 0x049A : 0x100049a, - 0x049B : 0x100049b, - 0x049C : 0x100049c, - 0x049D : 0x100049d, - 0x04A2 : 0x10004a2, - 0x04A3 : 0x10004a3, - 0x04AE : 0x10004ae, - 0x04AF : 0x10004af, - 0x04B0 : 0x10004b0, - 0x04B1 : 0x10004b1, - 0x04B2 : 0x10004b2, - 0x04B3 : 0x10004b3, - 0x04B6 : 0x10004b6, - 0x04B7 : 0x10004b7, - 0x04B8 : 0x10004b8, - 0x04B9 : 0x10004b9, - 0x04BA : 0x10004ba, - 0x04BB : 0x10004bb, - 0x04D8 : 0x10004d8, - 0x04D9 : 0x10004d9, - 0x04E2 : 0x10004e2, - 0x04E3 : 0x10004e3, - 0x04E8 : 0x10004e8, - 0x04E9 : 0x10004e9, - 0x04EE : 0x10004ee, - 0x04EF : 0x10004ef, - 0x0452 : 0x06a1, - 0x0453 : 0x06a2, - 0x0451 : 0x06a3, - 0x0454 : 0x06a4, - 0x0455 : 0x06a5, - 0x0456 : 0x06a6, - 0x0457 : 0x06a7, - 0x0458 : 0x06a8, - 0x0459 : 0x06a9, - 0x045A : 0x06aa, - 0x045B : 0x06ab, - 0x045C : 0x06ac, - 0x0491 : 0x06ad, - 0x045E : 0x06ae, - 0x045F : 0x06af, - 0x2116 : 0x06b0, - 0x0402 : 0x06b1, - 0x0403 : 0x06b2, - 0x0401 : 0x06b3, - 0x0404 : 0x06b4, - 0x0405 : 0x06b5, - 0x0406 : 0x06b6, - 0x0407 : 0x06b7, - 0x0408 : 0x06b8, - 0x0409 : 0x06b9, - 0x040A : 0x06ba, - 0x040B : 0x06bb, - 0x040C : 0x06bc, - 0x0490 : 0x06bd, - 0x040E : 0x06be, - 0x040F : 0x06bf, - 0x044E : 0x06c0, - 0x0430 : 0x06c1, - 0x0431 : 0x06c2, - 0x0446 : 0x06c3, - 0x0434 : 0x06c4, - 0x0435 : 0x06c5, - 0x0444 : 0x06c6, - 0x0433 : 0x06c7, - 0x0445 : 0x06c8, - 0x0438 : 0x06c9, - 0x0439 : 0x06ca, - 0x043A : 0x06cb, - 0x043B : 0x06cc, - 0x043C : 0x06cd, - 0x043D : 0x06ce, - 0x043E : 0x06cf, - 0x043F : 0x06d0, - 0x044F : 0x06d1, - 0x0440 : 0x06d2, - 0x0441 : 0x06d3, - 0x0442 : 0x06d4, - 0x0443 : 0x06d5, - 0x0436 : 0x06d6, - 0x0432 : 0x06d7, - 0x044C : 0x06d8, - 0x044B : 0x06d9, - 0x0437 : 0x06da, - 0x0448 : 0x06db, - 0x044D : 0x06dc, - 0x0449 : 0x06dd, - 0x0447 : 0x06de, - 0x044A : 0x06df, - 0x042E : 0x06e0, - 0x0410 : 0x06e1, - 0x0411 : 0x06e2, - 0x0426 : 0x06e3, - 0x0414 : 0x06e4, - 0x0415 : 0x06e5, - 0x0424 : 0x06e6, - 0x0413 : 0x06e7, - 0x0425 : 0x06e8, - 0x0418 : 0x06e9, - 0x0419 : 0x06ea, - 0x041A : 0x06eb, - 0x041B : 0x06ec, - 0x041C : 0x06ed, - 0x041D : 0x06ee, - 0x041E : 0x06ef, - 0x041F : 0x06f0, - 0x042F : 0x06f1, - 0x0420 : 0x06f2, - 0x0421 : 0x06f3, - 0x0422 : 0x06f4, - 0x0423 : 0x06f5, - 0x0416 : 0x06f6, - 0x0412 : 0x06f7, - 0x042C : 0x06f8, - 0x042B : 0x06f9, - 0x0417 : 0x06fa, - 0x0428 : 0x06fb, - 0x042D : 0x06fc, - 0x0429 : 0x06fd, - 0x0427 : 0x06fe, - 0x042A : 0x06ff, - 0x0386 : 0x07a1, - 0x0388 : 0x07a2, - 0x0389 : 0x07a3, - 0x038A : 0x07a4, - 0x03AA : 0x07a5, - 0x038C : 0x07a7, - 0x038E : 0x07a8, - 0x03AB : 0x07a9, - 0x038F : 0x07ab, - 0x0385 : 0x07ae, - 0x2015 : 0x07af, - 0x03AC : 0x07b1, - 0x03AD : 0x07b2, - 0x03AE : 0x07b3, - 0x03AF : 0x07b4, - 0x03CA : 0x07b5, - 0x0390 : 0x07b6, - 0x03CC : 0x07b7, - 0x03CD : 0x07b8, - 0x03CB : 0x07b9, - 0x03B0 : 0x07ba, - 0x03CE : 0x07bb, - 0x0391 : 0x07c1, - 0x0392 : 0x07c2, - 0x0393 : 0x07c3, - 0x0394 : 0x07c4, - 0x0395 : 0x07c5, - 0x0396 : 0x07c6, - 0x0397 : 0x07c7, - 0x0398 : 0x07c8, - 0x0399 : 0x07c9, - 0x039A : 0x07ca, - 0x039B : 0x07cb, - 0x039C : 0x07cc, - 0x039D : 0x07cd, - 0x039E : 0x07ce, - 0x039F : 0x07cf, - 0x03A0 : 0x07d0, - 0x03A1 : 0x07d1, - 0x03A3 : 0x07d2, - 0x03A4 : 0x07d4, - 0x03A5 : 0x07d5, - 0x03A6 : 0x07d6, - 0x03A7 : 0x07d7, - 0x03A8 : 0x07d8, - 0x03A9 : 0x07d9, - 0x03B1 : 0x07e1, - 0x03B2 : 0x07e2, - 0x03B3 : 0x07e3, - 0x03B4 : 0x07e4, - 0x03B5 : 0x07e5, - 0x03B6 : 0x07e6, - 0x03B7 : 0x07e7, - 0x03B8 : 0x07e8, - 0x03B9 : 0x07e9, - 0x03BA : 0x07ea, - 0x03BB : 0x07eb, - 0x03BC : 0x07ec, - 0x03BD : 0x07ed, - 0x03BE : 0x07ee, - 0x03BF : 0x07ef, - 0x03C0 : 0x07f0, - 0x03C1 : 0x07f1, - 0x03C3 : 0x07f2, - 0x03C2 : 0x07f3, - 0x03C4 : 0x07f4, - 0x03C5 : 0x07f5, - 0x03C6 : 0x07f6, - 0x03C7 : 0x07f7, - 0x03C8 : 0x07f8, - 0x03C9 : 0x07f9, - 0x23B7 : 0x08a1, - 0x2320 : 0x08a4, - 0x2321 : 0x08a5, - 0x23A1 : 0x08a7, - 0x23A3 : 0x08a8, - 0x23A4 : 0x08a9, - 0x23A6 : 0x08aa, - 0x239B : 0x08ab, - 0x239D : 0x08ac, - 0x239E : 0x08ad, - 0x23A0 : 0x08ae, - 0x23A8 : 0x08af, - 0x23AC : 0x08b0, - 0x2264 : 0x08bc, - 0x2260 : 0x08bd, - 0x2265 : 0x08be, - 0x222B : 0x08bf, - 0x2234 : 0x08c0, - 0x221D : 0x08c1, - 0x221E : 0x08c2, - 0x2207 : 0x08c5, - 0x223C : 0x08c8, - 0x2243 : 0x08c9, - 0x21D4 : 0x08cd, - 0x21D2 : 0x08ce, - 0x2261 : 0x08cf, - 0x221A : 0x08d6, - 0x2282 : 0x08da, - 0x2283 : 0x08db, - 0x2229 : 0x08dc, - 0x222A : 0x08dd, - 0x2227 : 0x08de, - 0x2228 : 0x08df, - 0x2202 : 0x08ef, - 0x0192 : 0x08f6, - 0x2190 : 0x08fb, - 0x2191 : 0x08fc, - 0x2192 : 0x08fd, - 0x2193 : 0x08fe, - 0x25C6 : 0x09e0, - 0x2592 : 0x09e1, - 0x2409 : 0x09e2, - 0x240C : 0x09e3, - 0x240D : 0x09e4, - 0x240A : 0x09e5, - 0x2424 : 0x09e8, - 0x240B : 0x09e9, - 0x2518 : 0x09ea, - 0x2510 : 0x09eb, - 0x250C : 0x09ec, - 0x2514 : 0x09ed, - 0x253C : 0x09ee, - 0x23BA : 0x09ef, - 0x23BB : 0x09f0, - 0x2500 : 0x09f1, - 0x23BC : 0x09f2, - 0x23BD : 0x09f3, - 0x251C : 0x09f4, - 0x2524 : 0x09f5, - 0x2534 : 0x09f6, - 0x252C : 0x09f7, - 0x2502 : 0x09f8, - 0x2003 : 0x0aa1, - 0x2002 : 0x0aa2, - 0x2004 : 0x0aa3, - 0x2005 : 0x0aa4, - 0x2007 : 0x0aa5, - 0x2008 : 0x0aa6, - 0x2009 : 0x0aa7, - 0x200A : 0x0aa8, - 0x2014 : 0x0aa9, - 0x2013 : 0x0aaa, - 0x2026 : 0x0aae, - 0x2025 : 0x0aaf, - 0x2153 : 0x0ab0, - 0x2154 : 0x0ab1, - 0x2155 : 0x0ab2, - 0x2156 : 0x0ab3, - 0x2157 : 0x0ab4, - 0x2158 : 0x0ab5, - 0x2159 : 0x0ab6, - 0x215A : 0x0ab7, - 0x2105 : 0x0ab8, - 0x2012 : 0x0abb, - 0x215B : 0x0ac3, - 0x215C : 0x0ac4, - 0x215D : 0x0ac5, - 0x215E : 0x0ac6, - 0x2122 : 0x0ac9, - 0x2018 : 0x0ad0, - 0x2019 : 0x0ad1, - 0x201C : 0x0ad2, - 0x201D : 0x0ad3, - 0x211E : 0x0ad4, - 0x2032 : 0x0ad6, - 0x2033 : 0x0ad7, - 0x271D : 0x0ad9, - 0x2663 : 0x0aec, - 0x2666 : 0x0aed, - 0x2665 : 0x0aee, - 0x2720 : 0x0af0, - 0x2020 : 0x0af1, - 0x2021 : 0x0af2, - 0x2713 : 0x0af3, - 0x2717 : 0x0af4, - 0x266F : 0x0af5, - 0x266D : 0x0af6, - 0x2642 : 0x0af7, - 0x2640 : 0x0af8, - 0x260E : 0x0af9, - 0x2315 : 0x0afa, - 0x2117 : 0x0afb, - 0x2038 : 0x0afc, - 0x201A : 0x0afd, - 0x201E : 0x0afe, - 0x22A4 : 0x0bc2, - 0x230A : 0x0bc4, - 0x2218 : 0x0bca, - 0x2395 : 0x0bcc, - 0x22A5 : 0x0bce, - 0x25CB : 0x0bcf, - 0x2308 : 0x0bd3, - 0x22A3 : 0x0bdc, - 0x22A2 : 0x0bfc, - 0x2017 : 0x0cdf, - 0x05D0 : 0x0ce0, - 0x05D1 : 0x0ce1, - 0x05D2 : 0x0ce2, - 0x05D3 : 0x0ce3, - 0x05D4 : 0x0ce4, - 0x05D5 : 0x0ce5, - 0x05D6 : 0x0ce6, - 0x05D7 : 0x0ce7, - 0x05D8 : 0x0ce8, - 0x05D9 : 0x0ce9, - 0x05DA : 0x0cea, - 0x05DB : 0x0ceb, - 0x05DC : 0x0cec, - 0x05DD : 0x0ced, - 0x05DE : 0x0cee, - 0x05DF : 0x0cef, - 0x05E0 : 0x0cf0, - 0x05E1 : 0x0cf1, - 0x05E2 : 0x0cf2, - 0x05E3 : 0x0cf3, - 0x05E4 : 0x0cf4, - 0x05E5 : 0x0cf5, - 0x05E6 : 0x0cf6, - 0x05E7 : 0x0cf7, - 0x05E8 : 0x0cf8, - 0x05E9 : 0x0cf9, - 0x05EA : 0x0cfa, - 0x0E01 : 0x0da1, - 0x0E02 : 0x0da2, - 0x0E03 : 0x0da3, - 0x0E04 : 0x0da4, - 0x0E05 : 0x0da5, - 0x0E06 : 0x0da6, - 0x0E07 : 0x0da7, - 0x0E08 : 0x0da8, - 0x0E09 : 0x0da9, - 0x0E0A : 0x0daa, - 0x0E0B : 0x0dab, - 0x0E0C : 0x0dac, - 0x0E0D : 0x0dad, - 0x0E0E : 0x0dae, - 0x0E0F : 0x0daf, - 0x0E10 : 0x0db0, - 0x0E11 : 0x0db1, - 0x0E12 : 0x0db2, - 0x0E13 : 0x0db3, - 0x0E14 : 0x0db4, - 0x0E15 : 0x0db5, - 0x0E16 : 0x0db6, - 0x0E17 : 0x0db7, - 0x0E18 : 0x0db8, - 0x0E19 : 0x0db9, - 0x0E1A : 0x0dba, - 0x0E1B : 0x0dbb, - 0x0E1C : 0x0dbc, - 0x0E1D : 0x0dbd, - 0x0E1E : 0x0dbe, - 0x0E1F : 0x0dbf, - 0x0E20 : 0x0dc0, - 0x0E21 : 0x0dc1, - 0x0E22 : 0x0dc2, - 0x0E23 : 0x0dc3, - 0x0E24 : 0x0dc4, - 0x0E25 : 0x0dc5, - 0x0E26 : 0x0dc6, - 0x0E27 : 0x0dc7, - 0x0E28 : 0x0dc8, - 0x0E29 : 0x0dc9, - 0x0E2A : 0x0dca, - 0x0E2B : 0x0dcb, - 0x0E2C : 0x0dcc, - 0x0E2D : 0x0dcd, - 0x0E2E : 0x0dce, - 0x0E2F : 0x0dcf, - 0x0E30 : 0x0dd0, - 0x0E31 : 0x0dd1, - 0x0E32 : 0x0dd2, - 0x0E33 : 0x0dd3, - 0x0E34 : 0x0dd4, - 0x0E35 : 0x0dd5, - 0x0E36 : 0x0dd6, - 0x0E37 : 0x0dd7, - 0x0E38 : 0x0dd8, - 0x0E39 : 0x0dd9, - 0x0E3A : 0x0dda, - 0x0E3F : 0x0ddf, - 0x0E40 : 0x0de0, - 0x0E41 : 0x0de1, - 0x0E42 : 0x0de2, - 0x0E43 : 0x0de3, - 0x0E44 : 0x0de4, - 0x0E45 : 0x0de5, - 0x0E46 : 0x0de6, - 0x0E47 : 0x0de7, - 0x0E48 : 0x0de8, - 0x0E49 : 0x0de9, - 0x0E4A : 0x0dea, - 0x0E4B : 0x0deb, - 0x0E4C : 0x0dec, - 0x0E4D : 0x0ded, - 0x0E50 : 0x0df0, - 0x0E51 : 0x0df1, - 0x0E52 : 0x0df2, - 0x0E53 : 0x0df3, - 0x0E54 : 0x0df4, - 0x0E55 : 0x0df5, - 0x0E56 : 0x0df6, - 0x0E57 : 0x0df7, - 0x0E58 : 0x0df8, - 0x0E59 : 0x0df9, - 0x0587 : 0x1000587, - 0x0589 : 0x1000589, - 0x055D : 0x100055d, - 0x058A : 0x100058a, - 0x055C : 0x100055c, - 0x055B : 0x100055b, - 0x055E : 0x100055e, - 0x0531 : 0x1000531, - 0x0561 : 0x1000561, - 0x0532 : 0x1000532, - 0x0562 : 0x1000562, - 0x0533 : 0x1000533, - 0x0563 : 0x1000563, - 0x0534 : 0x1000534, - 0x0564 : 0x1000564, - 0x0535 : 0x1000535, - 0x0565 : 0x1000565, - 0x0536 : 0x1000536, - 0x0566 : 0x1000566, - 0x0537 : 0x1000537, - 0x0567 : 0x1000567, - 0x0538 : 0x1000538, - 0x0568 : 0x1000568, - 0x0539 : 0x1000539, - 0x0569 : 0x1000569, - 0x053A : 0x100053a, - 0x056A : 0x100056a, - 0x053B : 0x100053b, - 0x056B : 0x100056b, - 0x053C : 0x100053c, - 0x056C : 0x100056c, - 0x053D : 0x100053d, - 0x056D : 0x100056d, - 0x053E : 0x100053e, - 0x056E : 0x100056e, - 0x053F : 0x100053f, - 0x056F : 0x100056f, - 0x0540 : 0x1000540, - 0x0570 : 0x1000570, - 0x0541 : 0x1000541, - 0x0571 : 0x1000571, - 0x0542 : 0x1000542, - 0x0572 : 0x1000572, - 0x0543 : 0x1000543, - 0x0573 : 0x1000573, - 0x0544 : 0x1000544, - 0x0574 : 0x1000574, - 0x0545 : 0x1000545, - 0x0575 : 0x1000575, - 0x0546 : 0x1000546, - 0x0576 : 0x1000576, - 0x0547 : 0x1000547, - 0x0577 : 0x1000577, - 0x0548 : 0x1000548, - 0x0578 : 0x1000578, - 0x0549 : 0x1000549, - 0x0579 : 0x1000579, - 0x054A : 0x100054a, - 0x057A : 0x100057a, - 0x054B : 0x100054b, - 0x057B : 0x100057b, - 0x054C : 0x100054c, - 0x057C : 0x100057c, - 0x054D : 0x100054d, - 0x057D : 0x100057d, - 0x054E : 0x100054e, - 0x057E : 0x100057e, - 0x054F : 0x100054f, - 0x057F : 0x100057f, - 0x0550 : 0x1000550, - 0x0580 : 0x1000580, - 0x0551 : 0x1000551, - 0x0581 : 0x1000581, - 0x0552 : 0x1000552, - 0x0582 : 0x1000582, - 0x0553 : 0x1000553, - 0x0583 : 0x1000583, - 0x0554 : 0x1000554, - 0x0584 : 0x1000584, - 0x0555 : 0x1000555, - 0x0585 : 0x1000585, - 0x0556 : 0x1000556, - 0x0586 : 0x1000586, - 0x055A : 0x100055a, - 0x10D0 : 0x10010d0, - 0x10D1 : 0x10010d1, - 0x10D2 : 0x10010d2, - 0x10D3 : 0x10010d3, - 0x10D4 : 0x10010d4, - 0x10D5 : 0x10010d5, - 0x10D6 : 0x10010d6, - 0x10D7 : 0x10010d7, - 0x10D8 : 0x10010d8, - 0x10D9 : 0x10010d9, - 0x10DA : 0x10010da, - 0x10DB : 0x10010db, - 0x10DC : 0x10010dc, - 0x10DD : 0x10010dd, - 0x10DE : 0x10010de, - 0x10DF : 0x10010df, - 0x10E0 : 0x10010e0, - 0x10E1 : 0x10010e1, - 0x10E2 : 0x10010e2, - 0x10E3 : 0x10010e3, - 0x10E4 : 0x10010e4, - 0x10E5 : 0x10010e5, - 0x10E6 : 0x10010e6, - 0x10E7 : 0x10010e7, - 0x10E8 : 0x10010e8, - 0x10E9 : 0x10010e9, - 0x10EA : 0x10010ea, - 0x10EB : 0x10010eb, - 0x10EC : 0x10010ec, - 0x10ED : 0x10010ed, - 0x10EE : 0x10010ee, - 0x10EF : 0x10010ef, - 0x10F0 : 0x10010f0, - 0x10F1 : 0x10010f1, - 0x10F2 : 0x10010f2, - 0x10F3 : 0x10010f3, - 0x10F4 : 0x10010f4, - 0x10F5 : 0x10010f5, - 0x10F6 : 0x10010f6, - 0x1E8A : 0x1001e8a, - 0x012C : 0x100012c, - 0x01B5 : 0x10001b5, - 0x01E6 : 0x10001e6, - 0x01D2 : 0x10001d1, - 0x019F : 0x100019f, - 0x1E8B : 0x1001e8b, - 0x012D : 0x100012d, - 0x01B6 : 0x10001b6, - 0x01E7 : 0x10001e7, - 0x01D2 : 0x10001d2, - 0x0275 : 0x1000275, - 0x018F : 0x100018f, - 0x0259 : 0x1000259, - 0x1E36 : 0x1001e36, - 0x1E37 : 0x1001e37, - 0x1EA0 : 0x1001ea0, - 0x1EA1 : 0x1001ea1, - 0x1EA2 : 0x1001ea2, - 0x1EA3 : 0x1001ea3, - 0x1EA4 : 0x1001ea4, - 0x1EA5 : 0x1001ea5, - 0x1EA6 : 0x1001ea6, - 0x1EA7 : 0x1001ea7, - 0x1EA8 : 0x1001ea8, - 0x1EA9 : 0x1001ea9, - 0x1EAA : 0x1001eaa, - 0x1EAB : 0x1001eab, - 0x1EAC : 0x1001eac, - 0x1EAD : 0x1001ead, - 0x1EAE : 0x1001eae, - 0x1EAF : 0x1001eaf, - 0x1EB0 : 0x1001eb0, - 0x1EB1 : 0x1001eb1, - 0x1EB2 : 0x1001eb2, - 0x1EB3 : 0x1001eb3, - 0x1EB4 : 0x1001eb4, - 0x1EB5 : 0x1001eb5, - 0x1EB6 : 0x1001eb6, - 0x1EB7 : 0x1001eb7, - 0x1EB8 : 0x1001eb8, - 0x1EB9 : 0x1001eb9, - 0x1EBA : 0x1001eba, - 0x1EBB : 0x1001ebb, - 0x1EBC : 0x1001ebc, - 0x1EBD : 0x1001ebd, - 0x1EBE : 0x1001ebe, - 0x1EBF : 0x1001ebf, - 0x1EC0 : 0x1001ec0, - 0x1EC1 : 0x1001ec1, - 0x1EC2 : 0x1001ec2, - 0x1EC3 : 0x1001ec3, - 0x1EC4 : 0x1001ec4, - 0x1EC5 : 0x1001ec5, - 0x1EC6 : 0x1001ec6, - 0x1EC7 : 0x1001ec7, - 0x1EC8 : 0x1001ec8, - 0x1EC9 : 0x1001ec9, - 0x1ECA : 0x1001eca, - 0x1ECB : 0x1001ecb, - 0x1ECC : 0x1001ecc, - 0x1ECD : 0x1001ecd, - 0x1ECE : 0x1001ece, - 0x1ECF : 0x1001ecf, - 0x1ED0 : 0x1001ed0, - 0x1ED1 : 0x1001ed1, - 0x1ED2 : 0x1001ed2, - 0x1ED3 : 0x1001ed3, - 0x1ED4 : 0x1001ed4, - 0x1ED5 : 0x1001ed5, - 0x1ED6 : 0x1001ed6, - 0x1ED7 : 0x1001ed7, - 0x1ED8 : 0x1001ed8, - 0x1ED9 : 0x1001ed9, - 0x1EDA : 0x1001eda, - 0x1EDB : 0x1001edb, - 0x1EDC : 0x1001edc, - 0x1EDD : 0x1001edd, - 0x1EDE : 0x1001ede, - 0x1EDF : 0x1001edf, - 0x1EE0 : 0x1001ee0, - 0x1EE1 : 0x1001ee1, - 0x1EE2 : 0x1001ee2, - 0x1EE3 : 0x1001ee3, - 0x1EE4 : 0x1001ee4, - 0x1EE5 : 0x1001ee5, - 0x1EE6 : 0x1001ee6, - 0x1EE7 : 0x1001ee7, - 0x1EE8 : 0x1001ee8, - 0x1EE9 : 0x1001ee9, - 0x1EEA : 0x1001eea, - 0x1EEB : 0x1001eeb, - 0x1EEC : 0x1001eec, - 0x1EED : 0x1001eed, - 0x1EEE : 0x1001eee, - 0x1EEF : 0x1001eef, - 0x1EF0 : 0x1001ef0, - 0x1EF1 : 0x1001ef1, - 0x1EF4 : 0x1001ef4, - 0x1EF5 : 0x1001ef5, - 0x1EF6 : 0x1001ef6, - 0x1EF7 : 0x1001ef7, - 0x1EF8 : 0x1001ef8, - 0x1EF9 : 0x1001ef9, - 0x01A0 : 0x10001a0, - 0x01A1 : 0x10001a1, - 0x01AF : 0x10001af, - 0x01B0 : 0x10001b0, - 0x20A0 : 0x10020a0, - 0x20A1 : 0x10020a1, - 0x20A2 : 0x10020a2, - 0x20A3 : 0x10020a3, - 0x20A4 : 0x10020a4, - 0x20A5 : 0x10020a5, - 0x20A6 : 0x10020a6, - 0x20A7 : 0x10020a7, - 0x20A8 : 0x10020a8, - 0x20A9 : 0x10020a9, - 0x20AA : 0x10020aa, - 0x20AB : 0x10020ab, - 0x20AC : 0x20ac, - 0x2070 : 0x1002070, - 0x2074 : 0x1002074, - 0x2075 : 0x1002075, - 0x2076 : 0x1002076, - 0x2077 : 0x1002077, - 0x2078 : 0x1002078, - 0x2079 : 0x1002079, - 0x2080 : 0x1002080, - 0x2081 : 0x1002081, - 0x2082 : 0x1002082, - 0x2083 : 0x1002083, - 0x2084 : 0x1002084, - 0x2085 : 0x1002085, - 0x2086 : 0x1002086, - 0x2087 : 0x1002087, - 0x2088 : 0x1002088, - 0x2089 : 0x1002089, - 0x2202 : 0x1002202, - 0x2205 : 0x1002205, - 0x2208 : 0x1002208, - 0x2209 : 0x1002209, - 0x220B : 0x100220B, - 0x221A : 0x100221A, - 0x221B : 0x100221B, - 0x221C : 0x100221C, - 0x222C : 0x100222C, - 0x222D : 0x100222D, - 0x2235 : 0x1002235, - 0x2245 : 0x1002248, - 0x2247 : 0x1002247, - 0x2262 : 0x1002262, - 0x2263 : 0x1002263, - 0x2800 : 0x1002800, - 0x2801 : 0x1002801, - 0x2802 : 0x1002802, - 0x2803 : 0x1002803, - 0x2804 : 0x1002804, - 0x2805 : 0x1002805, - 0x2806 : 0x1002806, - 0x2807 : 0x1002807, - 0x2808 : 0x1002808, - 0x2809 : 0x1002809, - 0x280a : 0x100280a, - 0x280b : 0x100280b, - 0x280c : 0x100280c, - 0x280d : 0x100280d, - 0x280e : 0x100280e, - 0x280f : 0x100280f, - 0x2810 : 0x1002810, - 0x2811 : 0x1002811, - 0x2812 : 0x1002812, - 0x2813 : 0x1002813, - 0x2814 : 0x1002814, - 0x2815 : 0x1002815, - 0x2816 : 0x1002816, - 0x2817 : 0x1002817, - 0x2818 : 0x1002818, - 0x2819 : 0x1002819, - 0x281a : 0x100281a, - 0x281b : 0x100281b, - 0x281c : 0x100281c, - 0x281d : 0x100281d, - 0x281e : 0x100281e, - 0x281f : 0x100281f, - 0x2820 : 0x1002820, - 0x2821 : 0x1002821, - 0x2822 : 0x1002822, - 0x2823 : 0x1002823, - 0x2824 : 0x1002824, - 0x2825 : 0x1002825, - 0x2826 : 0x1002826, - 0x2827 : 0x1002827, - 0x2828 : 0x1002828, - 0x2829 : 0x1002829, - 0x282a : 0x100282a, - 0x282b : 0x100282b, - 0x282c : 0x100282c, - 0x282d : 0x100282d, - 0x282e : 0x100282e, - 0x282f : 0x100282f, - 0x2830 : 0x1002830, - 0x2831 : 0x1002831, - 0x2832 : 0x1002832, - 0x2833 : 0x1002833, - 0x2834 : 0x1002834, - 0x2835 : 0x1002835, - 0x2836 : 0x1002836, - 0x2837 : 0x1002837, - 0x2838 : 0x1002838, - 0x2839 : 0x1002839, - 0x283a : 0x100283a, - 0x283b : 0x100283b, - 0x283c : 0x100283c, - 0x283d : 0x100283d, - 0x283e : 0x100283e, - 0x283f : 0x100283f, - 0x2840 : 0x1002840, - 0x2841 : 0x1002841, - 0x2842 : 0x1002842, - 0x2843 : 0x1002843, - 0x2844 : 0x1002844, - 0x2845 : 0x1002845, - 0x2846 : 0x1002846, - 0x2847 : 0x1002847, - 0x2848 : 0x1002848, - 0x2849 : 0x1002849, - 0x284a : 0x100284a, - 0x284b : 0x100284b, - 0x284c : 0x100284c, - 0x284d : 0x100284d, - 0x284e : 0x100284e, - 0x284f : 0x100284f, - 0x2850 : 0x1002850, - 0x2851 : 0x1002851, - 0x2852 : 0x1002852, - 0x2853 : 0x1002853, - 0x2854 : 0x1002854, - 0x2855 : 0x1002855, - 0x2856 : 0x1002856, - 0x2857 : 0x1002857, - 0x2858 : 0x1002858, - 0x2859 : 0x1002859, - 0x285a : 0x100285a, - 0x285b : 0x100285b, - 0x285c : 0x100285c, - 0x285d : 0x100285d, - 0x285e : 0x100285e, - 0x285f : 0x100285f, - 0x2860 : 0x1002860, - 0x2861 : 0x1002861, - 0x2862 : 0x1002862, - 0x2863 : 0x1002863, - 0x2864 : 0x1002864, - 0x2865 : 0x1002865, - 0x2866 : 0x1002866, - 0x2867 : 0x1002867, - 0x2868 : 0x1002868, - 0x2869 : 0x1002869, - 0x286a : 0x100286a, - 0x286b : 0x100286b, - 0x286c : 0x100286c, - 0x286d : 0x100286d, - 0x286e : 0x100286e, - 0x286f : 0x100286f, - 0x2870 : 0x1002870, - 0x2871 : 0x1002871, - 0x2872 : 0x1002872, - 0x2873 : 0x1002873, - 0x2874 : 0x1002874, - 0x2875 : 0x1002875, - 0x2876 : 0x1002876, - 0x2877 : 0x1002877, - 0x2878 : 0x1002878, - 0x2879 : 0x1002879, - 0x287a : 0x100287a, - 0x287b : 0x100287b, - 0x287c : 0x100287c, - 0x287d : 0x100287d, - 0x287e : 0x100287e, - 0x287f : 0x100287f, - 0x2880 : 0x1002880, - 0x2881 : 0x1002881, - 0x2882 : 0x1002882, - 0x2883 : 0x1002883, - 0x2884 : 0x1002884, - 0x2885 : 0x1002885, - 0x2886 : 0x1002886, - 0x2887 : 0x1002887, - 0x2888 : 0x1002888, - 0x2889 : 0x1002889, - 0x288a : 0x100288a, - 0x288b : 0x100288b, - 0x288c : 0x100288c, - 0x288d : 0x100288d, - 0x288e : 0x100288e, - 0x288f : 0x100288f, - 0x2890 : 0x1002890, - 0x2891 : 0x1002891, - 0x2892 : 0x1002892, - 0x2893 : 0x1002893, - 0x2894 : 0x1002894, - 0x2895 : 0x1002895, - 0x2896 : 0x1002896, - 0x2897 : 0x1002897, - 0x2898 : 0x1002898, - 0x2899 : 0x1002899, - 0x289a : 0x100289a, - 0x289b : 0x100289b, - 0x289c : 0x100289c, - 0x289d : 0x100289d, - 0x289e : 0x100289e, - 0x289f : 0x100289f, - 0x28a0 : 0x10028a0, - 0x28a1 : 0x10028a1, - 0x28a2 : 0x10028a2, - 0x28a3 : 0x10028a3, - 0x28a4 : 0x10028a4, - 0x28a5 : 0x10028a5, - 0x28a6 : 0x10028a6, - 0x28a7 : 0x10028a7, - 0x28a8 : 0x10028a8, - 0x28a9 : 0x10028a9, - 0x28aa : 0x10028aa, - 0x28ab : 0x10028ab, - 0x28ac : 0x10028ac, - 0x28ad : 0x10028ad, - 0x28ae : 0x10028ae, - 0x28af : 0x10028af, - 0x28b0 : 0x10028b0, - 0x28b1 : 0x10028b1, - 0x28b2 : 0x10028b2, - 0x28b3 : 0x10028b3, - 0x28b4 : 0x10028b4, - 0x28b5 : 0x10028b5, - 0x28b6 : 0x10028b6, - 0x28b7 : 0x10028b7, - 0x28b8 : 0x10028b8, - 0x28b9 : 0x10028b9, - 0x28ba : 0x10028ba, - 0x28bb : 0x10028bb, - 0x28bc : 0x10028bc, - 0x28bd : 0x10028bd, - 0x28be : 0x10028be, - 0x28bf : 0x10028bf, - 0x28c0 : 0x10028c0, - 0x28c1 : 0x10028c1, - 0x28c2 : 0x10028c2, - 0x28c3 : 0x10028c3, - 0x28c4 : 0x10028c4, - 0x28c5 : 0x10028c5, - 0x28c6 : 0x10028c6, - 0x28c7 : 0x10028c7, - 0x28c8 : 0x10028c8, - 0x28c9 : 0x10028c9, - 0x28ca : 0x10028ca, - 0x28cb : 0x10028cb, - 0x28cc : 0x10028cc, - 0x28cd : 0x10028cd, - 0x28ce : 0x10028ce, - 0x28cf : 0x10028cf, - 0x28d0 : 0x10028d0, - 0x28d1 : 0x10028d1, - 0x28d2 : 0x10028d2, - 0x28d3 : 0x10028d3, - 0x28d4 : 0x10028d4, - 0x28d5 : 0x10028d5, - 0x28d6 : 0x10028d6, - 0x28d7 : 0x10028d7, - 0x28d8 : 0x10028d8, - 0x28d9 : 0x10028d9, - 0x28da : 0x10028da, - 0x28db : 0x10028db, - 0x28dc : 0x10028dc, - 0x28dd : 0x10028dd, - 0x28de : 0x10028de, - 0x28df : 0x10028df, - 0x28e0 : 0x10028e0, - 0x28e1 : 0x10028e1, - 0x28e2 : 0x10028e2, - 0x28e3 : 0x10028e3, - 0x28e4 : 0x10028e4, - 0x28e5 : 0x10028e5, - 0x28e6 : 0x10028e6, - 0x28e7 : 0x10028e7, - 0x28e8 : 0x10028e8, - 0x28e9 : 0x10028e9, - 0x28ea : 0x10028ea, - 0x28eb : 0x10028eb, - 0x28ec : 0x10028ec, - 0x28ed : 0x10028ed, - 0x28ee : 0x10028ee, - 0x28ef : 0x10028ef, - 0x28f0 : 0x10028f0, - 0x28f1 : 0x10028f1, - 0x28f2 : 0x10028f2, - 0x28f3 : 0x10028f3, - 0x28f4 : 0x10028f4, - 0x28f5 : 0x10028f5, - 0x28f6 : 0x10028f6, - 0x28f7 : 0x10028f7, - 0x28f8 : 0x10028f8, - 0x28f9 : 0x10028f9, - 0x28fa : 0x10028fa, - 0x28fb : 0x10028fb, - 0x28fc : 0x10028fc, - 0x28fd : 0x10028fd, - 0x28fe : 0x10028fe, - 0x28ff : 0x10028ff -}; diff --git a/res/raw/libcrypto.so b/res/raw/libcrypto.so deleted file mode 100755 index 58f0e0c..0000000 Binary files a/res/raw/libcrypto.so and /dev/null differ diff --git a/res/raw/libssl.so b/res/raw/libssl.so deleted file mode 100755 index 992817d..0000000 Binary files a/res/raw/libssl.so and /dev/null differ diff --git a/res/raw/logo.js b/res/raw/logo.js deleted file mode 100755 index 9071ee7..0000000 --- a/res/raw/logo.js +++ /dev/null @@ -1 +0,0 @@ -noVNC_logo = {"width": 512, "height": 512, "data": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAgAAAAIACAYAAAD0eNT6AAAAAXNSR0IArs4c6QAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9oMEgwBBSD621YAACAASURBVHja7L1pkCXZdR723bz51qrqparXATAgMDMYDEACBElJpgVIHFsmAYIhUBBJSRGSHKRsSyFZCslSBMUlHOGQKcsRdiAoW0uESVkwAVoCgrJpk6AAiS6QGEo2iHUIzGDWnp6e7tr3t+XLzT+qsvA6O5e7nJuZ7/U9HS+6u+pl5s2bN+/5znc2wIoVK1asWLFixYoVK1asWLFixYoVK1asWLFixYoVK1asWLFixYoVK1asWLFixYoVK1asWLFixYoVK1asWLFixYoVK1asWLFixYoVK1asWLFixYoVK1asWLFixYoVK1asWLFixYoVK1asWLFixYoVK1asWLFixYoVK1asWLFixYoVK1asWLFixYoVK1asWLFixYoVK1asWLFixYoVK1asWLFixYoVK1asWLFixYoVK1asWLFixYoVK1asWLFixYoVK1asWLFixYoVK1asWLFixYoVK1asWLFixYoVK1asWLFixYoVK1asWLFixYoVK1asWLFixYoVK1asWLFixYoVK1asWLFixYoVK1asWLFixYoVK1asWLFixYoVK1asWLFixYoVK1asWLFixYoVK1asWLFixYoVK1asWLFixYoVK1asWLFixYoVK1asWLFixYoVK1asWLFixYoVK1asWLFixYoVK1asWLFixYoVK1asNFqYnYLmSRzHjDEW5/07jmNm11rpteLU3/Zdq3FJp55L3WOpYxzp6zZhLh5cpBl7zezf6T3JynyLY6eggZpSQMnP0QvIalD+WX/Xcb+shvtv+hrIei51rY86rttoMBjHMVugvceKtUrmnw2wa0rK4l/E6z2MjEFdFnKV1240G5BlkKTZACuWAbBiGIk3+GWry5rKuiar6Fp1MQsPo2HCUD2LYp+rBCCwYgGAFQMWP2MsngOUHTfE+l/Eay0CSDMN+ub9WbN5AJRW2VsAYKVCxT9nLyCr+BoM1W7OTQ0gZDlKJGvcrODeWM5x8wAY2IJcY25AZnovSv5vQcJ8imunwKJujY0qXrDrsQbMZ14GAxMARjLAQQZwFS7VGtYDq2hdZM19vKDrz8pDKHbBNcz6b3iqXx3Bdouw/u17Vj1QMB3MV0eQYOODBe0yny+xLoAGWPbpF+chp9NM+0SrovZt+l/+fFTxDEwHiFYdI9DcBzuzf1lXgGUArEgCgjl5gRbB38rsu9RYdoAZtqxNMhBVsgGNBABzkLFkxTIAzX55rOU/N5aULfRj1lpnhtfAPDICjc4SsCym3XStSLwgDX5JFsHPv8ibcbqcbJYFzXIs3zILvApLvAnWr6n7jOd0PoywAFnspmUILAB4qEFAOsivoQF/Jv3vsYFrsDl/PxapsuA8K8F4DuejUQrVKvz5EusCqEDxZ4GAhxwMNln5m6T18/LxFwmMV3VPJq4zz8GCjdvvrFgGwAKA+SnwY9oKZQ0+Xx59bt+z+bFcTQT5zZN7oLFpgpYFsAzAw42ymh/lX0XqnQnLj9rSNzFOq/yrZR7ihq7bhwoIFu15Ih0HrVgGYK6t/qy+2g/h82cNGuO8b+Ysw9I1bU2mLcsqLcwmWt9NZBbqOL8SILBBgRYAPHRAIOslaMhzN0l3U56bNWRMVQXqzVNAYJVggAJ8xITjoAJDccPnjIwNsAq/eWJdADUCggUGk4zoXBTn0T2XyaC2vHoCbI6eeRXjZsTjrXtdPpzWpm0jbBmARVbuWbT/Q2L1U1rqTVvXzL5vjWYK4prH1dRAwabWdLCMgAUApRYyA4BnnnnmzWEY/jiADwN4O4CbjLE20SI0cozMeVXGkD5O9hy640tfO47jB74nM09F3y07j87vGWNa1xa9fhzHcBynlvXagPdZ6Gcyx5s6XxRFytdQ/X3653Eca11L9DoUc5k+RuVYE+uB4hjK42fO4wPYiOP4FoDfAvAvn3766dfW19fZ008/XRsIaiQAeOaZZx4Nw/BvA/grjuO0OOdwHAecc7iua2QzpDinSWVcJBQKRmRcIsqfcqyi55YFNZQgqKq1NzvfKvOusvEl15i9rmmAYOIcdYKOrO+XzaWKUtUFW3VdQ+b4KIoKgZrueKjna/a8YRie/x2GIaIoCuI4/l8B/P2nn376NQsAANy6dcu5ffv20wD+Mef8Ha7rwnEcfPOb38RnP/tZPPvss7h79y5Go1HmS1W2sRZZzlm/y/vO7N/pnyUKLtk0866ZPjbvd1nXlrkvznnp+bPuK+/+kp/NKvLk3yLnyfpu3u/SYGH2947j5F5HZNyz1yh63ul7TY9LZC7LGJL0+XRYClFWQlQZmVIYZdec3ejzNv3Zc2WdN/l5+nfp78z+PXut2e9FUZQ79uSY9DnS188bc97v0ufN+s4sSEuPPWsu0ueZPT5vnoqeWR44LJrjonHlrZ0gCLC7u1t43qKxyn6n6DhZxoUxhkuXLuG9730vPvrRj+L7vu/7EIYhgiBAGIa3APwNAL9ZBxPQGACwvr7OGGM/Esfxp/r9frfb7eKZZ57BL/7iL+Lll19Gu92G67q5DEDez4oUMCUAcBwHcRyDcy6knLOUVNm1y5TL7L+T8aQVYlpRFlnJ6fPlKecsJZ6nZLPOV6S0875bBj7Sx2Tdmyjgybp22d9FzEcROBBhK1RcH7qMQVph6NDOWQAkT0FlHRtF0X2KS/XvMgo+rchFlFcWCJBVgrP/zztPFlOTNd4y4JGeSxFlnDXW9PMoGqvInCTjYoxhMplgY2MDnucJ3Z+Isi46BzUASP/ukUcewd/8m38TP/ADP4A4jjEYDKYAfurpp5/+5MMMAL6XMfaZ5eXla2EY4mMf+xg+9alPodVqodvtllLHIsrdBABI/k4Uv8i1yixH0e+XAYAyq7VsDrLOVwYEypRw2i+egIOi+U9b6elxlQGCvOeZsCNFrEMWYCgCBkVrMz1WkWNU4yvqiBmQ8U+nQUCW5V20wYpYgmVKflZ5ySrhLMVbxigUMQxF1yk7Lu/cIiAgOSb9DETmPQsElIE4WTZkNBrh7t27mfcmCiZEAUCZ0qcAALO//8hHPoKf/dmfBecch4eH+4yxP/30009/vsp3thFpgOvr62txHP+dXq93LY5j/MIv/AI+9alPYWlpCd1ut3BSRTa7ogeSdXwWhaNzDV1mIuvaecF3eeOkoHlFAveyxlZmJWeNLY9+z5sL1XvRsbazmI088CByH2W/0w2KNG5NlLBKZeslj2XJOpdO3IvM+ity4+QdRzmfoucsc4mmAVdWPI/uM9bZY2bPyTlHHMc4OTnB5ubmA8Akef46e25d78HsmH/9138dP/3TP40wDHHhwoXVKIr+9vr6+iMPHQAA8Edc1/2zrVYLn/jEJ/Abv/EbWF5efuAlrzLAo+z76YdMGC0qdK68l7YsQEzlRdD5vgygyWMhsuZZ5D7KXBx5ikfWCi8CDlkbsUqGQXqceZ8yUKK6mYkoZllAUHReGWYlC2TJurlE3zmV42TfP1H3FCVzQ3VOlSyF2XfRdV34vo+9vT3s7OwgCILKGS2K9S0qn//85/FLv/RL6Ha7aLVaPwLgBx4qALC+vn4pjuOPXLx4EV/5ylfwq7/6q+h0OkZQpgoIELFcZgP/yiz9MotSRGmmfXazY8iimYt811nnzztH2eIvur+sc+YFvzmOk7uZ5wX/lW2WRTR+ljVZppyygitn72v2b1GWIOv+ZBUGteRZliLKNYvNKWMIZOZABLiVsW3pZ5Q3bpHr5q1lkTigMmZwdpx51n1Z3FDRWqUCAaL3k/Vd13UxHo+xubmJw8NDhGGoxHaoAK06wcWnP/1pfOELX8Da2hqiKPrw+vr61YeJAbjuuu4f9zwPv/M7v4O9vT10Oh1lK1mEnpZNrxG1DmTPn16Asz5AESsj6ztlFrLM/chY6yZoUJ36AkUb4eymLLseRC0/GXeCqKJXcU1VyUpRWE2z1ypiZ4pAtCiAzmOFVBkl1XdAZX7LaGaZdEYTa0h2f3YcB8PhEBsbGxgOh6XPIS/wcB7l8PAQv/3bv40gCNBqtb4fwFsfGgAQx/GVpaWlt7344ov44he/iHa7bbRwBcWxZag6K6jIxLjSedoyG2VWmqLMxlMGSkSjxbNS81SpVdXfZSkdEWtOBehRReM3RUwV1JJlHXSuJRtAnMdi6Spw1WdbxCSIxk6JuI5k51/0fhzHwWAwwObmJqbTqdR7W5clTy1f/epX8eyzz2JlZeUtcRxfe5gYgEv9fr/9+uuv486dO2i1WpVtiKpxAaK5zNRjK0u307mGLIAoeymzXkxKC1ZUoYoCg/RmUpR5kKc4RHzwogGnRR9TVlvZOHSfhYhVLrte8o7LovrTriXR90f292U1QPLWXBaw1qlYSQmiZdhCkXTOWeW/s7OD7e1t+L5fCsiynnEVhbFMv3N37tzBiy++iKWlJTeO49WHiQHodzodbG9vYzKZKE2ybMCersWdRs0qgS+6NNpsnqwqjVg0T8m5ihTa7AZWlNefdY0iv7uopVZWV0E01TMdx1F2njyfcJlySftxZxWSaLxIU60d1fLUZYpPJDhUFryqKNXZuI4itiCL0RLJatBlMETvvwhEiijSLKtbBqil5+nu3bs4OjpCEAQPzFWRiyJ9DzJsXBMlCALcu3cvcX/3HyYGoNdqtXB0dJRpRTZF6nI3yEb61zF3ppWSyXvK2hBF/MCy9G2Zcl8UOlOmyJHoXKlu7mVphDIBuk1QKCpAx/S7LPr9rGd469YtDIdDofoDJue5Ke/c/v4+Wq0W4jiuDAC4TWAAOOcYjUb3LRTZh66zSERS54qKPoi+AKpBbHl59aZorCw6tczPaDq1UFTBigR75VnyRXMu4uvNmwfZuAxTz1XkWtRgSzRmIgt86SiwMqWS9W7LBAGKApOiZ1oGOGXXQwJsRO9d53mqlpN2HAee5+Hu3bv3+ftFnlFTg/6oxnVycpLsM72HBgAA6CdBILovQFW+IBGLMG+BiNDjZceKbI5FQX4i1KSIb3X252Vd77JqOohW1pulg0V9uDIR20UKq6i0c9Y8zY5RBbTpgghdwGDa0krfX15KV9ZmKqPc8uI7VLOHstayyIaf9d2iIkKz4CWLBhcFK1TPinJ/dRwHx8fH5/n9quNIjyWrSVbevBkyYknOM51OE2bq4WEAAPQSVJi1udcBAvK63sn4zESCV1SsBRXrnWJsaSUuM8dpJTp7vbzaB6rPKutnInOSd+4oigoVumjZaJ17aCr4LVtLIuA0r3xsnmVedEyewsjraphUk5v9flKFbrb5D4UFmKyhrAY/Kixjmf89ebfS95EHvGUyr/L2waJzcM6xs7OD/f19pXlNnz8NButkBahAxnA4TM61XNXYmxAD0E9yQPMsSJ0qfjLFamSVrgzVWHY/oi4I1bnQqV6WZaEXvagyc6hbxjfveYqmNZXdk+76S7MaovNT5YamkwEia1HLVt4TeW9E5lXUtVD0PR32QKW+gCnLVDaFV3dtMsawsbEhpfxFwJEIWKasYWFaxuNxci+VuQCaAACWGGMYj8ekfe11ovtFrKl0f3aK8cpGzYuCGhE/PpXyydpAdTY/1bK5onNdVHJXZ+NXUXC6KYLUYED0GqrpZiJAWDXFUBZgqzAbZZX2ZMBF2fNQLRSkEogpst5FxxOGITY3N3FyckJmaYs0HZpHGY/HyT+7VV2zETEAyc3LBGUV3pTrPkC9iVoms/8uK+OZ1XJXNCZApt63SMlQkf/LlPMVSbUqa89btDnmdRcs6r6Xfi55bZnT95PnupjtBpg1/vT3s8oQFz3TsnxwmbbWTRFZhaJS1Kuo41zRXpDuLifSMrao217eNdPXT7fhzWofPHud2fNkXTcrbiCh8mdTR7N+nz5+No4l63pZe2660U7W2EWe82g0ws7OzvneXtZ9Mc9qL+v8mOVWKWthrPqdrDmhkslkktz70sMEAHrJzZcxAKIg4ObNm0KV3cpKgoo0K8kDDaIbfVaZ2rTvswzEiFCgIj0BshRwGcApq+9fBBDyFH/RePOAWVFd/6Jr5s1tkQshK6ZBtPmMCrtB0e2wLoCgWw1TpjVw3oZe5CuWAQDpv9PWeRYAyWr5m8cc5sUHzP4uT+HkzUP6++n6+nmtlEWBU3qNJv8eDoc4ODiA4zhYWVmRBnp5ayALeFEBgLJ5ydJFR0dHZAzEZDJBFEUxHrYsgDiOMRqNHkCoqhub53la6URpel/WNaGSS1vVBq4S/6CavqhCz5so90pdxU5mPVRVuY8KBJSloaq4NnSvLXoMdf17mZ4ZKufQAUt110tJK/zZDIbDw0O8/vrr8H0/NwBY99p5gb1Vx84EQUDGAozH44RleahiAHpxHMeiVQBVqv7J+qDTPmLqVsJl329aUZ2y+RPZAKvsWCdikatY4qL+WJk4gio2aYq5LGOSdK+r+hxlgb6qT71ozKrvh857r9rLw6SEYYjt7W3cunULQRAYUf5ZoK+pxeNUGICz9MiHqxJgGIbwPI9MIckcI/oSVgUCquruRmGJmcpN11VcsiVRVTbwsl4NTRGTDamK4jYoQYDMs5BpoSzCDokaJarMiE5/jLpT32bdZb7vY2NjA3fu3JFmyapa1ybngErOAECnqntwGzCJ/SAIMJ1O0el0tPJRdZTSbGAKxUOtUqGrjo+quqDO88q7vupzUHUHqMyHrHuIMlc/r+CJ6n2naVSqqoQmrLMsZiUvBVWkYRfFGEVbZFMX2KlbEXLOz9v47u3tGbP6y/btpoACXZlOp+yhKgTEGOv6vs9UNp6iRiFl31cpL6lSlEhWuVZZ0EV2fOkoY1llrFKYSFa55R2jG5Mhez2qOadIkxSZe5GWuCoKM+t+RbtoygZJ5u0HZdcs23dExy6zXvOC1FSb3CRgtColmOyhR0dHuHfvHk5OTipV/nlruWoQQL1X+74Pxlj7oQEAALpJG0gdRauqmGV9aVVUJqyrqpuM1alasVB0vnV99yLWuQgbYHJdUNOk1LUpiuZDNvBNZE5VLWMRoFmmxEUVr0j9flUQkMdEiboXqvKHJ+/v3t4e7t27d17Ctm4lvChxAA9VECBjrJvl/zfpQ9el+2XHlhUlWpYnXyWSF7ke5fgo2xYX/Z7iOpT3lZViqTKeoiI9Rd/JG4dI8R/ZCHWVQEiq90A006TIJ6+TrSITE0AVpFrVvpGs28Tf73meVsD0PFjlVRpqZ/PZXl9fr+QmmgAAOnkBgCogQLRrW9VKzGQwFpUSrSJ7oUz56bSRFR2jaL4+VTCibBU9EQWvu3GprhWVyoOyFQupAgpV54sifkemBK1oyeO6xXEchGGIO3fuYGNjA2EYavfysEzAgwyA4zgtVBQIWCsAWF9f547jtGUyAJqkZGWOzav6ZaJWPuUcyqT56W50um2OZQvxiGyyplkEHcVa9buiq9hnrSZZMGAiq6BoXYimr5aBO5XuhRQggNo6Tcq1v/rqq9jb2ystXV43IKjq+tTXmUwm4Jy3UFExoLpjALqO47QmkwnpQi6yLrM6jOlG4cocO9tdro6XQmS8Mv5pCn++zsamwxZQ0K9UBZAoOkFWtYEVdaITeS/L4gF0fPQU4LNonCqxAarvvGpmQ/K95LoUIHYwGOC1117DdDo10jCIEtSm58ika4L63RyPx1hbW3MBVBIIWLcLoMs5b49GI7LFVNZPIO+cVboDimpqm36ZTJSfVW32o9udkNral7FiVBswyVjHVVhSOqyZrFtCt/aCjGUuwmypjJO6wU7ZutOpN0Gxdhhj2N/fxyuvvHKu/JtmhZddc55cApPJBK7r8jiOK0kFrBsAdBzHcURcADJlPsuQet7GVRUIUGkj3LRKcqIblapFRj0fIgpZVOmLfkd209exVPJ6S5T1VtDNP1dxYajGAuicS0eZ667t5ByqHUp19yWdeg53797F7du3pY2WOkpgF7FudZdWF5XhcAjOOUNFHQFrBQBxHPdc13WHwyHZpj9LeZX5p/PScEyCgKxmFqZBgKmKfVTWmer8yVSA0wk8VAFEIhYcRWBgUbOqso1Rd12I9JWXsVRVrXKZe1E9tokgQGbdqjzrV199Fdvb21rroynW97ywAGcxAMDDEgPAOZ/tg6y9mOtKp1N92WT9g6Yq5FF9R2R8ItS5DOgomr+iHHFVkCJjWej0s29qFUnd512U7y/ia89L4dVlUMqUvOw1s3LzdTIMqqgYyBjDdDrFrVu3pPblpsm8BgEOh8Oknf1DAQD6ruuiLAZA5kUoa+6jo4RMLRaTIED3e6IKU2SjVLk/UYpWNjBQt+OgThlqU8WFTKxTkeIysuPMAgQizzCv0l9ZHwjRAkMiFnfR2hZlCVQyZ8pKHsswaEWAZTAY4Pbt20iKs+nG6dRpgc9jOmDCAMRxXAkAaEIQoDQAKLMQKBYDhStAxlKscnzp+dK16kUatFBaOyo1DFS788k0oKGY6yZsYkW1DPKofd1cfVX2SaSypG6bYVHwVuaCogRlqtcoAj97e3t49dVXMZ1O59Yir5JJMwHQB4NBpS6AumMAllQBgCyyr6Ktbx4IoOwoJjo+yghyiuA0qmtSpxSqKgEZv7XJDnmUCkz2mlQBjCpKVrYfgypopPxdei3opDKqZt5kMWyzlf3CMCRtslY3CJiHsczKaDRKAEAlWQB1uwB6Ki6AIqVPTVfq+NyTyFlTjWLyxkdJRRdR+xTxABTKK2+MqhaRTtdCU3Oi++xkFYSuxUVZQEmkrkcWE1BE46uwW1nHiYwt73cq73tZ/RJZ95LnedjY2MD+/r5WVkQVxgSlIVMFWFWRqoMA63YB9HQYgKwXU7VZCfWGqNqYQ6Z6GAVTYcoaVbEK86w0FWpVtTmUSoqgSkMpmbmoulqgaO+AsrWvOl6ZdL0ihV9HYSVZIKnyvlP41hljGI1GuHPnDnZ3d+E4zlwEnZoAkk0CAGdpgIjjeHnhGYA4jvsUAOA+RHMWTFfW8a9KJkA3SEp0fCKBhLrsQBnAEg3ClLmWSpCfbjYC9T1SPa90NcsqwJ5sZobMnKkyM7MAW8WC12Wm8jIR8kBIkTtLpTFZGbguc6EdHR1hc3MTg8EArVZLyR1BnXFRlfXflKZFWTIajZJ94eHIAuCcI6kDQJ2DL9J+tKr62vPURliWahfZVCmUiGmrTjalUPb6Im1rRc5blwWr40MvU4Cy61ml3W7R9XQ6g4q4IEXdBSogoOzdmj13FEXY39/H5uYmptNpknJWudXbBCXcRCAwAwAeikqAPcdxkPQCoGpQIlIRUJUWamoHQcqAP5XxqRRToYryVy2oI2M16ZQdFhmjKM3elGJQWWMuWx9lc0gZrS8LHlSAqKxPXCT2QjUwUCQgOAxDbGxs4O7du/B9P/E116qA67welb6hlPF4XCkAqJsBWHYcB4PBgMzKlkV3pgpyVMk6iLo2KCPoRa3mvPuh8umLBt2pBvaZnEvd7oemwR1FwFyR+0aUFTARqEdt/WVF1stYnTqBgWXz5DgOxuMxtra2sLe3B8bYA++sSoBfk6n0sjE3dezj8Th5Fg+HCyBpMzmLRlXpsPQDlrFKVQOVVOpN510zz3+tUvgoPSc6yqHsdxTZC6JWmWzAHZUVqLM+ZNahKJgqm3Pdja5o7YhY6iIMS5FFphpnkeWnzwMJVMF0Zc9c1BWRRdnLsgDpY13XxfHxMTY3N3F0dFS6vlQCd6ms6SqlqVkAM9UXH440wAQAZC1MGWs5HXlcVYldE0wCRTVDGeucyspVKdMsGyWuGuRXZtVTKn8Z8KUSFyAKPCkKoYj6y0WU6exxImV3i0CNrIVaZqFTMAV5PnnZc+vEBMzOneu62Nvbw9bW1nl+uQlFTZHyWQeAaCILMJlMkjE9HAxAgnryFJXsC1+WJ2sKBFAFEcnQjDJ0FzWCpQje06X7VQILdXL+Ve5TFbjp1jKg3CQprOI80KdClatu8iogQJZFKQvMk1FCquxkMr8bGxvY2dmB7/vn+6vIvagoRh1lWnUac9rd0iQGYAYAPBxBgMlN6+TtZ20mqtSUaptZ3UVkMk2QspJc2e9EN22Z9CyZznkiKYUi35Wlh6lbCcs+56ZSsGWBgqq/k5mfovOLfFfV7aRSLjrLmJF5tpzz8za+W1tb8H3feLxIHZVCqRV2U2ogjEYjRFEUPywAYCmKorgMAJRtcGX+1ipAQFUUmipyle2FrvPC6hRO0rmeDHjQBRq6ykvke3X1hzC9AZeV7JbduFVcArLrgyo6X2WNixYL4pzD8zzcvn0bu7u7Rsv66hoxdSvfNNDWrW5IJb7vJxVkO1XMQ90ugE4URfA8T0sZzSoAx3FI8nxFqXPKkqeyG73sZqnaOEV1rDKKNz3nOoyIaB0DmRiRsmNMdCCUWbcqwah51zFd4CUPBBSt67zvi7YR1mGI8lyKMsxkWUxAmcsjAQF5649zjsFggLt3754XVhMN3qXc43SDTutyBzRFPM9LOjEuLTwDwBhbCsMQnucpWThZ1rAIU0BhUcle2wTrQN0sh9ofLkKB6rbV1WmQIlvWOCuKXYYBoACLIvUCdF0+sqV/VdeJasnfMkVKDch1qwmKjlPk/ctiAhzHwcHBAW7fvo3RaCTFPjWRIapS0iDStLtERIIgYIyx7sIDAADdIAgQBAGJojRRz1rWotAp3kMFAlTuh0r56yplExuKSJU0WeCgQknLKlHVeABTlpRo4R8Z0CBTeCnr5zruF5k1Y6KrIxUI2NnZwe3btzGdTqUDTk3Xq5gnaQoTcMYAVAIAanUBMMa6vu8zWeooL5pXpAENVYldlbK3IseruCpkX2TZzIqq0b9K5oKKG6BszkXdFSaYlzK6W9QS1WVuZAGsbOEfkfmXyaMXpdapLEdZt4eoO6AIHCXuAMYYtra2sLOz0yhFXZUryQTboBLrYSIToKoYgLpdAN3pdKpkOafbOlJ3Y9M9pgnuANFrVLFxyFK1MkyFKPgRmVALygAAIABJREFUyV7Isx5lrFIRa1l2zap2BlR1B6i4AGYVIkWQpSyYo+o3IbrWdAr2qILVRMIwxOuvv47t7W2tuB6duVgky1+1rbIJOYuJeygAQCcBADKbVVGZUZMggEKR61CjospB9JqqVHaRwig6R14QYl77WRErP+84WWAoMw+6kf9FoKNM+Wb5LEWOFf1ukdtBdIzpapyiYxGpZ1/UqlhkjenU/BdZZ6JZH6ogBziliG/duvVAZT9VsKk7dlPWeZVKWCeei3qcnufBcZz2+vp6a2EBwPr6OmOMdZJGQKITn+c3b6pVXyUTkBUgVHeKTZZ1WKbURc8nex6RsaYVV9k4VKoZygITEeVMvZZkmYassao0VtJprCMK/lQDvYpKd1fBigGneeKvvPIKptOpVkZKFWzAvDAPFBUzKWUymYBz3kYFcQB1MgAdx3FaohkAWS8NBW0zzyAga1OaBQFlTUkoqq2pPIMiK01nI876vwy1XARSioCJSjZBmSLQoct1ovhlwYhq+iOFchYFmqprTWb9mw4MjOMYR0dHeO2115RB57xJ1UF5KmnIJqpwnlXGdQEYdwPUCQC6nPN2krOqwgKkO3/J5nVXudB0ck51mABZd4OpIiE69ySrxE1bMSrtikWoWZEMgjIqvQ4RASxVZE2UsQmirhwKACoblJt3vuQ+dnZ2cOfOHeMWson352HJIiBmAFxUUA2wziyAHufcTbsAZBQC5cISiTyXaVFKTWnJXi+Kotx+3yY23KKNWFdhZwXAqQAB2e+oWANFIFS3eZNq4yCZcZgobFVUGz/vXc46RhQIllWGzAK9stkDIp37RNiBsmJB0+kUm5ubOD4+Pn+fRbMf8q6t2odB9Xuy3zVpjIg+zzpjAM4YACeO4/YiA4A255zPtD/U3tx0H4RqNzuZF0C3M5uMwkxShaqgs1RLnMqmPGYpSFFQodIRUCXCW6YToGjr56rArorbQee9LEvpy5vPMqVapiTzUinTAcZUDWNEG/DMvq/j8Rj37t3DaDRSZjeb2ve+qfegWv2QGgC4rosqGIDaXABxHPc55yzLBVD2klMEEVFZQHXVa5dR6jIUv2wQpmqFP5nI76Lx6XTaK7qOTKEglbbIopkbFBRqFqshC74o3Q2iGRQ67oGi7AmR84vOESXFPftsjo6OcOfOHQyHQ62W3qoKSjd7xoq6jEajBAAYbwlctwsAeQxAntWWR8NTInbZIi8mmQOKlz2ZkzzrOa8Fqq41TL1JlKV6qTAxOmOVKRQkqrRMMWCyIECUAlYBt2XUPiUFndcOOI8NMMkEiEgURTg4OMD29jaCIMh041HV6K+aHdDtGlg1k1EXezIej5PnbhwA1BkE2HNdF0UMQHqDEGkbS2llU1j2JihV6kBCiopYOspeJBOhDJCJttotswhlrFXR66vmYNeZoaKSSaBaAlgnS0C25r3oeyoLxmTXX9bvwzDE9vY2NjY2EIahNO3fhDr2Ve+vpq6lm5KqI4PBAJxzxHG8uAxAHMc9zrkQAEgeSvJCiFioVfnbdY5RoWF1FFi6m5gosyFKw+oE/Kn490UyP2SPl1EmsoGGVeVFmwwMVP2ean2P9PPKYw9EAtvKQEFeYF/6urLxB2VGiuM4mEwm2N7exuHhoXB6qWoZYRnDSTaQUYbFU2X/qmYBVAwoHTnLAgAWOQYAZy4AUQCQ9SKWKRiKeACdgiuUFf+orPQkRVC3YqJs7XuVuRABFGUWrMzxujUMKKoqZo1PtcIgJUMkUoiIsjui6BxTuJtEz0nJiiU/cxwHg8EA9+7dw8HBgXSxpyor8zXBQq86M6Aog8WUjEajylwAdcYA9EVdAFkgQMRazLMkZBaAbCS9CnjQGaPpoiBZ/lGTm3BevAIFRavLFuVZiJQ144tASl65XcoNU6ZPvKrlmNfLQ2c8RRH9Ku9oXtaASmxCUZOkg4MD7OzszFp95O+tDGieJx+9acUvw8RQynA4TIIAlxeeAUiCAMsszbJNp2wzrDI7QLUoEXVcQFH8gWqQl4ry11VCIteQ+b5OLYK8dVlm7Yv4h2UrIVL3lEgDSooa8aI1/FXPL8MOlIFbynWT1x9h9rjd3V1sbm7C8zwt5T+PkfjzNOYiEGAC9EwmEziOgziOF7cUcBzHy5xzDAaDwoksUvSyUa26DXaoqtdVCQKKLLMmFObI2ihlAEcRQClLK6NQLGUKpOh40U6COr3o86oGlgFEkTGJKnsRgCi6dqnTQlXApsr7Njv+KIpw79497O7u3hfsR13/Qbfgl+xxVddtqQKgiOyTJoIAz9bEkun7rDUN0HGccxdAFq2alfKnm+8qSpsWVS4TfRFUfUeitH7R+GSsQ5lgNpkYDN04gaziKGXnEXEPlRUK0gnuk12Dqn5eqtoAJhRM0brKeiey5kO1/HNRYaUy6jtvDFlrXyUFz3VdTCYTbG1t4ejoCIyx+wKb8+5fhoYWNYpUXAQUv6e2yE1frw7Xxlk3QKCCZkC1xgDMAoDZxXtGf0gpS5nNzITvVGbDoxqjKdpNtZgOtfLXYUJU8vxVqwPKunxEigDJrg+KSpMm1pls2do0CBPZB0R9+SIxC6qKp0xRuK6L4+Nj7OzsYDQaSQW06ioi2WN1lZ5sVkDVKdHU82eCATg7p/EYgNoBQLoQUBblIhqBajIFT+fYJpQ1pmyfSq28Raxr0eJEs9+XSXnUZQJUQKVsAKdJ0GQaDOTR7HnBe3lMYBnbRpGqp6KU83LHEys/CfbzPE85tY6aCWhC4N6iBA5Syng8Tp7jYhcCYozN3uy5ZPW1F920q/DTqxxLvdBFrEfTLxdFMxqdvPky/75qPW+RwjSiHQF1S+dSFgrSXW8m7kMkJkDUHZYHMijGLbIm82JQtra2sLm5Cd/3hdd+k1gc0xZv00Wlh4iOeJ53biQvMgDoJ2gniz6VzVevG72aisimeAFFF20ZNaoShGVqYxHdSGUt86xjVQPDRKv/ZSk7lYp6qgpZ5Jp5Y6RQLlSNmcqAAyUoKBtT4sbc2NjA7u5urlFTJTOokp1SFbBUvZcq2w1XBdhGo1Gyjhe7F0ARAJjddEx23JOt+1/EPFAGIaqMj8LHn1QLlM2Llw3QpAqqEwECKjELKn0HZOMOqDaUvHiAvHeizCcu071PtdR1GUgrcw2IANa8+RCZA9H7TgcGxnEMzjk8z8Pm5iaGw2FuLYeseAKR8alWCVT5rmqwoAoLp6qQqwo6zApMNwEEJpMJ4tOTLzQAWIrjGJPJpDAgRlTBpi0qKp+vygas833dzANqyovaWpf5vUzpYFXQIMMmyCi0PFCr231OdL5kgJFMqlveMTIlaUU28rzAQFlFWMQOmHLLjUYjbGxs3Le3UQfiqY6f8r6bAAKqkirvw/M8hGEIxthCxwB04ziOswCArDVBcUzVi5RyfFXMHyVVSEHLyrAiotdTyfnOcxFkzZ9O7rwI7W7iPdEtBqRb8Cet+GWemexaUAGz6f8PBgO8/vrrs6lcxkAyJbA2RaVX0VCnTjeASQCARY4BYIz1wzCcDXjIbMWps4gWDQToLFZZumo2G0PUKlYpjKLyoommc+kEzpUpGpFa9WXZBFTVAdPnK/Lv5/n8qaoQlhUKUt1kKYP8qEFA8qwPDg5w9+7d3KAxkTUl8/+qFJZOl8OmKdd5AAVBECAIAgDomB57rTEAQRDA8zy02+3SzVmkZjhFHj51hz6Z64kqPZnvU2xuMuct2vxEzyPb115lI1cZo8i1dFP9ZNeFzBouK2kqCw5lCwGV+fpFwWvaJahSFCYvp18lJiCKIuzu7mJ/f/8+q1+kZoCsa0LFlSETR0BNdVeVlaSSBaar6E0WJPJ9nzHGjDMAtQEAxljX932mkrZXZFFlnU8kfiCr6qDOQpQ9RoYuFLkfqvHJ1ErPux/dFrsy39OtGCg6h6LNqKjcI0XrVpbqFVWMuiBRJC5ARYGlN3sVBZ4FqlViBHzfPw/2O+vhLnQOUeXRFB96VQV7dGIbqpCqnsV0OgVjrG36OrXGAPi+L71RmaixL2OZ1LFIZKhs0cp1MspHtm+ATOUsKuUvC4pUYwHy7k/EHSDDRhSxXKLUvWpMAFUzINGfy2ZZZD1vndgA1WMmkwneeOMNjEaj3Hr+oulqumOn2ldMKlnT91UnUKK+tzMAsLhBgIyxzqz/X4Yuysqp1c0nVVlQVJuvKuqlBCkigYQUdQ90fa5FG6xsrEiZEhFVQjodEXV86mXKWMTNIbNG88YiUklSJGZCZf4pNmVZQBrHMYbDIe7cuQPf95U6f1KseVPKx1TTr0WQqgIOzypGttfX17nJ6zQKAMgopTQIMNHUpGomwFQUNzVI0Q3ek9nEZK8lAzp0I8hFKtapWscigY5FlnoRUBEJCpSdD9HKfTppjqJsju6+ULRe4jjG4eEh7t69qwSyqGtc6M4rFQtQZSR+E0GGiVoAjuO4MBwIWAsAWF9fbzmO004DABGLKA8EmKyapto8hAIEyJT8pWo6JNL+VsfSlrWOsyzbMqWeRZUXHS+6seVdW6XXfZnyzVPaRZu5jlLXZQZEWQPRrATR1Mg8gCPLLBStKcdxEIYhdnZ2sLu7Wxrlr1LumrKYli4IMFUhkCoYuSkgwNT7NRqNwDlvw3AxoLqCAHuO47Qmk4n2w4uiSLp0qq6ipIrKLrJiZa0oqsBFkc1qds5VrHjZYD7ZAjci54rjGPjoa8DTW6D0HLLfv4bWv3wnCUtS9Hx1nvXkwy8gfP8btBvhvWX0/uEfzi3rPfoH/w+NxfLZR9H6t2/L7YRYVlVPJuBw9hq+72N7exsnJyeZLXyTf3e/a4o3//fHpHN767/qYfR1V+geKAsEqZzrwvfE6D4eoX0T6D8Ro3MzRvtG+XHhABi9xBCeAKOXgNGLDOOXGSb3zLKuOvtlOl7GEANgNBCwLgDQdV23dXR09MBDU42ip1LIpo6vMh1RxSIQYQJEFZIoqKGgg/O+V3a9OI7hf+EiOk9v0W4O37mH8FdDuK6rNMay+9PdaMIwRPiuHfIXOvx3q+dlpNNyltNMItEPvQ7/D1bR3r6UqayKsoFklVry3dFohK2tLUyn0weyW9J7l0ojM5G9QCW1kwIklH2390SM5fdFuPSBCCvvU1e+fBnnx1/6YwDOYLm3CZx8meHgd4HD360zZp0ObImI53ngnPM4jrsLCQAcx+GzrYDTeb0qqWpVggCTwIFKKVPSZaKsAwXFV8ZGUFCfjDFEd3oId104V+gUFHohwhvHcHdXtax1USZAVoKLQ8SrHvnajr5+sZClo9wmwz/3IqKPfd8DYKOsH4LMxp1Q/icnJ9jb27tP+Rflz8dxjNjAvkGtmHSUF18GLn8oxNoPR+g9PgOADOyZ7RvA2odjrH0YCAchDn6HYe8zDCdfYUbuTWZ+s0pqU133LK2UwXA1wFoAQBzHXdd17wMAqopJ9RgdNwAFeyATQyBj/amOUbb5jap/nyIeQObZ5tUkYIyBcw7/Syvo/NABrTL8Q9uIfvNSblMl0eJJ1OA1jmMET+2Q79TRnS7aJyvgvYKAZcprPjLC9D98HZ1//9bSuVQtEhSGIQ4ODnBwcIAwDO/L8S8qomNKE+q0uqYCDu0bMW78ZIDVD0VmnmsZ8FgCrvxwjCs/HGO6Cdz9JYa9zzja+zrVnFH2mhiPxwmLaDQGoC5Opcs5RwIA0r5l04Ug8h5aU6XM56ei7Kn6oyfjK0qpU8nzFg34EylTmhUkyRiD67qIXlpBfLaPkX3ec5A7H2WBfqprQqTkbxRFiL5rj/x+o3+/Btd1CwEP+TU/eAfhpZEQ01M0R1nHB0GAnZ0d7O/v3wcghdYn6O+1bO2b7lHPl4G3/IyPpz41xeUPRfTvi8KndQP4jp+P8V3/6pSJoNzjVMASZR0Z4DwIcGEBQI9zjtFopE13USz4qnsGUKX7mUpfVJlb0WJBIpXaZAISVcaafMdxHLBnLyMaObQb9toUwYVhqdLX2TRU+qGHnSnix0/IN2Pn1UvJZpV5fwktTvrphfB+4gXhdSSyXhzHwWQywdbWFpL4JNEGQuf3auBDzZDJHLP2YwHe+SmvMYo/Cwi89edjPPGPQvSeqNaYMwkwEgYgjuPFAwBxHPdc18V4PCYJblKhROtuHCRTyU+GUlJJ2VPJp88bn2xN+TKlr6r88yL/s1gA/8vL5FtT9F17mbUqisCAaHMglWccxzH8d26R32e856K9fT8AyH4mBrb/x48wfWpLaV/IsqaHwyF2d3cxGAzAOdfIujAJAcTfYx1Q0L4R422/6OGRv+6DLzdR9d//WXlfjKc+HuLmXwor12cm2IaZ6pILyQAscc4xGAxyI2dly8+KVuMqa4gi03ZXdoxZCkkFeMj2T5C5J11LoqiOgU53Pl3lnwYpyf8554i+dhFxDNJP+Ie2EYahco0GmTz+WeCV94njGMG7d8nvM/raqfJP6P/8SHUY+fh/5kWEnWlh0GRZpULHcXB4eIjt7e1Z6lUoCDUbaNJ+ADM5+Xly+YMhHvvlCZbeGxl7bqY+N34qxhP/cwi+XKlBSw4CRqNREgNgNAiwLgDQz3MBqCoIUepXxEIVaWKiS91mHW8qgl/0GmWV5EQBRALoZCjYdPBW3r91lH+WcM7h/MEq4hHtq8DePEbc9aV90HnsiMinaB2GYYj48WPyF5n//nW4rlt4n0alF8L7kZdya1MU0fgJaEn8/UEQnFv+ZWs3f52Zp5spu4Cmf3/9r3l409+dgi9hbmX5fTHe/WsBuo9FRtefTgE2EQCw0DEArutithCQSHtRVcteRVGn83vLHrSpYELZ8qwmNhWZZ6D6/bIGO6pBhEWgK5nbVquF4Cv0wYD+u3aVg011XWNpBew/tY24F9IG4u210Nq6eJ/FXFUQ4Own/EPbmL51T6rhV5Lml/j7ZVN0CwFzxQ4A3QqBjDHw5Rhv/nsTrP1YiOYT/gJxKcvAE/84woUPRMaUmMnMjPF4nGSeGOUy6ooB6DuOg8FgILzJUTT+MF3CssrgQN2yxipsgywbU1QUhQo1i9KyRWzQuRuAeBMKvnNXOkdYJmNClFGIogjTtx3Qb7Rfv4RWqyXU/8D0hu/92RcRdf3COUyeRRLst7m5eb4H6QJKk/dJ/c48oASWIjz6sQlW3h8thPKfBQFv+wcRLv+wORBgan+biQEw2gugrkJAD7gAdPKfRdC7KP2fZyXKHlPF4pLJH6caU1FFMiolLlr2VsY1UEhjcw7+jTVEwzfA+oSbxeMniKIo16csMlZV/+LsHEZRhODde+Q52/yL188p87yiUN9mQAzvKJc9jJ5+Bcu/VVyGmXOO4+Nj7O/vYzKZ3Df2ogI/RSzVg6WHq1EwFBansxThLR+boPNYjDnIiFaSR38uxvjFGJOXzaYFZr1/qs9oBgAsZAxAz3EcoRgAUcvXlNKtok2varMdCtZBZS6LWATZQElV4KIKCvK+02q1EH11hXiVh5g+tV0aQ0HdeCV9jH/9GCCu/hfvtdDZufQAuDHdqrZIwj+2Af/6UebcJpb//v4+dnd3z5W/6vuQ+zxRDfiXYSXyfh/HMd7ysQm6jy2o5p/F4v8oQvdxM/dZZJiqykyG3OK5AAD0Hcc5LwREofTK0JZusxyKY2Sr/1FZ2mWLU7XQTtF3RAL/KDYz0WDBom56juPAcRzEX79EHwfw7l1h0FpE6acj2UW66SXWv/fUFj0t/exltFqtB9L/8hqkVEX7jn78W5n+fgDY29vDwcEBfN/PrQ6psmZN3ysUAndF9okbP+2dWv7Awn+cZeAtPx8Zyw6QaY4mCQAWrx1wAgBGo5Gy9SvaNlf3Ycj6v6tmHnTGp2qZq1wzzRpQK39dK4pzDvcba6dFgSjTAR87zo2FEO0mphpNn2RkTN9Fn/7X+v3rDwT/Za2Lb8c/VJMGFj0ywvDpV+7z9ydtfI+Oju5rWERpTZ8bITCRBqjWY6PomJUf9HHhB8O5S/PT+XQfB970c6HRPTurDLVlADLI0eQmq6KtKRSxKlOhuoHLghzdEsq6Y9QdnwyNpur3L9r0XddF9JUVxJR/Vr1TCl4RhIkUrCpiAoKLI0SPDGnvKUX/Z40lPc64wj/e+9+Af2EI13XheR62trZwcnJSysqVvQuiP6O+n3Twhq4x034sxNW/5lX6TJry58IHYqwYygwoiyeRBQBn51jINMB+cpOzHbZ02gCbUI4U51EtFqRrpRfRzDr3I5tzn75eVnU80XtTDfoTmSfHcU4D2p69RL7Yp+/aKawKmJfzL0I5lqWmTt66S7/RPXvpvPZ/2WZYj3kRYvhjz+Po6Ajb29vn/v6qy+g2QbLe9yt/1YMzx3n+uvLmn4vgLDU77mEymVQCAOrKAlgCTnse51EosgpStBIgxYuumk2g89KauD/V9stl1JfufMh0EKQsEsQ5R+ubV+CPXgd6dFaC/+49RJ+PcsvliigV2a6KCdiaPrVDHt3d/tL10ntJj7lqLBC8/QiDJ19G8IULmZH8IlH/qhYf9b3OugGyMhJk2h2v/KCP3nuiyp7H5GVg8BVg8hLDdCNHGbwvRvcJYPl7UEkFP2cJuPpTEbb+J053zhm3EkVXwDMAEC8qAOhFURSPx2PmOE5mb2UVEKBrLcscIzPOohTEKi0J1WpiIj+XTd0ratMrMm7V3gBFIMBxnFPa+IUlsO8+odvA3zRCcHGE1uiiELCkWhNBy4P/7n3aRbTfRm93FW5fbuuow95q/4U9BF9aAsY8FwSk3+VZhZ7H0GTtNfelPBp+h2WBy/n9LEVY/U99488iHAB7/xI4/C0H/mZ+fEgio6/F54D10g/HWP0wsPQ+s2Nc+4kYe5+OEWwyo89IlQXzPA9hGIIxtpiVAKMogud52l3R6pQqU/ZE/Oe66WSq3ehUJatkcLEVKW6ZqQQLJkWBmIFsgMlTO6SlQ0VcXuNHd+mjqZ8tr/2fBwCq/qAfofWXt4yU2s4DlCbug8J1wRjDhT81Bb9uNup/+58xvPRjHLv/3EW4zU9rbJytl8TNNvtJ/+z4X3Pc+i8dvPbTQDAwuz6u/lTUWN2SAAAsYgwAY6wbhuF9pYB1lRF1LjWlYq4KBIgeU1fNBN1cWZViTrKuAcdx0PrGGnkE8vRtB+f16vPWb1mtAJn6+lEUYfLUNvl9ZNH/Yg2L6vm43zuG8z0DJQZJSdHCQMYDAcMXxzGWfzAwNs/BCfDqTzrY++cu2MS9T8EXrdvZ380CguHvcbz4UYbBV8ytjYsfjOFej6l0Gi2LEobwfZ8xxroLyQAEQQDf90kt0rqYA9lIdR1L0EQDCtFIcxVXgMgLIjJ/eUyAbnpU+njHceD6HcRfWyEuC3yAsD2VAkUq7oBZqnX67j1aizqh/0/7lMs94xo/rb+wh7gbCDFCKlkBpsseiwLZIun/CXPW//hl4JUf5/Bfde9T+koK6exYx3GAMcftv+7g4DPm1sbln2guC3CmHxcPADDGumfohszqpc7XryvKV6iuOmHOv6ovPe/fIk19skr/Uijv9DhkNvj7GIBWC86zl8hTkCbfsZdr8YsUo5FZQ5Nrh4i6Aen4nZno//R48/7/baVY3x92NQD/6H4pu1K0Rsv2hPO1bOCPzN6U3Z44Ru+P+kbGFg5i3PkbLjDmD6wL3TWcuA02/r6D4VfNrI2LH4pIdIZONdc8OcteWbxCQIyxznQ6JVXWuhZiE5gDUYo8K9K0yoVJQe1nddKStipz5k+2j3v6Z47joP3NK+TmxuSdO1INklSBXhRFGL73Lvn4u1++kVn5T+i9rLkUXOuDx8CTQ6Hnr7r2jd2rBFjPHONShP73h0bm9c7fcIGRI2z1y85xAgLu/gyHv0E/fmcJuPDByMg+qKt7fN9fWADQnU6nUqVxZQDA7DG6xXF0LWzq43QVuk7p0LoyFmSpWxXln9502kEX+NoF0v1m+p17hfUAqCQIgtOgQ8q9cszR270M13WlXRam2wGLftw/v6e17oTfaTP6X+k9ZYyh+/2+kfnc++cOglvueUMoU/ur4ziIRw7u/YKZdbT8gZjUOKICAp7nwXGc9vr6ujEQUDkAWF9fdxlj7aIAQFlFmbvpNLB8ryylT60cqAMJVQr5iFq9usFZKkAh2XBc1wX/g8u0ZWo7IcaP7pG2Bc6isv0LQ4SXPNKx8xT9L/vcmlAKlj06BfvIrtRakH0PTZU9Vn0P4jhG7/vpg//CAXDw8ZaWv1/arfV1jpMv0M/v0vtjOMvm9ledjoCc8zYM9gOogwHoOI7TSooAyRbUMYncKRdAWQAgJVKmTkdUjdbPDYoiqJ5YBjiKeg0ovRiOg/Y31+ib1Ty5VWoty6SgZbm/hk/SN//pPHflAeu/DATU0Qyo7MM/eoh4dSrMKolYc6bvU2d/iOMY7fdG5GM6/q1y2l+3ZHH6Z47jYOcfOkbmuPfd+m4A3bLqaZlOp3Acx4XBQMA6AECXc96SZQBErNG87zaJCdBZGCqR9Dr0YR6jomshidDyCQhQ6YooEtCV9/vZOIBO2AP7Oq0bYPLuvSS/9wElLvN88r4bhiGG79ugVUBjjuWXbhbW/i8qkNMUF8B5LYP/YlvJTSRcrwLVZwHk/d59ewi2RB/9P/icW/lexhhDuO1g8Az9elr6AG3w+Oz+pSpnpfK5SQBQRyXAHufcHY1GWpR0WdvaOosJyearZ1UkU41DkFEiugtUlonJu78iF07WMVTXKGMAOOdwn70E7z1HZPMTXprAWxmiNVHrOVD2zPyWB//GgLQcXesPLp1mRsxYfLoBm3UKe+cY0X+yD/ZvVguBrtrPzN+rSDXApBOk+7aAfDzBFoP/igPOWemYVI2kIhBw/FsM/T9Km77Xfa+ewqZuBwycZgFwznkcx4vDAMRx3OGc88QFoNosR8RXrFpFrgomwJSyzZuXIpZEtfSyCljR6agoQ3vqUHaBJoNSAAAgAElEQVSzvQF637pKbm0Mn9zUWmtF9zd4x6YR+j8r0EvquTfsw/7UAeK1qfT6EFp/qM4NUCb8Oj39P/6ao1R/g2qfHT3jIBwSu4ZugCwOIG2QKN/naJS43RbKBdB3XZcNh0MyBSu6MVVlhVC0ENZ5YVSaFZl6WcteChF6vyh1Toa6ld2wTrMBenC+foE06Gj4vk0EQUAyn7OfKIowfJK2+h9GHCsZ9L88aGzWB70I8Z/LLs+spdwMBAFqsTfvCcnH47/CjJezLquKOfhd+nluPRaR3o+uvhkOhwkAMNa7sa4YACQuAN3JylJ2RQqw7DomQIJs9T6KMcjWQqCKIaBkAmavF0URabCjiHWXuAFa31gltTb8m0P4LU85jTPPugjDEJO3HdCmzn3j8jn9XwZC5okBiAGw7x0hft8J+Zo3Zf3LFu2K4xgw4P/3X+Fke4Bq7YXRM/TBgN3vpt/7dfbMszRAwGAWQF0xAA+0AtaloykWHrWlqwoCVGre644175plft2sjn5551dF/ulNTaQaoej5yjZSzjmWvnUVI7xGOu+Dd2yh98LbyTaQOI5x/MQGom5I+7I+f+W8vGvZe1dEeza2vdd/voP47yyB5XQMTL8beV0Cjd4re3BvyNovsp6H+/aIfDzTZzkcRz/1WidV2/u6g/HXIqXZjnOmOIZ6HEDWutDdvweDQVJ22xgDUDkAiOO477ouBoMBGSrM68Es286XQulStRAu+75QWdKS61Gk6ci2sM0qA1ykuEWfUVEgoUp740Q452hPenBeXEb4xIAOADy5jbXnvyMzsl5W8Sf0/8kTW6R93tmY48JLN8GXeCbwKnNX3e8KaygA6EWI/+QunH9x7dsZCxpKLDZxr7GcAp0NoKUeS7jFpOdJVdEX3t/IwfbfcrViyNIg7/RDt/fr6pOzOgAA0F84BiDtAtCZONWodhNWtgrwqHKMIm1kVVgY2bQpSqZCJlhLNp0q6VLW/sYljJ44IXsO43ftIvy1UNu3nsx/FEUYf8d+Zu14Vel849J99L8MCEj/Pm4uBwD80BGiry6Dv7iUafHLauum3Otp+h99BgCFBU+xH6TXJUUWAtVeRZGCfpYFACxYIaAe5xxldQBEJ07Xkq+yb4BoEJzqXFAdr0JhqY5RFTio1FpQUf4JC9B//ip50NHxE5ta8zb7GV05REBc/a///NUHov/z8vzL13yzP9Ff2hLq01DqPqq4CmDRWPjb6QMAg43izKqqy4XnNaJS/VAZVxTnGwwGCQBYNjWHdaQB9jnnuS4AFaWS9k9WEUegamGnrykDdEyAERULPO9nKhUGdccqk1GgCvYcx0F3sAx2t4cIIPscv2OzNMNBRKIowtETG6RjiyccF195pLD2v+gzYoyRjs3I50qA4CN7hWmnQoF3BsYWK+5pcRyTjyXYYkoMp0lgYKogUd1jG4/H4JwjjuOFcgH0OecYj8da9HLZJl9HGWDVtBYZ5kDU4sqax7xIbp25Fx2HaB+AojHKNgPKC8ZMriH6TBI3QPeLVzD40Ttk62X01kNEUXSfG6DIvVEEAE7O0v/IaLpvrD5Q/CcNXPOecXY9dDRe4o8cnLoC3ujlUrp51Pf9tK+5/SXLd5317yrmXSYgsWlC3T6+aL9R3h9Go2Sv6i0MAwCg5zhOYQyA7CQ+EIijGBTSxOZBlAtKtm5CeqMXdVfo5OWbLPxTtEGVXSfJBqBMOwouexhePRR+TrmWwtIJvBtD2tKo37qaW/xHBJA/AO7m5OP/1Ja+yw3NKAJkYiz+sxyLIFXu9apG1AwAMMYA1FIIyHEcYQag7IHlWalVteelRtBVgQDdY4oUtG48gE7zIFHgIFsxkXOO/nAF/G73LMyL5s/Bd72h5QaI4xiHT2ySjgkTB5devpmboSADzL+tiObjT/SoB/9P7Atn0GStHfpRqb1LztvDBoxETzk2maKXYV9VrjMej5PjFssFIMsAlE1k3gYuWxtf94HpbOKyQSOqmRJV3Z9uZkAek6CS7pe3TmTmISkK1Pv9qzh+5HWyeRo+uo8wDDPdEiLjC8MQg0f3SKne/gz9LwLWROZ9HlwAifh/ch/8q8vg+x1psB4DlRQ9EBpPPyKfd8ac0nGI9CqoW6pyAcymZGoAgIVyASwxxqQZgCxrT9QaVan+V3VgYJLKVXZsWkGodh4U7VaV7m5Vdl4KMKVbI1+3+E/ezznnWCZ2A3g3h5isDHMBYNkz9tseBu/crYT+V3lWjuNgOBzS0/Vf6ppzBfQjeD+5Wdp0LI8FIK9YCLXCVibmJtqmNxxMlxWukgUQNWREZKZY3kK5ALoJuqFGw0UbZdVUuwlUb6LHQRVd3WR99DIAIr0Jy9DpIlZAuijQqRugR5padSSQDpgHUo/etEM6FjbmuCxA/4uMMY5jHB0d4fj4mDwdjX/uIvBcx1haYPjkBNP3HisAawMfVcVlIl1yy6klwLpWJsUAIysio9EoGdtC9QJYStEb2orLZI19UyDAdOtUUzn8oi+MqiKXteyzhCK1Lm+Mruti6Uu0LMDJmRtAhuFInsPRE1ukY+l9cxXtdls6YyT9nKMowuHh4Znyp69Hz7mL1r+4ajQg0PupbYTdQJoJaUoQoJH+CZpdAFX2n0UAHCouh8lkknx/sQoBxXGMyWSi/WCTySxL69KxeOtgAlQQpW7J27LfU1D7ukyAjOSBAF3gxTnHhReukVpVJ0/uwm95hXORNe4wDHH0DloGYOn2qjD9nweQptMp9vf3MRgM7kuNo/w4joPu5jKc/+OiuQJBvQiTn9hWCEqlLwSkHu9jvigRdfrbvCt5WXa6yAUQRVHMGDMWA1BLKeA4juPJZMIoqJOs9D+ZALMmo0sTZYOpO/qpgAAZ61KkEZDKz1QAUlIPoDdYBr/Xg//IiGwu9x7bwJteeky4xwMAHL5pB0HXJ11zl16+Ae6qpXol/v6Tk5MHmn2Rt6Q5Axv937yG4+8ZIX50auQdnP7RY7j/7gLaLy0JMWGxgXsVib7PrAFgYt5BH8xXZ3Bgk4HKZDJJmMHFiQFgjPXCMITneUbay6pU4hOK7lWkqahYjnld0CJAq6wUr+g8ilYmTJcPFbnG7PdbrRZWvkxbGvj4LbsPsBZFmSFxHGP/sQ3a0r/fvIxu2FOi/x3HwcnJCQ4ODs7LfJu0RBk7ZWM6nQ66//sVo2WCRz+5iagXCq9R01a36JqNaypLrLLv1WWImUwD1C2V7HkegiAAFswF0A2C4D4LQVdpFdUqb6JyNV0qUyQ+wkQ5T1FlX0eMA+X8cs5x8YVrpL7Voyd3pWIXgiDA4Tu2Scdw4YVrcF1XiW4+OjrC0dERgiDIyY2n9ouzbzMyty7C/dwFY7EA0VqA0Y/sCGcfmYoBUGoUheYUJWo641qF8SO7F/m+zxhji8UABEHA0kFPOkpBV6lU0fRGF9So5LibRMmqPkmq71OAN1FXUfp759kA+226qPNOgP2bW8I1IUbLA0wvTkitu8sv35CK/meMIQxDHBwc4OjoCGEYFjAWZixRx3HQarXQ/82rwI5rjAXw/uMj+G8SLV9en+X9gPJvwDh098+q67JQShYzLTMH0+kUjLHFYQAYYx3f98kWx+xmWVWUv0wfbBNWfRXjpLgeRR550XekKtFp9A3POq/rulh6bpXUutp/YkvYHbX32AbptfvPXUYv6gvT/5xz+L6P/f390zz/kiBUE5bobH2GbthD75+ZzQoY/uSWkDKqy+rOfI8JP+GtOgjj+bP4s4xTlRLnMwCgvTAAAEC3qBWwKghQPYfJcrzUbMEi9ipQAQ0mWAPZjoOO4+DS126cv9wUn8MntoXSAcMwxM53vkF67YsvXBWm/5NKnnt7e+epSmXAgXKsWWvGdV30b10E/0qP/FrJJ3izh8GHd4RqNpi6V9l3i/QzQC2imnrcRHAg+zzPYuW66+vrRgL2KwUA6+vr3HGcTjpCWFeJ6PRelm3Lq2qB1rVIVVvgqr5oRS+rSq1skYAnGXo/q+KiSm4z5xwX91fBD9pkFtb00gQnawel68pzJxhfH5Bad6sS9P9wOMTBwQF83z+tOS/AGpiwyNOgpN1uY+XjN4GxY4wFmPyJQwSr02K2ifo+JTJaHlA4aI7/v+lKukpjSlTfeJ4Hx3FcGAoErJoB6DiO0yoDACrKX2WCdXPNqaxy3RiEMiWpa2U3lQmQjeTXWR/p73POz90AUQyyz8GbToMBi5pf7bz9Huk1l55bRS/qC83d8fExDg4OCv39WUI53ijOB2WdoIveL18lv17yCbsRjv7iRiHQMXWvshI1aCxNZSyprXxqgDOZTMA5b+Osgu5CAIAiF4DswyxLlSq7RtUggKrs5Dy8XFVmWagAPtmywVkgYO3rj5BaWdvfdfd8XFn3FEUR9h6nrf43S//nzWMURTg4OMDJyYlSpcUq/OLnKZrPrcL9at9cy+AnJxj+kYNa77VJ805l2VPUMGkiw6AzpvF4vFAMQJdz7ooAAJVNXSWYjaIRUBVR9xTKVbvPuUIlPxl6Pj2Pspa9bC0IWRCQBo2nboDLcAndAKPrA3juJHfOwzDEwTt2SDf1K6/cT/+nrxkEAfb29s47eJa5a0wHoxUpoyQr4MKnrxl1BZz8md0HygSbSnlUfWtNjqHq5jsie+wiuhfOGAAnjmMj1QArBQBxHHcdx3FlGgGJKB2RACTZRVMnnSR6bQqFrNOylyoVUHVDkNkk8ioDJnXrZYDlbAlq13Wx8twqabDVzts3MitcxnGMrbfdJb3WSk70f3LNyWSC3d1dTKdTredMHhgX51+Tc47eyRL6v37ZWEBg1A1x+Bc3MqvvmbzXsvf0vrmIzQUkzntQnqlx5hmhecXHRBgAzrkDQ9UAK2cAXNd1ZDsBlilwU3miJihs6nHWEbfQlCwLymNlewck1+Cc48qzN0ktrd3HNx8YTxK8uPvYJum1Lr2YH/0/HA6xvy/WqKgpVHTyzFzXxcXfvQr3BXNtgyffPcToPceV3KsSu4lmFSVqkvFUtbGXBk+i8zcej+G6LrAgLoCe67pKrYDLLDsVqr8uEEANEmSj7qsGAVW8mBSxHLLzH8fxeTaAe0DXmnb/iZ1MpRuGIQ7fsk9a2OXKKw+2/mWM4ejoCIeHh8rz+ODzqKYgzWyaZqvVwqWP3zBaJvj4x3cQdsOU1V3tvRavUcLPu0MSJWBa4dZZVli0q6noHIxGo4Sdm38XAIBekkNMtXBE05DmDQToUvumFazqNVXATRUvtGqucRJ4duF52qJA22+798B4jtYO4F2c0JX+fX4V/RT9H8cxdnd3MRwOaS2gmliA3skS+v/3ZWMsQLAW4ChVG2BRYwDiCvezRZI0/S+zbyYMQBzHS3MPAOI4VmYA8pSOrAuAGgQ0KYagKY2AKPL1Re+LusywbLBkAkCv/cEjpNbW9ts37nMDRFGEe0+9Tlv6d4b+T8r67uzsCPv75dZmdQ1y0uDs8m9dA3+9bYwFGP5HRxg/Pkwu2pzyuw0pSVwlM1k36KBuLT8ajRKGbnFcAAkDoKuMVa1DShBQdK6mg4CqshdU62Dn3ZdJK0GFUeGc4+LeZbiHbUSIST4779i+DwCEYYj9N++RnT9CjKuvntL/jLHzYL8gCIw0vaIcd5Rjj2YFWSUFgi7/b9fJxzD7Ofjx5HnFldyr0BpmJuZd7v2XZQ51g4VV9jSV7KGqZDQaJTEA888AAFjmnN/nAtBVCDoVAKt44PPABJii8lXYEVPWgclMkCQb4OJzq2SWVtAOcLj67Vzz4fIAw2sDsvNfPKP/Oefnlf0ogv3yARXxR+L6nHMsba1g+f+6bIwF8N88xeGHd82cX3WtN5QBaNp+q+NGVQEwMnpnhgFYjEJAnPMHXAA6IECn+pJSQROFinWU7Y6bAgLiBu0GTLBUqm6cRNFz4Jxj7SXaFsF3n3r9vCrg5tvukZ577aVraLVaODo6wvHxsdK7IMlG1+aLPg8I/J0rcPZcY/EAxz9yAH91avxe6ygDbMsB0+2JMvtQEgQYx7GRNEC34gnqpxkAXYtcl8bWZQJEj9e5jo6rQwYg5V1H93jql0wFSYuMUSeegHOOtXtX4Yz5/VHhGrL/5r3zkrv7b9ojtcAuv7GGw8ND5HXmpH9uBhCFJAjo+l2sfvw6tv/WXWP3efRnD4zdqxq9/fAp2KYYIxRyVgcAWBAXwFIeANC1QqvMG591P+jW8a/6pRENUinz21MFP6pU91Jt4DRL9YkyBElQoIjV1Wq1cOlba2TW1uDaAMPl08qAu0/QVf/rbvYR3A2NBPs1hQHIytZwXRcrty5g6bcvGGMBol5UebZD7vs4ZLUzAFVXSMWCjXEmDdCIC6BSBgBA13GcwiwAWSvyjB4htSxlF42M1axiJetWypu9Ztn1s7IqZCxulSAekXayWeeogrlJvhtFUeEYE1/z2ktXsfPebbIXZuM77sH1WqSW3Mr/exFRFAl3/6PYFKmxr8rpElfAlX99HcPvHyDqRZgHiRUVlXu7VTsDQBloLJqmW3cpdxGjSoYBODtueREYgGXGWGkdAKqa81UxAZS/M4Vqm9aYh4qpqIq+E0kPdBwHN169CWfiICb6s/n2Dew+sk12vhgxLnzzkjDgolNitH9U5bRjYAdrH79GPiZTf1QBr5HRLFWTjVOlFU6ZBUDlXpxlAM6OfbgKAcl0A1SlhOtSzlTXoaqh31QQYHoOdVIms+aRc36ad07oBjh89BA7hPR/+24X/ZN+DQCgGcFo52WCn7uE7tfMdQxsyr2SFz561K98r5Tdu6oq+Ca7d6gAjRkGYCGyALrJTVE8EKp2viYUURXZAU0rx1s3CKgiW6IoWj5RLldfukaaehV0QrJzXfri5fPc/0oBQIPS0RJXwI1PPAI2coyWCq77XpswlqZH/VdZCEilEuCZLEYQoAwAENmgs/zTMuxB3daoSdQpq8CaBAJkjtOt+08JAhzHwY1bN8EmHBHQuM+l5y9Xbv3DwH3Eiu9C8m/XddENu1j99JVGPifVe50V93aLfCzTd/mFlixV+m3V7KxOOrnouFX2mslkkhxjxAVQdRBgP7kp2QmU9a2IBHlRp61VVVxIdywq46wijZEqqI86PTAPBGQp0sS6XP3WGrYJgwFJ6LeE/u84NazHet+FrM3YdV2sfXkNR3/kGJN3TLBIwhiDM3bogy/7NE3XmhysR214zboAZGPWJpMJoiiKsSgxAFEUxZPJhLTjXd7CqJpinz2m6TWt56E7X5NjAvKYgESxXHu5eUFml790qRb6H2hOEGAWWLv5yRtgY9b4IMAmzLv/1qDx1nwTgGbRnihjbJwBADDGFoIB6EZRBBUAkDdxjDGjVcyqsJapmIOqC/HIfq/OuTQ1LwkTkK4//8itm3hu/BxZUSAKWX1+tRb6/0wTNfJ8nHMsnSxh9TdWsftjuw3VLOqHtp5rwX+KrthT8FRgdJ8RBQbR1QjDvzoinTT3iy46v6nXcydvz1M1iDzPQxAEwCK4ABhjvTAM4Xke2SJKb74mlOI8gYAqAIMpd0BRgZ6q5lK06E8aBMzm1J/nm7+whq2GuAG69+qj/5ss54GbX7iC4//gGNM3Txfq3kyI/5SPzgudyu9nVmlOn/IRvCsgPT///9zGPUPf9xEEARhj858FwBjrBkEAz/NIaSCRbAHdF6QKf5WJilRlsRN1BC9SPI+y8+rUQVBZT7ONdM7dAK9cb471//uXa6P/m6QIs+7/PCvgV64v3L23n2+Rn3P61FTqHZZh5EQKicVxDP8P05ewdm4x8r4t6eB0FePE932GRUkDPLsZZUWS/r4opVl1eqBqLICOn13mfBRllOsov2xy7nXvbdYVlbgB+Jg3Ipl89Vs10v9ArcnxImudc46V7RVc/o3Li1MIAADfdcnH433vVPu90Xo3l2IE3xeQ35f7TbeRHWKn0ykYY0Yol8oZgKz64xTKQOQcutXxVC3WqpiAqq27plmTJlOQZEHAuRvgxbXa5+Wc/ncs/Z+7EZ61dL7+uWtov9FeGOajdZue1g7fGiK4EtR2X5MPeeTn5N90yOacer/0PA+Msc76+jr5hls1AOhQNSBRLd9IGSluMle9DkBTJQNAdc8Ua8IECEjcAKt3VmuvJLP6pQbQ/3PQmD4Bbdd+7erCVAJq3WmBDennf/xD41r2iTiO4f/xKfn98G9w4wBZdR48z4PjOG0A5CxAZQBgfX294zhOO/H/U1q9Oo18mqD4qrwOdY39JnQ4bKIk2QE3b92sfSx10//zkvKVNHS68NoFXFy/uBAMgOM4aBmIA5h8YFJ5M6U4jjH50ATRVfrrul90yeacev2fAYAWDMQBVLkrdBzHaRUVAWqqT5nqeOpjVCoZ6lrZpjb4Khox6dSKUGFbGGPoRT2s1egGsPS/3Bo5ZwE+ew3unrsQ99r5Mr37OO7HGPypQbXPrB/D+3F6+p/tMPDbvJb1JiLj8Ric89ZcMwA4bQXckq0CWLbBmq4O1WQQYDLgpo4+A5QleZsAMoHT4LJrL12rL/jvS6vNiP5vUGBc6aboOOgEHVz7lWtzHwToOA56X+0ZGdf4B8fw3+JXtqcO/8oQcS+mD/77otvo7JjJZALHcfi8MwBdzjkvAwAq6XZVKuMmMgGmwE2dTEAd4EYEkMgyD6e9AW7UtnmsvrBqrX8FwyJxBfSf7c8Ne5F7LxOO9lfMBDYe/uxhJa6A0UdH8L/PN3Lu9m+2SdeOzM8lGAAexzF5MSCnwkXb5ZxzkUZAMvWkZ/PdLQjIXnC6NfbrnE8TLosqmQDHcU6bzrywWrnl2NpvNYf+r9gy1l2HSVbAzU/ehDNyGsECFAHSIlDLGDt1AxgYV9yLcfgz+SBAtuZH1s+9D3iYfHRiZPz8mxx8lxvtCKjToyQBAK7rYu4ZANd1GVUr4PTE6uR+LyIIoMjzT0SGai9iDkyxGLPXlJkfEyAg/fPzSnMvX61c51785sXSSplNslabMpbke5xzdIIOrv7KVcyzMMbQ/70+nF0z233waIC9/3FPqoqi6LMY/vkhhn95aGxu2p9uN7441hkDABgoB1wlAFjinGM0GpEukqwsgCpBgK6iNWXhUt9zWmGKVMurs5mS6Fh1gEAeMEqfj3NeSzbAla9dua9E8aIL9XpLwNvlb11upCtAdB6SbIDuF7rmrtmPcfjfHmL4o8P7Ogaqpmn77/Rx9AtH8D7oGRsz22Fwn3O1rHNRFkNnnxmNRsYAgFvhouxwziHKAKQpLBkaqew4ymOact2mbkRULX6b+vxEvu84DnpRD6svrGL/HfuVzH3roIWVnRU43Yb4/+e0+VviCrj6r67izuN3Kk99o7yPpX+zhMn7J4iumLuH0Y+OMP7BMXqf66H7TBd8Vw6ATr9niskHJwieCoyvm+4/6lbCkOkaM4kLwEQMQJV5Lkuu60oxAGWbbNrqr6P73MMkdcxnuod22TOueoxZxYeyfICJG6AqAHDxuYsPbe1/asbMcRz0T/q4/JnL2PvTe3M5J0kwYP//7GPwn5lN34v7MUY/OsLoR0fgr3O0nm/Bfd2Fs+uA4exdxreZl+CpAOFbQ/jv9O9jD0wKf47Dfd4FHPo9n7r/ygwDQE5DVQkA+ioMQNEmndVmcR4tV9ljypSiSTAjonDTP0uK4qgq7HnrrJh1fc45br52Ey/ghUrG0wT6vwn+f4oxJABu7Zk1DN8zxOSJCeZBsvqm9H+vj8n7JwjeWU0p3/DREOGjYePmpvPxzrn1rxsPJKL8dfalyWSyEDEAHdkYgKIFnZ7MvCyAOhrdqB4vk/0wb5uq6aj7rBQ+ma5+s/581SyEou/OugGqiP5f2VmpvfrffevUcAaAzLNWKSKVgIDrn7w+V3UAHmABOMfyJ5fBhqx5TY+qyo759CkjoRudL7I/J+9B2jiQueZgMADnHHEcL88tAIjjeFkXAKRf0KLWi00FAaqti8uUXVVKXydPXydgsqnFjGQVyNVXzEeUN4X+b3qZaBEgMOvi4Zyjd9LDpc9capSFL5se3H6jjf4n5yeokVTh3XbQ/bWusO6gAANZAdQyz2w8Hidgfq7TAPsUACD9UprejBahZLCpsatsQCKgiDKNsC4QkHUezjkeuf2I8Rftytdt9L+JdyIBAVc+d6XyjoGUFDXnHP1/10fnmQ4eJmEjhu7/0H3AAqd0ARTpJVWQcVYJEJhzF0DPcRzlGICsFyLL99w0i6SMtWgKcFA9tuq6BDJW2+wYdUAK1bpJ8sovPX9pIen/wrmeg1LAomnHrVYL1z55ba5cAOk9iHOOlV9aOa2B/5BQ/93/pgt3zzX6buSlk+q4GwaDQTLm+XUBAOg7jkPCAKSVqUwVwCb2DajC4jV531XUPzBVbyHv5yp9BorAEWMMURTB8zz0XukZexYXn394o/9l1pFqnMe5Bb3Vx8rnV+Z2ThzHAeccF//BRfDXF58t6vyTzmlr5JJsMpMMQLInyF5vYVwAswCASiFVUbOeilkQHauur9w0E6IbbJl8t0jJlils2aJEIko9fZ68wEDZOWGMIQgCHB8fYzKZGO0OaIv/6K/RMlbs3BXw2Svg+7wR96vyHjqOA9dzFx4EdP5JB+0vtHOD70y4irLWkk4p4LNj59sFwBi7zwVAUa/bpAVq4mWdt5gAVepc9N5FapmrzC+VYtABYwkzNZlMcHR0BM/zzgPJuve6Zuj/3erpf6F5aTg1LvtsHcdB22/j6ieuGqeuTQUTp0FA68uthaP9E+Vfd0lsnb15poEeeeRmpQxAgmaoFJVuw5u60u5E6GUTEelNcwPMi0WpwvAkyn88HuP4+Bi+759bIJxzXP7KZfKx10H/U5VunrexnKfU3VqeK1dAXplg13Ox8g9X0PnsYgQGshFD7+/2GqX8VdflZDJJjp1vBiALAOhMzKzvX9VnW1ctftlz6vqkq1LiVehkaooAACAASURBVDQ40snpznORUGc8xHGM0WiEk5MThGH4gNW1+uIq+fNravR/XWybyrVl1kZSJnjts2twxk5j57lsDhIw47oulv/FMvr/Sx9sNL8xJM5tB72/20PrjZaQ8q8qBkBVRqPRYgCAhA6l2iSoJrpq60WkJGRWnqoKHU15byZiLUQUqwmQpkL7i0aJR1GEk5MTDAaDzGfpOA76gz66G3QxPa2D6un/OhtZyZ67LBBQeQM9cwWs/coa5l2SwMD+v+9j5edX4H7Lnbt7aP1aC/2f6cPdd41VipXRS1nR/7Jj8jwPURTFjLG5BwBxURqgio9VxLor2xgoAud06wyU0fUym5ZI0QkZJSfqa9e1wmRcFhTjpE5hZIzB932cnJzMBu48cOx9bgAiX2eV9L9S3rRBv3jZv1XYHdGfJRT6hecvoPf1ntFUwCpqkiQgoH3Yxsp/t4LuJ7pzUTXQec1B9+910f1Xpw1+RGl/6hoAZXMvk7GWyGQySRjg+Y0BYIz1wjCE53lkirRplf9UFVUTq+KZ2mhUg/5MZVqoXC/PHeN53rnyLxsftRvgYSv+o7s2Vd+5LEBw3jHwV69W4gqoYp9K7mnpt5dw4W9fQPuZdiOfJ9tl6PzTDpZ+bgntF9rnyr/WMZX0A5CV6XSKIAgAgDxAo8qZ6gZBUAoAZCaJeqKbsDHpWMBNAgEq90VFzaqCiCJgVgbaxuMxBoMBfN8X2oAo3QCtQ/P0v2xBpaotK8q1rsK2Ja6AC5+50ChAoxNflbABrWkLy7+83CggkCj+/s/00fm9bzf2aVr9C4p3IAgCBEHAGGPkdQAqc/IwxrpBELAzJCM0cSLBG2VKsu52wJRd7Cha38525qOaF5FxlzE2Op0Qs44v6kCoev30tRMZjUYYDoeZJUaLzss5x+WvXsbGzQ2tNWaa/q+jnLKJcaqkjYqe69yt84XLGL9nDO8JD3UJdVlbzvmpZX3owP1lF+EnQ3jv9+B/wK+80x//Mkfrd1pwv+x+W+k7TIlan90/KOfexHs4nU5hIgagUgDg+z7pZIooFFEgYeoh5p0rS5mn/06o5iiK7qsiFccxwjCE67pYWVkRqj2d/nc6OOW+34MBLN8SVmlFnAUCipR5lnIX/VkR2Cl7HqJggTGGMAwxGo3O/f1595i3VhljuPzCZWx8SA8AXLh9gdz6J3ejGcYEunEAqkzc7HfOswI+sYbNn95E1ItI768KgFdU/Ojct+4x8H/LEX0uQvCWAME7A/jf6yN8Jz0YYLsM/HkO/hw/VfrjM6XPmbbFn95nTMwr1TPzPA+MMXL6pUoA0JlOp9TnJH0BdM+X98BnFXmizKMoQhiGCMPw7P8xwjA4/73ruuh0Omi1WnCYgziOwc9ewE6ni1arjQsXV3BldQ2u68IPguLAF4b7FXz+TSA6uw/HOb1uGIWIwuj8PgbDAaIwQqvVOleEURTBD/xMxa9aDUtUKVMzF2UgJwn2Gw6Hs726C8+b9bNZN8DkplqPeWfi4PKLl+H0HO0Nx3TL5io2WJmgVBOxQkmhpwufuYDDP33YWEtfJ+vqrDXtqYvgHkf7bhvRvzndt/x3+ogejRBdiRC+NUR0JUJ8RSB7ZsTg3HaAEcBvczi3HTivO+C7/D4jhXH6Fr4mKwFSyRkA6Kyvr7eefvppn+q8lQCA9fV1lzHWEfH/U0w0hUUvuomXHRcEAQ4PD+E4DsIwhMMcLC8tYanfB+MOep0eVi4sY3n5Avr9HlquC7fVQqfdQb/fx9JSH91+H912G5y74NwBwOC6HNx14XIX3e7pd13XPafE1N4EIDpT2N5kgtFohNFohKk3xdT3zxR9CDCGMAgxnXqYTCbwPA++H8APfHieB4cxhFGIMIgw9acYjUZotVqnIMH34QenfvI4OgUXplF0GuDpnnNyNjfT6fQcJMm6EJLxuK6LJ//pkxB1jT3wArsuWr3WA64Jk02nVN7T9/zX70EZAyhK4XPO0el0gJbccSr3rZJ6yznH5WcuY+XzK5mxEKJZN+dKlnOAy8+bqpIXTXdN1lgURd8GBy9xxC/GDwB/0THdp+wZAzi0jQCK+9XRTxTn9zwPjuO0oyjqApgvAIDTToCtWQCgummqPjwVd4LMonMcB61WC+12G9zh6Pf76PV6CIIA/W4Ply5fRq/XRb/bw/LyCi5cuoil5SV0O120Wi463R6WlvpY6vdPz8EduG4L7U4bnW4P7Vbr1BfHGMAYuOOAnW0OnHNwxwFYoW0vpTCjKEIYRYjCEFEUI4ojxAl7EccI/ACTyQTj8RjTqQdv6iMMAvi+h+PjAU4GJ5iMx/CmU/i+j8HJAOPRCOPJBNOph8APMA2mGA3HAAOCwIfnnTJEwRkTIgvGVEBbnrWfl7bjed55fj9FLAXnHL1e7/x+ZTe5cwVRwp7kxS9QWOBlcTjJPXY6nVxFINuQR7W6m25KqwiTkOwFrutmBk+KXm/2fkWfnW5tBlXQMPss8npolAGVLKaNmkqviO0mP+dkMkG/33dxmglwMm8AoOM4TiuvCJCq8s5bMKbo4LS0Wi2sLK9gZWXlXOFfXLmAlQsXcOHCBaysLOPq1au4ePEilpeXsbyygm67g1a7jU63g063i3bLhcNOlbnjOKf/ZjN+/yg+VcRnNHwcR4jCGEHgIwxCBEGYRIkiCkOEUQSobvAMcNjpOHjCMLguHO7A5ad/c8bhcoZuu4sLKyvgDgfjpxsyGEMcRogQn7s7wiiE752yAOPJGFNvitFojMPDQxwdHuJkMMTJyTGOj44wHA4xGA4xHo/gBz5GozHCKEwKYQhZ20XPMW9TEQGHURRhPB6fN7MSWWsiwDJhAUxsIllxJVXS0LNzMHuPurXtVWtP6AQBys5huk+JSo2BomtSBWbqniev/W3Wv+voVGqaXaxKJpMJVlZWXBB3BKwKAHQ55+5sJ0AKSp6Cope9dhzHWOovYXV1FZcvXca1a1dx4/oNXL9+Hatra7iytoZLly9heWUF/aU+uu0OuMvBmAMGhig69fuHQYTA9zEYewimU/jT4JQen57R7UGAYOqf/sz34QcBwiBAGIWIw1OLPDoHACHC4NRqjmI9AMDgnCp6x4HjunBdDpdzsDPlz9zT37mtFlyXo91un1o7rRa4657/v9VuodV20XJPf3fxwiWsra2BOxxwGBABURxi6vsYj0cYDkY4OTnG3v4+dnd3sbezi+3tbWxvb+Po6OjUlTAZZwYRimYZiCjlrBiGMAzPlX9ern3euVWAZXpTbNImZcLClPm+SGomVetoEQWsyhqInqtJNU3qWk8iTG+T5qkoCFg16PCskRiP43j+AEAcx13OOfc8TztwpaykokkQ0Gm3cf3adVxZu4K3vvWteMcT78Bjjz+GGzdu4OKli+h0unAchjgCAt+HN/VwcHIAb+zB8yaYjE/95VNviqnnnf576iPwz6x5P0AQBgiD06C6OIpO6fczBuBcS58O6BRQxCEQn7oFzn1xcXyqzBn7/9l70yhbrupM8NvnRNwppzfrPc0CTcCThCSLGQwCgzECbBpT4AYP3fYy7S5Xldu9usursLu6XF3lKrtrtb1cVdjtsauMvbDLZjBgg+AxCiEhGRCDEJLQ/PReviEz73xvnLP7xzkRN+7NuBEn4sa9mQkKrdTLvEPEiTgR59v723t/G6zZ5ARw7OsaADEAC3j2fUa4TxN7JJivCSKw/SoRoMm8RkSGARAEIQWIBDwpIX3DHHi+Z8Ii1YphPapVVKoV1Oo11Ko11Oo1VGpVVGtVHDl8GMeOHQPIhBfa7TbOnDmLxx9/HA8+8B089NCDOHPuLPqDAXr9XmF60MXzj78+HA7R7XbDGFwhBqKoEbDXFuoi1HJROd+8Hvq8POtFgsu86f+duH9cQkg7dT+XxTBMCwHl2azzIVByP4CF5QBIKUWokDZrpnJS6VoZ9E9aqGH/2j4cPXwBLrvsMhy/7jo897nPw4UXHYvit712F+dOnUW73Uan3UGn3UG300Gv2zOAPxggGA4RBIbKVzqA1jY+aGn7SPWTGZ7nA2AMhgMbUzPjCoIhhkpBaYVet4NKtYZup4tADVGt1dHtdFCrVjEIBmh3OlhZXkGn24EnJTzfR7vdxvLSMvrDAbRSaNQbaLWatrLARxAEqNcb6Pe6EEKgVqtDBQH8im/CAESoVusQAmBtDAJPGqBnGMOHbJ5CaCRE4Q0poqYjoWFQrVVRb9RRq9extLSExnIDS8tLaCw1cNGFF+LoBUdx9ZVX4bsPfxdf+9rXcP/992MDGxgMh4btKLC5aAQws8ldaLUQBEEulb28RkDWvZxFs+408M+Lfp61TfO8AH7ehkOe4++kwudONQ8rcx/zTAIsc+t2u+EatDdDAJ7npUqkFpnwMoRlsm4EKSWOHDiMY0cvxHXHj+PGm27EpZdfhka9jl6ni1NPPo2Nc+extdlEp9U2gD/oG1peKWhb5pesjGbq7YnZIKndKpUKTq4/jfsf/jbOnT+HTrcHKQU2NjdRqVYRDIbo9XuoVCvo9XvGcyeBwWCAql9BEARQKoDwJIaDAJ4nAQYCHaDiVxEEQ+O1k8BwGMD3PQRKQQqBaqWKXr+PSsWPDJSlRgO9Xs8YCZ7EYDDE2soKBsMAlWoVB/fvhyd9/MD1N+HA6j4jWgGYfAQiIAisAROjtYWpZpDCGAjSk6j4FVRqFdSX6lhZWcHa/n3Yt38fVlZXcc1zrsXhI0dw0YUX4p577sGjjz2GoR4iiFURpJUNTr42TSNACAGtNfr9PtrtdvRaGSxTVg5KHmCfF3tQRLN8Hp7/rMfO098ib0y+DCOhbBZi3uzLbvKsy6Tp5xkCKFNnIFZuvGcZgMQGKTtNa6bdCFJIHN53CBcfuxAvesGLcMONz8fBQwcxHAzx6FOncOb0GWycO492q43BYBDV9GMifjuiz6fV6FPcPYXn+/j8PV/E1755H5YaS5BSQAqT7T/sDOF5Pmr1GjxPYnl5OUoc9KQHhmEPwnwDv+JjOAggpKGvu70uPFtOKISJ7w8HQ0jfA7NGECj4no9Or2O8d8AaBBUMhkMMAuN5r58/CwZDbSo8/tTj6PW68HyJ17/idej3+pFQx/j5jakLgcEIAnOtBgOghy5oyxgEnu+hVqthZXUFBw8fxKEjh7Gytorrrr8eKysruOvOL+Eb3/ymMQBk/vlOMhjCZL9er7cN/MtQYSwC9HnAuqxyybLo5DKBp4yukWWIAc3SbGi3e8q7EbxdwHOeYF72uIsaA+12O6wqKbUh0KJyABpSyiiDugwPZt5KfVJK7FtewwWHjuDmG2/G8ePHsbS0hLPrZ7D+9DrOrp9Bq9nCYDAwwjnWv6UY4I29NuUcQtW96F/pwRMSL3/hS3HlFc+GEMIkHa7tR6fbweryChRrcKCxuroKFSjUaqYD1nA4xNLSkjVEACkFgiCA53nQltJmNmGFeq0G3/Oj95VSkeynqddmKKWh9BBC+Njc3Iyy/ZvNJur1GtqdNtrtDjQY62fWcdN1NwKso6RHgFMXyfBahXkLHPPOB/0Bhv0B2u0Ots5v4Oz6WRw+egQHDx3EhRdeiJtv/gEM+wN87RvfgFf3EbCaWvbm6jkHQYBut4terxcZBNNKA13uYddKgGmLcN5a/p3U3i+LJi876c/V085bIZB3v/NgHHbSs18U2O6l5L+yDOvvSQYgHgIo6+JTPPGtZCPg8L5DWF1exXOuvhbPuuJZEJ7E00+dxJlT69g4fx79nomhAybWjSlAL2I1slIICCmtsp+OSvY4jP8zo9NtY2NrA6v1FTQuNvkFGgbwa34NvU4P7XYL3V4Pjz/xJPr9nqkM0AqDYKQkGKghWI9CC+HrI6PDagZYK4UEwZNeFLuvVqoQZJL7qpUaPOmhUa8bwSHpQQ0VlmpLWKmvQBDhsmOXQIBwduM8luoNu++wQYcxcIQQ0DarPhxPdD/ENAzi11EHCu1OB/3BEO1WG63NJg4cPogD+/fjOc95DjY3t/DkySfhVT0oVrlo8jhAD4dDdDqdKNlvVgPSxRCYtYfCopmyWViBWcG/jP2Vtd+yAa1IAuMiDLayQHWeIL0bY/jzkBdutVp7PwQQZwBmXdSy6NhZssOXG8uoV2q49KJLcOzYMfi+j7PrZ3Dm9Bk0N5sIgsAk7hFtQ30CjTXQUIHCMBgiUAG2mk002030+n10ux2c39xEt9e24jhDKK3Q6XUxHA4x6PfBgKn/1zpS6AMQSQgDyFTSK2OTQgKEKAwRsRdhxzBhdAKkJ1H1q6jX6pBSoFKpoF6ro1FvYP/qGur1JdSrVaysrGBlacWoGUoPUspIw4BtaGA0z9Y7t2JCYUfJ/Qf2YW11DZdfchk2t7bQ7rVBksDgzEz/SWAdDAZoNpvbKP9p9HpZ4QBXkE9qPLMTi9q8vP55A9eiPPJFGhMuugh7rSPqTnnoe2GLlSB/b4QAyvD+0wC/aHyWiLBi6/wPHziIWrWKVrOFzY1NNDe3EKjAeMyxRI8QNEgQhoMhmq0mzpw7i3Mb53B+YwMn10+i1Wqj3eui1+taj93I4O6FGz00MpRShUQoBZkKgFBkaKnRQL1Wx9ryCo4ePYb9a/txYG0/Dh88hHqtDt8zGq8cN3zIzE+v28O5s2ehtUatVsXK6gqOHjmKhx99GFqpSCvcRc8fGCn7zdoxcBYmIK8RMe/ywbwezLzaNxdhBhYNvvM+53kBelnllzsN5LuxLfo82hKHIYA9mQMAIDIAyqT/04yAootk1a9gqWZi7jVb4re1uYV2s2Uzzg2lHUqwMjNa7TbOnDuDx596Ak+cfAJPnHwSm1vGWMhzvnulJCXvZkSLRiV7vb5RhHwCwDe+cz8AoOL7OLDvAC658BJcetHFuOjoRTi4/wDqtbpJNoxVUwz6QzQ3t6DUEjzpYXV5GaurKzi7cQ46ZpBlXedut7utMiVLMTBpnvLq8KeFBFwN2Lz0aN5EqbJK9PIep0gOgMvvRd6fRb53loz/RSfr7VSSYtp39vJamKY2WvScut1uuK59b4QAymYAyvKOGrUGGo066jaxztTvBwiUArEB/ornQ2mFU+un8O2Hv4MHHnoQjz35WARsWUbKM7TX9m0wHOLp9VN4ev0U7v7ql7HcWMIVl16Ba6+8Blde8Wwc3H8QzKOOg/3+AFIIBFrDr1SwsrSC85sbUA6ti4Ng1MdgmrGQx5gsGhJwKQssymbNw3ss2/POA/6u51ZGEl1RkC5D4resa5+3AdGit+/1dTCt1XuRrdPphGvV3mQAhBDodDpjVtAsYD0rHTttn7VKFfVaDVW/CmLCcKBshjzgVSrwpYfTZ0/jnq/ei69+6z6cWj8dfT9N//uZLd/W6rRx3/1fx333fx2XX3wZbjx+PZ5/3Y1YW11Dv9eDZsYgCGy1g0TNtk5Wwz5YTAfvIAjQarUwHA63KfulAXkZ7FIeNiDpft5J5cAywd8FUIt4+7N8vkx2ZJFe+LzDL7t137OwDotiF8o8zp43AIjIuZHKrAZA0WN40oNf8VHxrX6/sFK7YFSqFSil8eWv3YNP3/FZPPn0UyYxzibFhR30ntnK3x554lE88sSj+MYD38JrXnErrn72NYYJsAqJUkr4FR+1ShXdftdIIwPbFCMHgwHa7TaCIHAC+jzee9Lfee5DF3GrIvud9+K66Pr0WeSA8+wzbwx+HqGVMrs27jbveqco/p04bhnHjGno7M0QgBACvV6vtCYnWd9NUnrL2kyWu5GplUJCCBPvr9SqaLc7+MRnb8edX74L/UEfnu+BrU7/M57+YrYHHn4QT6+fwg+94tV42YtfBjBDBxpCSvjSh+9XTImj7WsQsjJKqUjW1+W+yNNRMO3vImxB3jyCMp6lop7RvBKwioDurIqAs1QwzFr+Vka9/05KAu9GdmAnt3loJsQMgL3JAABGzaisBcvl+3mMACKCJyUq0jfev2cy1iuVKvr9Pj5y+8fwxS/faTTxPS8S1XlmW+y21WziQ3//EQyDIV5362sxRABPBVGPASJhwX/UzGcwGIyxT0ndAad58En3XN6ywCJee15Ded6LctmZ4GUJ87iECvKEA4qMy3WMs8oTz3INyjDGZjWUvl/Af1JErCwDIHSmyxyvWNB1qU+cxMzWa15q1eliSFPnbrx/0/K24vu44+47cPdXvoxGowEVKAwGg2fAfwe3YTDEJz7zKXz9W9/A0vIShCAIz8ydCDsgEkEphXa7jVarVWixnWVhnLZQFvWaJ38WuaDNG/yzjuE6hqIJgGWdX5GEv0U2FvpeAurvt/W32+2G57x3DYBer1fewHOqtWUaFAAkkQET272uWq3i5Pop3P2Ve1Cr103r3iB4BoF3wwPR6+LTd3wO/X4fFataKKUwqoxW2a/ZbKLf7+fyoNPAJqmtp6snNg9vfZ5AUcb+iyb7pXnss2T/FzEK5hmTnwcg73YhoO8H4J5Hsq51OnnPGgBaay6rG2AeBsD9xiMQCdOlzir5eULiOw99B+1uB6w1hsPBM8i7i7aTp0/i5PrTaNTrVoFRAEJABQGazSaGYWviAgvkLIt0GmiVDeBJ7EAe+jhpH/MyTuYh+OO6j6I6AWUaO7OsT3tN4W+3jnGvGiCdTifs17L3DAAiqoctVpMmo2jJXt4kG5euUmT166UQ6PZ7ePzJJwHCMzH/Xbi1O22sn1uHkAKQBBKmz0Gv19vG1BTxELOAtKhntghPfpLRmDyXeYQTstgTV08/DyDmOWZe0C67UqCM9+dhUMxi0OxGUaKd3CYrj8piA/r9fij/vjerAJRSkQFQRmJEkU5pWbXUHO0bEJ6Hbq+Lcxtno+Y1z2y7axsOhjh9Zh0gIzMMNvMcdjacNDLTlLmyOv5NJuVN+ztJcW+aCt+0pMPd1DJ73iAyCwjnNdjysACuYywjcS8vY1PEaJqVjcgD/ruxQ98iuxdG0vAltinu9/th+XJtzxkARFQLm7jM6vmXNUnJZV561LkOwEZrC/3hAMyImu88s+0yaqzbAdlGRfZxg9bs1A64iAhQ1v00rRQQALzntSEu7wIM1P/Reup5De5agX6kDiJAfXMZ+tHGQq8rHerDu2UTzED1DWdBS8n3f/f9h0EgO8b6TMlu01iCg3/2Hacxt953AO0Pro1de601lt68CWaN5R9tQixvN+RbH1+COuWhe0cd6rS/DXyXf2wL+3+y6bZQP+jhyX92wHnxT3q/emWAy353y3muvvPOJQxOzkbmVi5krP2gYc2O/MQQciX5c0+910BG6x6B9v1lh2HN9gN3uOVZPf4fCU//1+3nffSdZo6P/STDSziP0x8A+k8Szn2K0H9y/gxAWZgVBAEB2HsGAIDacDikuBc9zSNz3UIVtzKNgKghLZnxbTWb6HQ7kFI8YwDs0m2r1URv2If0TMfCeIfGWY0Al+9kLgiHB/Bu2UT9H51JZJumbf4LmsALQtAxapPDu1agH61j+NHDczGemRn+69fhv/I8xJGh03hrb1uPxshtgd7fHkTwmf1Ax5vJe413vnR9ysN+EUQEeUUPjTdtoPbiTuZ5LL3WlCevvmsTva9W0fybFQy+VosMkOZnK9j3k45AemUAeWQIvV4prEZYe37f+ZybXxboPQmk5USnXetD7xji4BsDVC5kp/k+9u4ROKsmcOq/Spz9sAfVnN3TDtu7u+6BY89i41rG0XcyDrw6+zwO/6h55+L/mbF1F3DyvxC27i5XR2Mez6dNaK7uRQagOhgMplKcs5QBuizG00IO275rM8gJBJDAcDhEf9B/hv7fxVuv14PSymT/m1TARE++iIfvahAkef5cH6L64+uo3LppPNESHAF5SxPylib8t57G4C+PIPhYeYaAuHkDlZ86GXn6hcbb0Ki+bR3Vt62j//7DGHzkYKqgkisguo4lbCddf/sZNN68Veg8Ktf3cfD6PrpfqOHcbx0AAARPS7Tu8dC4yc0zrb+0j9bf+IU94uWXD53Hff6EyOVph++t/mCAC395CLnCheebloGj71Y4+m6Fk++VWH/fbHASGlyuYzHnQrjwf9I4+q5i57F8C3DVLYzzn2Q8/J5yU+LKDjsMBgMQUfXEiRPyVa96VSke6dwNgBMnTshJA6CMC1NWT4GJGRvjAlhrQyfrZ5L/dusWtioGjdgbJABMlnWelhOQV/lPPreN+j9+ErSkMa/Qo//WU/BefwaDPz0Gfc++qca1k9f/7sfg3bI1/gjMuFV+/DTkD2yi/58uAZ+p5Pb8J0HBaU1Y0lj7F0+jcn1v5vOovaSLQ795Gud/6wD0SYHW5yqo3+jWC3vpZT00/3rJyfiZfF1eEKB6lXIav2oCzc94uef8ol/rYe2VqtT5PvrzAdZeqfDIr3kYnhSZz1cZwClXgCt/W2P1Fp75PPbdClz7RwrffY9E/6nZgT+vCq2rASCE8JVSVQCldNZbRBVAVQhRiVcAJN2weRMD83bZS2MBDCFk/iNLIRMxmGCEZZ7J/t+1mw6VtyCs/58MHNOSrlxqzl3q/6MF/AfPofa/Pw5e0tDAXH94ScH/hScg3/VEYnZ/5k99CO89D0LcsjWX8dEVfVT/5cPgS9qJ1zOtIiH+t+vxlt7Sgnd9r7TxD7cMyBIRunfUEbTI6Xv+VQpoqMT7Let+bLys7zy+8yckdEukKliOJZcuKVz+3i5WXqnmMt/VaxhX/sEQtat1bmCPv+d6vCPvApZv4dLGP9gChluLqcIostnupRUApYUBFmUA+HERoGkXJ48lm8e6dpksQ/tTGAUAg4AFdo56Ziv6pNnyTYShfxqL++UVjsmTSb0tq//mDVR/5jSYsdCf4UmZX6+gPoT3vzwCcXlvrmNDQ6P2vz0OXNpxfka3GwJY+E/7Hg+n37M2AtiORPMzvvP3l17XTdVkmHauSy8fOh+jc690Bn+xrHHJb/ZRvUrP9bqJZeDynr780QAAIABJREFU/zDdCHB7rhb/s/klxnd+EVEuw6ygP48cgMFgACmljxITAReRA1CTUvqhFntZoO0am816fWwcjLGsEXoGXnf9RtH/2DA3wLbMn7zxftfqgLH79/AAlZ85Bb1gY7H53n3gz62hWmWnjoJhopV855PAZV0sJLrVUPB/4Un0//0loLPV1Gc/yRhb9DXt/oOHM7+6Bt/3IipXCIHO56tYfn3fLQRywwCtv+Zcjoq8QKFylXKaE9UEWp/1IYTbKnX4n/Wc9z3zM7kMXPQvh3jsl/3EcIALq7fQZ+gu4MF/Atv8Lf+qvygHsdvtYm1tTTDz3jEAmLkmpZSTIkAz32QpnnlRI2AKvDyz7QkzgMZoAZe5zpP1HwfWpL+9158FN+YX80/aNv/VIYhvr6JS8TMbGUWLq9bA606Dbmlioakth4fwfuokgv/7ssRnN+3vRY6z/TkfG/9+zXQElXIsgXR4Xw1BswmxnD2g6vOHJgzQ9TINnPD3xsv67sl/H/Yyjb1wW3tbH0uvUAu9jt4xxgW/HOCJ/7WSW59gkePc+CTw6HsQzXWZ+FT21ul0IKX0ymQAFhECqEkp5TQGYF5WVO790TOYv6dZgCn3QFIcf1r8OU+sf+y7h/qQt27NPeYf/xmBfwVSSuf7ng/2IX58faFjjXICjneBl5/LzLWYfH9R49v6WGUM/CevJxGh+bGq8/7qjmGA8L3K84fO+25+RkbsRFqipDyqsP9nBzsy3/WbNVbfkL93yqLGd+YDwGO/SjOBf5K4V/hT9tbv9+F5HlCiGuAiQgB1KSXS+gAUqq92bPCSdyLyfPrurc+OeZ1ggAkJxaec8Fu+98ZfSaJOp38n7XsxnznHtzh6MWvMnDomx/HYX1914DbnCSxS6z/5ULuKBOHmrVy0Zf8LNQy/VsHg9uXEsXjX9SCfNQADWHrX9qBk69cPQ6aAfxozpl93GpRHFa4l0P2bJQzvbECfii0XSwrV17RRfW0H8gL3iiR6w1moz+xzngPjEc7fJWx/rIrWfzbXVAiRyFIIIdD9fAVLb3XraeLfMEDHIQzAzKAljeqNgZP3239AYPigh9jUJ+6bmbH6tn6u66eawLk/E2h+WmD41GjcYpmx700aa2/SqFzofl33vSPAxodFrnV4EfN97gPA078porme1dsv2jskz9btdsPnfW8ZAJ7nTe0EmCXPOyvFkhXDHd9nIRtwHIA5DQhdwd/9r9Gx2WmcbhA8P+DPZYiwyzeKWe1ZJX9ZhsPYPi7vQTkOsP1b+8B3r8DzPDQayZ6H/k4N+tsaWmtsfGgN4ngX/mvaqLykh86vH4L89goq1XHwd1pYD/aBV246j3V4Rw29/+cQPM9D1fNAjZFno7WG+lgdrQ8HkLdtoP4ux+ypwwH0y89Bfv6gM2uhCk7+4Cs+ep+voP/xkUIhLTPqr+vBv2GA6o3GO+38XRWdFPCP3yf6u1X0HpAm0z9rcb1hCG4oUNfLTAKsvc79Hmp+WjoBlzyq0PiRwHm/rROEU/+nHzELnhe737uM83+uce59jH3vUDj0brckP3GMsXKbQusj7lBTdL7bdwPNE4SND2LccHkzsHSL+QGAjQ8Cp0oC/yQjYF6bDQGAmfeOAcDMqQxA2UmAsxkBlI8GYC7sb+czCqYAaSbwT/ex0zz+fEzFHDz+2Lk53x1jaQDFpX6z8gImDQatNcTlAyfPbfCJBuieNVRrlajldJp3GO4/eKCC4FvLCP5QQfYrEVDlyTpmZqibNkCOF7T/gWXw+w+iXjeGxuRYw7F5nofBRw+gC6D6Tkcj4JWb0J/dn6jmmfR3kZhw89+tILizDiklqtXR2DlgDD7oo/c3Gp3revCuVBh8YBmVip8K/pMsgLzSjQWovraLwQeWM8/Ru8Fd/Kf9Ud8KX6XnTtReHjjvc+N9Aht/4ENKMZXCDq/N5l8QGAEO/rybEbB8m0Lzb6Vz6XaR+T75q4TWp824pYzdpx3G+fcxzv0Zo/4DjNo15lzLBP95tP/9nmIApJRotVrOlJ+rul+RSZpmqVGEOhT95+b7uwKoO4hmQnEm3Z/XLMkAfo5/lzLOgHNcEZ4SLeHcHv9ozmhM3WRWqV+XzHrN2klRhR+polKphHG8qWOK64kLISClNMl7GhBVkSgykmVIa62hX7HhRP/rUxL4y0OoVs1Yw2cmCQzDZ6r/0QMYXteHvN4h2ffyPtQlHdATS5nAWIQSbv/mKvjuZVSr3raFXmsNIYRhML4pEXwT8P1kjzpxnSBC/+N1NH7KTYdFPGuYeD+N/b6k4T/fzQDo3yuBjgTJbIOv/vqB07ULniIL/jJVYj0e3976C6B28wD1m7P371/F8K/SCB50Y6zyzvfTv0bofEZASpHI6IXn07+X0b+3eLZ/GpOY9GzMgwGwa0dpjUEWYQA0PM9DVhJg3MKclzXlptNMyJ8J6B7HdwP+aXRhNhnOub1vnj6ubXQ/OY85P9Wfbbq40QAjjfBJai7t9yzgT/petGAtOSqRLWV3FkwycI1XIzOBKe3ZCS5uQx8eOl3K4EOrqHheYiJc0vMkhIDv+xh8eBW4bt3tiXlOG/x4I9PjZuZclPDwC1XwXcvwfX9sEZ6czxDskuY47XcAEF0P3c/5qLwsWxnQe+kAeK8GOtO1GryXuNP/nc96Tpn/8soAdNTt2m38hcwE/8l7VgiBjfdJVBzlkas3jRsAaQZrnvlunyB0PpMeEpls0FPWlrTfpO6zZRoA9p7dewzAtByArIUwzRItcnHT6f9FAX9eTzkd/LlQsIHTR8HFx5srDMBuwM+5Hsx890EW8GfpAOgmQA0HBuB5XfDH2ckozSsqkpaExMxQ17acPCtuC4gvr0aevwvTEBoo4lvLCB46D/GsbGDky7qRN14mAxB8sgHP81L3m3RdXZsWhWvP8I6qAXeHTb6oC/XJpanzJa9389R1i9D7nAfpYLCYkILDPptA/7NetkZKwrUb/INE79sBKldnH8e7SoHZc1q388x388Pl0vlFGYBFbCEDwMx7hwFg5oaUEq5lgC507SwGQCr1av8XayiXwwRwhnJ3T5mLx9ST33Wl+rO+lz/zIX+Mn/P5/VPKOPN4/KmZ/in3ZvBwBeKIQ0z4eV0M3nIatQ8cnQr4LqBbJPwVHBo4sRR8Xw21fgXk52tnGhoBwdfr4CscNPMvH2QaLXk9Qm4R8PU6REXkAjPXz8QZj8EdNQTNFshBE4CuH4BvbyQzDQ0F+dKh0zn2PiNBlv7PUq+kC7TbPu+VxuiT+ddTIkL3HgHpkBApr2Jnh891vnUT6N8rtnVCXKRya9qxnmEAYgyASwhgN0xahE4O2VI5fXh3KOYsvzcfoZ9+xGmZ/TlKEPOM1cHjLx4G4GQrIIf3n+XtJ4YEHq5AvdAtKUy9/jyGrz8P/78dsvLTgDxTgX/vmrPnn1dKm5mhLnNrkEOnPade5knvCSGA077bAn44cPa6nQ2AU95YTbeLxHNaEt00vf7ICPh8Bd7rsnMe6CUD8O9pUEduO5Z4cd/5/Pqf951AhZlBV7oZAMFJyu39x++34CS5jf8oZ+Zh5Z3v4VPzq7nfbd4/YHQArAGwp6SAG0KITB2AybataZM664RPXWQpB9bE0ZpSYGrq+zyeU+fk8ec1ChxCFOwSnigK17zNqskfrODUSUm8Fyib8SnDCIi2b9SgeSPfw/yWyVj5E+On0JGo/N0BAKY/Re3jh3PVzo95SlpDHRo6JSrKtsxteIy7KcKZwlUH+5AbMhWMTZKl2/64BXg5wL+IIRA3doI7qhCv7bl5yy/qAp9a3rZf4Ur/P03QX/XHMtxTj3dUO4cAZllPddOdshfHGDiF0kIAKmXsiwDnrP2XbZi0Wq3QAFjecwZAGgOQ1NbXJQQwy7bt+za/zdDJFP0wp0xkDNx5m/OZM2bOWfBYTMRnqlECl/BFkcwGnnZyhQwUTkN1wJQtiVFyIk1UASTdZ1mx/2lJekmeJRHBe6yO7lerwHUlyl3XFIIfHRkJ7Tefhny0hsq9q6h/4tDUMq2pDEDdVBFkLqpvPYfBW8/NNnbHPjDq0BD6nM7Mvlfa/bhpHR7zePpZRgEA4OtVBE8J0NHsAfLxAfh2PXYPcUODrxs6nd/go75z9QczQzfYaR4qPz1E5aeHM0236/yIowz1NJe2P63TsWSeW1b+yDxYiW63G+53b4UAiMg5BDCPEkAXFiDsBrgdhFJ01aHt29v1A+Il6VwY+IvEyDP8cp5VxGfa3pOo/nRmwn386SEPDueARHTRi5T8uTAFSfefEALyj/dj8K9OAUt6bg+SurSLwaVdtF97BksfOILGHQedPBJ1cAC1Czta6okVfBrguo6dOCdbUXC9CO8JIQSGH69CvMthbXtxH/h9DerGqgGu60MvaSfGUX3Vj5L/ssCfjurdOd+unr3j5zTvrG77ohmATqcT7nNvlQESUWoIIC9tU+aFHVvwCaAc1QA6BkNRFzoyHiiTXZBSyAOUCu8Zlfg8L9nevLX8eTIJ8ukBbGsJVGKznzQjQQgB/1wN6ncOYPjPzyzApFbYesdJ9K9pYd8fXeoUGtC7vKN1Gc2AqMCxpnmMLqwAEYG+VIN+p5tzQ9f1gbsaozl5Ud9JmEk/KICHPbBgp3j9XpjvdGAvTjR9L7dv37MMQDj43WpZaa0BWWBJYXMLciwNneL0Oln3n3jUq55zeNE7DPzZaY2ccLj0M3A7el4hIJp+rIzs+jzefxLtF4ajPM9D9dvL4H/L6P/iubkyAZFHcOMWgl94GAf/4xVjYbHJBCXO4VUtFPQdwD+PRygSmgm5gH+Rz0THXPcx+KoHXJ9No9MLe6A7a2ZuGhr6uoFTXob+ggeZoMQ4fczYtQyAy8rtzgBwLtxYpPc/D5zq9/vhcfdWEqCrAZAUe80T6yyyjXl9nPeG1iAStgmQBpjAxCCmcVjjkCPgqWYFl9aoJ/aeUy1/rASACjABHH4x7xlMkTwOGyqljDvNBgiDNq5lpa7x/qTcgMn3fd8HHliBfHcN3R8/j+CN7fl7Bdd2sPnq01j75JGp3mBeMZ1FAkIWCOcaO7sv1rN4/tvukTsq0Nc5xNGPDyAbJgygjvehlhzXnI9XndmSEYjuRprH7WPOZYA7cI7TKhkWwTz0er3wGEt7igFg5lwMwCItq2nlHE5FZwQwa5M6ECb1axiqzsahmciwAjZGQKCxYjU9lWcoIo4zQ4yfisT4OdNAmcpMTPzGic48Tx7KkQ/IF8NPAw3XMEH4eyhCI//6EIL370PvDVtQhwMEt86vDHbjzadRu3cV1fO1xPMwILo7GYAkw6woA4Cc2f6uCX9ZvQHkl+oY/kQbyNIEWGIEx/vw76pjeNyxS98XfPgO0r9FvejFznc2A5DnXt0Jqj+tR0Iau1iiAcBEVN1rBgD3er1cVyOr/rR0OocAAucSAYqaAZlSATtmGkMsDbaNO8LzCalhEYNPBiAiIVuewhGkAioXVxvMRfVvA/8CzISjkZML+HlUvLHt/BybQbkYCC75AKEojud58D/uQykF/ScazIzhC7pQh8flU4cv6EJdMVsmduuGDVROXJDYV0Ce8XdlTNjFk80TzxY59j9rmCD+nuxK0BerUK/JLgkcvrAH8cUKghf1ne5teYfvpFg4tp0Su3O+nZkh9/0RFteMp8g9UrYBoJQC9lIOABHVlFLo9/uFL/S0ZinlW3YUZZI5xaq0Bsj49MwG6DVpC0bWEGCCjlH/LMjYAMJ+LjqSNsBPHKMT4nzBlAfIQcRnMep9ecWBOVf4gjNqmsaDENk9JYomCLoYAXG9edu+M/qpfrW6bfHQf6fHYtfqcID+LR1039AEO+YStG7cwv5PHZnqoegWOe2r8f41ND66moslKfJMCyFQqVSiFSgNrPPkABRZoLng98JrK4SAuM/H4NXZLKc+3gfd2oFqOGT/twiVO6up3v+0EjTVRDYjAYD+tAL6b36m+NMscx2/TnDokZOH8ZE7yAYUYQtm2fr9fmgA7KkcgHoQBJm9AHbywo48yHz71aQjSt/QmRpgAUHGa2EGBMWBkSLzliz3H5awRZ5rFIun8BvWNCAHr78cjz+fel8eNsDBeEioJVSscD7IyK6n/EDuunBNA/3J9yfvz/i/Y/XfU8Au+rfJqH2ijvpnVnD2105CHc6WWlWX9DGsDlAZJLODdNpDcFm2dj0vA/V6PZGWd1Whc93CuvbMJEDHfEqp5wf4WWOs3FVHp9kEL3EWHwp1WyfMH05fnL/gb7t3XK81nxTQz3aQ6F0GfC9do3+WOc8bdiMi5/kmNrnbi8z8d1UznMfW7/cRBAGIaO8YAERUC4KAhsNh0e9vu4nmc/HZku80TVZ++zc0R0jO1hAgaCgAROFfGAG+GFcLYjYGMUfASCCO9bRjQFkTg+NCRZgP8Bft0OdaU5CP7jd/DHmA88FZaFaZ4B+2BE5N2Cogo5t0z6UBv+traYuilBJSSSz/1X6ce7dbh73uRV1UvltNNIDEugd1aTYL1722C/ERMdZ9sMiiP+0ZzftanpiwShEBygLPWb4XtW2+vYr+mxxynY4oJz68emfF2Ujadv1OEdSzHHIirgtQm+iK6DrXruCeZ63OM9+Cd4b+30lHdTAYEBGVFgIQC7gI1aLgv8gLG1l1MSjJZgBCT5+Nn84aTIbO1ZrN35oBzdAwP4YqCGU6NZSFf9aWJoYRGNIckt7WPGANxmg/I6NhHIh54rftMMtTjZ9c4M/pR4mPaHzvPPYTCfnw5HeAnu7g3HA9Hfwj/B/NmZFi4MI08LT3J/c3Tbo26bVpIDftuEIYEK4/UYe9hTJ/hvUAWo+HE8J//UeqTvvoXdrH4MBg6lg5I3PftcFP2vlva7fseP6cMldpYM8lhA4AoHqX+1xl/eBpAf/rlULgT0Sgh6TTcYJnKagjqhTwLuv7ua4TsFDvf5HHm2IAgIgqe8IAOHHiBBFRbTAYzHTRi9K4uY2AuIPucgitoaChYaxWhgV+xMFaj2A7/Dzb1zVbY8CUETI0NCtrCDCYFTQUNGNkKIyZAcZE0FMAfgJmE33vMXCOoTFPLd3jMLUh5Sij708NMnAy8Ie/tdUWNoJz7ooAEW0zPnmui73rg+0K+mkA6WokEBH0simLcvkJ6moqIHhnfef9PP7TT4wZElnevotRkGU8pV1L13ErLm7oZZ1nlnFARKg8WgE97OUa77Qf7/ZqovSv81p2Sjofq/lPW7lBbZauilmg6jpuzViI95/F6C2YAQARVU+cOFFKJcC8GYAKEVXyJgAmxU4nvaM5wL8p2UOWAHAM/2G9fVYWrA0oK20A3hgDDM0ammMLqvXoddxU0CakwCGrYOFdawZYgWOef1yBUGO0T214iJg8Lk8l48fgeQz4kQ78CXzDpNc/neq3zAEnsQHhbxqbwVm01NYMD2w2aLsaBUUWts0bttC8qunsLacBZvvq9jbve9qPty63AXe4n6UHlpz307ukhyfe+mRuQyb+vtYap1+17pzpn2ZYuY4bGcaZixHiyv5MvheuVdUvVZzHm/ZT/VJlJgDx7/OcjxVcEaD1s+2Zvffem3qFaf80tilz3hfk/e8GlcFerwchhA+gFANg3jkAdSGEn9cASNLdLpuaQgrIbXcrkzelFUiIiLo3FpUwuQTakNJRsk9cGtiWDQowWNtkPzIVBdDmgxQBOJk8AK1MSqAgCG1yA4yRxFEpjClFJICUPZ6YOA3O0RgoidJPgnsX4MfUhEUeM6gUNoZnMeSCjFH8PHN29cvLNE3LLTj3onM49fbTAIDGtxtY/coKDtx5YOr+ph2LmbH+qnWceeMZ5/op2fGmjtnrelj6cgPtm930CDZevIHhwSEu+qsLUTlbcX5mg3qA8y86j9NvNHkLratauPy9l+Uypph52u2W/QgXoPLzePpp+xJCoPHpBlpvm00Ayr/Pg3/GB0kqxFIREURHwP+ij+GL3MKv/Vv70Ic1lv9oCfK0dDeOlhi9W/vo/oTJfRgcH2L136zkcvYKz/eCt2n5QItmACqVig9TCbA16/7mbQBUpZR+0QqAtISteVhihjwmCNcIAHgEzIZDMAmAtijdePoi2repAoAFeNs2lWiU+M8AsVUUjHE0FBfcUcZGGANWeyyy+9ZRcqENDsQMgfFmhWUk+BUD/sn9BDzARnAWitXMkzgt8S6P6t806i/tHj1z6xmcedMIsDtXt9G5uo2n3/Y0Vr6ygtrjRgb20KcOTaUUW1e10L24i60bttC7pJdrMfTPeqnPzPK9y2jf5A5O7ataeOBXHsDqV1ZRe6KGA3cegNfztgHkmVvPRGxF++r22OR2rm7jkZ9/BJe997JciYGplM4M3rorM+TCHCW9JzsS1Tsr6L+weGdI/+t+buMjCaQqd/oYvtDdmB4eH+D8fxig8qUKvIc91E7UQO3t933nNmNEBscDDEMFRDu04PgQW7+yhRVHIyDxnEoUfioFFyae0bLCH0W2breLer3uoaRSwHkbADUppVdmCaBry+AiyEE5IyLauvehhoDxwnXUD8Dsz37GdgcymgECBB0TsTBtBYx0AEWePxkrI8JvaGMMxCsFmUfHiCcxaI4D/ogl4IijyOPxh151BpsQ3we77Nv81dc9bMbj/YwcakzIwdnAyeN3qf2f3M686kyqt968oYnmDU0AwOk3nM7t0WY+aN+qwet6IJ+meqerX13F2fWzCA4Fua7p1g1b2Lphy23cCWPuXN3Bw7/0MC5976Xwul7+hZLd53QeYJ+27yRlwOpdVfRfUNwAqJ+o5xf/STBYq1+qonuqC30kX1+KwQsGGLxggM7bO4XmJjgeYOtfb2Hl364kGhCl3fcLYgqKlv7NgwHo9XqQUkpmLsUAEHO+cHUppZxFBjjpohd5OJzvJ8pzfmGjFZO8Z+LxOhaPj0f5lc0FMB6KhoYKP8ujCgDW8WQ/m1egdJQfwGRinSqM/ZM9pq080GxyDsJ4OseSEu1ooRIrCaYBdOxzBGQlCILzgX9Ht7ARnB3fY4HnJjKIClC3eUAgaT9j4L9DP8v/sBw9K0lecFiqtvb3azsyvv7FfTz2848hqAW54rdRjw7XnwLgnuc+cBlz9VtVUIsKXafKnRWIjpgZPML5rn6wuiPzra5QaP5Kui7C1GuZc74Xve1k2WG324WUUpTFAMw7CbAmpaRZDIA08J8P3eLeDlhZUAeHIGyS/RSbjH/WJhmKtTK/h8l8rCxIj76noKFjVQWsFbQ24kLaQna4bwVzTGM4qG3VAbD7DSsStNbQWo1KEaN0QQ3muEEw+QROxvhTKgN4ZBAlGQ888WQzgC21gWawOVfLPW/Cn2vSWvjvyf/uJM7ctrPg76172PfFfYl5BPGxCiGw74v7UHm0smNGwCO/9EhimWHq3OU4RhHPftbKkElDy+t6qN5VDHgrE8l/PKMufu1EDfJhuTNGwOUKW7++5SRkVcgAWIDnP+1Z2ilDwRoAQElywPM2AOpSylIaAcUpGGET78o2AogQ6fqRgyeqmaFYQVnxHwO0ocevoYyJgMD68iH4c1gKyDpiAnT0GQ1WKiohVNqAqzE0RhneIbtgSgrZHnv0WcMRAAqjUj/WDNYW/pkjwCb7i7ZsBGLvJSdHThgJnMQaTI/9a2ZsBGfRVSV2y4u3W+DsTP+kDPPJ96dlocPO9cm3nsTmSzax09v+D+yPehCkZUuHPQqO/OERiI7YkbEODw7x+Lsfz8z8nvW5dp3jIn9Puz/G6Pe78ydpU5tQ+3ItV6lZmpEasgBLv7NUjIovYdNHNFq/0pqz07YY+n83bDEDYPeXATJz1fO8UgyAvHW6xThk+8uoq0yGAaAMbGsTAogKAbW2JYIhYFsvnzUCHYYB9DYmwHj4FtDD0kG711H4QMeEgmxYQY90AcyxGWOFgVHJoTFVWI+MjjDQoMLzCDkEmvDeOZnqT5LuTRb9CcMlAc4H6xjoXsl3G42kgKi49+da59/f34eqqR31/MHA2l+vYfVrq86lsVJK1DZqOPT/HtqR8fqP+Ljgdy5wYmKKMgCzUPxlhAAAk5MhTolcY69+qjpmyJVFV3tnPDR+u7Ej8y0eEmj8X41813AXhQBmmYt5GA2dTgee54GZS2kJPG83YElKiU6nM9ME5LmghScLxsqjCWcyNQTAysTdQ+CNQFxBKUvXx15nbQGdFZRlAlRIz8dA3EK+zREYfV/b70agr8Y+PXpfKyhlDBGlrdogG0EhA/IGuJQdR6hRAFKANQbiIQ3NGpoUdKayX7oSYaD7OBesI+DhnJ5WgEhsawfsAuiutH+4+Wd9HPqDQ1j+u+UdBf8DnzoAz/OcF5uwZfHKQys4/NuHFzre+pfrOPbvjqF6vjrGVmQa+gUBIe9c5xF1Sttf6DHWP13PZwDcXc0NGln3apQL8K0qGv9msUaA90UPS/9iCXJd5mM1dmEOwG5hLGIMQKOM/c27CqAxqwGQZDlmeTszVQeQew6Ajur/baY/BMDaJOMLm/nPGMvrN3s2Cv9qwtQQWoBtdUDYTVBF+gGmxp8s5x4vKxyRFxx562RzAQQIrMnsx75vWhIooxlgWxEbv9+0HiLY49qnkW2PAmMc0FjnPQG3vgR93cFWsOGu7DcLk0PZvblddAEmjc74ayGQHvjQAVS/VcXGT2zkj3UWtdo7Avvftx+r963C9/2pevEuRoD4DYEz/+MZqEPzHfu+P9uHtTvX4Ff8xOc3lQWYUQegyN9FvxPNkRCo3VND+61uYS75iETlsQogZo/7J803EZnkxPcQur+YvzIg71b9gyoqJ0wvg9zCbbugCqCckPJ8qgDs9dwTQkBVKeWOdAKcxQhwNQGYFZgIsMDMYQ27gBUCQljbZ/sMMMAUNQAy32NAmH0oUqM2wMxWzMc2c7HIrmNjY6shIGDKCpljfenJ6AmEjYk4houayZbjHrPGAAAgAElEQVQIhnBs1AtoQk9dxA1yMXrqQtAnJqtJgKRehdFfHdWaSdmvyJxlAXzRz8RfC1vaiocE6v9HHZuv2UT7h9vQjfktrst/v4y129dQHVbh+V5m0540gPJ9H8tPL6P6L6vYePUGtn6s/Dmq31PH2gfXUNuowfO9iOLOC755Fu4y8oPKCCN4Zzz43/AxfF4245XX+8/buS+6Xx+rwPtlD7039NB/e7/0+fbu9FD5iwq8Mx6EFLu2Uc9e8/zDrdVqwfM8AFje9QYAM8/MACRNyGQSoEtf99KtT8Bk42sbNhAjb5q0+Tds/iOiGnqytfsEkKnfFzDJecIgOhAXI2aCJoIAmWMRgTTAwgoPseleaPsPGqvDGhthowyyxH3YsTD03omNGgALAmnLKAgdQSlHZoG9KNqcI8M24WDTDEnYmn0Ox06xozCjqTbQ093FPB0hW8LJVGhSRUnez0y+FnrTQggcOHEAa7evofmSJvrX9tG7uRzDV56RWPrcEpbvWEZlUDGdAj2ZmAyb15gOwwfh2DdfvYn2y9szMwIrf7OCxj80UD1fhed5kP5ovHk6AuZiAErw4MtiDiKv+8tVDJ+bbQBU7q4UPq8soIrfq6EBVv9oHdW/raL3hh6CW4OZGYHKn1fg3eVBrpt5JkHFy7V3EHOntQHfLYZAyACUpQMwbwZg2fM8tFqtUjz/eNZt+LdLK0oXI4BCBbkc9oJmHnnR2oQAGMrQ7hRAWCUeQ8ZTrJ0vg1hbYA9h2hABRvkHEBQWtSuYT8IqBBKgtZEZFmzDDhhjCziU3yMj+gMrN8xi5NVHfQ+18ek5BvehwWK66sUukObYOM056Sg8YP4CC9slUaE5PIchhgt6NEIDBCiqIpSXAYjfm1LK6N99X9oH/UUN/YcavWt6GFxiyt7UYYXOy7KN4cbnG/DOeAABq59YjWhUKSVkRZaalRw3YLTWOPDpA9j3qX3QWmPrh7YABgaXDtC7qZdqoDQ+1zCAd38V1SeqZqxSQlREqoiKkyebkxIui86fVUuCyGT1t9/STq2H97/pwz/rWydivh5sOBdRnsJH6+CPGENrcNvApA5frhG8cLpYFJ0m+Cd8E+f/hgfxXREZFiRLuDd3KARQNtgXEQ/K2trtdsj6lZIEOPcQgBCi9BBAvFlQeUbAKELPcAMRrYPoc0QCoUK/JdShMIrVW6iEIkBoghCMAARiY0KYbwubjGj6DDAEiK3vLsJovAFlQabPgISGERkMxXqElRQ2Z6JtXJ9hjqstW8GaI7xka5mQNqqEigXIfjeK8ccs46gNp2YIwQCk0SUAAFJQOsCmOjtqf2xJDWHnQCMh+3QG9b9t8+gg85v22jSKeppHE74exjpDMAUA/2Ef/NCobGz/n+/PvL/DxVQIAVGNLa5zLEcKjYzQS9da4+CnD0a/8x8nl+eFY4qPMRzzNHYuD71ORLj4H18MpVTmZz3PA2R+JqAIe+D6GdmTOPBPDmR2EoR0B6lZwwGT91n4WfkxOSpx/N3slsPxsZd1bxIRlt+57K61P6c09jJKUeexdTqd8NnaG0mAQojSygDji5VSKpcksNNnLFSTcxKgRijZaxQAyYTzYeLyIY1vcJltuMCEBljFEM+kAIw8aabIaADZdEGbUxB+TplsIRtKiKFoyDLYfgORoRRR/7A9A4T5uu1bAM0mg54TMvgtu2DGZHUSSBhVQk3QpCKmYKB6o2Q/EZ6cWd8Umy4LkqxhwoCgcpCfYj/x3eVN7pv2mazXkxiBuFEQ/35W+GrSS3MxUso0BABTLhhpTtgOgy5G+bRzcqWppzEUWbkOSfXaswo9zWogxMfvEi4om/p3NbAmGVbj3GgnNrbs+zB8dpLY3qkGSInH3u1bLAlwT4QAGkRUag7ALJOUtXDSGIpkb8bDt5n21t9mJuslKxMiCAFAA4IZZOl7TWQa/9jYPBiQpMaBCAxiaT14W94W4qXWILI1+1aknwimCsHaAmElQBi7Dw0bYgKxiqRzo9ABhxUIo/prFQNq5lHnQ4IGCSAAR8mFHdVBU21AMEHLMDlxlGYY5jxoFrZjoTCsgU14FI7MSzL8x82A/FUAaQula1gg6R6N/+6SDe0KnkkLvysjltdTTAPfMhqjpAHb5PHLBPWyvPys8U8rgcszV7N0NMy7toZ5VmV70kVY3nkZGmWN1eVcytxvt9sNr0UpSoDzNgCWhBBzMQCmWa6z3QEjHHHqBqgDA2LW0RcRvR1LuNNB9IoigrCU/wiywkA7QREZLORRZ0JgCAgBsIq0CsKOgqaKQBtAh83U16ZlMIXATkDI2ZtLJqxhEP9dhPmJxoCxzL0wVY2AIOvhj6r8BYRNDGQoELaCDfRUy4Y+rKSArT7QUZslA/hCKGg2XMjIYxc26XFWVo/HlADTOvu5JAC6fDctPJD2nTSWoYgxnFeqdCeAJy9dnef1eQJ/md8r43oWYVPKElIr+3OLAmNXY383qxR2Op3wud8TIYBaaLWUbVHNUiY0jXaFEIh32s00AMJugJbqV5YiDwjGC44g3njrEcAxLHcwAnoSDFYjK4KJRuV7WkdlhHHGnKKyPwOsZNxpa3hQLDEwJO9NhoKI9mXCFiANYb19EcuAUGGFg+1IOEouJKhQxUATttQZ9K2y36h0kMCsARtWMHaEttUFplJCC8SqH7TNgdCWIcjXm3HUrIhmKu1z9fRdGYA87+X14rM898lk2TKTnPLsq0ywmiUGvhuMhp0At90C6nthK/v8ymYuYli6J5IA6/MwAGa9qFONgJFPPkEJJG8KDGhlSl5Yg0PQUoASo70xj7x9YkCFMfdIKZQgNAMsRvoBFhjjsjsRjLPx2LXNF6Aog98S/WokJGQ8e7KfHYGzCUOEAKwtnNskRdtOmMLkwLC00eYShO2ONQc4G5yH0oOo4kEJAbJVB0IAxDrSLlC2MoG0BoQRPlIi5AcIAgqKZcQMGENgxFWk3heYXgAwC7hPA28XUHdJgHPx4ovc75P7mZUdSAL8eXiaed+b92uLOOZu8P6/nzeX0t/dAP6AyQGwY9sTQkBzMQDSvJ3ZjABONAmmYY9iC5taIOTNNQAJgtY08vFp1KdWIKwWoFBAEARCAIKgwBgBoUhQrD8BxZITyEr5Rq+IkEcw9QQiFByKMvbtt42jbUMEJvQQl/sRNm9R2QRGskyFsAcTPDJYhnqAc+qsjRFglKOglQVzQGu7QzECcMEaTCZ8oKEATZa/sBkCwnRBFMIO1p6npmQ+QCSUbiY9u3ni9rMmAboYCS7GQtriXTTeP4tnXwaFXBaoLSI0sBP7nwWwZzHuvl89/3mB/7yMgH6/H45vT+QA1LXW3Ov1aJ6TNpkxWtwIoJEdYNE1TYiEOQSuEVBxTJyFmAChABaGHWC2an8CwnrBCOGS2JbfKSslLEzmnLTGAFtQ1IAWBuxNYYEwHj+0EQjiwLxG2mbdjzzoOBNhtAsIFC8vUDaXgUx3AYGYwA/IChhpdFUfG8OzYCJIm70noM14I1ZDQJJJQtQghHy/tkaAMZQQSwQkQGoIZYsSMD52qOSsZCFkVF4YMQEinzefhyXIuieLAr1L2+sspmA30sFlgmpZr+8Wg2CeLMhOgvesx1v0eCc1Znbz1ul0oLVmItr9BgAR1bXWpesAxNubJk1gcSMgdKtDj1pE6n1Jm9Y6pjtvyXrFCCX2iQx1ztAQoSBQTDyItI3FE4c5fSOZ3bDYXtkqAyKwBUfWRiqYySQHmlJAhtAEJrYKgcJ44wKjvgGWgdCKI8wXTFFcP+qxYXMLwuRGDW0+R4TmcAvNYDPaVwCrTmjDEqHo0FiTACWhoAAlIUhZhsFWBgiGCNWFVMgkIGISRvZYMgMw3ng4tNrcvHwXRsDVQ3BN9MuK2xddBMvyNHbKiyyL1l6kIeBaCjhv2r/onOzWuP8iEvHi5ZfzVPsrmwEYDAahJsaeYABqSin0+/3SL2ga0BcxAsY8SMevBhyM6vytMp9gEcXewSPlfrZ0Otm6/hCBKURiq6THI3WeyKjQJKKSwbAZEEigAsIbj/04vrZ1Lx5uPWA86YjeD2WGrfdvLRARNgSyZoi2FQCR7cM2Vi/MJy6sXoqb1l6ET6x/GKeGJ9FTrdG4mBFvGQSE9hBBKNNQyLAWgTkvoa3CoIV0UyIALUQM5lV0TcPAgcKoRHKKFZAQBnDT/k9jBFyZgiwP3zWeP0vJ02728nZbZcCs4F2WGM+8rsNObmUlmC5yvHOpKMN89Dp6vR6CIAAR7X4dACKqB0GAwWAwF4tKa11aveoY7++4aVvkFgG5ZqMNEOXjUZS1zxYYo+Y9xs2PwM5Q9KPywFDvX8Bo9XOU+W/NFNboqx66Gz08y78aD+J+hLskkC3ds53+SINse7+AzfHDLoN65HOPdAKsB04ALuLLoNoaj28+ir7XN+l6YWKeUCBI2xfAxvMtG6GgjHiQHuUYSE2mVNGGThSECZNY0REBYSMFtp1i2MeABBRr53nMUv+bBtKur7uA/SxUvytLsJsX9nkkApYFhLN4vrsF/BcFootiCRatue+S87MbtyAIMBwOCSUJAYk5X+TqcDikIAjmRg+lKVbl3DNigQA3A0Aro5IGFQn/MGvzOzQ0a/MZ1lBgKNZgVoj+0/Z9aARQUPY9DQZrbfelEbDZv/mPoWH2ExDjv9z+J7hi37NxUe2ySLFNhccFQ0NBaQPIpn0xQ0Gbz4R/sRqNzf4wMw5UjuCag8/D7330d9Hmpv2mhmKzP6XYShabc9RgKLa/s9l7eC1Myh+bsWgeCSdB2fJCe15a2+ti8hBMHELlaCOcDahpDWmKvJ73vWmfc6XRs36KLL5l7DPr867vl+H1T+sKmOde2AngXhTY7ra8gd1g1O6FEEBoBBDRnqgCqJXp/U+7oEqpMfnIeVIwYxMBNfLmw45/wiTLSaurr22MHNBWZx+QzKaNcFi2p8MmuxqCBYiUrdM3XrsgAa1t5z4bJghL9PSlA3zx63fglme9GI93H8GQlVXtG5XTEdsYPRTCyjoCGaofRhMcmqFC0UImMCkcr9+Erzx4L9YPPIUDctUYJcKyA0JYLQCC0gJSMKB1WIMQS/gznv0QgLCfF8RQWkYVDMIaC2A5iuaThrB5hdDCWZ45tOBc6P68JX5FxH/yevTOGugLWrzn5YGWHRYowzufZ8ihbOOh7HyKnTICFi3AM0/Kf1Fbv98HEVVPnDjhvepVr5rJu56bAXDixAlfCFFdhAEQMgGT7xUGfx5XvpvKAMQ800jZT9tWukS2Xl6MHFM2yX6BELEyPhsWsOEAUyVg5XqFNSpCwZ6o9bABaQKwfEEDH7n7g/jXx38Dz25cg/tb99kYvsng2+fvx5q/H3VRR8NbQkVUQSAM9AAd1UZf9bClNrGpz49aF0PgSOUiXL7yLPzzD/0SVm5qIIA2eQgaEJCgsNxPCJBWCBSBJEbiP9pG7wWipEMlKKZWYI0PJaBsIiUJBRGKEygbIhDGeCrSKK0MWr9obN81qz9v9n+ehXmyVHCeNGtZVPFuEQ0qAvCLBMx5GF07aSR8ryr/zcMB7ff7EEL4SqkqgN1pAACoCSH8RRkAZcVxKCYrn3VbaK1tzX6sj0AYo6ewcp+jbn8MMi0/tRrlCGCUgRe1DLbfNbmChECETYVsroF9XdgmQtVne/jbL3wYL735pXio+20se2u4dvk5uKR+GVa9fVjyluGJ5KlWWqEdtNBUW3iy/xgeaj2Ax7rfxY37XoBP3vNxdC7agMRK1CkQWoKhLDALsLKvgyCVEfYJpYYEBJRN5pdRW2IBJWxSHxMUsVUaJEjr8ZOWhg8RGhJhZYJIc/hHRha53Rdlve7KNrneny5ywXkXuXl0NltEEmDZHviiPfm833G9h3Yj4zPLer7IY84ivb2bGABrANQAtHerAVAVQvhlVgDMy6KK7R1WrM6tFwB0lMEPxBL0YNX0tPXiYTrhCWKQjivwjUn7RKp9NpZguQMGa4AgjZQuW5lgK88LFqjur+ILX/kMXnnzrXj7hT+F/dWD8IXvBERSSKxW1rCKNVxUvwQ3rb4Qp3onsU8cwG/d/xto3NgwIr3atj0SylD7VsiHSRqNAggEVglJQoMFQxuVgCgR0pylBPToOpseB8IYBySiq2HEgthmRAjTTXHqrI1jP8/IBsyDEcjzmTJYgp0EBFemYVE0dl5ho3kZCjvJIuxWoNsJz3+RIYB5qQEuLS35KEENcK4MgJTS29raWtgFnYUFoHxRZgBAwMrUx4dZ6+FiA0PRAzYr3zYYUJGyno1tx0r9WDCk7R9gi+xMx0BLSwgEUcw+/J7SgBCMi2oX462v/wksVRuo+Ptn8qo84eGixiUYqiF+8Y3/FLef/wgebj9o/Xm21L4xYEgIKA5AJMGsouuoSVhBnzBMYEgPsjrJBGFaDNuwhhBWUIkViKTtQ6AgyMb+KUwGmM4AhGcjiCAElU7zF2EE8hgDeRaMvVD+tUiZ4Fm6DS4amBep8Jfn+3lFr/Za/DxL92Mvbb1eD6urq5KZd68BwMw1IYQ3DwYg60GdFvNMvcEjN9K9FFCHgkSWD4gS9zDy7EGj14y2P0MJS2zHxmoS3sLQgUa8HyBbipwjQ8X85pGPlx54BV566AdRlbVSFwtf+njO/uvw7NVr8NmzH8cnTn0MA/RBIRVPJpQhhARYQWkCJEAsIFgbap+N2WAqNUxWoCnbVFBsehYAAGsJEmx6A0BB2vCC5lAMSDiUq9A20aaiUr9p30l7PQ/NmMcoSLr/90J71EU3Cprle/Mq79uJc5mFLVnEvbETwDuLyNZuZACklB5K6Ag4Twag7nmeKFMF0PWCxvUB8rICI+05OB0nlPmPFHWtkA/F5HasJI/N87fAaUGcEbbMZQgSYLbqfFHcn22m/Sh9ThChLqu47dhbcP3+m+ZyU4f7q8gKXnPkNhz2j+Evn/pTtIJ26GoDEGCrFxAm9HFYacBGE0BBR2KJJiyibCOgMKRABuhVKPhjuhAKoax6oYBgFTYOdpvDGXsBZHlFLt+bt/efx1BYRMLTouSDd1JUaLeA/24C8722zVv5bxFbt9uFlBIoQQ1w3iGAUhsBAcaDFDG9/SxDYfLfqfslwkjBJ3o00g0AaOPFh93zYmI9JhSgbEMdDQGKpWva5Lcw7KDDzH5zTMUEoUPlQI4lCppvVEUdb7noHbh27Xlzf4DDh+WG/TejKmr40yfei1bQhLYGSdgLgKzgEGAqISAIkqPgv2E+YIwbk/9n0yKtUqHZByOwokpKmZwHgKFFemvgpNh/2nxPe6/Id/KAdx5voAzPIeneL6uTZtHeBUVDeLNWY5Qh8lQUQPMYly7vl8kALYpN2qnjTd6zZT4Lrng1JwYA2OU5AHUpJTqdTukn7yIslHfCJQlopcYQJev2UNo2ASLLBET1bWRof7aa+GHznai9r0keZNtB0BgBbF1X089PWdbcNOwxx2AW8IjwpmNv3Qb+ZcW3kvYTXsdr156Hd+ifwR89/p8w1ENTzw8AWkKwAstYB0QljQKheQogtLm2JttfQEtz7YQQJgHS/k9Y7QMI20SI2ezL6Uk3P1rrSH2yCNgXBedFAvxuDwHMs/nNvPa5qO/Mi+WYx2d28r7Y6Xu4jK08obrR1m634XkemHlp1xoAzNyYBwPQbhereshaMD0hoZQaayuTWQbIKgzzR+hPlvQnEYIXjXnwps2u6YwXrxowuKlMT5yI5rXecWgbgHHr0R/G8w/cvA38H336Efx/H/sTLNWX8dM/8j/gwOqBQg1lWt0mfu/D/xnrm6fxMz/8s7jmkmvHlMOu338Tbuu/BX/11PuiYj8Ie92UOVNhkx4hTDkfFEOF4XltwhthXoTSDBEmO7IwzYysQRRKFIcdBtNwPz7HgdZj911Rz34WRmAnPP48FOhOLrQuFGzZXQQXCf7zjOuXGTaYl4TybgTkydywvbz1+/29xQDkXdzKom+ThIGmhQQqlSqEiJWtuVh3rCIIYrZ0fZgkp2N5AMS2xj9WA6AtUxBSRaYHsM30DykGW19ARljoquVr8MojP5To+f/xJ/4ADy8/CNVXWPncMn7uDe/OtdiH+/nLz70fn9j6W1SXK/jtj/0Wfvfnft/mJoz2c+sFP4xvte7DfZtfBZECaWFz+01lgOkmqACtbfDDnKsUts2vtiyBMOqApsafIG2YIOzEqMjkTUBzdo1GJNxEOHL4MC685MLEMFDS7yFVl3R/xP+dpPPif0+7r5KOk8ZMTX5+0QZC2YtukgZB0j0Z95Sy9Avi78ePMfn6tN+T9hXKaMfHM7nfcIxJrycdI21ck/ubNo7w/fCz065T2vGSrrftKDd1bGnzl3QN0uZ22nwkfT5tf5O/ux5rEvinjTXLoMzS05iHQZu0xXIAdn0SYOkMQNnW4GiFhY1V52gGxCrKzA9ddmYFIgEdVQcoq7AXKv6Z5DarAxQxDfG5Z3DUfjfMCfAIeO2hH4Ev/cQb5eg1F2DDOwsCsI/2Fb42q0eWcWBlPyCAo/qCbdeD2SQr3nborfhm8xtQaggW2gY2DNWvLLhrlkb+14ZFlH0/TCAUylQ+kM0dYKEglLDvGwZg1BTYMZZG5voVAdlp8cmk5kJZID3t/SxZ4L0O/nlEh1wTGYuwG2ltm6ftc7LVOBE5U7iTn83bTjrNS3WRsZ42zmngl3Rv5b1eLsebfG7K9L5DY3raNY7P5yJYsEVtnU5n9ycBhiGAsnIAyl4EExd7jlHN8eLyKZuy0r4s2H6XTHY/G86eLYgTs00ADLP+7eLCo6CBYkQ5AGEewSiFgHDd6gtw1f6rp57HW577Nnz6/O1oyCX84IFXF6ZlX//cN0KcZpwZrOOHD7956sNyxb5n45bVF+ML5z9thywgoIyeD0ycn4UyHr/1zoViaCKYln82y18b1kBYXQPbQQDQyvY+CIsAlfu9wtMT4LJYoWkJQ2n3T1piWsgSuOSiJOVzlJUrEB9PHAymLaLzoHVdwHfa7/HX0qobXM4lDZwngdTFEHD1/JLO38UYcX12pwFt0r7SEjnnoRzpuq/4GLKMZZfrnnR/l3FOrtfP5b08n4kbAMy8qxmAxjySABfmycSIgakMgC1OY01WQ5+gw8mzXqxBRLYSA4YZ0GxAXggyNf4UFbxFTLaGNS5A8D2Jm5ZeACIxlXo6snwB3rb83890kzMzGpUGfuzit2dSXUSEF628HHdtfAF97sPo/hkdACbTEBhK2tCGhoCEEgxiCYY2+QJEFtyHUJAAC2hiCD1qiwxtWAQ3AoAsf4JtWhBZXk8a9T/t3ywjwCVb3rUdcJ76/6TPpIUrkgyjSW+0yMIVvp7lneYBBxcjYPL3SQBMMzCSwDOk5ZPmIOxBkrSP+HVNAt9pbatdvPRJwyQLkLKOldYgK+kz01psT7vGrt/LYt6S7sfJc89iMp5hABYUAshrAJTl5aflCUzeKLMcU9se9eNkgU1wC515MgqBmgBobf19SzVoI+bPCPczEgCKGx8X+ZfguiPXOTMas3pzrvt57pHjuPDpS/BQ79uAgNUqAEhoABJEptWwgACTsnkRiOr7jUyykQ8mDiBImv3AZARgCAgZQMMYSg6DN4uDA9AkAXfoEefx9F3uwSygTXpvlqqOslTPsjxGVw+vyHened1hLsY0o2SS4ZgGaFkGw2QsXggxBvZxD3MyNyCvZzsJ5lkgPEnnTwP/pByAtGd78tlIMi7yeL3zVt9zDecUYR/mtZVhfHS73XCd2t0MgBACZSsBlmU0bLPWx7x/RyXAkJbWpnOd8fRttr8O98QgC0pG/15EsYZI9ldzFBqADQ+YHsICIMJl8gp4U2L/83i48tCOV/nX4oH2N2PNjRhCh02L2XYIZFsCKSDEEJoFCDJqAgQrE6wUIGPUi20VYNIDpc5gbKLgivkrp3E3zdtIo+vDxMFZ79O0RT4uaOWiRTDPOuusxSsc6zSP37UtcjwOnwYs8xYMSqPs81LAaYZOEXo67+fyfj4r2dr1+s4DTIuEZRZZAeBiZM3KAOwZA2A3hQDSbu6RB8ZwSgAArG5AmOVvvXriqN7fGBahGBAi+dwRWW1S50KfP2C2egJkG+goCC1w9dI1u5aOunr5ufjQ+fcDWgJQkBBQIsxulCDL3hNkyH3YZj/mUknbBYl0WB0hrJJgqMlAEJzRCyA2XWGSYpon4pKs5wrergtmUdZpVs9/Xgagq6GQJ5Eui7VxoXmT6HrX7PFZr4vL+3k88CJlvGXFune6VHQWo2NRXvpOlRXGKut2dwiAiJwNgJ3ocDbu5VHuMRjYDwXt7b7CxSpiCSimKUAgjun8R5pAMdlgNr0AOHwPjIO1w7vWADhUPwyQMI2RyKojakDaDkBChCaOhiBhOyQCpBhCEAIYY0eQMaY4NAZErD1ylhDAmLlm2zBPiXNPo+bHjcBkyni7sZgeby8Sr58MQeS+J3cwtplGtyfRstMW07T4cVpPhqy4fhabk2RohHOtlHJe8CcZnLT8g2lG5OT5xvczDeinVatMy4hPCn8llSEWZVazWBOXa+ESWph2X2QZnzsB4C7GRda4+v1++JldzQDUiGjhZYBFvCuKZPxcuwAgojpZhCDFJvnflAXYxD7b1Q9GHpeFBlkFQALbenjzeYKysr8mEZCtjkDNq+Pg0sGFG0mu28Hlg1iSKzg/PBcBsGnnZ0IhrG0BpCBbImkof0GwcX3TD0AxIEmZpD9SIEVQJExjJAEI7SIFNBpCGrgU9eZdPew8TajSEqP2wlbES83rzaXR5q5NmmapGkij/V3Araxr6BrLL2vu4rkAeWPXRTPh8xoZafO3VxP9ssbdbre/9xiAXXfBHSIB2n6Ao5bAOgJzExGIlwfarn42P4Ct4pARHVKRt2sr442RwAQKCE+efRLNdjNKOtw+jmyrnWCOnVOSaRqmGq+EBFq9JlJtNAUAACAASURBVHRfQ0FBWc1+I4akI5aEiGy3QwEJhha2UhICIAWpAQhCYHMB2PYDEDZ3QiiFTPHnlBYOaQCbVSEwjRGYB4OVd4HcDYZCVl2763fSEtuSQgpp+3YJObh6olkGRNGkLtcyvyJUtEv1hmuFR1FWdRH3XdI8fz80Norl1e3uHABmRtndAOfJFvAE6mdlAiiYkrUowY+NmA20SQgUCBv6mfx+TcbtjfoEWKXAy5cvxxUrzwaY8XD7ITzWesSMjwnnumfx7t//OXCgY4aGgWQNjc3hBoa6j5EcEUXCO9Hf5mQRdhaMzpsI/397bx4lyVXeC/6+eyNyq+qq6lWtbkndLaml1i4QCCQhTMsywpgD+PHALEZejt97Pu/MMCPbY73jYx8844NtwRh7BObB4IMwNm/GoGdbGhs/bIxsIQkZtCC0lZaWulrqrXqryqrcIu693/wREVlR2ZlZkVVZVVnd369PdlVlRmZG3Ii4v9/33W9RSUUipBsQxw+VZN+lX0/c29Ez2tfYePMYckMKcFGBo/OHdmH3ukvgk49XK69if2VfMyjQIopvtABU7BGxALSdK/cTpUJGnoM4RjAD989F/3MPE0LWfP+FYgWyToDL0ZtgEO6jXq3Ehdz5ixEgWV3zSyHdrMVysri0O7n+exGFvRz/UgRG1gJW/RIUvXjZVqrM76CkD9br9WQ/BtsD4JwbCAGwkEt33gQf1+ePC3MuQDwWltWc1Q7AWo7WuNnBkkqVqAWcJSji2BJ3GPJGcftFv4SbN/8E8joq61y3dTxw9Dv4b69+DVVbRb6Yxyf+w/+MYX/dXI0BAJYtZky56RWgef9T0xOf/p9jcRBz9xzZzzXtS1X+SwuHuGoh0zxXgIaHhqvjvkP3omxOoYASPrrrF3HbOe/BsD8MADAuxPdPPIR79n8R0/VpKJ0SUC7+TK2aBK7dXFEhBkU1g6DAnay6xPGSkmzUZvLMsv7faWJbKOe/XcevLN+ZRRRkzUpYKU/ZYirstfucrAVxOn1XuxoD3dLhuln9WQg52T6d9tf6GZ3W+zvl/S8khrJkO/RSMKjdZ3c7/qw1AnoVPwvVJ8giaNp5YfohZgbJMO20n1prGGOYiAZXABBRIQgCHhoaGnjThuPiPM66OB4g+/sYJnbzR2l7kaEdlcMla+MMgaj4DRHDcWL3K3x85y/i1q3vnHeyC7qAn972HsABX9r3BRA03nveB1D0i4M5dmB8+8Df4ZRjfGjnz+MDcRGh5Hg85ePmzXuhnYfPvvSpqAa50nGR36gNs7JJKKUGyEXxFAmnWgI0LyjFoh/RzW0dn3Zhd7PkF2uFZ22Bu1jizhL1ntWT0S+rsF9rzgutmWd1sWdxcS/ktcliyXcrZtRrvvliz8FSCictxZuxVohzuQh30PZ1ZGQk6Xa65GZAajl3tFqt8rZt25alJ3K/0bzBOe1EzjDBc9r57ODYwjoHdhaOohK/DgY2ERlxY4/LRq7ET277qY4T/W3b340LiuejETZQrpTnqe1BeQDATHUG9UYdG3Ib8bPnfbDj8dx4zs14w9ibYWBhnIliBmBh2cJwCMMWzGH8rEHoDEJn4eAQhgaGM5YCpvT5y3bjL7a6XrdmK1ks4KVOOO2awPTrvC5lIl2KEMm6lNKP9e2FqjT2Q/QsJIKyVoLMOmYLNaNa6ncs5lythnd3JfdpIcOi3991wQUXJIGAS74wl5OZZ6anp/HOd75zjajADlblAtYvNyMHOBX0F/1zzHDgOFjQwToHBwsG47LcZad12Zt3Ykhhd24PQg4GfuxCF+JCfzdyXr7r5HGxvhSWLSw7OGvhLMM6B+s4on1nYZ2FYwdmB8cMY2Oh4LoIAOK5mArONlH0QnzdKqp1EwZZ6/9nJd+1ECeQteBRN/JeKCYjC4m2e61TdbxeRUYva97ttlto2anda52qSC61Uc+gX0ud0m+TmJPkeBIjMynOtVDjrn57kFdqTJ1zuPXWWzEzM8NEVB5kD8DT1WoVe/fuXVQhkNVE0wmQIfe8ufbM0WO+HHBgWLBjMLtYFETLBaqx8OoLVRWYBn/sLDG8WobVpFq0sg9n4RA9mOOf1sJGURWxSIjKCDPbOOrbLnkyWUlXYb9rj6+1IMFW4stCvP2sqtjtvCV/pys5pp9r91ndrOhuJLNcRNSttXWnbfppvfazpPpiiLa1ZkGWcsxnggcAAG644QbUajUFYHyQPQAPW2sVEeFXfuVXBsYiWajm+uk+gG696NPEn8SjRevVHL/GzHDxv0QQWGY4szCxW2sQctgx/W9Q4MAITLjw8TgLZw0sDIxzkcUPB8sGBgzLBs4lXgEHRmqpoEMioNJRnUFOLcQQstXSb70WslqWnbwCvUyaa5XYl2oVLcW13208szR8yvK9nfoPrLTXpN9xGFkF2EqTWT/unV48Rmsdn/jEJ9LX6L8OsgD4HoCjtVoNt99+O0ZHRwd2ompr/VOyLNDtRsS8JQCXtv5TSwHpRLXo8x04wxJD6Az2lV9Gb+WJVmMMbaY9jEImHQxz08IPnYF1DOdMRPwcRnEBsPNEgjEdlkqUigQac8diTotNUeqlYtdiJ5pOVeLWItn3IyYia7+DfhfZWYyo6RdZrsTST6cGRMs9ZssllFYq9W+QsGXLFvzcz/0carUamPkEgAcHWQDUAPyhtRbDw8O4++67B36AKUXTyTW1QMZw066fs/gRewTcvLoCjNQEmZHQp8NpNGw46PQPa22mY2Jm2GTd38bLAPFPwxaWTUT2sLA2fnD8s0M1gGh5hZNKzM3RXgz5Lpcl1+t6czsiXWrgXpbc934HDbYr1duLV6DbmvdiPAntPD6dAgE7NSfqp/Xc7Xi6xay0bteufHQilNK9EXpdYsmyhNAqXLN8z2LutU5lkrN8V5Z+H73sx2p5SD772c+iWCxGmVTAHwKoDKwA2Lt3bwjgXufcE7Ozs7j66qvx+c9/HqVSCYMJiqr0pYTAQpirBJi2+Oese24h/t7oKX4/D34MgOvJIrMwMdFbF637GxtlThhEqZjO2kgscBwgGAdPdhmoufbLiGoL9GoldiOm1q5/S1kzXaxrfDFWeC9ZAsvtFVjO92bJCOjVwl1sWl8WMbNQeuggueHT49DrfvWSgZBlyW0Qx2clMDIygi984Qu48sorMTs7C+fcUwDu3bt375Jb7S53ft5BAL9mjJmtVqu48cYb8eUvfxl79+4dSPcSpR32WRoCJhZ/c/V/vsXfDBEA5i0GcMZug4Pu+k8Q0XiG8qvgeC0/tvNdnDYZP2BDGGdgnIVBGLn/Y8+Asbb7OPHird/WiTjr5NLNKlvsRLsW0c1zsRjSX8797BehZz3P/bQ+l/s4O+3rYgg7y3f0UkejnXfjbMCtt96KL37xi3jLW96C2dlZGGOqAH4dwEQ/Pn85KwFi7969/MADDzwC4OONRuMzzrmLL774Yvz2b/82Pvaxj+Gf//mf8dBDD+G1114bID9A7A1AcpFRV0JDyt5P/z93faYt/iQGgHEmXb6dgqfabWcBWBu1DYZyUDxXWtggqqCoAFgX9VRQoKhpkFr6PmadtFqru2WZ2NpVf+t10l8LQYL9bLzSz7bD/fiOrJXnFtq+07ZZKvuthKHTad+79RJY6f1e6P45k0XAzp07ccMNN2Dv3r24+OKLUSqVUKlUYIx5BcBvAnhw7969fTl4b7kPZu/eveEDDzzw9wCOBUFwhzHmA8PDw7j22muxa9cufPCDH0Sj0eib+l9sNbcXx1/E0z/6cWyic9TWlxa2aLMQ//zXzqyLlmN7PmsQYET+gCXXbHdMcUfFqHeCivIu2Ka6CSadA7N5Sy666CJ8+OMfWdAK66Uk72KfPxNr/y+HiFhKHEOn5zuJ0qzf34/nOr3W6xhkaXyzmHFdaEz7FWOSZVwW+1mL/YzlyLRYKncppZDP5zE6OoqRkRFYa1GtVuGc+1si+iyAR+Pl9b7AW4kbPhYBjxDRK8z8zZmZmZ/RWt9ULBZ3jI2Naa1122CWlZww69UaXn7hRbjAIjtNz1n084j+tNfbPnsGTegu0xIAEFVFjAhexW0IHOAo7qWgQMpiruWQij+XOp6R5BVOjXGpVMKFF17YN6GYDoQqFosQDBbq9TqstZlSP5fbU9AL0fWTQHrpr9Bv789SvqufnQiX+xhXwovmnIMxBkEQ2JmZmQPW2oeVUn9PRA8CONwvy39FBUAsAhjA4QceeOCbSqkHmfmCWq02VqvVSgB8XmV/zhOPPXHziRMn37t+3eiOrETNPN/Ob7X4E/Y/fYngDPMEsIPLcDiMKKCPEFn7BMCqhMgVLDloGwsDhcgLA0B1EQDzRzNqyLR//8ST+/fv/0xM2pmZvtumSikmoo1f+cpXPlcoFJZ1ONeSd2C13bCzs7P44Ac/+PubNm16otFo5DPu82J2mrOOx2Ld00uYA/lMOZ+tY5Hcv3yWLPrHxxsCqBLRtFJqAsDRvXv3Lks0uLfSBxgfyOH4MTC4+S1vK/i+/46xkdE51/8CsXrcEtWfJv75dM/zlgEYjLqtnzEXrYXNlK0QNV2K1v8t2WiYnYIG4GBBipqx/tYCmuKxJOooMBLrPykFzMyYnpo6+va3v/2/t3EW9HQvtj7xt3/7t9uNMQjDcEECX6nqaGvbc9SfXgj79+9/5N3vfvd3lokoeZm37weB95McB4Jokzr3HPVA70vde8EACIBBhWOXGKWZo/RPs+251W+QEgdJyUpYvF55DUEpS43/tUEgJmNtg6gUsgMTgxwAIqionyIAQDsCK45aBAMwHHkGmBk2aw4zAOK2A8c9DuhpHaEmJibUzp07O9bfVpjfQLr/QqD1G7JZFGlripmYiGk1Lap+f/Xk5KRb4DwSlp/IV4P4B4awl4P8038zM4kIEAGwnNMS5hzJ2W8tPs3i5xbrdM4LEHKIA5UDaGS2/tfG9R4V48kotBBF/iezso0JLc64B1nb7MykYsKzCujcCoCAzGmVp5EB9XISNm/e7HmeN9KHCU4s/T4in88XF7h5lpPMV/MmXQ7Ln1bjmBKST10zlPYCCPmLAFjheypjN0A+/T2txA8AVVvD65UDMGzOxBk+U9MiZoZ1DFY2Lt8bk3xMiNZFgVwqDhC07ECUxe7lXuZF7mbld8PY2Jjv+/4yWviCxYgF3/f1Eq39lSZ9XqX3dhPFPSnpZTjv81z9rT8FIgBWTEtnLtPDpyX6zfMGJD/LYRmHa4cGvqnPYuGIwS5bIqCFBSxBUWTjNz0ASkU5/3GfhKQBk2LAWgVHGc5fs3wzL8Xi6/hN69ev16taybLXRYyzBFpr1ZNyX13LfdDIfyDQ6gEQiABYvduTs2/MaSv4tOcZxxvHcaw+eUYPmeNsg+Y4DtwCYJkAOBBF9r1yUZEgUnGOAHMkCAgAbPeP516LLGeaFE+bjEqlkud5vd0y4h3on6W/gAAYdAIfpEC/1s9bNSEgxC8CYHB4P1VTPosQaNJ8m3Q/x4wj9cOYDqbOgsk8WxpgUjLZuji4DwAphiJEpYAJIEsAMZQCXMrs71YjornkwvOI5bSmgEv1CuTzeT9LZUDBykIp5S8zkS7VaqdVeO+asPxbxYBczSIAVunqO/3+WCgbIL3+n7Y+DRscrL6OqqmeJeIpu9vEWgtFCrG9H73TRpn+UEnFXwdn586JgoZ1NtusRh09AT2t97d7r+/7Siz6gRQAegBJL03ei/1uWgYRsKrBfgt5AUQEiABYrYvQEc3z6GNhx1Traj8jsCFeqx5A6Lqn+Sla2JLUpNdA1cAoFztrzXwbd0yMbnMVR/fZiPgdgZUCpVZzFQiWui0BtIgPXnDCzbTe3/Zm8TwtHoCBvHe9Plvs/SLZfu3HcqQLrrrbP/1TiF8EwCo7AJRrGvWgTLcItwiAqqniYPX1yJ29ACZnjy64zbHKMawNwmEcm104zqFcLwPOwSoVVwN0zXF2UJHrP13zXKmoywBn4Op5cQjkMu94D0LA930/S9MjwaoKgEEh/9Xch07eiIElWUn1EwGwygKg9zswXd1vOpzC0dqRzBb7d/b/I369+psYKY22DYiarkzhwUMPILfZH/yLSHl47NgPcOjkIWzbsK2t5V8P6/jOvn+EG2VQTKJWISr9C4CVBVjDURQnACgoZ6N8gG55gKlpbQk5TJmEgFJKlgAGE2oViXfgyXW1Lf7E6k+IvtULkH5dsPI3jmDxqhWOGccakzhSO9yTu/4l/QL+4K8/1STI9IOZ8Xv3/u84VjoKxYOv0TzyUVlXwe/e+zsw1px2PADwf/1/f4zHzA+bjZE4MvthlYOFg0NUJZHZRcsvnDwXpRhacIZpbclzSNfwT6WUr5SCPFb3kTQOS64vpZS3HOd7Fcj1rCJByQAQD8BACmVqUlT3+9HB4lD1ICqm0rvyGiX83y9+Aae+cAr/8bZfxaXn7QEAjL/+PL74rT/FX89+E/7Fem1MCQ4gH/jr8l9h9k9m8b+85w5cccEVUEpj35GXcc93voI/f/3P4F+hYdmCoGP1GXUCBBjsAFLxUkD8mrUMpQiWGK6Lcd6cwbkZVtg6mS468E/ul9UX2Rme95Z4XlfT4udlm8gGlOjF8hcBMHgc5pxjPp05ulHHgdkJNFwj203Q5o70L9G4d///g2//6bewNRe5zg+HBzF7bjki/7V2Me3Q+MeD38L3vvSv2O6fB0UKk+ERnNp0Ev5lc2KG4xgJCwWKG/5EhB81ACYCLAhQDhaAZgXAZprpuH1BgKWKgeQa0WdJU7K1JhIW8mT2m6z7JSKWlXcHRQS0uv3lihUBMJCWf6qiTPx79/snK/l3mzG8nRrVc2ewr/5CdNcWCV5u7ZA/xf+ax7NdIdhSwyvVFyOLvAj4ed3RdZAMcZT1p+AoKgDkwFAumsWMst3D+lr7oC/T5Ouc80QADCT8FSL+tWKhD+RFKoF+IgAGXgKsxi1EeQJ16WSeJWVwNdGa9UA+QKOL4dhIEMyJgfj4bbQM0O3M8VwN5l5OdU876ZyTLIDBhF7GO3cttNrtR82B5Z3jhPhFAAy8JZsKWhuUW2kmLONY+Ri2jm0dyHGbqkTZDyj0d3bkOBMA7OCgsEyGd09CwPM8r1arSXnfwbIqUSgU1Bog/+Wdvga4U0Q78hdvgAiAgUKhWGTtefB8H1qp+UGAq3hbOc/ib5/477jqgquaGQKDhPsfvw9Vr7o8QxQ3T+I4SyDrVOh7PadOcpZJtdForHfOiQAYMAHQaDRGMdi19pft8AdJsLSu8bcSvAT/iQAY3IHwPFaKACJwXBJwIC5RAr7y4pfxpsevx09f9+625JNFFHQiraW895HnH8bnfvTHoItWZKrv+krUjTCqydCnyWXeZxw5cmSdtXaPLAEMJHYeOnRo/bZt206dwVb+moIQvAiAtWVJOAYTgeI0wGhmGIxruHreLP7zvf8Bv3b4N/HBm34OW9dvPY2guxF5N4t1MV6FEzMn8DeP/jU+890/wNTlJ+YFAS4XVLfvmJeY1fdzxgAQBMElzHyTeAAGzwOglLomDMM3AvjnASH/1bD+B+FcULdIfxEFIgDWgnZNrubB2SMfqF45i08++lv4wnc+h23D2+F7ORhrMFIawR/e/mlcsv3StkRORDg1exK//pVfw8Tkq/B05B43NsS2jefhM7/4R9i6fmvH9x44dgD/5Wu/iaNTR+BrH6ENcbh8CIeLB5G7XIMKA0KGp8cA9iX1L4Fz7iIiuqzXdsCCFbE2dzLzVT0KgH4H96XT7pY7BY8H8Bxwpyp/AhEAa9C0GLAbLAfkrvFwsjaJ49WjUWlcAnIuh3Kj3PW9DRPgyeIP8fp5B+ZK6irgMB1ELezesbAaVvD48KM4OXQiqdALdTEhX/IG6FTN53rqPEEv3gOh1AWdus4lXhTxDCzdml/k+xQR7cpIzss1U/Ayzh59FbPLKQLkKhYBsCbh2DWpo1/1QZflJisSdHFuDhjSJWjdvW6AIoXixnyz7n6Cos4v2GxIKYXS5iKm7eCmIjLPN70cc5ZJNLMoOHLkyB7f939GCH6gxcPbjhw58satW7c+0XK+l4P8V3JqaBUwqz4ttbP2U+dBuvuJAFibAkDH6cRJaRvqZlP2csMsp/lhM27Xbgdchh1LevMMKJRWUIrmHWCG2A3uxTvg+/5bAdwgAmCgcaVz7jYAT6ygNb6cpJ+29ge6i58QvwiAM8eSaLH+FRQsurGsWpAh5Y7ofcwyfxKpeJrk+Yqrt4mWO3kFpqenh5RSb9JaS+OsAb+orLXXTk1NDY+Njc0soyW+0tPRwCLd4U+IXwTAGUf/2ZYBlss8Vhho03tJ6N9xMXNz7XjObKKlNv9pfpRz7lat9b/zPA9SBnigyQgAbrHW/nsA9ywTEa/UBTDwlr9ABMCZNYHEDnEGx6Ti4u5yq0+SJDNB99nZxQFk8dkDc9gPqysIAhDRW33f35wiGcGAwvf9MWZ+exAEX83lctyPa2AFLI41Q/bdCvsIRACsddvfMsOB46juAfNLrAEBtar7OeetITAh7Mdnlsvln/Q874NpL4Ng4L0At05NTX1gy5Yt966hW21NuPpbiT8dCChXnwiAM8ALQB1ppT84c936vNrigPs/l2qt3+Gc29FoNOTmWCvXIfO5vu+/C8C9PVw1q6lfeQ2N7TyLX4hfBMAZLQf6j/6TPxEtmKXQaRsCZUoDBNGSpqkVnyV4aSevVqvR0aNHP+T7/scWGh/BQBLVu44fP/7R3bt3/7cBvEQHtmlPFk9AO7e/LAWIADgD6D7KJo8rysd36uBf0zVTR2i7e7xDGyJ0p29jnEFggq7vbYSNqFiQHuRYhOSsRUHJRM0Ex0VNtBMTE/9Ja/37xpiRpQizZNngbI4dSBdIWsFllK3Ouc+88MILlUsvvfS+ASThNUOWrcTejuiF/EUArHk44hDENuISWjMSPUQDT732I7z5wus7bvPc68/gSP30lr1HG0fw1IGncNE5F3d877MHn8EpcxKkaY3MWsREVO8w0S5YAOjZZ5/9d2EY/haAEbkr1jTOyeVyf/AXf/EXRz/+8Y9/H6cH2610oN+asfzTln6ndX6x+kUAnGk+AObmfZoEfa2B+1UD//WHn8d7rn7vaU2CAKAe1vGn3/scwg2nr2NznvFfH/kcbr3iVoyURk97fboyhS88cjfoPI1Bjl2gZvZm03/DGSyv1mIr+NSnPvUT73rXuz5VrVa3yf1wRngfLtm9e/dn//Iv//L2n//5n3/pvvvuo/e9732rYekPTBW/HsePOuX6C/mLADjD6J848SIz85papHtt437c/vmP4g8/+hlcccGVyPt5GGuwf/JV/B9/9bt4yPsXtK1jQ8CP8o/jlz5/O37vI7+P3dsuaTb8eeH1cfzO//tbeG79M9078Q3CRIV0UUPK+pZ5+NrXvnbltdde+5ljx47tloj/Mwf1ev369evX/8k999zzi7/0S7907K677lJ79uxhAHjf+94nJ7qL9d/6vIyOCIAz2VwwYHagKPk/ago8iNf86ZkEapjw5KYf4s57fx3vueJ9OH/j+ThePo7/8dw/4Hv8APQ5nQPZ9EaFB4Pv4s6/+g28+8r34JzRc3Bk6gj+/pn78YPS96HXr0wQ3NLjC5r07wiUKWw/tgj5S1/60radO3f+n865NzYaDcn3P4MQBAEKhcJthULhM3/2Z3/2q3feeWf9jjvu0O94xztccv6X0fJfE4SfWPhytYgAOKt9AAkVtfYCWB1C64T2rni9SeFH9Dgef/SHcFUGFQjeuaor+Tffe67Co5MP4aEHHwTXGapI0NsV9OaVi4DnDuKml/GmjBPwfffdR4kF+NWvfnV4+/btf8TMt1prIe1+zzyEYUhbtmz5yMTExMl/+Id/+I2pqSn6l3/5F7V169az2hPQycoXa18EwNnoAnAAXDOWnJYWA7Aad5DeqKA3Lo609RYFvWW1U97cksY7VcTZdiP+8fFxuvzyy/n73/++GhkZ+YPh4eEPNBoN5HI5uQ3OUBhjvAsvvPA/jo+PH7/nnnt+/5ZbbilMTU2ZPXv22D7c3muuWGe7QL/TDlIC/UQAnEVqOATBzN3GUoB3jZ3AKAiQwCDqmtt45MgRuvPOO93Xv/71Oy+66KLbG42GLhQKvVwrzfQ2SfXrk/xOjWPr2PbxHi9efvnl/+vdd9998Lvf/e6f33zzzcWvf/3rND4+bvfs2cNL8ATw2r99JL1PBMDZPAEhVfqfYg/AwCyLncmNgfpJIs0T2PbEjY+P0/j4uLrnnnvMl7/85V+87rrr7giCYDifzy920mxLXILeiX/F7iSlNr7hDW/45N133330e9/73v+4+eabi+Pj4wzAZRAAabfgmrUQugX4idUvAuDsNCBBlkAhYu6ngbq/V4v814jwIIBclLlBREw4vRnQHXfcoQ8ePKi+8Y1vhJ/73Od++uabb/6kc25Tv9z+3SxWEQWrS/qtyOfzO97whjd8+rOf/ezkBz7wgR/df//9ubGxsTDJEGgjBNqlj65Zl3+vngCBCICzARaAWep9fWYtHKwhrwPFegXEjLlmQMm6/759+/T9998ffPrTn37zbbfd9mnP8y6w1q7uLmdYQhgUr0LrfrTbr7Trfjlc+P3Exo0br7j++uv/+N/+7d8+ds011xzet2+f3rp1qxkfH+dUrYAz4lZutfCF6AUiALqak8Bi0wDkrlolgkqt3igoSsh/fHycHn/8cX3//fcHn/zkJy96//vf/yfFYvFyay2kzv/ZjS1btrzt+uuvv9vzvNsPHjzYePzxx/XQ0BDfddddfOedd55x5N/qBRARIBABMCeNQwIMN1l8MN22Z5aHoT9LDEnhZgYBRMzgBhCt+T/++ON6bGyMP/GJT2z5hV/4hS+uX7/+rcYYIX8BiAjnnXfeewD80ZYtW371G9/4hj8xMaH27Nlj77rrLlqrWs859gAAIABJREFUIqCbu19IXyACoL3lbhmwFC0kx3FkNIj7eQahT0sMFK//x82AwDB33XUXxsfH1fHjx/WGDRv8j3/843efe+657wjDEL7vywUvSAhR79q16+NKqcm/+Zu/+e1rr702//DDD/NNN93k1rIImLNr5lL9hPwFIgC6GaMJwzJHVuWAioAzzYJfumcjXrZpegKYvv3tb+uDBw/6v/zLv1y74YYbfm/Xrl3vN8aoJOhPyv0KkhgGIsrv3r37P3/rW9/68Uc+8pFvfvOb3/SxRtNuOuX1C/kLRAB0NSLJEMgg8QA06wEKlt2Cx/yWaUuREaTATBwePHgwV6/X81/60pe8U6dO5TZv3tzYtGmTr7WeR/4iBM5e4k9+D4KAjx49OvODH/zggr/7u7/z6/W6evjhh9UgewFaiV6q+glEACyNOxgElzCQUmL7rzSWNFMRRSs3IJADh2HoGWMKYRjqRx55hHft2mV3796N9evXY2RkBMViEb7vQ2sNImo+2gkDEQlrk9yTv5m5eQ6ZGc45BEGAWq2G2dlZTE9P49VXX8ULL7zA09PTOSLi48eP2/HxcU4aBw0a+Xez+IX0BSIAeuZ/OEqF/xFI8rfX0tmbcyGwY6eMMb5zrgBAf+hDH9qzZcuW0RMnTuDkyZPQWsP3fZRKJQwPD6NYLCKfz8P3fXieB61186GUOu06aBdAuBLXyiALkdU4/jSxJ7DWgplhrYVzDsYYWGthjEEQBKjX66hUKgjDsPkaEdG2bdu2/dRP/dSmRx99VBMRV6tVhSg1eDDFsqzpC0QA9NX6DBwQzEsBlBCANWL1JQ8CCMzg0FqbY+a8c279l7/85a/ddtttR84777y3btmyZevQ0NC6QqEAZsbMzAxmZ2ebZK+1Ri6Xg9Yanuc1BYFSqvlIvAaJOEh+tvMkpMmx0/Pttkn/bPf+LM+1ey0rwaYt5oVea32u03u7eVVa39/6AADn3LznnHPN55LfnXOw1jZJPwzDee8F0PT8BEFgp6enTxw/fvyV559//r7vfOc73w6CoJTP5ysDPVelLH4RAgIRAMthUTaZX+6ttXG+EpKLYjfiSZIAeIcOHSrfc88932XmJ/fs2bNr165d5xcKhdFzzz139JJLLtk0NjY2XCwWC7lczlNKkVJKa61VmujTIqD1+VYRkCbdbsSehfCzCoJVIKGuhN+LIGjdNk3WacJPrPvk9eT4O4gJZmZ2zplYCATVarV64sSJ6fHx8SMnTpyYmp2dPfT8888/NzEx8SIRHVNKzQ5iemhry95uDXwEAhEAi6MQJoJLuL+ZCSj8v0bon+eCNomMUsoysyWigJnjKo8IxsfHXxsfH5+Mr/38yMhIoVgs+p7nKa01EZF39dVXj23cuDG/adOm0tjYWLFUKvmxMIBSCuvWrSu1eAUon8+rVg9AOzGwkMWe3qYbGXUi/+UQBZ2WHrotSTjnTiPwbt6AbpZ+8qhWqzYtEqy1bnZ2tpaQoXOOy+VyvVKpBAcPHizPzMyYp5566gQRwRhjgiAIq9VqrVKpzAAoE9EsgBmKmkc5AEYpFXqeZ0ul0qpnASREn1j5aeJPB/mlvQDiERCIAFjcJGeZozW/aP0fnXrK9Igzt5HPYvXRsugqolQWIEKllLHW1omoQkQ6thgNgDozFwD4AHS5XEa5XJ7n6pmYmEjXe8+0u1prstZCay030wJISjAnY5WMW/r5DmWauYfLq/XmdfEjJKIQQC0m/xkimlZKzWita7lcrlEqlcymTZvcSgcALmTZZynuI+QvEAGwSDoj4mYTICKCgmqWmF08ztwufivRO3Vh9qUm9ytSIAUopWw+n28AgDGGAYTMXGfmMoACgHx87SvM7+626ENwzjWt91YhIMKgvZci/TMZv/RY9uQAWvhcMaKgvjC2+OtEVIsfFc/zarlcrr5u3bpgw4YNTfUxCCmAUshHIAJguW8yBQOQmU8sssw2+CKDU+s1AIFYKQpHR0eDmZkZ12g0rDGm4ZyrMnOOmX0APjMrzJV/6tuJZmYopcDM8DyP4uc4/XcsSpp/n0kwxnD6uJK/k2MG5pY2Epf/Mq+7pwWAI6LECxAQUai1bnieF/i+b0qlktmwYYPdsWOH27NnDw8K+YtlLxABsPxwFJvrzeVJmvMGCAbbezNXDRAAqXDbtm32+PHjXK1Wba1WC4wxNWOMx8wq9aAercnF3WTe3G1WLBapVqtxu7+T34vF4rz9aPfcSiL9/cnv6X1ut23rPqePeTW0Y4pIHRE5rbVRSjnP82yxWLSlUslt2rTJbdy4kVeS/KVyn0AEwEBQSEvlPwKUirwALJGAAwvtaSiKLEgVnz9FxDfddJMbHx9nAPbEiRNmdnaW6vU6xfndiXW6KqRaKBTm/X3BBRfQ5OQkt3ut9fUEW7ZsOe259PPpn8lrrX+3Ppf+vPTnt9u/dvvZ7fVO26/YROd5nP49l8txoVDg4eFhTkgfWDmXfzrAT4hfIAJglREFAXIUBKgAIgWVRGWfdcUA1k7gIsWWv5pbBmAwbDyRMwDcddddND4+Tq1BXePj4wNzYnfs2NHz6+2e27NnD8XCBzt27Jj392233db8Pb1t8rP185K/05+xVtEuoC99Taymu18i+AUiAFafSlwcBQikswCIVtX+X51MxDUUuJg0byKCmiveNC+EPC0GEtx11100iGVe+zEi73//+9OEzXv27EGb35t/x891G4vW961ZtBD9qrj5JahPIAJg8DwADoAFVBRXhnRO9erdp4MyQwxySQRC5LWJ+gEQEy1cwnWtt3ld6LJ53/vet5zbC3qbW2ih5j2dnhMIRACs0G0aFQPiODY8cf/LPTlIQqQt+8dLNjxXGM7JGROs6mXZQuatFn9aFAjxC1YLSoagCQvAUaqsLEkzgLUy3TbPV3z+rIyJYDUJf7nfJxCIB6CPKBSL0c3IUTQ5EYHUUsm/fTCdVBhejglYNQMCSdw2ggEi/nZWvgT+CUQADBCUiiPIkwCADHCzC923g2OIrmXRsdC+RxX40FwCICLxAAiWlfR7yd3vRvBC/gIRAIMDPo15uoiBY788sxYnr4HuK794ARelbcYnTSZVwfJNEm2C+qQhj2BNzpsyBE3mZ47K/sXVZWMykdt40GfjZsEmMMdBmyxBgIK+WPqtpXjTXflam/C0duoTCEQArM0bP0kpa+cXEAyUcIuEGiW9GyRmU9AH4u/0fLdufUL8AhEAa3YgqFlKVrDWJACBovKNABQrUuIBEPRdBLQj/26CQCAQAbD2+KTZTFwlSWVyiw/6ZN1s7EsMWGPFEhP03fJPLwmI1S8QAXAm3fyKQIqYU/czKZpLLxMMJHw/F3Xbo7iLIwHFoaIMjKAv5N8qAoT4BSIAzswZACBySV95BiOXyyGfz4sHYIAxPDyEYrEAOI5i/xWBtJYe6kLoC1rqrZX5ul0zEtkvOBMhaYDJDe7AAAI4IKkkOzo6inw+D55meJ4HY8xA7KvWGhs2bIBSCtZaEBGstTh16lRfU/xKpRKICJVKBUopOOf69rlbtmwBM+PgwYOLHldSCtvP3YZ8Pg9jLeJcDrahMa3R2+0meFm/PTOJP32ue8nXX4qHQCAQAbCG4ZwBAMfMYEcw1mLzxk3YsnELDh89Aq11z0Q1NjaKIAhRrVabGQX9IGjf93HxxRejWCwiDENorVGtVvHkk08iDMOlTqBgZqxbtw5vfvOb4fs+Xn/9dTz//PN9GedisYhdu3YhCAJ4noddu3bh5ZdfXtTYbDlnC6699g1wxkXHTQTnGMZZCQI8i4m/ncXeSexJPX7B2QxZAkgEADM7Zhf3l4U1BkOlIVx9+RXwPQ+e76W6Ay6M7du3453vvBUXXnghRkdHwczguG3tUhEEAZ555hmcOHECQ0NDyOVy0Fr35bOZGSMjI7juuuvwyiuv4ODBg7jqqqswNjbWl3FOPuell17C888/j+HhYXietyhhdP2b34wLd+zE9NR0s2kTM7OzdsE0rvSknwR3CQmsDaJf4PptW5CnmxiQ8y4QD8BZDo4IxEZx5EyOGcYavOHaN+LBRx/CqxP7kcvl0Gg0Mn3e+edvx/bt5+HUqTJ27dqFcrmMxx57DJVKpQ/eCoeZmRmEYdi02JVSfXP/7969G6+99hr2798PALDW4vzzz0e5XF7yMki5XMaWLVtwwQUXwDkHz/PmHUdWbNu2De/5mffABdFYaM+bGx44u5Cl144YOlmTgsGy7lufa3cuO4kAsfYFAvEAtFMAAMNEpnoU9x8EAcZGRvGed/4Mcrkccrk44jwDHnvsCTz44EN49tln8U//9E+YmprCnj17+jUhzltS6Kd3AQCeeeYZbNiwAfl8Hps3b0Yul8Mrr7zSlxiISqWCV155BSMjI/A8DxdddBGuuebqnsi/UCjgox/9KK649Aoc2H8AWuu4aCODwZa5fSXArLnd7d7TzUMghNJfqz5rul16u1b3f7fPlhEXCMQD0GpVMwDHFFUEZhBACtV6HVdddiXe+fafxP3/9PfQnoa1tithERGMMXj88cehdbT9U0891XTTL9VSTyz+MIziC5xzqNVqfQvSazQayOVyeNOb3oRcLodyuYxqtdo38TIzM4NnnnkmPhaH6657I5555hnYDEv3+XweH/7oh/Hen3kv9r/wMmrVKvLFPFDjJFnDwUUCoJu1t1Bed7fSru1IR7B8ln/6XGVx8XcSekL+AoEIgPaukMh6NkkjmbmWMox6UMctb78FhaES/u3xH+DwkcMol8tdCTqBtbbt70slUWbGSy+9hJdeemlZxuPhhx+G53lwzvVNWKT3P8HExAFMTBxIujF2xe7du/HhD38Yt73zNhzc9xqOHplEaWgIoEiwRTUBYTnuwZx1wu9EDq3rxq2CoV1ueKe/z9ZlhU5jstDYtY53J8G2WC+DQCAQATDnAYhiAEJ27DheDwBxVAiIFAIT4G3X34CrrrgK4/tewI+feRqvvLoPJ46fWPF9XalufsuR9thp3yMHTHuLf/fu3dh7y17cestPYtP6jXjx6RcweWQSpaEilAY4XrIhMBzYgBduB9yOyBfTtrXTe7sRfiupnS3CoF38RauF38N1RJKzLxCIAOgLrHMO4MDBOaTmY0LUapagMD09Az/n4bor34BrrrgaR09O4oUXX8S+fS9j4sAEytPlgakVsJZRKpVw/gXn44rLr8Rb3/oWXL7nMhS8Ao4ePoznH38WzlmUSsNR9wZSYDg4x2AmMCNwzgZLsRCztHbtRN6dAtE6iYJO69ULpa1leX4hEZIlsC7L+9tZ9QuRc7vgvF4s9cWINYFAIAKgvQCwlpk5ZGbmee3/onazWmsorVCtVFCeLkMphfXFdfiJt7wNb7/xbSjPlnH4yBFMvDaBif0TmDx2DDN9XDvvpwXejziEfkFrjdHRUWzctAm7du3EpZdcgksuuRTnnrMVhVwR5VPTePnZF3HyxEmY0KBYLGBoaDhuARwt3bh40YbBcNYagJe01tJpPbmTpd/NAm39vZMnoJ0oaEes3QrbZF1yyLKM0a3dbRaRkdWj0s2DIqQuEIgAWBG4SADUbbxQn+oIAKXiBxG058E6h0YYoFKtwDFDEaFQKGLnuefjsov3AAoIwhDHTx7H0cmjmJycxOTkJKamplAulzE7O4t6vQ5rbd/X1wcNRJF40p6H4aEhjI6OYnRsFFvP2Yrt27dj27Zt2LZtGzaMrUfOz6E+W8fJEycw/qPnUJ4uIwxDKKWQz+eRLxTg53JRFgSSts0KgI3oP0rdbDAQLNOxcC/k1q0wTetzWVPUOtWk7xQQ183LkUXI9LIP3cag2/EJuQsEIgBWm6qYiGastYajkrKplwClVTP9jojgKQJrBRcaNOJo/MmjUQyhr30Mr1uHYrGAay69Cv41uSjIUBFmKrOYnZ3BbGUWU9PTmJqawvT0NCqVCur1Omr1GmrVGmq1GoIggDEGxphmMB4zw7EDO160Fb+Y9ymloqWQ+PiVUhGxaw0/56NYLKJUKqFYKKJYKmGoVMLI2Cg2jm3Aho0bMDo6ipF167B+bD0KhQLCekTs5alpnDx8EodeOoBTJ0/BGAsHB0978DwPvu/D8314vo5F2PzzoBQB8aoLOwfHXAGjtsyihjOMMS0Umd6pJkEnobEQwbdLhevmfejW3rbd+xZy1XcK7hOiFwhEAAy6B8ABqARBYNi5OKc84X+CUjoiwZh0bBwcqJSGVgxWDM+LivSExuD4seOwLkoXjOIINIbXDaNYLMDzfZy3eTsuOv/CyI2tPOSLeVhnEIQBGo0QYRjAuqjE7WxlFo2gjnq9AWMMarUawjBEaAw4FgX1RgPOubn6AM6hVq9HzyXHyJGI0FrP63BYKBSianxzegf5fB7a0wADuXwOntYoFUvwfB/FQgG5fB5DQ0MYKpbgeT60p5D388jlcigUiiBmVGarcM5CKYXKTAXHDk5i8sBR1CpVTE9PN/sYEAhKK3ieB+1peORB6UhgRMIDcTAmgXQ07kiJgIh8AOssQhvWHdvaal9P3chuMUFqS10bzxow1y3lsRcPiATiCQQiANYSGIxqYALbzPPnOULUCfmTgiINopi8ojbCUETgJL2NAO1pKJ6rzsfMmJ6extSpKTAYB16dQNJ5UClCsVhCvpCLBEVMfEPDwxgZHsZIYRhKRzWbNCkwolbFxaEhFIoFgBlB0IBSuvmZYIcgaICUbnYz5DjSXinVlDcEQj6XAwDY+HUiIOflmttYE2KmPIMkP4LibYkI7CymT5QxW56BYwdrHZy1aNTrqFSq85Y4ovbK0Rh6vjevqFJrEaOmlR8TPpGCVgqaVPQ5IOj4J3OUsdEI6nDWNQCyg3yh9SPQbaHts+TCZyX0LN4HsfYFAhEAaxYPPvI9d/MNN9WNNbYeBJEHwDkkRYGUVnEsgJr3IHaxAFBgYtiEe5rmdNSonoi6VhGsN+qo1qpAKgTROQdimmtH3Pw1st/9fD76THZQSoPU6SSqFM3zZCRipKkTYmHAjue+Jy6FlJC3CQ2CoAHHcaY9A0zc3C4h9XTbZK01cvlcK0PMX1pJP58m/aarX4GUmhNZybjH2yB+OBcJj3qjAWdtwIMS4bhYJdqmkU0vf/fLO7DU/RYIBCIA1gwcEFrnXKVeiSzZhEcYINIgpUHKRqSUrEHH/1g5EAPKKYABBxcRNgNZZsRkPb2n/XUW9XoIQofvYCCd0ZBUEEzERdry7lZGWJFCLp9fgF2w8IF24GVK/qOU9Z8QfuJ1UTRv3KPtVPM7gzBALWiAweFavw57jYgfFNIV8hcIRACsXcvLuQoc29nZWTSCBgAXcRYRlOI4CE5Bx+QUWdiRS90pBXIKRK65Pt1KwP1Ov0ss4izwfR++76MRNOCsRS6fB4EQNBpx5dwl1qLp8bBOc/kn/2gu0K+ZfaFi939KACTLMgwGs8NsdTaqtOgwhbgSoEAgEAhEAGTjMMvHmfl4YMMdM7MzOGfTlojAKXJzRwQEkNJRVH+chqbIQSmCawamzefD1cy7V0rB83y8fvQgXtr3Eiw7aE/DhAbnbNqMSy+8FDk/hyAI+tZMaLFCoGndU0pgNZcBoodKpQCSIjABgTWYmilHtRzALwII5WoWCAQCEQCZ8f3HHp296cYbDzLzdSfLpxCGIUqxfZrEAUSkRDEZqcjVrwhwcwGB5CIi47g6/WqQPzNDKwXP9/HoY4/iVGUa7/rpd+HGG29EsVjExMQBfOtbf48Hvv+vuPn6mzBcGkK9Xl8REdAu4C/t/lfpCP/47yj4Us29lxKfATA1PY1qrQrHjtny+IOPfE/KMQoEAoEIgN5gjZsGA7PVCo6dPIb169eDwVG8mdJNYtJKNV3UzkUWK8cueVZxe16muSWATgFwyygAhoaG8OiTP8SJmVO44447cPPNN2PdunVQSuGyPZfhyiuuwFf//Kv43sMP4ZYb34G8n0PDBPNSBJdZCcz9CkplVah43X8u8JKUbqYCIlWHoFqvYfLkMTAAZ5011p6Uq1ggEAgWhpIhaCFOx/9mjDGaFA4dO4JKtQJNUT48qSQynZpkpFKR60m6WhScnhradCD/CljYjCi3/9jJ4/jxc0/jxptuxI4dOxAEAYIgQBiGCIIAvu/jhrfeAPIVnnj6SeQK+SjrYIVAiQiglACg+ZUX0ymAKs7/j96moLTC5IlJVCqz0ErBGPM6gP1yFQsEAoEIgJ7hrHuqVq+FWnuoNxqYeH1iLtUtSUPDXBogEkuVUtXylALi4MCk0M1KkX8kYhwK+Txe3r8PjaCBsdExzM7OYmZmBuVyGTMzM80HM2P9+vV45cCrqNaqUUGgFfBUUJP4k0JL81MsqZnyp6B1HACo5jIAPM/DzMwsDh87iuJQCc5ZBPXGPjgWD4BAIBBkgCwBnM6eT4eN8KC19uKR0REcOnYUGzdsxvnnbgcY0FrBWoqj0jWMsiBHUKTBykJpgnMK5FzTuk0y8BNiXe6gQEUEZmB6ehrr168HEWFychLGGAwPD8PzPNRqNUxPT2N6ehojIyMwzqJSrWJsZBShWb4Yunnr/Zi/1j8X9EfzRIBOREHz+BTYWex77VU0wgaKhVJUJTE03yWQZAAIBAKBCIDe8cMfPT795je+6YlqvXrxxk0bAQAvTbyM4eEhrB8ZaxIR0VxRGkexHRu7rJXSUMRgisIA5ycDroCGiR9Ka3i+h+nyNA4dOoRyuYxisQilFMIwRKVSwczMDIyxyOVy0X6uhPXfGmOQWvtvLrM01/qp+RyaywLAxKEDOD51HGNj6zFTjnormNA89NhTj0suukAgEIgAWBzCMLx3enr6Q1vP2Yqx0VFMz5TxzAvP4apLr0AxV0AYhs0ugKc1pyGCUxR5AjjKCEgK6K6UFyDpP3DO5nNwaPIwZmZmkM/lMTMzE/UBoKR6nkUQBJgpl1EsFDE8NAxn3bItVczV7Y8LEiXLAHHMxFze/1w1QEUEraJGQDntwYHx0sQrODZ1HBvWb0CxUMLk0UnUq9WnmPk5uXoFAoEgGyQGoC2BugerlcprU1NTIFLYtGEjrLN4+oVncHjyCJx1yPk5+LkctJdEp8+1p51LY5uLAVjJIEAiQq1ew84LdkIrhSNHjsBa2yT8JBDQOYfZ2VkcPnIYO7ZfgGKhCGPNiuxf5AnA3DgpSgkp1Vwe0J4HP5eDpz3M1qv48fgz2HdgH9avX4/h4WFUKrM4efIkgiC8F8RTcvUKBAJBNmgZgtOxeePmmjFmFISfGBoexujYKIqFAgIT4vDkYUyeOAZnLfK5qBY/kQLHLXpd4uxnBjPA7OZVBEynBi6npW2Mwci6dSgWS/jR0z9CPl/A6LqRWLBEHoByuYwfP/00ctrDjW96K8LAwDm7LPuV/szE+qc4cFLrudbCWmv4WsPP5ZHP5eD5Hqq1Gg4cPoAXXnkRJ6dPYfv287BhbAzWWRw6fBiHDx86Va/Wf/vJp586JFevQCAQiABYNCaPH+P1o+uPOnb/fmhoaHhkZB1830ehUEQul8OxE8fx+uHXMT1TRi2owVgbV9zz4la7iMk/arKTdBbk+F96DXw5RUCj0cDWLVuRL+Qx/tI4jh0/hmq1iqnpKRw4cAAvvvQiirkCfuKGt8NXGkGjEWUwLCP5J0GAqlnvX0dWvu8jF7cTBhGCIMDJ8im8fuQgDhx6DZMnjyGfL2Dzxk3YsuUcEBFOnjyJQ4cP48SJE1+x1v7l5PFjVq5egUAgEAGwJGzbeu5J51zeOHtLqVhCqVhEzvcxNDSEfC4PUgrVehWnpqdx/OQxHD91EtMz5YhE45RBL27rGxFfiliTnrorAGMMtp+zDdu3boO1FpWZWczOVpDzc7jwvF249vKr4ZFGtV7P3FdgsQKAUgV8tNbwPR++n4syK5xDtVbFsVPHcfjYERycPIKT5VOoB3Xkcjls3rQZY6NjyOcLKBTzaAQBDhw4gKNHj040GvX/8sxzz74uV61AIBD0MDfLEHTGVZdfuR1a3bvjgvPfetGFF2FkZASlYglBGGJ2ZgahMajXa6hUqwiCBirVKmxooXWcvkYaeT+Pgp+H9jQUKfieB0/pKFI/7RlwkXcgWh3oX9YAx8GKvp8DaQXrLBB7IRQpGGNgjOmLJ4JSFY9UKrUveY3ZIbQWxoQIjUUjbKAR1BFag9CGccVFBS/no1QaQqlYwLrhYXheLmpm5HloBAE8T+PkyZN4ed8+nDhx4nfY8qeefu5pif4XCAQCEQD9wyUXXfz+dWOjf3nxhRcN7dyxE8VSCWDGzOwstNZgdgiCAMZYzFRmEDYChCZErV5HGISoVquwxiA0UXCdB4V8oYCcl0OxUECxUIzWwCmyij3Pg6e9VJW8NgGELR6E1myC1jS71pgDQhyHwPPyE5of3Wq5t/NcJN/JqZbJlqNAw9AYWGNgnEEYGtTqVVTqNYRhiNCGsNaCAWhPI5/Po1goIp/LoTQ8HK37aw+lUgm+7yHn5+Z5JhpBgFqtioOHDuH1115/oFGv/+z4Sy9My5UqEAgEIgD6jsv2XP7JsbHR3925cye2nXsuCvkiGvV6lGef81GvVmGsQRAYgC3qjQAMwIQBqtUqgjBErVZHo1GHCUMEYUSQQRg018OZGZo0SBFyXg6e58P3fHhaw/M0tNLwPD9Ki9MKSnvQpAAwdLLUwAApgqe9uO1AQvxRTEISZR+RdsTmc5wexSqE1kUeAgass1EcAzOsc7DWwDkH4xysMbDOwsQWfSMM4GwUAlkP6jAmBEDNgD/f9+B7PrTWUfCk76FQKGC4NIRcIQ/f80BEzTiKKN7Cb6ZZMoBKZRazlQpOTZ3CoUOHJ2qzlZ99dvy5J+UKFQgEgt4hdQCygPmPpqamdr+6/9WPGRPinC1bobWCT0AYMJxjKBURs7EOvu8DYHg6igNwzKjmqrB2GI4Z9XoN1jqEJoQxBuxo7b6YAAAISUlEQVSi39kxgjBAYEMENgAaQK1eh4qJWvseTBC5ynVcIx/EUKQBivcjrpvvnItd6pEXwblIKDiO8vzZxRa8s1HgH0UuemZAk4KLBUFUU4BgnYVj1/w8HafuIc7TZ3bw/Rw8z8OQV4LSUUEkTytoHXk1tOdFVf1iUVMqFpHLRcsjiXgpFApN7wM7hiMGkUO90cDho0dx8uQJzM5WTtartd8Q8hcIBALxACw7Lrn4klHlqd9ft27df9q0eZMuFYsoFYYwNFSE70cWrYmb7Bhj4HkenGWQAhqNBowxqNXrIFDsBQibBB0Rf9gkYDAjX8jDOYdKpQLP8yNPgSLY0MJY07Tc4y54YHawzsFTGsbZqKCPjgsTOSDyohOMMwAjJQxsXH5XwdlIyORzuZj80czPZxe1PfY9H845aK2jPXAWKo5pyHk+mBi5XA4mNIlfAQoKuULk2k/iHJRSKBQKyOVzcI7BzsHL5TBUKsaeCQcCwVnG9NQUDk8ewdHJSbCzLznH/9vz48/fJ1elQCAQiABYEVx6yaXa0/rnSKv/CYQbCrkCNm3ciLGx9RgqleD5Pow1cNZCaw/WGoAIYRBCKUKtVgMphaDRgDUWvu/DGANrDdgRHFt4vt+0ukMTwout49BE7vdoPZzn1sXdXHqh53nRd2kNa23UoEhrmNCAVFx7X2kQCNrTcM7G6/FzQYGkKK7UF1n11lpQHLwYBRBGzYYYQM73wQAa9QaUUvBzPpxlgKKgRjDAxNAqSjYpFAtRieK4yE+xVILWCoCC5ymY0EBrD8YahEGASq2K6XIZU6dOYXp6qhYa+xdDxeLnx1984Wm5GgUCgUAEwIrj8ksv2xaEwc31RuN2P+e/a926dWp4aBhDpSHk8jnk83l42oPS0fq17/uRmz8IYJyFMRZsLQBCEIZxfwFq2vQMhgnDKFUul4tIGAAo8h4k9fHZORhjQYriGIGok18jCKI6+klpYmZopRAEQdxcJ4o1sNbGn8OwziDn5wACjLFxgSMGu8iO19qDCQ2YIrHgnIP2PHhao1qtNo81atkbWfhBEEIr1WyI5HkevDgbQmkPvu9FFQqdhXMOYdBAIwhRr9dRqcyiUq2gVqvvt9beC3Z/o5X32P4DE4FcgQKBQCACYDXHiLaes3VEKX2ZVurtpOi9Wusrc/nccLFQVLlclLpWLBYjwo0L4Gil4OJa/SYwgKI4Lz5et487DkbWt4sIFYgyDsCwoQHF2wIEL7b2EQuEfD6PRqPRtNKBqHVusVBEvVGDNRaOI2+BtaZZdldpBecs2DJIKWhNcBwFELo4XiBav1cIGkGziI+vPQQmEiVJ0SMGx56HEEQKYRg04wlU3Ngn+p1QbzRQb9SjDIEgQKMRGGvM68aa7zPjfrb8aMM0Dh87dixpUdgp3U/SAAUCgUAEwKLHIv1Al99P+7tUKuXXDa/b5WnvahBuIaJLlFI7tKeLnvaGlFIewKliOB7AQC6fAxEhn8vDWhMVEPL9ZgMcxwxNBOsYuZzfrBsQBQBG4f2KCJ7vo9FoNAsQkdZRpkKqpa51cadcx4ACrHUAMzzPjz0CJoodiAManUNTJDSXHeIYBeNss3ZBIkCMMWAGjIn6DFhmWGsQNkI4djDGwDGD5wIRa9bammM3zc69BMYTzPxwEAQ/nipPTxljbAu5cwvRt3ue2zwEAoFAIAKgI/ErRJURdfx7+kGpn5keRETrhtft9H3/HEV0DYPPI9CQA1/orBsGoQDGmNJqCEAzQE5pDV9peHEmASUd8XT0nBe73a2LAwhjjotiDmwkBuKUOutc870mNFGWgFbN7X3fQxAEcI7hmAE4MBPArmmlJ0F7WqtmAyHrolx/MMPYKODQxSmB1sRxBXF9AOecZeYpx24GjFBrfQiEwwAqSqnnnLEvBmFwpFKtnuxA3q1E7lJE79r8TB42fqRfEwgEAoEIgCYSkvcA+PHD6yIGVItoQItIaLdd8+Fpr6S1Xqe1XgfGzsAE53raI+3pIju32Tm3yTH7vudpBgpEVASjBKICEXJEpLTSxGBCktuv4kT/OO9eKQIjek5rFbGfcyBG5DVITn68Pu+sidMCaX6BH0q1LWaGc8zWOQY4ZMehY1cBUCeiKjsOrLNOk6oorY46x1NhGBqlVE1rfYDZHbLW1kJjuhG9SxG2XWC7VsJPk74BEKZ+WhEAAoFAIAKgmwDwUgLA6+IN6OQRUC3v6bQd2vwNdF5uaH1tMeey0+vdXORZ1ts7ueTbPdfNVd9K/q3WPVK/d9retQiARASIABAIBAIRAG3HoB156zYErroQeas3gDoQv+pA6J3EQNbfs55b6kLuC62Xc5dtO5F/u787iYJWggfmu/wX4xFwLSJCIBAIBCIA2gqBhX7v9rPX13ohd1rk+ct6jnmR23EfREK3n+3ERLefnOGzBAKBQEhPhmBJY0V9HmdaI+eNe9yWsPT0PUn/EwgEAhEAgj6dcyFPgUAgEAgEAoFAIBAIBAKBQCAQCAQCgUAgEAgEAoFAIBAIBAKBQCAQCAQCgUAgEAgEAoFAIBAIBAKBQCAQCAQCgUAgEAgEAoFAIBAIBAKBQCAQCAQCgUAgEAgEAoFAIBAIBAKBQCAQCAQCgUAgEAgEAoFAIBAIBAKBQCAQCAQCgUAgEAgEAoFAIBAIBAKBQCAQCAQCgUAgEAgEAoFAIBAIBAKBQCAQCAQCgUAgEAgEAoFAIBAIBAKBQCAQCAQCgUAgEAgEAoFAIBAIBAKBQCAQCAQCgUAgEAgEAoFAIBAIBAKBQCAQCAQCgUAgEAgEAoFAIBAIBAKBQCAQCAQCgUAgEAgEAoHgTMP/D/vIzuWuYbaKAAAAAElFTkSuQmCC"}; diff --git a/res/raw/novnc.html b/res/raw/novnc.html deleted file mode 100755 index ce36e17..0000000 --- a/res/raw/novnc.html +++ /dev/null @@ -1,34 +0,0 @@ - - - - - droid VNC server - - - - - - - - - -
Loading
- - - - Java version (older)
- Not working? Click here - - - diff --git a/res/raw/plain.css b/res/raw/plain.css deleted file mode 100755 index a2ecd1d..0000000 --- a/res/raw/plain.css +++ /dev/null @@ -1,104 +0,0 @@ - - -#VNC_controls { - overflow: hidden; -} -#VNC_controls ul { - list-style: none; - margin: 0px; - padding: 0px; -} -#VNC_controls li { - float: left; - margin-right: 15px; -} - -#VNC_host { - width: 100px; -} -#VNC_port { - width: 50px; -} -#VNC_password { - width: 80px; -} -#VNC_encrypt { -} -#VNC_connectTimeout { - width: 30px; -} -#VNC_connect_button { - width: 110px; -} - -#VNC_status_bar td { - margin-top: 15px; - padding: 0px; - margin: 0px; -} -#VNC_status_bar div { - font-size: 12px; - margin: 0px; - padding: 0px; -} -.VNC_status_button { - font-size: 10px; - margin: 0px; - padding: 0px; -} -#VNC_status { - text-align: center; -} - -#java{ - text-align: center; -} - -#VNC_settings_menu { - display: none; - position: absolute; - width: 12em; - border: 1px solid #888; - background-color: #f0f2f6; - padding: 5px; margin: 3px; - z-index: 100; opacity: 1; - text-align: left; white-space: normal; -} -#VNC_settings_menu ul { - list-style: none; - margin: 0px; - padding: 0px; -} - -.VNC_buttons_right { - text-align: right; -} -.VNC_buttons_left { - text-align: left; -} -.VNC_status_normal { - background: #eee; -} -.VNC_status_error { - background: #f44; -} -.VNC_status_warn { - background: #ff4; -} - -/* Do not set width/height for VNC_screen or VNC_canvas or incorrect - * scaling will occur. Canvas resizes to remote VNC settings */ -#VNC_screen { - text-align: center; - display: table; -} -#VNC_canvas { - background: #eee; -} - -#VNC_clipboard_clear_button { -} -#VNC_clipboard_text { - font-size: 9px; -} - diff --git a/res/raw/playback.js b/res/raw/playback.js deleted file mode 100755 index 22a00a3..0000000 --- a/res/raw/playback.js +++ /dev/null @@ -1,90 +0,0 @@ -/* - * noVNC: HTML5 VNC client - * Copyright (C) 2011 Joel Martin - * Licensed under LGPL-3 (see LICENSE.LGPL-3) - */ - -"use strict"; -/*jslint browser: true, white: false */ -/*global Util, VNC_frame_data, finish */ - -var rfb, mode, test_state, frame_idx, frame_length, - iteration, iterations, istart_time, - - // Pre-declarations for jslint - send_array, next_iteration, queue_next_packet, do_packet; - -// Override send_array -send_array = function (arr) { - // Stub out send_array -}; - -next_iteration = function () { - if (iteration === 0) { - frame_length = VNC_frame_data.length; - test_state = 'running'; - } else { - rfb.disconnect(); - } - - if (test_state !== 'running') { return; } - - iteration += 1; - if (iteration > iterations) { - finish(); - return; - } - - frame_idx = 0; - istart_time = (new Date()).getTime(); - rfb.connect('test', 0, "bogus"); - - queue_next_packet(); - -}; - -queue_next_packet = function () { - var frame, foffset, toffset, delay; - if (test_state !== 'running') { return; } - - frame = VNC_frame_data[frame_idx]; - while ((frame_idx < frame_length) && (frame.charAt(0) === "}")) { - //Util.Debug("Send frame " + frame_idx); - frame_idx += 1; - frame = VNC_frame_data[frame_idx]; - } - - if (frame === 'EOF') { - Util.Debug("Finished, found EOF"); - next_iteration(); - return; - } - if (frame_idx >= frame_length) { - Util.Debug("Finished, no more frames"); - next_iteration(); - return; - } - - if (mode === 'realtime') { - foffset = frame.slice(1, frame.indexOf('{', 1)); - toffset = (new Date()).getTime() - istart_time; - delay = foffset - toffset; - if (delay < 1) { - delay = 1; - } - - setTimeout(do_packet, delay); - } else { - setTimeout(do_packet, 1); - } -}; - -do_packet = function () { - //Util.Debug("Processing frame: " + frame_idx); - var frame = VNC_frame_data[frame_idx]; - rfb.recv_message({'data' : frame.slice(frame.indexOf('{', 1) + 1)}); - frame_idx += 1; - - queue_next_packet(); -}; - diff --git a/res/raw/rfb.js b/res/raw/rfb.js deleted file mode 100755 index 6b7e83e..0000000 --- a/res/raw/rfb.js +++ /dev/null @@ -1,1565 +0,0 @@ -/* - * noVNC: HTML5 VNC client - * Copyright (C) 2011 Joel Martin - * Licensed under LGPL-3 (see LICENSE.txt) - * - * See README.md for usage and integration instructions. - */ - -/*jslint white: false, browser: true, bitwise: false, plusplus: false */ -/*global window, Util, Display, Keyboard, Mouse, Websock, Websock_native, Base64, DES, noVNC_logo */ - - -function RFB(defaults) { -"use strict"; - -var that = {}, // Public API methods - conf = {}, // Configuration attributes - - // Pre-declare private functions used before definitions (jslint) - init_vars, updateState, fail, handle_message, - init_msg, normal_msg, framebufferUpdate, print_stats, - - pixelFormat, clientEncodings, fbUpdateRequest, - keyEvent, pointerEvent, clientCutText, - - extract_data_uri, scan_tight_imgQ, - keyPress, mouseButton, mouseMove, - - checkEvents, // Overridable for testing - - - // - // Private RFB namespace variables - // - rfb_host = '', - rfb_port = 5900, - rfb_password = '', - rfb_uri = '', - - rfb_state = 'disconnected', - rfb_version = 0, - rfb_max_version= 3.8, - rfb_auth_scheme= '', - - - // In preference order - encodings = [ - ['COPYRECT', 0x01 ], - ['HEXTILE', 0x05 ], - - ['TIGHT_PNG', -260 ], - ['HEXTILE', 0x05 ], - ['RRE', 0x02 ], - ['RAW', 0x00 ], - ['DesktopSize', -223 ], - ['Cursor', -239 ], - - // Psuedo-encoding settings - ['JPEG_quality_lo', -32 ], - //['JPEG_quality_hi', -23 ], - ['compress_lo', -255 ] - //['compress_hi', -247 ] - ], - - encHandlers = {}, - encNames = {}, - encStats = {}, // [rectCnt, rectCntTot] - - ws = null, // Websock object - display = null, // Display object - keyboard = null, // Keyboard input handler object - mouse = null, // Mouse input handler object - sendTimer = null, // Send Queue check timer - connTimer = null, // connection timer - disconnTimer = null, // disconnection timer - msgTimer = null, // queued handle_message timer - - // Frame buffer update state - FBU = { - rects : 0, - subrects : 0, // RRE - lines : 0, // RAW - tiles : 0, // HEXTILE - bytes : 0, - x : 0, - y : 0, - width : 0, - height : 0, - encoding : 0, - subencoding : -1, - background : null, - imgQ : [] // TIGHT_PNG image queue - }, - - fb_Bpp = 4, - fb_depth = 3, - fb_width = 0, - fb_height = 0, - fb_name = "", - - scan_imgQ_rate = 40, // 25 times per second or so - last_req_time = 0, - rre_chunk_sz = 100, - - timing = { - last_fbu : 0, - fbu_total : 0, - fbu_total_cnt : 0, - full_fbu_total : 0, - full_fbu_cnt : 0, - - fbu_rt_start : 0, - fbu_rt_total : 0, - fbu_rt_cnt : 0 - }, - - test_mode = false, - - def_con_timeout = Websock_native ? 2 : 5, - - /* Mouse state */ - mouse_buttonMask = 0, - mouse_arr = []; - -// Configuration attributes -Util.conf_defaults(conf, that, defaults, [ - ['target', 'wo', 'dom', null, 'VNC display rendering Canvas object'], - ['focusContainer', 'wo', 'dom', document, 'DOM element that captures keyboard input'], - - ['encrypt', 'rw', 'bool', false, 'Use TLS/SSL/wss encryption'], - ['true_color', 'rw', 'bool', true, 'Request true color pixel data'], - ['local_cursor', 'rw', 'bool', false, 'Request locally rendered cursor'], - ['shared', 'rw', 'bool', true, 'Request shared mode'], - - ['connectTimeout', 'rw', 'int', def_con_timeout, 'Time (s) to wait for connection'], - ['disconnectTimeout', 'rw', 'int', 3, 'Time (s) to wait for disconnection'], - - ['check_rate', 'rw', 'int', 217, 'Timing (ms) of send/receive check'], - ['fbu_req_rate', 'rw', 'int', 1413, 'Timing (ms) of frameBufferUpdate requests'], - - // Callback functions - ['onUpdateState', 'rw', 'func', function() { }, - 'onUpdateState(rfb, state, oldstate, statusMsg): RFB state update/change '], - ['onPasswordRequired', 'rw', 'func', function() { }, - 'onPasswordRequired(rfb): VNC password is required '], - ['onClipboard', 'rw', 'func', function() { }, - 'onClipboard(rfb, text): RFB clipboard contents received'], - ['onBell', 'rw', 'func', function() { }, - 'onBell(rfb): RFB Bell message received '], - ['onFBUReceive', 'rw', 'func', function() { }, - 'onFBUReceive(rfb, fbu): RFB FBU received but not yet processed '], - ['onFBUComplete', 'rw', 'func', function() { }, - 'onFBUComplete(rfb, fbu): RFB FBU received and processed '], - - // These callback names are deprecated - ['updateState', 'rw', 'func', function() { }, - 'obsolete, use onUpdateState'], - ['clipboardReceive', 'rw', 'func', function() { }, - 'obsolete, use onClipboard'] - ]); - - -// Override/add some specific configuration getters/setters -that.set_local_cursor = function(cursor) { - if ((!cursor) || (cursor in {'0':1, 'no':1, 'false':1})) { - conf.local_cursor = false; - } else { - if (display.get_cursor_uri()) { - conf.local_cursor = true; - } else { - Util.Warn("Browser does not support local cursor"); - } - } -}; - -// These are fake configuration getters -that.get_display = function() { return display; }; - -that.get_keyboard = function() { return keyboard; }; - -that.get_mouse = function() { return mouse; }; - - - -// -// Setup routines -// - -// Create the public API interface and initialize values that stay -// constant across connect/disconnect -function constructor() { - var i, rmode; - Util.Debug(">> RFB.constructor"); - - // Create lookup tables based encoding number - for (i=0; i < encodings.length; i+=1) { - encHandlers[encodings[i][1]] = encHandlers[encodings[i][0]]; - encNames[encodings[i][1]] = encodings[i][0]; - encStats[encodings[i][1]] = [0, 0]; - } - // Initialize display, mouse, keyboard, and websock - try { - display = new Display({'target': conf.target}); - } catch (exc) { - Util.Error("Display exception: " + exc); - updateState('fatal', "No working Display"); - } - keyboard = new Keyboard({'target': conf.focusContainer, - 'onKeyPress': keyPress}); - mouse = new Mouse({'target': conf.target, - 'onMouseButton': mouseButton, - 'onMouseMove': mouseMove}); - - rmode = display.get_render_mode(); - - if (typeof noVNC_logo !== 'undefined') { - display.set_logo(noVNC_logo); - } - - ws = new Websock(); - ws.on('message', handle_message); - ws.on('open', function() { - if (rfb_state === "connect") { - updateState('ProtocolVersion', "Starting VNC handshake"); - } else { - fail("Got unexpected WebSockets connection"); - } - }); - ws.on('close', function() { - if (rfb_state === 'disconnect') { - updateState('disconnected', 'VNC disconnected'); - } else if (rfb_state === 'ProtocolVersion') { - fail('Failed to connect to server'); - } else if (rfb_state in {'failed':1, 'disconnected':1}) { - Util.Error("Received onclose while disconnected"); - } else { - fail('Server disconnected'); - } - }); - ws.on('error', function(e) { - fail("WebSock error: " + e); - }); - - - init_vars(); - - /* Check web-socket-js if no builtin WebSocket support */ - if (Websock_native) { - Util.Info("Using native WebSockets"); - updateState('loaded', 'noVNC ready: native WebSockets, ' + rmode); - } else { - Util.Warn("Using web-socket-js bridge. Flash version: " + - Util.Flash.version); - if ((! Util.Flash) || - (Util.Flash.version < 9)) { - updateState('fatal', "WebSockets or Adobe Flash<\/a> is required"); - } else if (document.location.href.substr(0, 7) === "file://") { - updateState('fatal', - "'file://' URL is incompatible with Adobe Flash"); - } else { - updateState('loaded', 'noVNC ready: WebSockets emulation, ' + rmode); - } - } - - Util.Debug("<< RFB.constructor"); - return that; // Return the public API interface -} - -function connect() { - Util.Debug(">> RFB.connect"); - - var uri = ""; - if (conf.encrypt) { - uri = "wss://"; - } else { - uri = "ws://"; - } - uri += rfb_host + ":" + rfb_port + "/" + rfb_uri; - Util.Info("connecting to " + uri); - ws.open(uri); - - Util.Debug("<< RFB.connect"); -} - -// Initialize variables that are reset before each connection -init_vars = function() { - var i; - - /* Reset state */ - ws.init(); - - FBU.rects = 0; - FBU.subrects = 0; // RRE and HEXTILE - FBU.lines = 0; // RAW - FBU.tiles = 0; // HEXTILE - FBU.imgQ = []; // TIGHT_PNG image queue - mouse_buttonMask = 0; - mouse_arr = []; - - // Clear the per connection encoding stats - for (i=0; i < encodings.length; i+=1) { - encStats[encodings[i][1]][0] = 0; - } -}; - -// Print statistics -print_stats = function() { - var i, s; - Util.Info("Encoding stats for this connection:"); - for (i=0; i < encodings.length; i+=1) { - s = encStats[encodings[i][1]]; - if ((s[0] + s[1]) > 0) { - Util.Info(" " + encodings[i][0] + ": " + - s[0] + " rects"); - } - } - Util.Info("Encoding stats since page load:"); - for (i=0; i < encodings.length; i+=1) { - s = encStats[encodings[i][1]]; - if ((s[0] + s[1]) > 0) { - Util.Info(" " + encodings[i][0] + ": " + - s[1] + " rects"); - } - } -}; - -// -// Utility routines -// - - -/* - * Page states: - * loaded - page load, equivalent to disconnected - * disconnected - idle state - * connect - starting to connect (to ProtocolVersion) - * normal - connected - * disconnect - starting to disconnect - * failed - abnormal disconnect - * fatal - failed to load page, or fatal error - * - * RFB protocol initialization states: - * ProtocolVersion - * Security - * Authentication - * password - waiting for password, not part of RFB - * SecurityResult - * ClientInitialization - not triggered by server message - * ServerInitialization (to normal) - */ -updateState = function(state, statusMsg) { - var func, cmsg, oldstate = rfb_state; - - if (state === oldstate) { - /* Already here, ignore */ - Util.Debug("Already in state '" + state + "', ignoring."); - return; - } - - /* - * These are disconnected states. A previous connect may - * asynchronously cause a connection so make sure we are closed. - */ - if (state in {'disconnected':1, 'loaded':1, 'connect':1, - 'disconnect':1, 'failed':1, 'fatal':1}) { - if (sendTimer) { - clearInterval(sendTimer); - sendTimer = null; - } - - if (msgTimer) { - clearInterval(msgTimer); - msgTimer = null; - } - - if (display && display.get_context()) { - keyboard.ungrab(); - mouse.ungrab(); - display.defaultCursor(); - if ((Util.get_logging() !== 'debug') || - (state === 'loaded')) { - // Show noVNC logo on load and when disconnected if - // debug is off - display.clear(); - } - } - - ws.close(); - } - - if (oldstate === 'fatal') { - Util.Error("Fatal error, cannot continue"); - } - - if ((state === 'failed') || (state === 'fatal')) { - func = Util.Error; - } else { - func = Util.Warn; - } - - if ((oldstate === 'failed') && (state === 'disconnected')) { - // Do disconnect action, but stay in failed state. - rfb_state = 'failed'; - } else { - rfb_state = state; - } - - cmsg = typeof(statusMsg) !== 'undefined' ? (" Msg: " + statusMsg) : ""; - func("New state '" + rfb_state + "', was '" + oldstate + "'." + cmsg); - - if (connTimer && (rfb_state !== 'connect')) { - Util.Debug("Clearing connect timer"); - clearInterval(connTimer); - connTimer = null; - } - - if (disconnTimer && (rfb_state !== 'disconnect')) { - Util.Debug("Clearing disconnect timer"); - clearInterval(disconnTimer); - disconnTimer = null; - } - - switch (state) { - case 'normal': - if ((oldstate === 'disconnected') || (oldstate === 'failed')) { - Util.Error("Invalid transition from 'disconnected' or 'failed' to 'normal'"); - } - - break; - - - case 'connect': - - connTimer = setTimeout(function () { - fail("Connect timeout"); - }, conf.connectTimeout * 1000); - - init_vars(); - connect(); - - // WebSocket.onopen transitions to 'ProtocolVersion' - break; - - - case 'disconnect': - - if (! test_mode) { - disconnTimer = setTimeout(function () { - fail("Disconnect timeout"); - }, conf.disconnectTimeout * 1000); - } - - print_stats(); - - // WebSocket.onclose transitions to 'disconnected' - break; - - - case 'failed': - if (oldstate === 'disconnected') { - Util.Error("Invalid transition from 'disconnected' to 'failed'"); - } - if (oldstate === 'normal') { - Util.Error("Error while connected."); - } - if (oldstate === 'init') { - Util.Error("Error while initializing."); - } - - // Make sure we transition to disconnected - setTimeout(function() { updateState('disconnected'); }, 50); - - break; - - - default: - // No state change action to take - - } - - if ((oldstate === 'failed') && (state === 'disconnected')) { - // Leave the failed message - conf.updateState(that, state, oldstate); // Obsolete - conf.onUpdateState(that, state, oldstate); - } else { - conf.updateState(that, state, oldstate, statusMsg); // Obsolete - conf.onUpdateState(that, state, oldstate, statusMsg); - } -}; - -fail = function(msg) { - updateState('failed', msg); - return false; -}; - -handle_message = function() { - //Util.Debug(">> handle_message ws.rQlen(): " + ws.rQlen()); - //Util.Debug("ws.rQslice(0,20): " + ws.rQslice(0,20) + " (" + ws.rQlen() + ")"); - if (ws.rQlen() === 0) { - Util.Warn("handle_message called on empty receive queue"); - return; - } - switch (rfb_state) { - case 'disconnected': - case 'failed': - Util.Error("Got data while disconnected"); - break; - case 'normal': - if (normal_msg() && ws.rQlen() > 0) { - // true means we can continue processing - // Give other events a chance to run - if (msgTimer === null) { - Util.Debug("More data to process, creating timer"); - msgTimer = setTimeout(function () { - msgTimer = null; - handle_message(); - }, 10); - } else { - Util.Debug("More data to process, existing timer"); - } - } - break; - default: - init_msg(); - break; - } -}; - - -function genDES(password, challenge) { - var i, passwd = []; - for (i=0; i < password.length; i += 1) { - passwd.push(password.charCodeAt(i)); - } - return (new DES(passwd)).encrypt(challenge); -} - -function flushClient() { - if (mouse_arr.length > 0) { - //send(mouse_arr.concat(fbUpdateRequest(1))); - ws.send(mouse_arr); - setTimeout(function() { - ws.send(fbUpdateRequest(1)); - }, 50); - - mouse_arr = []; - return true; - } else { - return false; - } -} - -// overridable for testing -checkEvents = function() { - var now; - if (rfb_state === 'normal') { - if (! flushClient()) { - now = new Date().getTime(); - if (now > last_req_time + conf.fbu_req_rate) { - last_req_time = now; - ws.send(fbUpdateRequest(1)); - } - } - } - setTimeout(checkEvents, conf.check_rate); -}; - -keyPress = function(keysym, down) { - var arr; - arr = keyEvent(keysym, down); - arr = arr.concat(fbUpdateRequest(1)); - ws.send(arr); -}; - -mouseButton = function(x, y, down, bmask) { - if (down) { - mouse_buttonMask |= bmask; - } else { - mouse_buttonMask ^= bmask; - } - mouse_arr = mouse_arr.concat( pointerEvent(x, y) ); - flushClient(); -}; - -mouseMove = function(x, y) { - //Util.Debug('>> mouseMove ' + x + "," + y); - mouse_arr = mouse_arr.concat( pointerEvent(x, y) ); -}; - - -// -// Server message handlers -// - -// RFB/VNC initialisation message handler -init_msg = function() { - //Util.Debug(">> init_msg [rfb_state '" + rfb_state + "']"); - - var strlen, reason, length, sversion, cversion, - i, types, num_types, challenge, response, bpp, depth, - big_endian, red_max, green_max, blue_max, red_shift, - green_shift, blue_shift, true_color, name_length; - - //Util.Debug("ws.rQ (" + ws.rQlen() + ") " + ws.rQslice(0)); - switch (rfb_state) { - - case 'ProtocolVersion' : - if (ws.rQlen() < 12) { - return fail("Incomplete protocol version"); - } - sversion = ws.rQshiftStr(12).substr(4,7); - Util.Info("Server ProtocolVersion: " + sversion); - switch (sversion) { - case "003.003": rfb_version = 3.3; break; - case "003.006": rfb_version = 3.3; break; // UltraVNC - case "003.007": rfb_version = 3.7; break; - case "003.008": rfb_version = 3.8; break; - default: - return fail("Invalid server version " + sversion); - } - if (rfb_version > rfb_max_version) { - rfb_version = rfb_max_version; - } - - if (! test_mode) { - sendTimer = setInterval(function() { - // Send updates either at a rate of one update - // every 50ms, or whatever slower rate the network - // can handle. - ws.flush(); - }, 50); - } - - cversion = "00" + parseInt(rfb_version,10) + - ".00" + ((rfb_version * 10) % 10); - ws.send_string("RFB " + cversion + "\n"); - updateState('Security', "Sent ProtocolVersion: " + cversion); - break; - - case 'Security' : - if (rfb_version >= 3.7) { - // Server sends supported list, client decides - num_types = ws.rQshift8(); - if (ws.rQwait("security type", num_types, 1)) { return false; } - if (num_types === 0) { - strlen = ws.rQshift32(); - reason = ws.rQshiftStr(strlen); - return fail("Security failure: " + reason); - } - rfb_auth_scheme = 0; - types = ws.rQshiftBytes(num_types); - Util.Debug("Server security types: " + types); - for (i=0; i < types.length; i+=1) { - if ((types[i] > rfb_auth_scheme) && (types[i] < 3)) { - rfb_auth_scheme = types[i]; - } - } - if (rfb_auth_scheme === 0) { - return fail("Unsupported security types: " + types); - } - - ws.send([rfb_auth_scheme]); - } else { - // Server decides - if (ws.rQwait("security scheme", 4)) { return false; } - rfb_auth_scheme = ws.rQshift32(); - } - updateState('Authentication', - "Authenticating using scheme: " + rfb_auth_scheme); - init_msg(); // Recursive fallthrough (workaround JSLint complaint) - break; - - // Triggered by fallthough, not by server message - case 'Authentication' : - //Util.Debug("Security auth scheme: " + rfb_auth_scheme); - switch (rfb_auth_scheme) { - case 0: // connection failed - if (ws.rQwait("auth reason", 4)) { return false; } - strlen = ws.rQshift32(); - reason = ws.rQshiftStr(strlen); - return fail("Auth failure: " + reason); - case 1: // no authentication - if (rfb_version >= 3.8) { - updateState('SecurityResult'); - return; - } - // Fall through to ClientInitialisation - break; - case 2: // VNC authentication - if (rfb_password.length === 0) { - // Notify via both callbacks since it is kind of - // a RFB state change and a UI interface issue. - updateState('password', "Password Required"); - conf.onPasswordRequired(that); - return; - } - if (ws.rQwait("auth challenge", 16)) { return false; } - challenge = ws.rQshiftBytes(16); - //Util.Debug("Password: " + rfb_password); - //Util.Debug("Challenge: " + challenge + - // " (" + challenge.length + ")"); - response = genDES(rfb_password, challenge); - //Util.Debug("Response: " + response + - // " (" + response.length + ")"); - - //Util.Debug("Sending DES encrypted auth response"); - ws.send(response); - updateState('SecurityResult'); - return; - default: - fail("Unsupported auth scheme: " + rfb_auth_scheme); - return; - } - updateState('ClientInitialisation', "No auth required"); - init_msg(); // Recursive fallthrough (workaround JSLint complaint) - break; - - case 'SecurityResult' : - if (ws.rQwait("VNC auth response ", 4)) { return false; } - switch (ws.rQshift32()) { - case 0: // OK - // Fall through to ClientInitialisation - break; - case 1: // failed - if (rfb_version >= 3.8) { - length = ws.rQshift32(); - if (ws.rQwait("SecurityResult reason", length, 8)) { - return false; - } - reason = ws.rQshiftStr(length); - fail(reason); - } else { - fail("Authentication failed"); - } - return; - case 2: // too-many - return fail("Too many auth attempts"); - } - updateState('ClientInitialisation', "Authentication OK"); - init_msg(); // Recursive fallthrough (workaround JSLint complaint) - break; - - // Triggered by fallthough, not by server message - case 'ClientInitialisation' : - ws.send([conf.shared ? 1 : 0]); // ClientInitialisation - updateState('ServerInitialisation', "Authentication OK"); - break; - - case 'ServerInitialisation' : - if (ws.rQwait("server initialization", 24)) { return false; } - - /* Screen size */ - fb_width = ws.rQshift16(); - fb_height = ws.rQshift16(); - - /* PIXEL_FORMAT */ - bpp = ws.rQshift8(); - depth = ws.rQshift8(); - big_endian = ws.rQshift8(); - true_color = ws.rQshift8(); - - red_max = ws.rQshift16(); - green_max = ws.rQshift16(); - blue_max = ws.rQshift16(); - red_shift = ws.rQshift8(); - green_shift = ws.rQshift8(); - blue_shift = ws.rQshift8(); - ws.rQshiftStr(3); // padding - - Util.Info("Screen: " + fb_width + "x" + fb_height + - ", bpp: " + bpp + ", depth: " + depth + - ", big_endian: " + big_endian + - ", true_color: " + true_color + - ", red_max: " + red_max + - ", green_max: " + green_max + - ", blue_max: " + blue_max + - ", red_shift: " + red_shift + - ", green_shift: " + green_shift + - ", blue_shift: " + blue_shift); - - /* Connection name/title */ - name_length = ws.rQshift32(); - fb_name = ws.rQshiftStr(name_length); - - display.set_true_color(conf.true_color); - display.resize(fb_width, fb_height); - keyboard.grab(); - mouse.grab(); - - if (conf.true_color) { - fb_Bpp = 4; - fb_depth = 3; - } else { - fb_Bpp = 1; - fb_depth = 1; - } - - response = pixelFormat(); - response = response.concat(clientEncodings()); - response = response.concat(fbUpdateRequest(0)); - timing.fbu_rt_start = (new Date()).getTime(); - ws.send(response); - - /* Start pushing/polling */ - setTimeout(checkEvents, conf.check_rate); - setTimeout(scan_tight_imgQ, scan_imgQ_rate); - - if (conf.encrypt) { - updateState('normal', "Connected (encrypted) to: " + fb_name); - } else { - updateState('normal', "Connected (unencrypted) to: " + fb_name); - } - break; - } - //Util.Debug("<< init_msg"); -}; - - -/* Normal RFB/VNC server message handler */ -normal_msg = function() { - //Util.Debug(">> normal_msg"); - - var ret = true, msg_type, length, text, - c, first_colour, num_colours, red, green, blue; - - if (FBU.rects > 0) { - msg_type = 0; - } else { - msg_type = ws.rQshift8(); - } - switch (msg_type) { - case 0: // FramebufferUpdate - ret = framebufferUpdate(); // false means need more data - break; - case 1: // SetColourMapEntries - Util.Debug("SetColourMapEntries"); - ws.rQshift8(); // Padding - first_colour = ws.rQshift16(); // First colour - num_colours = ws.rQshift16(); - for (c=0; c < num_colours; c+=1) { - red = ws.rQshift16(); - //Util.Debug("red before: " + red); - red = parseInt(red / 256, 10); - //Util.Debug("red after: " + red); - green = parseInt(ws.rQshift16() / 256, 10); - blue = parseInt(ws.rQshift16() / 256, 10); - Util.Debug("*** colourMap: " + display.get_colourMap()); - display.set_colourMap([red, green, blue], first_colour + c); - } - Util.Info("Registered " + num_colours + " colourMap entries"); - //Util.Debug("colourMap: " + display.get_colourMap()); - break; - case 2: // Bell - Util.Debug("Bell"); - conf.onBell(that); - break; - case 3: // ServerCutText - Util.Debug("ServerCutText"); - if (ws.rQwait("ServerCutText header", 7, 1)) { return false; } - ws.rQshiftBytes(3); // Padding - length = ws.rQshift32(); - if (ws.rQwait("ServerCutText", length, 8)) { return false; } - - text = ws.rQshiftStr(length); - conf.clipboardReceive(that, text); // Obsolete - conf.onClipboard(that, text); - break; - default: - fail("Disconnected: illegal server message type " + msg_type); - Util.Debug("ws.rQslice(0,30):" + ws.rQslice(0,30)); - break; - } - //Util.Debug("<< normal_msg"); - return ret; -}; - -framebufferUpdate = function() { - var now, hdr, fbu_rt_diff, ret = true; - - if (FBU.rects === 0) { - //Util.Debug("New FBU: ws.rQslice(0,20): " + ws.rQslice(0,20)); - if (ws.rQwait("FBU header", 3)) { - ws.rQunshift8(0); // FBU msg_type - return false; - } - ws.rQshift8(); // padding - FBU.rects = ws.rQshift16(); - //Util.Debug("FramebufferUpdate, rects:" + FBU.rects); - FBU.bytes = 0; - timing.cur_fbu = 0; - if (timing.fbu_rt_start > 0) { - now = (new Date()).getTime(); - Util.Info("First FBU latency: " + (now - timing.fbu_rt_start)); - } - } - - while (FBU.rects > 0) { - if (rfb_state !== "normal") { - return false; - } - if (ws.rQwait("FBU", FBU.bytes)) { return false; } - if (FBU.bytes === 0) { - if (ws.rQwait("rect header", 12)) { return false; } - /* New FramebufferUpdate */ - - hdr = ws.rQshiftBytes(12); - FBU.x = (hdr[0] << 8) + hdr[1]; - FBU.y = (hdr[2] << 8) + hdr[3]; - FBU.width = (hdr[4] << 8) + hdr[5]; - FBU.height = (hdr[6] << 8) + hdr[7]; - FBU.encoding = parseInt((hdr[8] << 24) + (hdr[9] << 16) + - (hdr[10] << 8) + hdr[11], 10); - - conf.onFBUReceive(that, - {'x': FBU.x, 'y': FBU.y, - 'width': FBU.width, 'height': FBU.height, - 'encoding': FBU.encoding, - 'encodingName': encNames[FBU.encoding]}); - - if (encNames[FBU.encoding]) { - // Debug: - /* - var msg = "FramebufferUpdate rects:" + FBU.rects; - msg += " x: " + FBU.x + " y: " + FBU.y; - msg += " width: " + FBU.width + " height: " + FBU.height; - msg += " encoding:" + FBU.encoding; - msg += "(" + encNames[FBU.encoding] + ")"; - msg += ", ws.rQlen(): " + ws.rQlen(); - Util.Debug(msg); - */ - } else { - fail("Disconnected: unsupported encoding " + - FBU.encoding); - return false; - } - } - - timing.last_fbu = (new Date()).getTime(); - - ret = encHandlers[FBU.encoding](); - - now = (new Date()).getTime(); - timing.cur_fbu += (now - timing.last_fbu); - - if (ret) { - encStats[FBU.encoding][0] += 1; - encStats[FBU.encoding][1] += 1; - } - - if (FBU.rects === 0) { - if (((FBU.width === fb_width) && - (FBU.height === fb_height)) || - (timing.fbu_rt_start > 0)) { - timing.full_fbu_total += timing.cur_fbu; - timing.full_fbu_cnt += 1; - Util.Info("Timing of full FBU, cur: " + - timing.cur_fbu + ", total: " + - timing.full_fbu_total + ", cnt: " + - timing.full_fbu_cnt + ", avg: " + - (timing.full_fbu_total / - timing.full_fbu_cnt)); - } - if (timing.fbu_rt_start > 0) { - fbu_rt_diff = now - timing.fbu_rt_start; - timing.fbu_rt_total += fbu_rt_diff; - timing.fbu_rt_cnt += 1; - Util.Info("full FBU round-trip, cur: " + - fbu_rt_diff + ", total: " + - timing.fbu_rt_total + ", cnt: " + - timing.fbu_rt_cnt + ", avg: " + - (timing.fbu_rt_total / - timing.fbu_rt_cnt)); - timing.fbu_rt_start = 0; - } - } - if (! ret) { - return ret; // false ret means need more data - } - } - - conf.onFBUComplete(that, - {'x': FBU.x, 'y': FBU.y, - 'width': FBU.width, 'height': FBU.height, - 'encoding': FBU.encoding, - 'encodingName': encNames[FBU.encoding]}); - - return true; // We finished this FBU -}; - -// -// FramebufferUpdate encodings -// - -encHandlers.RAW = function display_raw() { - //Util.Debug(">> display_raw (" + ws.rQlen() + " bytes)"); - - var cur_y, cur_height; - - if (FBU.lines === 0) { - FBU.lines = FBU.height; - } - FBU.bytes = FBU.width * fb_Bpp; // At least a line - if (ws.rQwait("RAW", FBU.bytes)) { return false; } - cur_y = FBU.y + (FBU.height - FBU.lines); - cur_height = Math.min(FBU.lines, - Math.floor(ws.rQlen()/(FBU.width * fb_Bpp))); - display.blitImage(FBU.x, cur_y, FBU.width, cur_height, - ws.get_rQ(), ws.get_rQi()); - ws.rQshiftBytes(FBU.width * cur_height * fb_Bpp); - FBU.lines -= cur_height; - - if (FBU.lines > 0) { - FBU.bytes = FBU.width * fb_Bpp; // At least another line - } else { - FBU.rects -= 1; - FBU.bytes = 0; - } - //Util.Debug("<< display_raw (" + ws.rQlen() + " bytes)"); - return true; -}; - -encHandlers.COPYRECT = function display_copy_rect() { - //Util.Debug(">> display_copy_rect"); - - var old_x, old_y; - - if (ws.rQwait("COPYRECT", 4)) { return false; } - old_x = ws.rQshift16(); - old_y = ws.rQshift16(); - display.copyImage(old_x, old_y, FBU.x, FBU.y, FBU.width, FBU.height); - FBU.rects -= 1; - FBU.bytes = 0; - return true; -}; - -encHandlers.RRE = function display_rre() { - //Util.Debug(">> display_rre (" + ws.rQlen() + " bytes)"); - var color, x, y, width, height, chunk; - - if (FBU.subrects === 0) { - if (ws.rQwait("RRE", 4+fb_Bpp)) { return false; } - FBU.subrects = ws.rQshift32(); - color = ws.rQshiftBytes(fb_Bpp); // Background - display.fillRect(FBU.x, FBU.y, FBU.width, FBU.height, color); - } - while ((FBU.subrects > 0) && (ws.rQlen() >= (fb_Bpp + 8))) { - color = ws.rQshiftBytes(fb_Bpp); - x = ws.rQshift16(); - y = ws.rQshift16(); - width = ws.rQshift16(); - height = ws.rQshift16(); - display.fillRect(FBU.x + x, FBU.y + y, width, height, color); - FBU.subrects -= 1; - } - //Util.Debug(" display_rre: rects: " + FBU.rects + - // ", FBU.subrects: " + FBU.subrects); - - if (FBU.subrects > 0) { - chunk = Math.min(rre_chunk_sz, FBU.subrects); - FBU.bytes = (fb_Bpp + 8) * chunk; - } else { - FBU.rects -= 1; - FBU.bytes = 0; - } - //Util.Debug("<< display_rre, FBU.bytes: " + FBU.bytes); - return true; -}; - -encHandlers.HEXTILE = function display_hextile() { - //Util.Debug(">> display_hextile"); - var subencoding, subrects, tile, color, cur_tile, - tile_x, x, w, tile_y, y, h, xy, s, sx, sy, wh, sw, sh, - rQ = ws.get_rQ(), rQi = ws.get_rQi(); - - if (FBU.tiles === 0) { - FBU.tiles_x = Math.ceil(FBU.width/16); - FBU.tiles_y = Math.ceil(FBU.height/16); - FBU.total_tiles = FBU.tiles_x * FBU.tiles_y; - FBU.tiles = FBU.total_tiles; - } - - /* FBU.bytes comes in as 1, ws.rQlen() at least 1 */ - while (FBU.tiles > 0) { - FBU.bytes = 1; - if (ws.rQwait("HEXTILE subencoding", FBU.bytes)) { return false; } - subencoding = rQ[rQi]; // Peek - if (subencoding > 30) { // Raw - fail("Disconnected: illegal hextile subencoding " + subencoding); - //Util.Debug("ws.rQslice(0,30):" + ws.rQslice(0,30)); - return false; - } - subrects = 0; - cur_tile = FBU.total_tiles - FBU.tiles; - tile_x = cur_tile % FBU.tiles_x; - tile_y = Math.floor(cur_tile / FBU.tiles_x); - x = FBU.x + tile_x * 16; - y = FBU.y + tile_y * 16; - w = Math.min(16, (FBU.x + FBU.width) - x); - h = Math.min(16, (FBU.y + FBU.height) - y); - - /* Figure out how much we are expecting */ - if (subencoding & 0x01) { // Raw - //Util.Debug(" Raw subencoding"); - FBU.bytes += w * h * fb_Bpp; - } else { - if (subencoding & 0x02) { // Background - FBU.bytes += fb_Bpp; - } - if (subencoding & 0x04) { // Foreground - FBU.bytes += fb_Bpp; - } - if (subencoding & 0x08) { // AnySubrects - FBU.bytes += 1; // Since we aren't shifting it off - if (ws.rQwait("hextile subrects header", FBU.bytes)) { return false; } - subrects = rQ[rQi + FBU.bytes-1]; // Peek - if (subencoding & 0x10) { // SubrectsColoured - FBU.bytes += subrects * (fb_Bpp + 2); - } else { - FBU.bytes += subrects * 2; - } - } - } - - /* - Util.Debug(" tile:" + cur_tile + "/" + (FBU.total_tiles - 1) + - " (" + tile_x + "," + tile_y + ")" + - " [" + x + "," + y + "]@" + w + "x" + h + - ", subenc:" + subencoding + - "(last: " + FBU.lastsubencoding + "), subrects:" + - subrects + - ", ws.rQlen():" + ws.rQlen() + ", FBU.bytes:" + FBU.bytes + - " last:" + ws.rQslice(FBU.bytes-10, FBU.bytes) + - " next:" + ws.rQslice(FBU.bytes-1, FBU.bytes+10)); - */ - if (ws.rQwait("hextile", FBU.bytes)) { return false; } - - /* We know the encoding and have a whole tile */ - FBU.subencoding = rQ[rQi]; - rQi += 1; - if (FBU.subencoding === 0) { - if (FBU.lastsubencoding & 0x01) { - /* Weird: ignore blanks after RAW */ - Util.Debug(" Ignoring blank after RAW"); - } else { - display.fillRect(x, y, w, h, FBU.background); - } - } else if (FBU.subencoding & 0x01) { // Raw - display.blitImage(x, y, w, h, rQ, rQi); - rQi += FBU.bytes - 1; - } else { - if (FBU.subencoding & 0x02) { // Background - FBU.background = rQ.slice(rQi, rQi + fb_Bpp); - rQi += fb_Bpp; - } - if (FBU.subencoding & 0x04) { // Foreground - FBU.foreground = rQ.slice(rQi, rQi + fb_Bpp); - rQi += fb_Bpp; - } - - tile = display.getTile(x, y, w, h, FBU.background); - if (FBU.subencoding & 0x08) { // AnySubrects - subrects = rQ[rQi]; - rQi += 1; - for (s = 0; s < subrects; s += 1) { - if (FBU.subencoding & 0x10) { // SubrectsColoured - color = rQ.slice(rQi, rQi + fb_Bpp); - rQi += fb_Bpp; - } else { - color = FBU.foreground; - } - xy = rQ[rQi]; - rQi += 1; - sx = (xy >> 4); - sy = (xy & 0x0f); - - wh = rQ[rQi]; - rQi += 1; - sw = (wh >> 4) + 1; - sh = (wh & 0x0f) + 1; - - display.setSubTile(tile, sx, sy, sw, sh, color); - } - } - display.putTile(tile); - } - ws.set_rQi(rQi); - FBU.lastsubencoding = FBU.subencoding; - FBU.bytes = 0; - FBU.tiles -= 1; - } - - if (FBU.tiles === 0) { - FBU.rects -= 1; - } - - //Util.Debug("<< display_hextile"); - return true; -}; - - -encHandlers.TIGHT_PNG = function display_tight_png() { - //Util.Debug(">> display_tight_png"); - var ctl, cmode, clength, getCLength, color, img; - //Util.Debug(" FBU.rects: " + FBU.rects); - //Util.Debug(" starting ws.rQslice(0,20): " + ws.rQslice(0,20) + " (" + ws.rQlen() + ")"); - - FBU.bytes = 1; // compression-control byte - if (ws.rQwait("TIGHT compression-control", FBU.bytes)) { return false; } - - // Get 'compact length' header and data size - getCLength = function (arr) { - var header = 1, data = 0; - data += arr[0] & 0x7f; - if (arr[0] & 0x80) { - header += 1; - data += (arr[1] & 0x7f) << 7; - if (arr[1] & 0x80) { - header += 1; - data += arr[2] << 14; - } - } - return [header, data]; - }; - - ctl = ws.rQpeek8(); - switch (ctl >> 4) { - case 0x08: cmode = "fill"; break; - case 0x09: cmode = "jpeg"; break; - case 0x0A: cmode = "png"; break; - default: throw("Illegal basic compression received, ctl: " + ctl); - } - switch (cmode) { - // fill uses fb_depth because TPIXELs drop the padding byte - case "fill": FBU.bytes += fb_depth; break; // TPIXEL - case "jpeg": FBU.bytes += 3; break; // max clength - case "png": FBU.bytes += 3; break; // max clength - } - - if (ws.rQwait("TIGHT " + cmode, FBU.bytes)) { return false; } - - //Util.Debug(" ws.rQslice(0,20): " + ws.rQslice(0,20) + " (" + ws.rQlen() + ")"); - //Util.Debug(" cmode: " + cmode); - - // Determine FBU.bytes - switch (cmode) { - case "fill": - ws.rQshift8(); // shift off ctl - color = ws.rQshiftBytes(fb_depth); - FBU.imgQ.push({ - 'type': 'fill', - 'img': {'complete': true}, - 'x': FBU.x, - 'y': FBU.y, - 'width': FBU.width, - 'height': FBU.height, - 'color': color}); - break; - case "jpeg": - case "png": - clength = getCLength(ws.rQslice(1, 4)); - FBU.bytes = 1 + clength[0] + clength[1]; // ctl + clength size + jpeg-data - if (ws.rQwait("TIGHT " + cmode, FBU.bytes)) { return false; } - - // We have everything, render it - //Util.Debug(" png, ws.rQlen(): " + ws.rQlen() + ", clength[0]: " + clength[0] + ", clength[1]: " + clength[1]); - ws.rQshiftBytes(1 + clength[0]); // shift off ctl + compact length - img = new Image(); - //img.onload = scan_tight_imgQ; - FBU.imgQ.push({ - 'type': 'img', - 'img': img, - 'x': FBU.x, - 'y': FBU.y}); - img.src = "data:image/" + cmode + - extract_data_uri(ws.rQshiftBytes(clength[1])); - img = null; - break; - } - FBU.bytes = 0; - FBU.rects -= 1; - //Util.Debug(" ending ws.rQslice(0,20): " + ws.rQslice(0,20) + " (" + ws.rQlen() + ")"); - //Util.Debug("<< display_tight_png"); - return true; -}; - -extract_data_uri = function(arr) { - //var i, stra = []; - //for (i=0; i< arr.length; i += 1) { - // stra.push(String.fromCharCode(arr[i])); - //} - //return "," + escape(stra.join('')); - return ";base64," + Base64.encode(arr); -}; - -scan_tight_imgQ = function() { - var data, imgQ, ctx; - ctx = display.get_context(); - if (rfb_state === 'normal') { - imgQ = FBU.imgQ; - while ((imgQ.length > 0) && (imgQ[0].img.complete)) { - data = imgQ.shift(); - if (data['type'] === 'fill') { - display.fillRect(data.x, data.y, data.width, data.height, data.color); - } else { - ctx.drawImage(data.img, data.x, data.y); - } - } - setTimeout(scan_tight_imgQ, scan_imgQ_rate); - } -}; - -encHandlers.DesktopSize = function set_desktopsize() { - Util.Debug(">> set_desktopsize"); - fb_width = FBU.width; - fb_height = FBU.height; - display.resize(fb_width, fb_height); - timing.fbu_rt_start = (new Date()).getTime(); - // Send a new non-incremental request - ws.send(fbUpdateRequest(0)); - - FBU.bytes = 0; - FBU.rects -= 1; - - Util.Debug("<< set_desktopsize"); - return true; -}; - -encHandlers.Cursor = function set_cursor() { - var x, y, w, h, pixelslength, masklength; - //Util.Debug(">> set_cursor"); - x = FBU.x; // hotspot-x - y = FBU.y; // hotspot-y - w = FBU.width; - h = FBU.height; - - pixelslength = w * h * fb_Bpp; - masklength = Math.floor((w + 7) / 8) * h; - - FBU.bytes = pixelslength + masklength; - if (ws.rQwait("cursor encoding", FBU.bytes)) { return false; } - - //Util.Debug(" set_cursor, x: " + x + ", y: " + y + ", w: " + w + ", h: " + h); - - display.changeCursor(ws.rQshiftBytes(pixelslength), - ws.rQshiftBytes(masklength), - x, y, w, h); - - FBU.bytes = 0; - FBU.rects -= 1; - - //Util.Debug("<< set_cursor"); - return true; -}; - -encHandlers.JPEG_quality_lo = function set_jpeg_quality() { - Util.Error("Server sent jpeg_quality pseudo-encoding"); -}; - -encHandlers.compress_lo = function set_compress_level() { - Util.Error("Server sent compress level pseudo-encoding"); -}; - -/* - * Client message routines - */ - -pixelFormat = function() { - //Util.Debug(">> pixelFormat"); - var arr; - arr = [0]; // msg-type - arr.push8(0); // padding - arr.push8(0); // padding - arr.push8(0); // padding - - arr.push8(fb_Bpp * 8); // bits-per-pixel - arr.push8(fb_depth * 8); // depth - arr.push8(0); // little-endian - arr.push8(conf.true_color ? 1 : 0); // true-color - - arr.push16(255); // red-max - arr.push16(255); // green-max - arr.push16(255); // blue-max - arr.push8(0); // red-shift - arr.push8(8); // green-shift - arr.push8(16); // blue-shift - - arr.push8(0); // padding - arr.push8(0); // padding - arr.push8(0); // padding - //Util.Debug("<< pixelFormat"); - return arr; -}; - -clientEncodings = function() { - //Util.Debug(">> clientEncodings"); - var arr, i, encList = []; - - for (i=0; i> fbUpdateRequest"); - if (!x) { x = 0; } - if (!y) { y = 0; } - if (!xw) { xw = fb_width; } - if (!yw) { yw = fb_height; } - var arr; - arr = [3]; // msg-type - arr.push8(incremental); - arr.push16(x); - arr.push16(y); - arr.push16(xw); - arr.push16(yw); - //Util.Debug("<< fbUpdateRequest"); - return arr; -}; - -keyEvent = function(keysym, down) { - //Util.Debug(">> keyEvent, keysym: " + keysym + ", down: " + down); - var arr; - arr = [4]; // msg-type - arr.push8(down); - arr.push16(0); - arr.push32(keysym); - //Util.Debug("<< keyEvent"); - return arr; -}; - -pointerEvent = function(x, y) { - //Util.Debug(">> pointerEvent, x,y: " + x + "," + y + - // " , mask: " + mouse_buttonMask); - var arr; - arr = [5]; // msg-type - arr.push8(mouse_buttonMask); - arr.push16(x); - arr.push16(y); - //Util.Debug("<< pointerEvent"); - return arr; -}; - -clientCutText = function(text) { - //Util.Debug(">> clientCutText"); - var arr, i, n; - arr = [6]; // msg-type - arr.push8(0); // padding - arr.push8(0); // padding - arr.push8(0); // padding - arr.push32(text.length); - n = text.length; - for (i=0; i < n; i+=1) { - arr.push(text.charCodeAt(i)); - } - //Util.Debug("<< clientCutText:" + arr); - return arr; -}; - - - -// -// Public API interface functions -// - -that.connect = function(host, port, password, uri) { - //Util.Debug(">> connect"); - - rfb_host = host; - rfb_port = port; - rfb_password = (password !== undefined) ? password : ""; - rfb_uri = (uri !== undefined) ? uri : ""; - - if ((!rfb_host) || (!rfb_port)) { - return fail("Must set host and port"); - } - - updateState('connect'); - //Util.Debug("<< connect"); - -}; - -that.disconnect = function() { - //Util.Debug(">> disconnect"); - updateState('disconnect', 'Disconnecting'); - //Util.Debug("<< disconnect"); -}; - -that.sendPassword = function(passwd) { - rfb_password = passwd; - rfb_state = "Authentication"; - setTimeout(init_msg, 1); -}; - -that.sendCtrlAltDel = function() { - if (rfb_state !== "normal") { return false; } - Util.Info("Sending Ctrl-Alt-Del"); - var arr = []; - arr = arr.concat(keyEvent(0xFFE3, 1)); // Control - arr = arr.concat(keyEvent(0xFFE9, 1)); // Alt - arr = arr.concat(keyEvent(0xFFFF, 1)); // Delete - arr = arr.concat(keyEvent(0xFFFF, 0)); // Delete - arr = arr.concat(keyEvent(0xFFE9, 0)); // Alt - arr = arr.concat(keyEvent(0xFFE3, 0)); // Control - arr = arr.concat(fbUpdateRequest(1)); - ws.send(arr); -}; - -// Send a key press. If 'down' is not specified then send a down key -// followed by an up key. -that.sendKey = function(code, down) { - if (rfb_state !== "normal") { return false; } - var arr = []; - if (typeof down !== 'undefined') { - Util.Info("Sending key code (" + (down ? "down" : "up") + "): " + code); - arr = arr.concat(keyEvent(code, down ? 1 : 0)); - } else { - Util.Info("Sending key code (down + up): " + code); - arr = arr.concat(keyEvent(code, 1)); - arr = arr.concat(keyEvent(code, 0)); - } - arr = arr.concat(fbUpdateRequest(1)); - ws.send(arr); -}; - -that.clipboardPasteFrom = function(text) { - if (rfb_state !== "normal") { return; } - //Util.Debug(">> clipboardPasteFrom: " + text.substr(0,40) + "..."); - ws.send(clientCutText(text)); - //Util.Debug("<< clipboardPasteFrom"); -}; - -// Override internal functions for testing -that.testMode = function(override_send) { - test_mode = true; - that.recv_message = ws.testMode(override_send); - - checkEvents = function () { /* Stub Out */ }; - that.connect = function(host, port, password) { - rfb_host = host; - rfb_port = port; - rfb_password = password; - updateState('ProtocolVersion', "Starting VNC handshake"); - }; -}; - - -return constructor(); // Return the public API interface - -} // End of RFB() diff --git a/res/raw/swfobject.js b/res/raw/swfobject.js deleted file mode 100755 index 8eafe9d..0000000 --- a/res/raw/swfobject.js +++ /dev/null @@ -1,4 +0,0 @@ -/* SWFObject v2.2 - is released under the MIT License -*/ -var swfobject=function(){var D="undefined",r="object",S="Shockwave Flash",W="ShockwaveFlash.ShockwaveFlash",q="application/x-shockwave-flash",R="SWFObjectExprInst",x="onreadystatechange",O=window,j=document,t=navigator,T=false,U=[h],o=[],N=[],I=[],l,Q,E,B,J=false,a=false,n,G,m=true,M=function(){var aa=typeof j.getElementById!=D&&typeof j.getElementsByTagName!=D&&typeof j.createElement!=D,ah=t.userAgent.toLowerCase(),Y=t.platform.toLowerCase(),ae=Y?/win/.test(Y):/win/.test(ah),ac=Y?/mac/.test(Y):/mac/.test(ah),af=/webkit/.test(ah)?parseFloat(ah.replace(/^.*webkit\/(\d+(\.\d+)?).*$/,"$1")):false,X=!+"\v1",ag=[0,0,0],ab=null;if(typeof t.plugins!=D&&typeof t.plugins[S]==r){ab=t.plugins[S].description;if(ab&&!(typeof t.mimeTypes!=D&&t.mimeTypes[q]&&!t.mimeTypes[q].enabledPlugin)){T=true;X=false;ab=ab.replace(/^.*\s+(\S+\s+\S+$)/,"$1");ag[0]=parseInt(ab.replace(/^(.*)\..*$/,"$1"),10);ag[1]=parseInt(ab.replace(/^.*\.(.*)\s.*$/,"$1"),10);ag[2]=/[a-zA-Z]/.test(ab)?parseInt(ab.replace(/^.*[a-zA-Z]+(.*)$/,"$1"),10):0}}else{if(typeof O.ActiveXObject!=D){try{var ad=new ActiveXObject(W);if(ad){ab=ad.GetVariable("$version");if(ab){X=true;ab=ab.split(" ")[1].split(",");ag=[parseInt(ab[0],10),parseInt(ab[1],10),parseInt(ab[2],10)]}}}catch(Z){}}}return{w3:aa,pv:ag,wk:af,ie:X,win:ae,mac:ac}}(),k=function(){if(!M.w3){return}if((typeof j.readyState!=D&&j.readyState=="complete")||(typeof j.readyState==D&&(j.getElementsByTagName("body")[0]||j.body))){f()}if(!J){if(typeof j.addEventListener!=D){j.addEventListener("DOMContentLoaded",f,false)}if(M.ie&&M.win){j.attachEvent(x,function(){if(j.readyState=="complete"){j.detachEvent(x,arguments.callee);f()}});if(O==top){(function(){if(J){return}try{j.documentElement.doScroll("left")}catch(X){setTimeout(arguments.callee,0);return}f()})()}}if(M.wk){(function(){if(J){return}if(!/loaded|complete/.test(j.readyState)){setTimeout(arguments.callee,0);return}f()})()}s(f)}}();function f(){if(J){return}try{var Z=j.getElementsByTagName("body")[0].appendChild(C("span"));Z.parentNode.removeChild(Z)}catch(aa){return}J=true;var X=U.length;for(var Y=0;Y0){for(var af=0;af0){var ae=c(Y);if(ae){if(F(o[af].swfVersion)&&!(M.wk&&M.wk<312)){w(Y,true);if(ab){aa.success=true;aa.ref=z(Y);ab(aa)}}else{if(o[af].expressInstall&&A()){var ai={};ai.data=o[af].expressInstall;ai.width=ae.getAttribute("width")||"0";ai.height=ae.getAttribute("height")||"0";if(ae.getAttribute("class")){ai.styleclass=ae.getAttribute("class")}if(ae.getAttribute("align")){ai.align=ae.getAttribute("align")}var ah={};var X=ae.getElementsByTagName("param");var ac=X.length;for(var ad=0;ad'}}aa.outerHTML='"+af+"";N[N.length]=ai.id;X=c(ai.id)}else{var Z=C(r);Z.setAttribute("type",q);for(var ac in ai){if(ai[ac]!=Object.prototype[ac]){if(ac.toLowerCase()=="styleclass"){Z.setAttribute("class",ai[ac])}else{if(ac.toLowerCase()!="classid"){Z.setAttribute(ac,ai[ac])}}}}for(var ab in ag){if(ag[ab]!=Object.prototype[ab]&&ab.toLowerCase()!="movie"){e(Z,ab,ag[ab])}}aa.parentNode.replaceChild(Z,aa);X=Z}}return X}function e(Z,X,Y){var aa=C("param");aa.setAttribute("name",X);aa.setAttribute("value",Y);Z.appendChild(aa)}function y(Y){var X=c(Y);if(X&&X.nodeName=="OBJECT"){if(M.ie&&M.win){X.style.display="none";(function(){if(X.readyState==4){b(Y)}else{setTimeout(arguments.callee,10)}})()}else{X.parentNode.removeChild(X)}}}function b(Z){var Y=c(Z);if(Y){for(var X in Y){if(typeof Y[X]=="function"){Y[X]=null}}Y.parentNode.removeChild(Y)}}function c(Z){var X=null;try{X=j.getElementById(Z)}catch(Y){}return X}function C(X){return j.createElement(X)}function i(Z,X,Y){Z.attachEvent(X,Y);I[I.length]=[Z,X,Y]}function F(Z){var Y=M.pv,X=Z.split(".");X[0]=parseInt(X[0],10);X[1]=parseInt(X[1],10)||0;X[2]=parseInt(X[2],10)||0;return(Y[0]>X[0]||(Y[0]==X[0]&&Y[1]>X[1])||(Y[0]==X[0]&&Y[1]==X[1]&&Y[2]>=X[2]))?true:false}function v(ac,Y,ad,ab){if(M.ie&&M.mac){return}var aa=j.getElementsByTagName("head")[0];if(!aa){return}var X=(ad&&typeof ad=="string")?ad:"screen";if(ab){n=null;G=null}if(!n||G!=X){var Z=C("style");Z.setAttribute("type","text/css");Z.setAttribute("media",X);n=aa.appendChild(Z);if(M.ie&&M.win&&typeof j.styleSheets!=D&&j.styleSheets.length>0){n=j.styleSheets[j.styleSheets.length-1]}G=X}if(M.ie&&M.win){if(n&&typeof n.addRule==r){n.addRule(ac,Y)}}else{if(n&&typeof j.createTextNode!=D){n.appendChild(j.createTextNode(ac+" {"+Y+"}"))}}}function w(Z,X){if(!m){return}var Y=X?"visible":"hidden";if(J&&c(Z)){c(Z).style.visibility=Y}else{v("#"+Z,"visibility:"+Y)}}function L(Y){var Z=/[\\\"<>\.;]/;var X=Z.exec(Y)!=null;return X&&typeof encodeURIComponent!=D?encodeURIComponent(Y):Y}var d=function(){if(M.ie&&M.win){window.attachEvent("onunload",function(){var ac=I.length;for(var ab=0;ab' + sheets[i].title + ''; - } - html += ' Style'; - - // Logging selection dropdown - html += '
  • Logging
  • '; - - html += '
    '; - html += '
  • > settingsDisabled"); - $D('VNC_encrypt').disabled = disabled; - $D('VNC_true_color').disabled = disabled; - if (rfb && rfb.get_display() && rfb.get_display().get_cursor_uri()) { - $D('VNC_cursor').disabled = disabled; - } else { - UI.updateSetting('cursor', false); - $D('VNC_cursor').disabled = true; - } - $D('VNC_shared').disabled = disabled; - $D('VNC_connectTimeout').disabled = disabled; - //Util.Debug("<< settingsDisabled"); -}, - -// Save/apply settings when 'Apply' button is pressed -settingsApply: function() { - //Util.Debug(">> settingsApply"); - UI.saveSetting('encrypt'); - UI.saveSetting('true_color'); - if (UI.rfb.get_display().get_cursor_uri()) { - UI.saveSetting('cursor'); - } - UI.saveSetting('shared'); - UI.saveSetting('connectTimeout'); - UI.saveSetting('stylesheet'); - UI.saveSetting('logging'); - - // Settings with immediate (non-connected related) effect - WebUtil.selectStylesheet(UI.getSetting('stylesheet')); - WebUtil.init_logging(UI.getSetting('logging')); - - //Util.Debug("<< settingsApply"); -}, - - - -setPassword: function() { - UI.rfb.sendPassword($D('VNC_password').value); - return false; -}, - -sendCtrlAltDel: function() { - UI.rfb.sendCtrlAltDel(); -}, - -updateState: function(rfb, state, oldstate, msg) { - var s, sb, c, klass; - s = $D('VNC_status'); - sb = $D('VNC_status_bar'); - c = $D('VNC_connect_button'); - switch (state) { - case 'failed': - case 'fatal': - c.disabled = true; - UI.settingsDisabled(true, rfb); - klass = "VNC_status_error"; - break; - case 'normal': - c.value = "Disconnect"; - c.onclick = UI.disconnect; - c.disabled = false; - UI.settingsDisabled(true, rfb); - klass = "VNC_status_normal"; - break; - case 'disconnected': - case 'loaded': - c.value = "Connect"; - c.onclick = UI.connect; - - c.disabled = false; - UI.settingsDisabled(false, rfb); - klass = "VNC_status_normal"; - break; - case 'password': - c.value = "Send Password"; - c.onclick = UI.setPassword; - - c.disabled = false; - UI.settingsDisabled(true, rfb); - klass = "VNC_status_warn"; - break; - default: - c.disabled = true; - UI.settingsDisabled(true, rfb); - klass = "VNC_status_warn"; - break; - } - - if (typeof(msg) !== 'undefined') { - s.setAttribute("class", klass); - sb.setAttribute("class", klass); - s.innerHTML = msg; - } - -}, - -clipReceive: function(rfb, text) { - Util.Debug(">> UI.clipReceive: " + text.substr(0,40) + "..."); - $D('VNC_clipboard_text').value = text; - Util.Debug("<< UI.clipReceive"); -}, - - -connect: function() { - var host, port, password; - - UI.closeSettingsMenu(); - - host = $D('VNC_host').value; - port = $D('VNC_port').value; - password = $D('VNC_password').value; - if ((!host) || (!port)) { - throw("Must set host and port"); - } - - UI.rfb.set_encrypt(UI.getSetting('encrypt')); - UI.rfb.set_true_color(UI.getSetting('true_color')); - UI.rfb.set_local_cursor(UI.getSetting('cursor')); - UI.rfb.set_shared(UI.getSetting('shared')); - UI.rfb.set_connectTimeout(UI.getSetting('connectTimeout')); - - UI.rfb.connect(host, port, password); -}, - -disconnect: function() { - UI.closeSettingsMenu(); - - UI.rfb.disconnect(); -}, - -displayBlur: function() { - UI.rfb.get_keyboard().set_focused(false); - UI.rfb.get_mouse().set_focused(false); -}, - -displayFocus: function() { - UI.rfb.get_keyboard().set_focused(true); - UI.rfb.get_mouse().set_focused(true); -}, - -clipClear: function() { - $D('VNC_clipboard_text').value = ""; - UI.rfb.clipboardPasteFrom(""); -}, - -clipSend: function() { - var text = $D('VNC_clipboard_text').value; - Util.Debug(">> UI.clipSend: " + text.substr(0,40) + "..."); - UI.rfb.clipboardPasteFrom(text); - Util.Debug("<< UI.clipSend"); -} - -}; diff --git a/res/raw/util.js b/res/raw/util.js deleted file mode 100755 index 738c7bb..0000000 --- a/res/raw/util.js +++ /dev/null @@ -1,275 +0,0 @@ -/* - * noVNC: HTML5 VNC client - * Copyright (C) 2011 Joel Martin - * Licensed under LGPL-3 (see LICENSE.txt) - * - * See README.md for usage and integration instructions. - */ - -"use strict"; -/*jslint bitwise: false, white: false */ -/*global window, console, document, navigator, ActiveXObject */ - -// Globals defined here -var Util = {}; - - -/* - * Make arrays quack - */ - -Array.prototype.push8 = function (num) { - this.push(num & 0xFF); -}; - -Array.prototype.push16 = function (num) { - this.push((num >> 8) & 0xFF, - (num ) & 0xFF ); -}; -Array.prototype.push32 = function (num) { - this.push((num >> 24) & 0xFF, - (num >> 16) & 0xFF, - (num >> 8) & 0xFF, - (num ) & 0xFF ); -}; - -/* - * ------------------------------------------------------ - * Namespaced in Util - * ------------------------------------------------------ - */ - -/* - * Logging/debug routines - */ - -Util._log_level = 'warn'; -Util.init_logging = function (level) { - if (typeof level === 'undefined') { - level = Util._log_level; - } else { - Util._log_level = level; - } - if (typeof window.console === "undefined") { - if (typeof window.opera !== "undefined") { - window.console = { - 'log' : window.opera.postError, - 'warn' : window.opera.postError, - 'error': window.opera.postError }; - } else { - window.console = { - 'log' : function(m) {}, - 'warn' : function(m) {}, - 'error': function(m) {}}; - } - } - - Util.Debug = Util.Info = Util.Warn = Util.Error = function (msg) {}; - switch (level) { - case 'debug': Util.Debug = function (msg) { console.log(msg); }; - case 'info': Util.Info = function (msg) { console.log(msg); }; - case 'warn': Util.Warn = function (msg) { console.warn(msg); }; - case 'error': Util.Error = function (msg) { console.error(msg); }; - case 'none': - break; - default: - throw("invalid logging type '" + level + "'"); - } -}; -Util.get_logging = function () { - return Util._log_level; -}; -// Initialize logging level -Util.init_logging(); - - -// Set configuration default for Crockford style function namespaces -Util.conf_default = function(cfg, api, defaults, v, mode, type, defval, desc) { - var getter, setter; - - // Default getter function - getter = function (idx) { - if ((type in {'arr':1, 'array':1}) && - (typeof idx !== 'undefined')) { - return cfg[v][idx]; - } else { - return cfg[v]; - } - }; - - // Default setter function - setter = function (val, idx) { - if (type in {'boolean':1, 'bool':1}) { - if ((!val) || (val in {'0':1, 'no':1, 'false':1})) { - val = false; - } else { - val = true; - } - } else if (type in {'integer':1, 'int':1}) { - val = parseInt(val, 10); - } else if (type === 'func') { - if (!val) { - val = function () {}; - } - } - if (typeof idx !== 'undefined') { - cfg[v][idx] = val; - } else { - cfg[v] = val; - } - }; - - // Set the description - api[v + '_description'] = desc; - - // Set the getter function - if (typeof api['get_' + v] === 'undefined') { - api['get_' + v] = getter; - } - - // Set the setter function with extra sanity checks - if (typeof api['set_' + v] === 'undefined') { - api['set_' + v] = function (val, idx) { - if (mode in {'RO':1, 'ro':1}) { - throw(v + " is read-only"); - } else if ((mode in {'WO':1, 'wo':1}) && - (typeof cfg[v] !== 'undefined')) { - throw(v + " can only be set once"); - } - setter(val, idx); - }; - } - - // Set the default value - if (typeof defaults[v] !== 'undefined') { - defval = defaults[v]; - } else if ((type in {'arr':1, 'array':1}) && - (! (defval instanceof Array))) { - defval = []; - } - // Coerce existing setting to the right type - //Util.Debug("v: " + v + ", defval: " + defval + ", defaults[v]: " + defaults[v]); - setter(defval); -}; - -// Set group of configuration defaults -Util.conf_defaults = function(cfg, api, defaults, arr) { - var i; - for (i = 0; i < arr.length; i++) { - Util.conf_default(cfg, api, defaults, arr[i][0], arr[i][1], - arr[i][2], arr[i][3], arr[i][4]); - } -} - - -/* - * Cross-browser routines - */ - -// Get DOM element position on page -Util.getPosition = function (obj) { - var x = 0, y = 0; - if (obj.offsetParent) { - do { - x += obj.offsetLeft; - y += obj.offsetTop; - obj = obj.offsetParent; - } while (obj); - } - return {'x': x, 'y': y}; -}; - -// Get mouse event position in DOM element -Util.getEventPosition = function (e, obj, scale) { - var evt, docX, docY, pos; - //if (!e) evt = window.event; - evt = (e ? e : window.event); - if (evt.pageX || evt.pageY) { - docX = evt.pageX; - docY = evt.pageY; - } else if (evt.clientX || evt.clientY) { - docX = evt.clientX + document.body.scrollLeft + - document.documentElement.scrollLeft; - docY = evt.clientY + document.body.scrollTop + - document.documentElement.scrollTop; - } - pos = Util.getPosition(obj); - if (typeof scale === "undefined") { - scale = 1; - } - return {'x': (docX - pos.x) / scale, 'y': (docY - pos.y) / scale}; -}; - - -// Event registration. Based on: http://www.scottandrew.com/weblog/articles/cbs-events -Util.addEvent = function (obj, evType, fn){ - if (obj.attachEvent){ - var r = obj.attachEvent("on"+evType, fn); - return r; - } else if (obj.addEventListener){ - obj.addEventListener(evType, fn, false); - return true; - } else { - throw("Handler could not be attached"); - } -}; - -Util.removeEvent = function(obj, evType, fn){ - if (obj.detachEvent){ - var r = obj.detachEvent("on"+evType, fn); - return r; - } else if (obj.removeEventListener){ - obj.removeEventListener(evType, fn, false); - return true; - } else { - throw("Handler could not be removed"); - } -}; - -Util.stopEvent = function(e) { - if (e.stopPropagation) { e.stopPropagation(); } - else { e.cancelBubble = true; } - - if (e.preventDefault) { e.preventDefault(); } - else { e.returnValue = false; } -}; - - -// Set browser engine versions. Based on mootools. -Util.Features = {xpath: !!(document.evaluate), air: !!(window.runtime), query: !!(document.querySelector)}; - -Util.Engine = { - 'presto': (function() { - return (!window.opera) ? false : ((arguments.callee.caller) ? 960 : ((document.getElementsByClassName) ? 950 : 925)); }()), - 'trident': (function() { - return (!window.ActiveXObject) ? false : ((window.XMLHttpRequest) ? ((document.querySelectorAll) ? 6 : 5) : 4); }()), - 'webkit': (function() { - try { return (navigator.taintEnabled) ? false : ((Util.Features.xpath) ? ((Util.Features.query) ? 525 : 420) : 419); } catch (e) { return false; } }()), - //'webkit': (function() { - // return ((typeof navigator.taintEnabled !== "unknown") && navigator.taintEnabled) ? false : ((Util.Features.xpath) ? ((Util.Features.query) ? 525 : 420) : 419); }()), - 'gecko': (function() { - return (!document.getBoxObjectFor && window.mozInnerScreenX == null) ? false : ((document.getElementsByClassName) ? 19 : 18); }()) -}; -if (Util.Engine.webkit) { - // Extract actual webkit version if available - Util.Engine.webkit = (function(v) { - var re = new RegExp('WebKit/([0-9\.]*) '); - v = (navigator.userAgent.match(re) || ['', v])[1]; - return parseFloat(v, 10); - })(Util.Engine.webkit); -} - -Util.Flash = (function(){ - var v, version; - try { - v = navigator.plugins['Shockwave Flash'].description; - } catch(err1) { - try { - v = new ActiveXObject('ShockwaveFlash.ShockwaveFlash').GetVariable('$version'); - } catch(err2) { - v = '0 r0'; - } - } - version = v.match(/\d+/g); - return {version: parseInt(version[0] || 0 + '.' + version[1], 10) || 0, build: parseInt(version[2], 10) || 0}; -}()); diff --git a/res/raw/vnc.js b/res/raw/vnc.js deleted file mode 100755 index 4ce6cda..0000000 --- a/res/raw/vnc.js +++ /dev/null @@ -1,43 +0,0 @@ -/* - * noVNC: HTML5 VNC client - * Copyright (C) 2011 Joel Martin - * Licensed under LGPL-3 (see LICENSE.txt) - * - * See README.md for usage and integration instructions. - */ - -/*jslint evil: true */ -/*global window, document, INCLUDE_URI */ - -/* - * Load supporting scripts - */ -function get_INCLUDE_URI() { - return (typeof INCLUDE_URI !== "undefined") ? INCLUDE_URI : ""; -} - -(function () { - "use strict"; - - var extra = "", start, end; - - start = "