From 30f00471a805ffa6a82420326ed8de94f5921b85 Mon Sep 17 00:00:00 2001 From: hy5528 <95360525+hy5528@users.noreply.github.com> Date: Wed, 17 Jan 2024 12:37:43 +0800 Subject: [PATCH] Delete diyp directory --- diyp/TestTV.php | 116 - diyp/channel.php | 5831 ------------------------------------------- diyp/channel_epg.db | Bin 647168 -> 0 bytes diyp/epg.php | 274 -- diyp/gz.php | 19 - diyp/img.php | 134 - diyp/index.html | 1 - diyp/info.php | 369 --- diyp/json.php | 58 - diyp/live.php | 94 - diyp/m3u.php | 93 - diyp/myfile.php | 1073 -------- diyp/xml2db.php | 216 -- 13 files changed, 8278 deletions(-) delete mode 100644 diyp/TestTV.php delete mode 100644 diyp/channel.php delete mode 100644 diyp/channel_epg.db delete mode 100644 diyp/epg.php delete mode 100644 diyp/gz.php delete mode 100644 diyp/img.php delete mode 100644 diyp/index.html delete mode 100644 diyp/info.php delete mode 100644 diyp/json.php delete mode 100644 diyp/live.php delete mode 100644 diyp/m3u.php delete mode 100644 diyp/myfile.php delete mode 100644 diyp/xml2db.php diff --git a/diyp/TestTV.php b/diyp/TestTV.php deleted file mode 100644 index d121653..0000000 --- a/diyp/TestTV.php +++ /dev/null @@ -1,116 +0,0 @@ -exec($createTableSQL); - -// 清空list表 -$emptyTableSQL = "DELETE FROM list"; -$db->exec($emptyTableSQL); - -// 准备查询现有记录的SQL语句 -$selectSQL = "SELECT url FROM list WHERE item = :item AND title = :title"; -$selectStmt = $db->prepare($selectSQL); - -// 准备更新现有记录的SQL语句 -$updateSQL = "UPDATE list SET url = :new_url WHERE item = :item AND title = :title"; -$updateStmt = $db->prepare($updateSQL); - -// 准备插入新记录的SQL语句 -$insertSQL = "INSERT INTO list (item, title, epg, url, isdel) VALUES (:item, :title, :epg, :url, :isdel)"; -$insertStmt = $db->prepare($insertSQL); - -// 网站数据源数组 -$dataSources = [ - 'https://ghproxy.net/https://github.com/hy5528/tvbox/blob/main/live.txt', - 'http://home.jundie.top:81/Cat/tv/live.txt' -]; - -// 初始化isdel计数器 -$isdelCounter = 1; - -foreach ($dataSources as $dataSource) { - // 获取数据 - $data = file_get_contents($dataSource); - - // 将数据分割成行 - $lines = explode("\n", $data); - - // 当前分类项目 - $currentItem = ''; - - foreach ($lines as $line) { - $line = trim($line); - if (empty($line)) continue; // 跳过空行 - - if (strpos($line, '#genre#') !== false) { - // 新的分类项目 - $currentItem = str_replace('#genre#', '', $line); - } else { - // 分割标题和URL - $parts = explode(',', $line, 2); - if (count($parts) == 2) { - list($title, $url) = $parts; - $title = trim($title); - $url = trim($url); - - // 替换标题中的指定字符串 - $title = preg_replace('/CCTV\-(\d+)\s+.*/', 'CCTV$1', $title); - $title = str_replace('CCTV-5+ 体育赛事', 'CCTV5+', $title); // 特殊处理CCTV-5+ - $title = str_replace('CCTV-4K 超高清', 'CCTV4K', $title); // 替换CCTV-4K - $title = str_replace('CCTV-8K 超高清', 'CCTV8K', $title); // 替换CCTV-8K - - // 绑定参数并查询现有记录 - $selectStmt->bindValue(':item', $currentItem); - $selectStmt->bindValue(':title', $title); - $result = $selectStmt->execute(); - $existingRecord = $result->fetchArray(SQLITE3_ASSOC); - - if ($existingRecord) { - // 如果存在记录,则合并URLs - $existingUrls = explode('#', $existingRecord['url']); - if (!in_array($url, $existingUrls)) { - // 只有当URL不在现有URLs中时才合并 - $newUrl = $existingRecord['url'] . '#' . $url; - $updateStmt->bindValue(':new_url', $newUrl); - $updateStmt->bindValue(':item', $currentItem); - $updateStmt->bindValue(':title', $title); - $updateStmt->execute(); - } - } else { - // 如果不存在记录,则插入新记录 - $insertStmt->bindValue(':item', $currentItem); - $insertStmt->bindValue(':title', $title); - $insertStmt->bindValue(':epg', ''); // epg字段为空 - $insertStmt->bindValue(':url', $url); - $insertStmt->bindValue(':isdel', $isdelCounter); - $insertStmt->execute(); - } - - // 递增isdel计数器 - $isdelCounter++; - } - } - } -} - -// 关闭数据库连接 -$db->close(); - -echo "Data processed successfully."; - -?> diff --git a/diyp/channel.php b/diyp/channel.php deleted file mode 100644 index c1fd12c..0000000 --- a/diyp/channel.php +++ /dev/null @@ -1,5831 +0,0 @@ -. -// -// //////////////////////////////////////////////////////////////////////// -// -// Please report any bugs you may encounter to our issue tracker here: -// https://bitbucket.org/phpliteadmin/public/issues?status=new&status=open - -// -// This is sample configuration file -// -// You can configure phpliteadmin in one of 2 ways: -// 1. Rename phpliteadmin.config.sample.php to phpliteadmin.config.php and change parameters in there. -// You can set only your custom settings in phpliteadmin.config.php. All other settings will be set to defaults. -// 2. Change parameters directly in main phpliteadmin.php file -// -// Please see https://bitbucket.org/phpliteadmin/public/wiki/Configuration for more details - -//password to gain access -$password = 'admin'; - -//directory relative to this file to search for databases (if false, manually list databases in the $databases variable) -$directory = '.'; - -//whether or not to scan the subdirectories of the above directory infinitely deep -$subdirectories = false; - -//if the above $directory variable is set to false, you must specify the databases manually in an array as the next variable -//if any of the databases do not exist as they are referenced by their path, they will be created automatically -$databases = array( - array( - 'path'=> 'database1.sqlite', - 'name'=> 'Database 1' - ), - array( - 'path'=> 'database2.sqlite', - 'name'=> 'Database 2' - ), -); - - -/* ---- Interface settings ---- */ - -// Theme! If you want to change theme, save the CSS file in same folder of phpliteadmin or in folder "themes" -$theme = 'phpliteadmin.css'; - -// the default language! If you want to change it, save the language file in same folder of phpliteadmin or in folder "languages" -// More about localizations (downloads, how to translate etc.): https://bitbucket.org/phpliteadmin/public/wiki/Localization -$language = 'en'; - -// set default number of rows. You need to relog after changing the number -$rowsNum = 1000; - -// reduce string characters by a number bigger than 10 -$charsNum = 300; - -// maximum number of SQL queries to save in the history -$maxSavedQueries = 10; - -/* ---- Custom functions ---- */ - -//a list of custom functions that can be applied to columns in the databases -//make sure to define every function below if it is not a core PHP function -$custom_functions = array( - 'md5', 'sha1', 'time', 'strtotime', - // add the names of your custom functions to this array - /* 'leet_text', */ -); - -// define your custom functions here -/* -function leet_text($value) -{ - return strtr($value, 'eaAsSOl', '344zZ01'); -} -*/ - - -/* ---- Advanced options ---- */ - -//changing the following variable allows multiple phpLiteAdmin installs to work under the same domain. -$cookie_name = 'pla3412'; - -//whether or not to put the app in debug mode where errors are outputted -$debug = false; - -// the user is allowed to create databases with only these extensions -$allowed_extensions = array('db','db3','sqlite','sqlite3'); - - -// English language-texts. -// Read our wiki on how to translate: https://bitbucket.org/phpliteadmin/public/wiki/Localization -$lang = array( - "direction" => "LTR", - "date_format" => 'g:ia \o\n F j, Y (T)', // see http://php.net/manual/en/function.date.php for what the letters stand for - "ver" => "鐗堟湰", - "for" => "for", - "to" => "to", - "go" => "鎵ц", - "yes" => "鏄", - "no" => "鍚", - "sql" => "SQL", - "csv" => "CSV", - "csv_tbl" => "Table that CSV pertains to", - "srch" => "鎼滅储", - "srch_again" => "缁х画鎼滅储", - "login" => "鐧诲綍", - "logout" => "鐧诲嚭", - "view" => "棰勮", - "confirm" => "纭", - "cancel" => "鍙栨秷", - "save_as" => "鍙﹀瓨涓", - "options" => "閫夐」", - "no_opt" => "鏃犻夐」", - "help" => "甯姪", - "installed" => "宸插畨瑁", - "not_installed" => "鏈畨瑁", - "done" => "瀹屾垚", - "insert" => "鎻掑叆", - "export" => "瀵煎嚭", - "import" => "瀵煎叆", - "rename" => "閲嶅懡鍚", - "empty" => "娓呯┖琛", - "drop" => "鍒犻櫎琛", - "tbl" => "鏁版嵁琛", - "chart" => "鍥捐〃", - "err" => "閿欒", - "act" => "鍔ㄤ綔", - "rec" => "鏁版嵁閲", - "col" => "鎵鍦ㄥ垪", - "cols" => "鍒", - "rows" => "琛", - "edit" => "缂栬緫", - "del" => "鍒犻櫎", - "add" => "娣诲姞", - "backup" => "澶囦唤鏁版嵁搴撲负鏂囦欢", - "before" => "Before", - "after" => "After", - "passwd" => "瀵嗙爜", - "passwd_incorrect" => "瀵嗙爜閿欒", - "chk_ext" => "Checking supported SQLite PHP extensions", - "autoincrement" => "鑷姩閫掑", - "not_null" => "涓嶄负 NULL", - "attention" => "Attention", - "none" => "None", - "as_defined" => "As defined", - "expression" => "Expression", - - "sqlite_ext" => "SQLite 鎵╁睍", - "sqlite_ext_support" => "It appears that none of the supported SQLite library extensions are available in your installation of PHP. You may not use %s until you install at least one of them.", - "sqlite_v" => "鏁版嵁搴撶増鏈", - "sqlite_v_error" => "It appears that your database is of SQLite version %s but your installation of PHP does not contain the necessary extensions to handle this version. To fix the problem, either delete the database and allow %s to create it automatically or recreate it manually as SQLite version %s.", - "report_issue" => "The problem cannot be diagnosed properly. Please file an issue report at", - "sqlite_limit" => "Due to the limitations of SQLite, only the field name and data type can be modified.", - - "php_v" => "PHP 鐗堟湰", - "new_version" => "There is a new version!", - - "db_dump" => "database dump", - "db_f" => "鏁版嵁搴撴枃浠", - "db_ch" => "鏇存敼鏁版嵁搴", - "db_event" => "Database Event", - "db_name" => "鏁版嵁搴撳悕绉", - "db_rename" => "閲嶅懡鍚嶆暟鎹簱", - "db_renamed" => "Database '%s' has been renamed to", - "db_del" => "鍒犻櫎鏁版嵁搴", - "db_path" => "鏁版嵁搴撶洰褰", - "db_size" => "鏁版嵁搴撳ぇ灏", - "db_mod" => "鏁版嵁搴撲笂娆′慨鏀规椂闂", - "db_create" => "鍒涘缓鏂扮殑鏁版嵁搴", - "db_vac" => "The database, '%s', has been VACUUMed.", - "db_not_writeable" => "The database, '%s', does not exist and cannot be created because the containing directory, '%s', is not writable. The application is unusable until you make it writable.", - "db_setup" => "There was a problem setting up your database, %s. An attempt will be made to find out what's going on so you can fix the problem more easily", - "db_exists" => "A database, other file or directory of the name '%s' already exists.", - - "exported" => "宸插鍑", - "struct" => "缁撴瀯", - "struct_for" => "structure for", - "on_tbl" => "on table", - "data_dump" => "Data dump for", - "backup_hint" => "鎻愮ず锛氳澶囦唤鏁版嵁搴擄紝鏈绠鍗曠殑鏂规硶鏄 %s.", - "backup_hint_linktext" => "涓嬭浇鏁版嵁搴撴枃浠", - "total_rows" => "鎬诲叡鏈 %s 琛", - "total" => "鎬绘暟", - "not_dir" => "The directory you specified to scan for databases does not exist or is not a directory.", - "bad_php_directive" => "It appears that the PHP directive, 'register_globals' is enabled. This is bad. You need to disable it before continuing.", - "page_gen" => "Page generated in %s seconds.", - "powered" => "Powered by", - "free_software" => "This is free software.", - "please_donate" => "Please donate.", - "remember" => "Remember me", - "no_db" => "Welcome to %s. It appears that you have selected to scan a directory for databases to manage. However, %s could not find any valid SQLite databases. You may use the form below to create your first database.", - "no_db2" => "The directory you specified does not contain any existing databases to manage, and the directory is not writable. This means you can't create any new databases using %s. Either make the directory writable or manually upload databases to the directory.", - - "create" => "鍒涘缓", - "created" => "has been created", - "create_tbl" => "鍒涘缓鏂扮殑鏁版嵁琛", - "create_tbl_db" => "鍦ㄦ暟鎹簱涓垱寤烘柊鐨勬暟鎹〃", - "create_trigger" => "Creating new trigger on table", - "create_index" => "鍦ㄦ暟鎹〃涓垱寤虹储寮", - "create_index1" => "鍒涘缓绱㈠紩", - "create_view" => "Create new view on database", - - "trigger" => "Trigger", - "triggers" => "Triggers", - "trigger_name" => "Trigger name", - "trigger_act" => "Trigger Action", - "trigger_step" => "Trigger Steps (semicolon terminated)", - "when_exp" => "WHEN expression (type expression without 'WHEN')", - "index" => "Index", - "indexes" => "Indexes", - "index_name" => "绱㈠紩鍚嶇О", - "name" => "鍚嶇О", - "unique" => "Unique", - "seq_no" => "Seq. No.", - "emptied" => "has been emptied", - "dropped" => "has been dropped", - "renamed" => "has been renamed to", - "altered" => "has been altered successfully", - "inserted" => "宸叉彃鍏", - "deleted" => "宸插垹闄", - "affected" => "affected", - "blank_index" => "Index name must not be blank.", - "one_index" => "You must specify at least one index column.", - "docu" => "浣跨敤鏂囨。", - "license" => "鐗堟潈璁稿彲璇", - "proj_site" => "椤圭洰涓婚〉", - "bug_report" => "This may be a bug that needs to be reported at", - "return" => "杩斿洖", - "browse" => "娴忚", - "fld" => "瀛楁", - "fld_num" => "Number of Fields", - "fields" => "瀛楁", - "type" => "绫诲瀷", - "operator" => "杩愮畻绗", - "val" => "鍊", - "update" => "鏇存柊", - "comments" => "鏁版嵁搴撳娉", - - "specify_fields" => "You must specify the number of table fields.", - "specify_tbl" => "You must specify a table name.", - "specify_col" => "You must specify a column.", - - "tbl_exists" => "Table of the same name already exists.", - "show" => "鏄剧ず", - "show_rows" => "鏄剧ず %s 琛. ", - "showing" => "鏄剧ず", - "showing_rows" => "鏄剧ず琛屾暟鑼冨洿", - "query_time" => "(鏈鎼滄煡璇㈠叡鑰楁椂 %s 绉)", - "syntax_err" => "There is a problem with the syntax of your query (Query was not executed)", - "run_sql" => "瀵规暟鎹簱 '%s' 鎵цSQL璇彞", - "recent_queries" => "鏈杩戞煡璇㈣鍙", - "full_texts" => "Show full texts", - "no_full_texts" => "Shorten long texts", - - "ques_empty" => "鏄惁瑕佹竻绌烘暟鎹〃 '%s'?", - "ques_drop" => "鏄惁瑕佸垹闄ゆ暟鎹〃 '%s'?", - "ques_drop_view" => "鏄惁瑕佸垹闄よ鍥 '%s'?", - "ques_del_rows" => "鏄惁瑕佸垹闄よ %s 鍦ㄦ暟鎹〃 '%s' 涓?", - "ques_del_db" => "鏄惁瑕佸垹闄ゆ暟鎹簱 '%s'?", - "ques_column_delete" => "鏄惁瑕佸垹闄ゅ垪 %s 鍦ㄦ暟鎹〃 '%s' 涓?", - "ques_del_index" => "鏄惁瑕佸垹闄ょ储寮 '%s'?", - "ques_del_trigger" => "鏄惁瑕佸垹闄よЕ鍙戝櫒 '%s'?", - "ques_primarykey_add" => "鏄惁瑕佹坊鍔犱富閿垪 %s 鍦ㄦ暟鎹〃 '%s' 涓?", - - "export_struct" => "瀵煎嚭缁撴瀯", - "export_data" => "瀵煎嚭鏁版嵁", - "add_drop" => "娣诲姞娓呴櫎琛", - "add_transact" => "娣诲姞浜嬪姟", - "fld_terminated" => "Fields terminated by", - "fld_enclosed" => "Fields enclosed by", - "fld_escaped" => "Fields escaped by", - "fld_names" => "Field names in first row", - "rep_null" => "Replace NULL by", - "rem_crlf" => "Remove CRLF characters within fields", - "put_fld" => "Put field names in first row", - "null_represent" => "NULL represented by", - "import_suc" => "瀵煎叆鎴愬姛", - "import_into" => "瀵煎叆鍒", - "import_f" => "浣跨敤鏂囦欢瀵煎叆", - "rename_tbl" => "閲嶅懡鍚嶈〃 '%s' 涓", - - "rows_records" => "琛, 寮濮嬭鏁(0涓虹涓琛)涓 ", - "rows_aff" => "琛 琚慨鏀", - - "as_a" => "鍦", - "readonly_tbl" => "'%s' is a view, which means it is a SELECT statement treated as a read-only table. You may not edit or insert records.", - "chk_all" => "鍏ㄩ", - "unchk_all" => "鍙栨秷鍏ㄩ", - "with_sel" => "閫夊畾鐨勯」鐩墽琛", - - "no_tbl" => "鏁版嵁搴撲腑娌℃湁鏁版嵁琛", - "no_chart" => "If you can read this, it means the chart could not be generated. The data you are trying to view may not be appropriate for a chart.", - "no_rows" => "There are no rows in the table for the range you selected.", - "no_sel" => "鎮ㄦ湭閫夋嫨浠讳綍鏁版嵁", - - "chart_type" => "Chart Type", - "chart_bar" => "Bar Chart", - "chart_pie" => "Pie Chart", - "chart_line" => "Line Chart", - "lbl" => "Labels", - "empty_tbl" => "This table is empty.", - "click" => "Click here", - "insert_rows" => "to insert rows.", - "restart_insert" => "鏈〉鏄剧ず鎻掑叆妗嗘暟閲忎负", - "ignore" => "蹇界暐", - "func" => "鍑芥暟", - "new_insert" => "鎻掑叆鏂拌", - "save_ch" => "淇濆瓨鏇存敼", - "def_val" => "榛樿鍊", - "prim_key" => "涓婚敭", - "tbl_end" => "涓瓧娈靛湪琛ㄦ湯灏", - "query_used_table" => "鍒涘缓琛ㄨ鍙", - "query_used_view" => "Query used to create this view", - "create_index2" => "鍒涘缓涓涓储寮曞湪绗", - "create_trigger2" => "鍒涘缓涓涓柊鐨勮Е鍙戝櫒", - "new_fld" => "Adding new field(s) to table '%s'", - "add_flds" => "Add Fields", - "edit_col" => "Editing column '%s'", - "vac" => "Vacuum", - "vac_desc" => "Large databases sometimes need to be VACUUMed to reduce their footprint on the server. Click the button below to VACUUM the database '%s'.", - "event" => "Event", - "each_row" => "For Each Row", - "define_index" => "Define index properties", - "dup_val" => "Duplicate values", - "allow" => "Allowed", - "not_allow" => "Not Allowed", - "asc" => "Ascending", - "desc" => "Descending", - "warn0" => "You have been warned.", - "warn_passwd" => "You are using the default password, which can be dangerous. You can change it easily at the top of %s.", - "warn_dumbass" => "You didn't change the value dumbass ;-)", - "counting_skipped" => "Counting of records has been skipped for some tables because your database is comparably big and some tables don't have primary keys assigned to them so counting might be slow. Add a primary key to these tables or %sforce counting%s.", - "sel_state" => "Select Statement", - "delimit" => "鍒嗛殧绗", - "back_top" => "Back to Top", - "choose_f" => "Choose File", - "instead" => "Instead of", - "define_in_col" => "Define index column(s)", - - "delete_only_managed" => "You can only delete databases managed by this tool!", - "rename_only_managed" => "You can only rename databases managed by this tool!", - "db_moved_outside" => "You either tried to move the database into a directory where it cannot be managed anylonger, or the check if you did this failed because of missing rights.", - "extension_not_allowed" => "The extension you provided is not within the list of allowed extensions. Please use one of the following extensions", - "add_allowed_extension" => "You can add extensions to this list by adding your extension to \$allowed_extensions in the configuration.", - "directory_not_writable" => "The database-file itself is writable, but to write into it, the containing directory needs to be writable as well. This is because SQLite puts temporary files in there for locking.", - "tbl_inexistent" => "Table %s does not exist", - - // errors that can happen when ALTER TABLE fails. You don't necessarily have to translate these. - "alter_failed" => "Altering of Table %s failed", - "alter_tbl_name_not_replacable" => "could not replace the table name with the temporary one", - "alter_no_def" => "no ALTER definition", - "alter_parse_failed" =>"failed to parse ALTER definition", - "alter_action_not_recognized" => "ALTER action could not be recognized", - "alter_no_add_col" => "no column to add detected in ALTER statement", - "alter_pattern_mismatch"=>"Pattern did not match on your original CREATE TABLE statement", - "alter_col_not_recognized" => "could not recognize new or old column name", - "alter_unknown_operation" => "Unknown ALTER operation!", - - /* Help documentation */ - "help_doc" => "甯姪鏂囨。", - "help1" => "SQLite Library Extensions", - "help1_x" => "%s uses PHP library extensions that allow interaction with SQLite databases. Currently, %s supports PDO, SQLite3, and SQLiteDatabase. Both PDO and SQLite3 deal with version 3 of SQLite, while SQLiteDatabase deals with version 2. So, if your PHP installation includes more than one SQLite library extension, PDO and SQLite3 will take precedence to make use of the better technology. However, if you have existing databases that are of version 2 of SQLite, %s will be forced to use SQLiteDatabase for only those databases. Not all databases need to be of the same version. During the database creation, however, the most advanced extension will be used.", - "help2" => "鍒涘缓鏂扮殑鏁版嵁搴", - "help2_x" => "When you create a new database, the name you entered will be appended with the appropriate file extension (.db, .db3, .sqlite, etc.) if you do not include it yourself. The database will be created in the directory you specified as the \$directory variable.", - "help3" => "Tables vs. Views", - "help3_x" => "On the main database page, there is a list of tables and views. Since views are read-only, certain operations will be disabled. These disabled operations will be apparent by their omission in the location where they should appear on the row for a view. If you want to change the data for a view, you need to drop that view and create a new view with the appropriate SELECT statement that queries other existing tables. For more information, see http://en.wikipedia.org/wiki/View_(database)", - "help4" => "Writing a Select Statement for a New View", - "help4_x" => "When you create a new view, you must write an SQL SELECT statement that it will use as its data. A view is simply a read-only table that can be accessed and queried like a regular table, except it cannot be modified through insertion, column editing, or row editing. It is only used for conveniently fetching data.", - "help5" => "瀵煎嚭鏁版嵁缁撴瀯涓烘枃浠", - "help5_x" => "During the process for exporting to an SQL file, you may choose to include the queries that create the table and columns.", - "help6" => "Export Data to SQL File", - "help6_x" => "During the process for exporting to an SQL file, you may choose to include the queries that populate the table(s) with the current records of the table(s).", - "help7" => "Add Drop Table to Exported SQL File", - "help7_x" => "During the process for exporting to an SQL file, you may choose to include queries to DROP the existing tables before adding them so that problems do not occur when trying to create tables that already exist.", - "help8" => "Add Transaction to Exported SQL File", - "help8_x" => "During the process for exporting to an SQL file, you may choose to wrap the queries around a TRANSACTION so that if an error occurs at any time during the importation process using the exported file, the database can be reverted to its previous state, preventing partially updated data from populating the database.", - "help9" => "Add Comments to Exported SQL File", - "help9_x" => "During the process for exporting to an SQL file, you may choose to include comments that explain each step of the process so that a human can better understand what is happening.", - "help10" => "Partial Indexes", - "help10_x" => "Partial indexes are indexes over a subset of the rows of a table specified by a WHERE clause. Note this requires at least SQLite 3.8.0 and database files with partial indexes won't be readable or writable by older versions. See the SQLite documentation." - -); - -//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -//there is no reason for the average user to edit anything below this comment -//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - -//- Initialization - -// load optional configuration file -$config_filename = './phpliteadmin.config.php'; -if (is_readable($config_filename)) -{ - include_once $config_filename; -} - -//constants 1 -define("PROJECT", "phpLiteAdmin"); -define("VERSION", "1.9.7.1"); -define("PAGE", basename(__FILE__)); -define("FORCETYPE", false); //force the extension that will be used (set to false in almost all circumstances except debugging) -define("SYSTEMPASSWORD", $password); // Makes things easier. -define('PROJECT_URL','http://www.phpliteadmin.org/'); -define('DONATE_URL','http://www.phpliteadmin.org/donate/'); -define('VERSION_CHECK_URL','https://www.phpliteadmin.org/current_version.php'); -define('PROJECT_BUGTRACKER_LINK','https://bitbucket.org/phpliteadmin/public/issues?status=new&status=open'); -define('PROJECT_INSTALL_LINK','https://bitbucket.org/phpliteadmin/public/wiki/Installation'); - -// Resource output (css and javascript files) -// we get out of the main code as soon as possible, without inizializing the session -if (isset($_GET['resource'])) -{ - Resources::output($_GET['resource']); - exit(); -} - -// don't mess with this - required for the login session -ini_set('session.cookie_httponly', '1'); -session_start(); -// generate CSRF token -if (empty($_SESSION['token'])) -{ - if (function_exists('mcrypt_create_iv')) - { - $_SESSION['token'] = bin2hex(mcrypt_create_iv(32, MCRYPT_DEV_URANDOM)); - } else { - $_SESSION['token'] = bin2hex(openssl_random_pseudo_bytes(32)); - } -} -$token = $_SESSION['token']; -$token_html = ''; - -// checking CSRF token -if($_SERVER['REQUEST_METHOD'] === 'POST' || isset($_GET['download'])) // all POST forms need tokens! downloads are protected as well -{ - if($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['token'])) - $check_token=$_POST['token']; - elseif($_SERVER['REQUEST_METHOD'] === 'GET' && isset($_GET['token'])) - $check_token=$_GET['token']; - - if (!isset($check_token)) - { - die("CSRF token missing"); - } - elseif ((function_exists('hash_equals') && !hash_equals($_SESSION['token'], $check_token)) || - (!function_exists('hash_equals') && $_SESSION['token']!==$check_token) ) // yes, timing attacks might be possible here. update your php ;) - { - die("CSRF token is wrong - please try to login again"); - } -} - -if($debug==true) -{ - ini_set("display_errors", 1); - error_reporting(E_STRICT | E_ALL); -} else -{ - @ini_set("display_errors", 0); -} - -// class MicroTimer (issue #146) -// wraps calls to microtime(), calculating the elapsed time and rounding output -// -class MicroTimer { - - private $startTime, $stopTime; - - // creates and starts a timer - function __construct() - { - $this->startTime = microtime(true); - } - - // stops a timer - public function stop() - { - $this->stopTime = microtime(true); - } - - // returns the number of seconds from the timer's creation, or elapsed - // between creation and call to ->stop() - public function elapsed() - { - if ($this->stopTime) - return round($this->stopTime - $this->startTime, 4); - - return round(microtime(true) - $this->startTime, 4); - } - - // called when using a MicroTimer object as a string - public function __toString() - { - return (string) $this->elapsed(); - } - -} - -// start the timer to record page load time -$pageTimer = new MicroTimer(); - -// load language file -if($language != 'en') { - $temp_lang=$lang; - if(is_file('languages/lang_'.$language.'.php')) - include('languages/lang_'.$language.'.php'); - elseif(is_file('lang_'.$language.'.php')) - include('lang_'.$language.'.php'); - $lang = array_merge($temp_lang, $lang); - unset($temp_lang); -} -// version-number added so after updating, old session-data is not used anylonger -// cookies names cannot contain symbols, except underscores -define("COOKIENAME", preg_replace('/[^a-zA-Z0-9_]/', '_', $cookie_name . '_' . VERSION) ); - -// stripslashes if MAGIC QUOTES is turned on -// This is only a workaround. Please better turn off magic quotes! -// This code is from http://php.net/manual/en/security.magicquotes.disabling.php -// if ( function_exists('get_magic_quotes_gpc') && get_magic_quotes_gpc() ) { -$get_magic_quotes_gpc = (($quotes_gpc = ini_get('magic_quotes_gpc')) && strtolower($quotes_gpc) !== 'off'); // 缁撴灉鍜 get_magic_quotes_gpc()鐨勭粨鏋滅瓑鏁 -if ( function_exists('get_magic_quotes_gpc') && $get_magic_quotes_gpc ) { - $process = array(&$_GET, &$_POST, &$_COOKIE, &$_REQUEST); - while (list($key, $val) = each($process)) { - foreach ($val as $k => $v) { - unset($process[$key][$k]); - if (is_array($v)) { - $process[$key][stripslashes($k)] = $v; - $process[] = &$process[$key][stripslashes($k)]; - } else { - $process[$key][stripslashes($k)] = stripslashes($v); - } - } - } - unset($process); -} - - -//data types array -$sqlite_datatypes = array("INTEGER", "REAL", "TEXT", "BLOB","NUMERIC","BOOLEAN","DATETIME"); - -//available SQLite functions array (don't add anything here or there will be problems) -$sqlite_functions = array("abs", "hex", "length", "lower", "ltrim", "random", "round", "rtrim", "trim", "typeof", "upper"); - -//- Support functions - -//function that allows SQL delimiter to be ignored inside comments or strings -function explode_sql($delimiter, $sql) -{ - $ign = array('"' => '"', "'" => "'", "/*" => "*/", "--" => "\n"); // Ignore sequences. - $out = array(); - $last = 0; - $slen = strlen($sql); - $dlen = strlen($delimiter); - $i = 0; - while($i < $slen) - { - // Split on delimiter - if($slen - $i >= $dlen && substr($sql, $i, $dlen) == $delimiter) - { - array_push($out, substr($sql, $last, $i - $last)); - $last = $i + $dlen; - $i += $dlen; - continue; - } - // Eat comments and string literals - foreach($ign as $start => $end) - { - $ilen = strlen($start); - if($slen - $i >= $ilen && substr($sql, $i, $ilen) == $start) - { - $i+=strlen($start); - $elen = strlen($end); - while($i < $slen) - { - if($slen - $i >= $elen && substr($sql, $i, $elen) == $end) - { - // SQL comment characters can be escaped by doubling the character. This recognizes and skips those. - if($start == $end && $slen - $i >= $elen*2 && substr($sql, $i, $elen*2) == $end.$end) - { - $i += $elen * 2; - continue; - } - else - { - $i += $elen; - continue 3; - } - } - $i++; - } - continue 2; - } - } - $i++; - } - if($last < $slen) - array_push($out, substr($sql, $last, $slen - $last)); - return $out; -} - -//function to scan entire directory tree and subdirectories -function dir_tree($dir) -{ - $path = ''; - $stack[] = $dir; - while($stack) - { - $thisdir = array_pop($stack); - if($dircont = scandir($thisdir)) - { - $i=0; - while(isset($dircont[$i])) - { - if($dircont[$i] !== '.' && $dircont[$i] !== '..') - { - $current_file = $thisdir.DIRECTORY_SEPARATOR.$dircont[$i]; - if(is_file($current_file)) - { - $path[] = $thisdir.DIRECTORY_SEPARATOR.$dircont[$i]; - } - elseif (is_dir($current_file)) - { - $path[] = $thisdir.DIRECTORY_SEPARATOR.$dircont[$i]; - $stack[] = $current_file; - } - } - $i++; - } - } - } - return $path; -} - -//the function echo the help [?] links to the documentation -function helpLink($name) -{ - global $lang; - return "[?]"; -} - -// function to encode value into HTML just like htmlentities, but with adjusted default settings -function htmlencode($value, $flags=ENT_QUOTES, $encoding ="UTF-8") -{ - return htmlentities($value, $flags, $encoding); -} - -// 22 August 2011: gkf added this function to support display of -// default values in the form used to INSERT new data. -function deQuoteSQL($s) -{ - return trim(trim($s), "'"); -} - -// reduce string chars -function subString($str) -{ - global $charsNum; - if($charsNum > 10 && (!isset($_SESSION[COOKIENAME.'fulltexts']) || !$_SESSION[COOKIENAME.'fulltexts']) && strlen($str)>$charsNum) - { - $str = substr($str, 0, $charsNum).'...'; - } - return $str; -} - -// checks the (new) name of a database file -function checkDbName($name) -{ - global $allowed_extensions; - $info = pathinfo($name); - if(isset($info['extension']) && !in_array($info['extension'], $allowed_extensions)) - { - return false; - } else - { - return (!is_file($name) && !is_dir($name)); - } - -} - -// check whether a path is a db managed by this tool -// requires that $databases is already filled! -// returns the key of the db if managed, false otherwise. -function isManagedDB($path) -{ - global $databases; - foreach($databases as $db_key => $database) - { - if($path == $database['path']) - { - // a db we manage. Thats okay. - // return the key. - return $db_key; - } - } - // not a db we manage! - return false; -} - -// from a typename of a colun, get the type of the column's affinty -// see http://www.sqlite.org/datatype3.html section 2.1 for rules -function get_type_affinity($type) -{ - if (preg_match("/INT/i", $type)) - return "INTEGER"; - else if (preg_match("/(?:CHAR|CLOB|TEXT)/i", $type)) - return "TEXT"; - else if (preg_match("/BLOB/i", $type) || $type=="") - return "NONE"; - else if (preg_match("/(?:REAL|FLOA|DOUB)/i", $type)) - return "REAL"; - else - return "NUMERIC"; -} - - -//- Check user authentication, login and logout -$auth = new Authorization(); //create authorization object - -// check if user has attempted to log out -if (isset($_POST['logout'])) - $auth->revoke(); -// check if user has attempted to log in -else if (isset($_POST['login']) && isset($_POST['password'])) - $auth->attemptGrant($_POST['password'], isset($_POST['remember'])); - -//- Actions on database files and bulk data -if ($auth->isAuthorized()) -{ - - //- Create a new database - if(isset($_POST['new_dbname'])) - { - if($_POST['new_dbname']=='') - { - // TODO: Display an error message (do NOT echo here. echo below in the html-body!) - } - else - { - $str = preg_replace('@[^\w-.]@','', $_POST['new_dbname']); - $dbname = $str; - $dbpath = $str; - if(checkDbName($dbname)) - { - $tdata = array(); - $tdata['name'] = $dbname; - $tdata['path'] = $directory.DIRECTORY_SEPARATOR.$dbpath; - if(isset($_POST['new_dbtype'])) - $tdata['type'] = $_POST['new_dbtype']; - else - $tdata['type'] = 3; - $td = new Database($tdata); - $td->query("VACUUM"); - } else - { - if(is_file($dbname) || is_dir($dbname)) $dbexists = true; - else $extension_not_allowed=true; - } - } - } - - //- Scan a directory for databases - if($directory!==false) - { - if($directory[strlen($directory)-1]==DIRECTORY_SEPARATOR) //if user has a trailing slash in the directory, remove it - $directory = substr($directory, 0, strlen($directory)-1); - - if(is_dir($directory)) //make sure the directory is valid - { - if($subdirectories===true) - $arr = dir_tree($directory); - else - $arr = scandir($directory); - $databases = array(); - $j = 0; - for($i=0; $i $database) - { - if($database['path'] == $tdata['path']) - { - $_SESSION[COOKIENAME.'currentDB'] = $database; - break; - } - } - } - } - else //the directory is not valid - display error and exit - { - echo "
".$lang['not_dir']."
"; - exit(); - } - } - else - { - for($i=0; $iexport_sql($tables, $drop, $structure, $data, $transaction, $comments); - } - else if($_POST['export_type']=="csv") - { - header("Content-type: application/csv"); - header('Content-Disposition: attachment; filename="'.$export_filename.'.'.$_POST['export_type'].'";'); - header("Pragma: no-cache"); - header("Expires: 0"); - if(isset($_POST['tables'])) - $tables = $_POST['tables']; - else - { - $tables = array(); - $tables[0] = $_POST['single_table']; - } - $field_terminate = $_POST['export_csv_fieldsterminated']; - $field_enclosed = $_POST['export_csv_fieldsenclosed']; - $field_escaped = $_POST['export_csv_fieldsescaped']; - $null = $_POST['export_csv_replacenull']; - $crlf = isset($_POST['export_csv_crlf']); - $fields_in_first_row = isset($_POST['export_csv_fieldnames']); - $db = new Database($_SESSION[COOKIENAME.'currentDB']); - echo $db->export_csv($tables, $field_terminate, $field_enclosed, $field_escaped, $null, $crlf, $fields_in_first_row); - } - exit(); - } - - //- Import a file into an existing database - if(isset($_POST['import'])) - { - $db = new Database($_SESSION[COOKIENAME.'currentDB']); - $db->registerUserFunction($custom_functions); - if($_POST['import_type']=="sql") - { - $data = file_get_contents($_FILES["file"]["tmp_name"]); - $importSuccess = $db->import_sql($data); - } - else - { - $field_terminate = $_POST['import_csv_fieldsterminated']; - $field_enclosed = $_POST['import_csv_fieldsenclosed']; - $field_escaped = $_POST['import_csv_fieldsescaped']; - $null = $_POST['import_csv_replacenull']; - $fields_in_first_row = isset($_POST['import_csv_fieldnames']); - $importSuccess = $db->import_csv($_FILES["file"]["tmp_name"], $_POST['single_table'], $field_terminate, $field_enclosed, $field_escaped, $null, $fields_in_first_row); - } - } - //- Download (backup) a database file (as SQLite file, not as dump) - if(isset($_GET['download']) && isManagedDB($_GET['download'])!==false) - { - header("Content-type: application/octet-stream"); - header('Content-Disposition: attachment; filename="'.basename($_GET['download']).'";'); - header("Pragma: no-cache"); - header("Expires: 0"); - readfile($_GET['download']); - exit; - } -} - -//- HTML: output starts here -header('Content-Type: text/html; charset=utf-8'); -?> - - - - - - -<?php echo PROJECT ?> - -", PHP_EOL; -else - // only use the default stylesheet if an external one does not exist - echo "", PHP_EOL; - -// HTML: output help text, then exit -if(isset($_GET['help'])) -{ - //help section array - $help = array - ( - $lang['help1'] => sprintf($lang['help1_x'], PROJECT, PROJECT, PROJECT), $lang['help2'] => $lang['help2_x'], $lang['help3'] => $lang['help3_x'], - $lang['help4'] => $lang['help4_x'], $lang['help5'] => $lang['help5_x'], $lang['help6'] => $lang['help6_x'], - $lang['help7'] => $lang['help7_x'], $lang['help8'] => $lang['help8_x'], $lang['help9'] => $lang['help9_x'], $lang['help10'] => $lang['help10_x'] - ); - ?> - - -
- "; - echo "".PROJECT." v".VERSION." ".$lang['help_doc']."

"; - foreach((array)$help as $key => $val) - { - echo "".$key."
"; - } - echo "
"; - echo "

"; - foreach((array)$help as $key => $val) - { - echo "
"; - echo "".$key.""; - echo "
"; - echo $val; - echo "
"; - echo "".$lang['back_top'].""; - echo "
"; - } - ?> - - - - - - - - -".$lang['bad_php_directive'].""; - echo ""; - exit(); -} - -//- HTML: login screen if not authorized, exit -if(!$auth->isAuthorized()) -{ - echo "
"; - echo "

v".VERSION."

"; - echo "
"; - if ($auth->isFailedLogin()) - echo "".$lang['passwd_incorrect']."

"; - echo "
"; - echo $token_html; - echo $lang['passwd'].":
"; - echo "

"; - echo ""; - echo ""; - echo "
"; - echo "
"; - echo "
"; - echo "
"; - echo "
"; - echo "".$lang['powered']." ".PROJECT." | "; - printf($lang['page_gen'], $pageTimer); - echo "
"; - echo ""; - exit(); -} - -//- User is authorized, display the main application - -//- Select database (from session or first available) -if(!isset($_SESSION[COOKIENAME.'currentDB']) && count($databases)>0) -{ - //set the current database to the first existing one in the array (default) - $_SESSION[COOKIENAME.'currentDB'] = reset($databases); -} -if(sizeof($databases)>0) - $currentDB = $_SESSION[COOKIENAME.'currentDB']; -else // the database array is empty, offer to create a new database -{ - //- HTML: form to create a new database, exit - if($directory!==false && is_writable($directory)) - { - echo "
"; - printf($lang['no_db'], PROJECT, PROJECT); - echo "
"; - if(isset($extension_not_allowed)) - { - echo "
"; - echo $lang['err'].': '.$lang['extension_not_allowed'].': '; - echo implode(', ', array_map('htmlencode', $allowed_extensions)); - echo '
'.$lang['add_allowed_extension']; - echo "

"; - } - echo "
".$lang['db_create'].""; - echo "
"; - echo $token_html; - echo " "; - if(class_exists('SQLiteDatabase') && (class_exists('SQLite3') || class_exists('PDO'))) - { - echo ""; - } - echo ""; - echo "
"; - echo "
"; - } - else - { - echo "
"; - echo $lang['err'].": ".sprintf($lang['no_db2'], PROJECT); - echo "

"; - } - exit(); -} - -//- Switch to a different database with drop-down menu -if(isset($_POST['database_switch'])) -{ - foreach($databases as $db_id => $database) - { - if($database['path'] == $_POST['database_switch']) - { - $_SESSION[COOKIENAME."currentDB"] = $database; - break; - } - } - $currentDB = $_SESSION[COOKIENAME.'currentDB']; -} -else if(isset($_GET['switchdb'])) -{ - foreach($databases as $db_id => $database) - { - if($database['path'] == $_GET['switchdb']) - { - $_SESSION[COOKIENAME."currentDB"] = $database; - break; - } - } - $currentDB = $_SESSION[COOKIENAME.'currentDB']; -} -if(isset($_SESSION[COOKIENAME.'currentDB']) && in_array($_SESSION[COOKIENAME.'currentDB'], $databases)) - $currentDB = $_SESSION[COOKIENAME.'currentDB']; - -//- Open database (creates a Database object) -$db = new Database($currentDB); //create the Database object -$db->registerUserFunction($custom_functions); - -// collect parameters early, just once -$target_table = isset($_GET['table']) ? $_GET['table'] : null; - -//- Switch on $_GET['action'] for operations without output -if(isset($_GET['action']) && isset($_GET['confirm'])) -{ - switch($_GET['action']) - { - //- Table actions - - //- Create table (=table_create) - case "table_create": - $num = intval($_POST['rows']); - $name = $_POST['tablename']; - $primary_keys = array(); - for($i=0; $i<$num; $i++) - { - if($_POST[$i.'_field']!="" && isset($_POST[$i.'_primarykey'])) - { - $primary_keys[] = $_POST[$i.'_field']; - } - } - $query = "CREATE TABLE ".$db->quote($name)." ("; - for($i=0; $i<$num; $i++) - { - if($_POST[$i.'_field']!="") - { - $query .= $db->quote($_POST[$i.'_field'])." "; - $query .= $_POST[$i.'_type']." "; - if(isset($_POST[$i.'_primarykey'])) - { - if(count($primary_keys)==1) - { - $query .= "PRIMARY KEY "; - if(isset($_POST[$i.'_autoincrement']) && $db->getType() != "SQLiteDatabase") - $query .= "AUTOINCREMENT "; - } - $query .= "NOT NULL "; - } - if(!isset($_POST[$i.'_primarykey']) && isset($_POST[$i.'_notnull'])) - $query .= "NOT NULL "; - if($_POST[$i.'_defaultoption']!='defined' && $_POST[$i.'_defaultoption']!='none' && $_POST[$i.'_defaultoption']!='expr') - $query .= "DEFAULT ".$_POST[$i.'_defaultoption']." "; - elseif($_POST[$i.'_defaultoption']=='expr') - $query .= "DEFAULT (".$_POST[$i.'_defaultvalue'].") "; - elseif(isset($_POST[$i.'_defaultvalue']) && $_POST[$i.'_defaultoption']=='defined') - { - $typeAffinity = get_type_affinity($_POST[$i.'_type']); - if(($typeAffinity=="INTEGER" || $typeAffinity=="REAL" || $typeAffinity=="NUMERIC") && is_numeric($_POST[$i.'_defaultvalue'])) - $query .= "DEFAULT ".$_POST[$i.'_defaultvalue']." "; - else - $query .= "DEFAULT ".$db->quote($_POST[$i.'_defaultvalue'])." "; - } - $query = substr($query, 0, sizeof($query)-2); - $query .= ", "; - } - } - if (count($primary_keys)>1) - { - $compound_key = ""; - foreach ($primary_keys as $primary_key) - { - $compound_key .= ($compound_key=="" ? "" : ", ") . $db->quote($primary_key); - } - $query .= "PRIMARY KEY (".$compound_key."), "; - } - $query = substr($query, 0, sizeof($query)-3); - $query .= ")"; - $result = $db->query($query); - if($result===false) - $error = true; - $completed = $lang['tbl']." '".htmlencode($_POST['tablename'])."' ".$lang['created'].".
".htmlencode($query).""; - $backlinkParameters = "&action=column_view&table=".urlencode($name); - break; - - //- Empty table (=table_empty) - case "table_empty": - $query = "DELETE FROM ".$db->quote_id($_POST['tablename']); - $result = $db->query($query); - if($result===false) - $error = true; - $query = "VACUUM"; - $result = $db->query($query); - if($result===false) - $error = true; - $completed = $lang['tbl']." '".htmlencode($_POST['tablename'])."' ".$lang['emptied'].".
".htmlencode($query).""; - $backlinkParameters = "&action=row_view&table=".urlencode($name); - break; - - //- Create view (=view_create) - case "view_create": - $query = "CREATE VIEW ".$db->quote($_POST['viewname'])." AS ".$_POST['select']; - $result = $db->query($query); - if($result===false) - $error = true; - $completed = $lang['view']." '".htmlencode($_POST['viewname'])."' ".$lang['created'].".
".htmlencode($query).""; - $backlinkParameters = "&action=column_view&table=".urlencode($_POST['viewname']); - break; - - //- Drop table (=table_drop) - case "table_drop": - $query = "DROP TABLE ".$db->quote_id($_POST['tablename']); - $result=$db->query($query); - if($result===false) - $error = true; - $completed = $lang['tbl']." '".htmlencode($_POST['tablename'])."' ".$lang['dropped']."."; - $backlinkParameters = ""; - break; - - //- Drop view (=view_drop) - case "view_drop": - $query = "DROP VIEW ".$db->quote_id($_POST['viewname']); - $result=$db->query($query); - if($result===false) - $error = true; - $completed = $lang['view']." '".htmlencode($_POST['viewname'])."' ".$lang['dropped']."."; - $backlinkParameters = ""; - break; - - //- Rename table (=table_rename) - case "table_rename": - $query = "ALTER TABLE ".$db->quote_id($_POST['oldname'])." RENAME TO ".$db->quote($_POST['newname']); - if($db->getVersion()==3) - $result = $db->query($query, true); - else - $result = $db->query($query, false); - if($result===false) - $error = true; - $completed = $lang['tbl']." '".htmlencode($_POST['oldname'])."' ".$lang['renamed']." '".htmlencode($_POST['newname'])."'.
".htmlencode($query).""; - $backlinkParameters = "&action=row_view&table=".urlencode($_POST['newname']); - break; - - //- Row actions - - //- Create row (=row_create) - case "row_create": - $completed = ""; - $num = $_POST['numRows']; - $fields = explode(":", $_POST['fields']); - $z = 0; - - $query = "PRAGMA table_info(".$db->quote_id($target_table).")"; - $result = $db->selectArray($query); - - for($i=0; $i<$num; $i++) - { - if(!isset($_POST[$i.":ignore"])) - { - $query_cols = ""; - $query_vals = ""; - $all_default = true; - for($j=0; $jquote_id($fields[$j]).","; - - $type = $result[$j]['type']; - $typeAffinity = get_type_affinity($type); - $function = $_POST["function_".$i."_".$j]; - if($function!="") - $query_vals .= $function."("; - if(($typeAffinity=="TEXT" || $typeAffinity=="NONE") && !$null) - $query_vals .= $db->quote($value); - elseif(($typeAffinity=="INTEGER" || $typeAffinity=="REAL"|| $typeAffinity=="NUMERIC") && $value=="") - $query_vals .= "NULL"; - elseif($null) - $query_vals .= "NULL"; - else - $query_vals .= $db->quote($value); - if($function!="") - $query_vals .= ")"; - $query_vals .= ","; - } - $query = "INSERT INTO ".$db->quote_id($target_table); - if(!$all_default) - { - $query_cols = substr($query_cols, 0, strlen($query_cols)-1); - $query_vals = substr($query_vals, 0, strlen($query_vals)-1); - - $query.=" (". $query_cols . ") VALUES (". $query_vals. ")"; - } else { - $query .= " DEFAULT VALUES"; - } - $result1 = $db->query($query); - if($result1===false) - $error = true; - $completed .= "".htmlencode($query)."
"; - $z++; - } - } - $completed = $z." ".$lang['rows']." ".$lang['inserted'].".

".$completed; - $backlinkParameters = "&action=column_view&table=".urlencode($target_table); - break; - - //- Delete row (=row_delete) - case "row_delete": - $pks = json_decode($_GET['pk']); - - $query = "DELETE FROM ".$db->quote_id($target_table)." WHERE (".$db->wherePK($target_table,json_decode($pks[0])).")"; - for($i=1; $iwherePK($target_table,json_decode($pks[$i])).")"; - } - $result = $db->query($query); - if($result===false) - $error = true; - $completed = sizeof($pks)." ".$lang['rows']." ".$lang['deleted'].".
".htmlencode($query).""; - $backlinkParameters = "&action=row_view&table=".urlencode($target_table); - break; - - //- Edit row (=row_edit) - case "row_edit": - $pks = json_decode($_GET['pk']); - $fields = explode(":", $_POST['fieldArray']); - - $z = 0; - - $query = "PRAGMA table_info(".$db->quote_id($target_table).")"; - $result = $db->selectArray($query); - - if(isset($_POST['new_row'])) - $completed = ""; - else - $completed = sizeof($pks)." ".$lang['rows']." ".$lang['affected'].".

"; - - for($i=0; $iquote_id($fields[$j]).","; - - $type = $result[$j]['type']; - $typeAffinity = get_type_affinity($type); - $function = $_POST["function_".$j][$i]; - if($function!="") - $query_vals .= $function."("; - if(($typeAffinity=="TEXT" || $typeAffinity=="NONE") && !$null) - $query_vals .= $db->quote($value); - elseif(($typeAffinity=="INTEGER" || $typeAffinity=="REAL"|| $typeAffinity=="NUMERIC") && $value=="") - $query_vals .= "NULL"; - elseif($null) - $query_vals .= "NULL"; - else - $query_vals .= $db->quote($value); - if($function!="") - $query_vals .= ")"; - $query_vals .= ","; - } - $query = "INSERT INTO ".$db->quote_id($target_table); - if(!$all_default) - { - $query_cols = substr($query_cols, 0, strlen($query_cols)-1); - $query_vals = substr($query_vals, 0, strlen($query_vals)-1); - - $query.=" (". $query_cols . ") VALUES (". $query_vals. ")"; - } else { - $query .= " DEFAULT VALUES"; - } - $result1 = $db->query($query); - if($result1===false) - $error = true; - $z++; - } - else - { - $query = "UPDATE ".$db->quote_id($target_table)." SET "; - for($j=0; $jquote_id($fields[$j])."="; - if($function!="") - $query .= $function."("; - if($null) - $query .= "NULL"; - else - $query .= $db->quote($_POST[$j][$i]); - if($function!="") - $query .= ")"; - $query .= ", "; - } - $query = substr($query, 0, sizeof($query)-3); - $query .= " WHERE ".$db->wherePK($target_table, json_decode($pks[$i])); - $result1 = $db->query($query); - if($result1===false) - { - $error = true; - } - } - $completed .= "".htmlencode($query)."
"; - } - if(isset($_POST['new_row'])) - $completed = $z." ".$lang['rows']." ".$lang['inserted'].".

".$completed; - $backlinkParameters = "&action=row_view&table=".urlencode($target_table); - break; - - //- Column actions - - //- Create column (=column_create) - case "column_create": - $num = intval($_POST['rows']); - for($i=0; $i<$num; $i++) - { - if($_POST[$i.'_field']!="") - { - $query = "ALTER TABLE ".$db->quote_id($target_table)." ADD ".$db->quote($_POST[$i.'_field'])." "; - $query .= $_POST[$i.'_type']." "; - if(isset($_POST[$i.'_primarykey'])) - $query .= "PRIMARY KEY "; - if(isset($_POST[$i.'_notnull'])) - $query .= "NOT NULL "; - if($_POST[$i.'_defaultoption']!='defined' && $_POST[$i.'_defaultoption']!='none' && $_POST[$i.'_defaultoption']!='expr') - $query .= "DEFAULT ".$_POST[$i.'_defaultoption']." "; - elseif($_POST[$i.'_defaultoption']=='expr') - $query .= "DEFAULT (".$_POST[$i.'_defaultvalue'].") "; - elseif(isset($_POST[$i.'_defaultvalue']) && $_POST[$i.'_defaultoption']=='defined') - { - $typeAffinity = get_type_affinity($_POST[$i.'_type']); - if(($typeAffinity=="INTEGER" || $typeAffinity=="REAL" || $typeAffinity=="NUMERIC") && is_numeric($_POST[$i.'_defaultvalue'])) - $query .= "DEFAULT ".$_POST[$i.'_defaultvalue']." "; - else - $query .= "DEFAULT ".$db->quote($_POST[$i.'_defaultvalue'])." "; - } - if($db->getVersion()==3 && - ($_POST[$i.'_defaultoption']=='defined' || $_POST[$i.'_defaultoption']=='none' || $_POST[$i.'_defaultoption']=='NULL') - // Sqlite3 cannot add columns with default values that are not constant - && !isset($_POST[$i.'_primarykey']) - // sqlite3 cannot add primary key columns - && (!isset($_POST[$i.'_notnull']) || $_POST[$i.'_defaultoption']!='none') - // SQLite3 cannot add NOT NULL columns without DEFAULT even if the table is empty - ) - // use SQLITE3 ALTER TABLE ADD COLUMN - $result = $db->query($query, true); - else - // use ALTER TABLE workaround - $result = $db->query($query, false); - if($result===false) - $error = true; - } - } - $completed = $lang['tbl']." '".htmlencode($target_table)."' ".$lang['altered']."."; - $backlinkParameters = "&action=column_view&table=".urlencode($target_table); - break; - - //- Delete column (=column_delete) - case "column_delete": - $pks = explode(":", $_GET['pk']); - $query = "ALTER TABLE ".$db->quote_id($target_table).' DROP '.$db->quote_id($pks[0]); - for($i=1; $iquote_id($pks[$i]); - } - $result = $db->query($query); - if($result===false) - $error = true; - $completed = $lang['tbl']." '".htmlencode($target_table)."' ".$lang['altered']."."; - $backlinkParameters = "&action=column_view&table=".urlencode($target_table); - break; - - //- Add a primary key (=primarykey_add) - case "primarykey_add": - $pks = explode(":", $_GET['pk']); - $query = "ALTER TABLE ".$db->quote_id($target_table).' ADD PRIMARY KEY ('.$db->quote_id($pks[0]); - for($i=1; $iquote_id($pks[$i]); - } - $query .= ")"; - $result = $db->query($query); - if($result===false) - $error = true; - $completed = $lang['tbl']." '".htmlencode($target_table)."' ".$lang['altered']."."; - $backlinkParameters = "&action=column_view&table=".urlencode($target_table); - break; - - //- Edit column (=column_edit) - case "column_edit": - $query = "ALTER TABLE ".$db->quote_id($target_table).' CHANGE '.$db->quote_id($_POST['oldvalue'])." ".$db->quote($_POST['0_field'])." ".$_POST['0_type']; - $result = $db->query($query); - if($result===false) - $error = true; - $completed = $lang['tbl']." '".htmlencode($target_table)."' ".$lang['altered']."."; - $backlinkParameters = "&action=column_view&table=".urlencode($target_table); - break; - - //- Delete trigger (=trigger_delete) - case "trigger_delete": - $query = "DROP TRIGGER ".$db->quote_id($_GET['pk']); - $result = $db->query($query); - if($result===false) - $error = true; - $completed = $lang['trigger']." '".htmlencode($_GET['pk'])."' ".$lang['deleted'].".
".htmlencode($query).""; - $backlinkParameters = "&action=column_view&table=".urlencode($target_table); - break; - - //- Delete index (=index_delete) - case "index_delete": - $query = "DROP INDEX ".$db->quote_id($_GET['pk']); - $result = $db->query($query); - if($result===false) - $error = true; - $completed = $lang['index']." '".htmlencode($_GET['pk'])."' ".$lang['deleted'].".
".htmlencode($query).""; - $backlinkParameters = "&action=column_view&table=".urlencode($target_table); - break; - - //- Create trigger (=trigger_create) - case "trigger_create": - $str = "CREATE TRIGGER ".$db->quote($_POST['trigger_name']); - if($_POST['beforeafter']!="") - $str .= " ".$_POST['beforeafter']; - $str .= " ".$_POST['event']." ON ".$db->quote_id($target_table); - if(isset($_POST['foreachrow'])) - $str .= " FOR EACH ROW"; - if($_POST['whenexpression']!="") - $str .= " WHEN ".$_POST['whenexpression']; - $str .= " BEGIN"; - $str .= " ".$_POST['triggersteps']; - $str .= " END"; - $query = $str; - $result = $db->query($query); - if($result===false) - $error = true; - $completed = $lang['trigger']." ".$lang['created'].".
".htmlencode($query).""; - $backlinkParameters = "&action=column_view&table=".urlencode($target_table); - break; - - //- Create index (=index_create) - case "index_create": - $num = $_POST['num']; - if($_POST['name']=="") - { - $completed = $lang['blank_index']; - } - else if($_POST['0_field']=="") - { - $completed = $lang['one_index']; - } - else - { - $str = "CREATE "; - if($_POST['duplicate']=="no") - $str .= "UNIQUE "; - $str .= "INDEX ".$db->quote($_POST['name'])." ON ".$db->quote_id($target_table)." ("; - $str .= $db->quote_id($_POST['0_field']).$_POST['0_order']; - for($i=1; $i<$num; $i++) - { - if($_POST[$i.'_field']!="") - $str .= ", ".$db->quote_id($_POST[$i.'_field']).$_POST[$i.'_order']; - } - $str .= ")"; - if(isset($_POST['where']) && $_POST['where']!='') - $str.=" WHERE ".$_POST['where']; - $query = $str; - $result = $db->query($query); - if($result===false) - $error = true; - $completed = $lang['index']." ".$lang['created'].".
".htmlencode($query).""; - } - $backlinkParameters = "&action=column_view&table=".urlencode($target_table); - break; - } -} - -// are we working on a view? let's check once here -$target_table_type = $target_table ? $db->getTypeOfTable($target_table) : null; - -//- HTML: sidebar -echo '
'; -echo "
"; -echo "

"; -echo " v".VERSION.""; -echo "

"; -echo ""; - -//- HTML: database list -$db->print_db_list(); -echo "
"; -echo "25) - $name = "...".substr($name, strlen($name)-22, 22); -echo ">".htmlencode($name).""; -echo ""; - -//- HTML: table list -$query = "SELECT type, name FROM sqlite_master WHERE type='table' OR type='view' ORDER BY name"; -$result = $db->selectArray($query); -$j=0; -for($i=0; $i[".$lang[$result[$i]['type']=='table'?'tbl':'view']."] "; - echo "".htmlencode($result[$i]['name'])."
"; - $j++; - } -} -if($j==0) - echo $lang['no_tbl']; -echo "
"; - -//- HTML: form to create a new database -if($directory!==false && is_writable($directory)) -{ - echo "
".$lang['db_create']." ".helpLink($lang['help2']).""; - echo "
"; - echo $token_html; - echo ""; - if(class_exists('SQLiteDatabase') && (class_exists('SQLite3') || class_exists('PDO'))) - { - echo ""; - } - echo ""; - echo "
"; - echo "
"; -} - -echo "
"; -echo "
"; -echo $token_html; -echo ""; -echo "
"; -echo "
"; -echo "
"; -echo '
'; - -//- HTML: breadcrumb navigation -echo "".htmlencode($currentDB['name']).""; -if ($target_table) - echo " → ".htmlencode($target_table).""; -echo "

"; - -//- HTML: confirmation panel -//if the user has performed some action, show the resulting message -if(isset($_GET['confirm'])) -{ - echo "
"; - echo "
"; - if(isset($error) && $error) //an error occured during the action, so show an error message - echo $lang['err'].": ".htmlencode($db->getError())."
".$lang['bug_report'].' '.PROJECT_BUGTRACKER_LINK; - else //action was performed successfully - show success message - echo $completed; - echo "
"; - if($_GET['action']=="row_delete" || $_GET['action']=="row_create" || $_GET['action']=="row_edit") - echo "

".$lang['return'].""; - else if($_GET['action']=="column_create" || $_GET['action']=="column_delete" || $_GET['action']=="column_edit" || $_GET['action']=="index_create" || $_GET['action']=="index_delete" || $_GET['action']=="trigger_delete" || $_GET['action']=="trigger_create") - echo "

".$lang['return'].""; - else - echo "

".$lang['return'].""; - echo "
"; -} - -//- Show the various tab views for a table -if(!isset($_GET['confirm']) && $target_table && isset($_GET['action']) && ($_GET['action']=="table_export" || $_GET['action']=="table_import" || $_GET['action']=="table_sql" || $_GET['action']=="row_view" || $_GET['action']=="row_create" || $_GET['action']=="column_view" || $_GET['action']=="table_rename" || $_GET['action']=="table_search" || $_GET['action']=="table_triggers")) -{ - //- HTML: tabs for tables - if($target_table_type == 'table') - { - echo "".$lang['browse'].""; - echo "".$lang['struct'].""; - echo "".$lang['sql'].""; - echo "".$lang['srch'].""; - echo "".$lang['insert'].""; - echo "".$lang['export'].""; - echo "".$lang['import'].""; - echo "".$lang['rename'].""; - echo "".$lang['empty'].""; - echo "".$lang['drop'].""; - echo "
"; - } - else - //- HTML: tabs for views - { - echo "".$lang['browse'].""; - echo "".$lang['struct'].""; - echo "".$lang['sql'].""; - echo "".$lang['srch'].""; - echo "".$lang['export'].""; - echo "".$lang['drop'].""; - echo "
"; - } -} - -//- Switch on $_GET['action'] for operations with output -if(isset($_GET['action']) && !isset($_GET['confirm'])) -{ - echo "
"; - switch($_GET['action']) - { - //- Table actions - - //- Create table (=table_create) - case "table_create": - $query = "SELECT name FROM sqlite_master WHERE type='table' AND name=".$db->quote($_POST['tablename']); - $results = $db->selectArray($query); - if(sizeof($results)>0) - $exists = true; - else - $exists = false; - echo "

".$lang['create_tbl'].": '".htmlencode($_POST['tablename'])."'

"; - if($_POST['tablefields']=="" || intval($_POST['tablefields'])<=0) - echo $lang['specify_fields']; - else if($_POST['tablename']=="") - echo $lang['specify_tbl']; - else if($exists) - echo $lang['tbl_exists']; - else - { - $num = intval($_POST['tablefields']); - $name = $_POST['tablename']; - echo "
"; - echo $token_html; - echo ""; - echo ""; - echo ""; - echo ""; - $headings = array($lang['fld'], $lang['type'], $lang['prim_key']); - if($db->getType() != "SQLiteDatabase") $headings[] = $lang['autoincrement']; - $headings[] = $lang['not_null']; - $headings[] = $lang['def_val']; - for($k=0; $k" . $headings[$k] . ""; - echo ""; - - for($i=0; $i<$num; $i++) - { - $tdWithClass = ""; - echo $tdWithClass; - echo ""; - echo ""; - echo $tdWithClass; - echo ""; - echo ""; - echo $tdWithClass; - echo ""; - echo ""; - if($db->getType() != "SQLiteDatabase") - { - echo $tdWithClass; - echo ""; - echo ""; - } - echo $tdWithClass; - echo ""; - echo ""; - echo $tdWithClass; - echo ""; - echo ""; - echo ""; - echo ""; - } - echo ""; - echo ""; - echo ""; - echo "
"; - echo "
"; - echo " "; - echo "".$lang['cancel'].""; - echo "
"; - echo "
"; - if($db->getType() != "SQLiteDatabase") echo ""; - } - break; - - //- Perform SQL query on table (=table_sql) - case "table_sql": - if(isset($_POST['query']) && $_POST['query']!="") - { - $delimiter = $_POST['delimiter']; - $queryStr = $_POST['queryval']; - //save the queries in history if necessary - if($maxSavedQueries!=0 && $maxSavedQueries!=false) - { - if(!isset($_SESSION['query_history'])) - $_SESSION['query_history'] = array(); - $_SESSION['query_history'][md5(strtolower($queryStr))] = $queryStr; - if(sizeof($_SESSION['query_history']) > $maxSavedQueries) - array_shift($_SESSION['query_history']); - } - $query = explode_sql($delimiter, $queryStr); //explode the query string into individual queries based on the delimiter - - for($i=0; $iquery($query[$i]); - - echo "
"; - echo "".htmlencode($query[$i]).""; - if($table_result === NULL || $table_result === false) - { - echo "
".$lang['err'].": ".htmlencode($db->getError())."
"; - } - echo "

"; - if($row = $db->fetch($table_result, 'assoc')) - { - $headers = array_keys($row); - echo ""; - echo ""; - for($j=0; $j"; - echo htmlencode($headers[$j]); - echo ""; - } - echo ""; - $rowCount = 0; - for(; $rowCount==0 || $row = $db->fetch($table_result, 'assoc'); $rowCount++) - { - $tdWithClass = ""; - for($z=0; $zNULL"; - else - echo htmlencode(subString($row[$headers[$z]])); - echo ""; - } - echo ""; - } - $queryTimer->stop(); - echo "
"; - echo "


"; - - - if($table_result !== NULL && $table_result !== false) - { - echo "
"; - if($rowCount>0 || $db->getAffectedRows()==0) - { - printf($lang['show_rows'], $rowCount); - } - if($db->getAffectedRows()>0 || $rowCount==0) - { - echo $db->getAffectedRows()." ".$lang['rows_aff']." "; - } - printf($lang['query_time'], $queryTimer); - echo "
"; - } - - - } - } - } - } - else - { - $delimiter = ";"; - $queryStr = "SELECT * FROM ".$db->quote_id($target_table)." WHERE 1"; - } - - echo "
"; - echo "".sprintf($lang['run_sql'],htmlencode($db->getName())).""; - echo "
"; - echo $token_html; - if(isset($_SESSION['query_history']) && sizeof($_SESSION['query_history'])>0) - { - echo "".$lang['recent_queries']."

"; - } - echo "
"; - echo ""; - echo "
"; - echo "
"; - echo $lang['fields']."
"; - echo ""; - echo ""; - echo "
"; - echo "
"; - echo $lang['delimit']." "; - echo ""; - echo "
"; - echo "
"; - break; - - //- Empty table (=table_empty) - case "table_empty": - echo "
"; - echo $token_html; - echo ""; - echo "
"; - echo sprintf($lang['ques_empty'], htmlencode($target_table))."

"; - echo " "; - echo "".$lang['cancel'].""; - echo "
"; - break; - - //- Drop table (=table_drop) - case "table_drop": - echo ""; - echo $token_html; - echo ""; - echo "
"; - echo sprintf($lang['ques_drop'], htmlencode($target_table))."

"; - echo " "; - echo "".$lang['cancel'].""; - echo "
"; - break; - - //- Drop view (=view_drop) - case "view_drop": - echo ""; - echo $token_html; - echo ""; - echo "
"; - echo sprintf($lang['ques_drop_view'], htmlencode($target_table))."

"; - echo " "; - echo "".$lang['cancel'].""; - echo "
"; - break; - - //- Export table (=table_export) - case "table_export": - echo ""; - echo $token_html; - echo "
".$lang['export'].""; - echo ""; - echo ""; - echo "
"; - echo "
"; - - echo "
".$lang['options'].""; - echo " ".helpLink($lang['help5'])."
"; - echo " ".helpLink($lang['help6'])."
"; - echo " ".helpLink($lang['help7'])."
"; - echo " ".helpLink($lang['help8'])."
"; - echo " ".helpLink($lang['help9'])."
"; - echo "
"; - - echo ""; - - echo "
"; - echo "

"; - echo "
".$lang['save_as'].""; - $file = pathinfo($db->getPath()); - $name = $file['filename']; - echo " "; - echo "
"; - echo "
"; - echo "
".sprintf($lang['backup_hint'], "".$lang["backup_hint_linktext"]."")."
"; - break; - - //- Import table (=table_import) - case "table_import": - if(isset($_POST['import'])) - { - echo "
"; - if($importSuccess===true) - echo $lang['import_suc']; - else - echo $lang['err'].': '.htmlencode($importSuccess); - echo "

"; - } - echo "
"; - echo $token_html; - echo "
".$lang['import_into']." ".htmlencode($target_table).""; - echo ""; - echo "
"; - echo "
"; - - echo "
".$lang['options'].""; - echo $lang['no_opt']; - echo "
"; - - echo ""; - - echo "
"; - echo "

"; - - echo "
".$lang['import_f'].""; - echo " "; - echo "
"; - break; - - //- Rename table (=table_rename) - case "table_rename": - echo ""; - echo $token_html; - echo ""; - printf($lang['rename_tbl'], htmlencode($target_table)); - echo " "; - echo "
"; - break; - - //- Search table (=table_search) - case "table_search": - $searchValues = array(); - if(isset($_GET['done'])) - { - $query = "PRAGMA table_info(".$db->quote_id($target_table).")"; - $result = $db->selectArray($query); - $primary_key = $db->getPrimaryKey($target_table); - $j = 0; - $arr = array(); - for($i=0; $iquote_id($field)." ".$operator; - else{ - if($operator == "LIKE%"){ - $operator = "LIKE"; - if(!preg_match('/(^%)|(%$)/', $value)) $value = '%'.$value.'%'; - $searchValues[$field] = array($value); - $value_quoted = $db->quote($value); - } - elseif($operator == 'IN' || $operator == 'NOT IN') - { - $value = trim($value, '() '); - $values = explode(',',$value); - $values = array_map('trim', $values, array_fill(0,count($values),' \'"')); - if($operator == 'IN') - $searchValues[$field] = $values; - $values = array_map(array($db, 'quote'), $values); - $value_quoted = '(' .implode(', ', $values) . ')'; - } - else - { - $searchValues[$field] = array($value); - $value_quoted = $db->quote($value); - } - $arr[$j] = $db->quote_id($field)." ".$operator." ".$value_quoted; - } - $j++; - } - } - $query = "SELECT *"; - // select the primary key column(s) last (ROWID if there is no PK). - // this will be used to identify rows, e.g. when editing/deleting rows - $primary_key = $db->getPrimaryKey($target_table); - foreach($primary_key as $pk) - { - $query.= ', '.$db->quote_id($pk); - $query.= ', typeof('.$db->quote_id($pk).')'; - } - $query .= " FROM ".$db->quote_id($target_table); - $whereTo = ''; - if(sizeof($arr)>0) - { - $whereTo .= " WHERE ".$arr[0]; - for($i=1; $iquote_id($target_table) . $whereTo; - $queryTimer = new MicroTimer(); - $arr = $db->selectArray($query); - $queryTimer->stop(); - - echo "
"; - echo ""; - if($arr!==false) - { - $affected = sizeof($arr); - echo $lang['showing']." ".$affected." ".$lang['rows'].". "; - printf($lang['query_time'], $queryTimer); - echo "
"; - } - else - { - echo $lang['err'].": ".htmlencode($db->getError()).".
".$lang['bug_report'].' '.PROJECT_BUGTRACKER_LINK.'
'; - } - echo "".htmlencode($query_disp).""; - echo "

"; - - if(sizeof($arr)>0) - { - if($target_table_type == 'view') - { - echo sprintf($lang['readonly_tbl'], htmlencode($target_table))." http://en.wikipedia.org/wiki/View_(database)"; - echo "

"; - } - - echo ""; - echo ""; - if($target_table_type == 'table') - { - echo ""; - } - - $header = array(); - for($j=0; $j"; - echo htmlencode($headers[$j]); - echo ""; - } - echo ""; - - $pkFirstCol = sizeof($result)+1; - for($j=0; $j $pk will always be the last columns in each row of the array because we are doing "SELECT *, PK_1, typeof(PK_1), PK2, typeof(PK_2), ... FROM ..." - $pk_arr = array(); - for($col = $pkFirstCol; array_key_exists($col, $arr[$j]); $col=$col+2) - { - // in $col we have the type and in $col-1 the value - if($arr[$j][$col]=='integer' || $arr[$j][$col]=='real') - // json encode as int or float, not string - $pk_arr[] = $arr[$j][$col-1]+0; - else - // encode as json string - $pk_arr[] = $arr[$j][$col-1]; - } - $pk = json_encode($pk_arr); - $tdWithClass = ""; - if($target_table_type == 'table') - { - echo $tdWithClass."".$lang['edit'].""; - echo $tdWithClass."".$lang['del'].""; - } - for($z=0; $z', ''), htmlencode($fldResult)); - echo ""; - } - echo ""; - } - echo "
"; - #todo: make sure the search keywords are kept - #echo ""; - #echo "&".($_SESSION[COOKIENAME.'fulltexts']?'r':'l')."arr; T &".($_SESSION[COOKIENAME.'fulltexts']?'l':'r')."arr;"; - echo "
"; - echo "


"; - } - - echo "".$lang['srch_again'].""; - } - else - { - $query = "PRAGMA table_info(".$db->quote_id($target_table).")"; - $result = $db->selectArray($query); - - echo "
"; - echo $token_html; - - echo ""; - echo ""; - echo ""; - echo ""; - echo ""; - echo ""; - echo ""; - - for($i=0; $i"; - $tdWithClassLeft = ""; - echo $tdWithClassLeft; - echo htmlencode($field); - echo ""; - echo $tdWithClassLeft; - echo htmlencode($type); - echo ""; - echo $tdWithClassLeft; - echo ""; - echo ""; - echo $tdWithClassLeft; - if($typeAffinity=="INTEGER" || $typeAffinity=="REAL" || $typeAffinity=="NUMERIC") - echo ""; - else - echo ""; - echo ""; - echo ""; - } - echo ""; - echo ""; - echo ""; - echo "
".$lang['fld']."".$lang['type']."".$lang['operator']."".$lang['val']."
"; - echo "
"; - echo ""; - echo "
"; - echo "
"; - } - break; - - //- Row actions - - //- View row (=row_view) - case "row_view": - if(!isset($_POST['startRow'])) - $_POST['startRow'] = 0; - - if(isset($_POST['numRows'])) - $_SESSION[COOKIENAME.'numRows'] = intval($_POST['numRows']); - - if(!isset($_SESSION[COOKIENAME.'numRows'])) - $_SESSION[COOKIENAME.'numRows'] = $rowsNum; - - if(isset($_GET['fulltexts'])) - $_SESSION[COOKIENAME.'fulltexts'] = $_GET['fulltexts']; - - if(!isset($_SESSION[COOKIENAME.'fulltexts'])) - $_SESSION[COOKIENAME.'fulltexts'] = false; - - if(isset($_SESSION[COOKIENAME.'currentTable']) && $_SESSION[COOKIENAME.'currentTable']!=$target_table) - { - unset($_SESSION[COOKIENAME.'sortRows']); - unset($_SESSION[COOKIENAME.'orderRows']); - } - if(isset($_POST['viewtype'])) - { - $_SESSION[COOKIENAME.'viewtype'] = $_POST['viewtype']; - } - - $rowCount = $db->numRows($target_table); - $lastPage = intval($rowCount / $_SESSION[COOKIENAME.'numRows']); - $remainder = intval($rowCount % $_SESSION[COOKIENAME.'numRows']); - if($remainder==0) - $remainder = $_SESSION[COOKIENAME.'numRows']; - - //- HTML: pagination buttons - echo "
"; - //previous button - if($_POST['startRow']>0) - { - echo "
"; - echo "
"; - echo $token_html; - echo ""; - echo " "; - echo " "; - echo "
"; - echo "
"; - echo "
"; - echo "
"; - echo $token_html; - echo ""; - echo " "; - echo " "; - echo "
"; - echo "
"; - } - - //show certain number buttons - echo "
"; - echo "
"; - echo $token_html; - echo " "; - echo " "; - echo $lang['rows_records']; - - if(intval($_POST['startRow']+$_SESSION[COOKIENAME.'numRows']) < $rowCount) - echo ""; - else - echo " "; - echo $lang['as_a']; - echo " "; - echo "
"; - echo "
"; - - //next button - if(intval($_POST['startRow']+$_SESSION[COOKIENAME.'numRows'])<$rowCount) - { - echo "
"; - echo "
"; - echo $token_html; - echo ""; - echo " "; - echo " "; - echo "
"; - echo "
"; - echo "
"; - echo "
"; - echo $token_html; - echo ""; - echo " "; - echo " "; - echo "
"; - echo "
"; - } - echo "
"; - echo "
"; - - //- Query execution - if(!isset($_GET['sort'])) - $_GET['sort'] = NULL; - if(!isset($_GET['order'])) - $_GET['order'] = NULL; - - $numRows = $_SESSION[COOKIENAME.'numRows']; - $startRow = $_POST['startRow']; - if(isset($_GET['sort'])) - { - $_SESSION[COOKIENAME.'sortRows'] = $_GET['sort']; - $_SESSION[COOKIENAME.'currentTable'] = $target_table; - } - if(isset($_GET['order'])) - { - $_SESSION[COOKIENAME.'orderRows'] = $_GET['order']; - $_SESSION[COOKIENAME.'currentTable'] = $target_table; - } - $_SESSION[COOKIENAME.'numRows'] = $numRows; - $query = "SELECT * "; - // select the primary key column(s) last (ROWID if there is no PK). - // this will be used to identify rows, e.g. when editing/deleting rows - $primary_key = $db->getPrimaryKey($target_table); - foreach($primary_key as $pk) - { - $query.= ', '.$db->quote_id($pk); - $query.= ', typeof('.$db->quote_id($pk).')'; - } - $query .= " FROM ".$db->quote_id($target_table); - $queryDisp = "SELECT * FROM ".$db->quote_id($target_table); - $queryCount = "SELECT MIN(COUNT(*),".$numRows.") AS count FROM ".$db->quote_id($target_table); - $queryAdd = ""; - if(isset($_SESSION[COOKIENAME.'sortRows'])) - $queryAdd .= " ORDER BY ".$db->quote_id($_SESSION[COOKIENAME.'sortRows']); - if(isset($_SESSION[COOKIENAME.'orderRows'])) - $queryAdd .= " ".$_SESSION[COOKIENAME.'orderRows']; - $queryAdd .= " LIMIT ".$startRow.", ".$numRows; - $query .= $queryAdd; - $queryDisp .= $queryAdd; - - $resultRows = $db->select($queryCount); - $resultRows = $resultRows['count']; - - //- Show results - if($resultRows>0) - { - $queryTimer = new MicroTimer(); - $table_result = $db->query($query); - $queryTimer->stop(); - - - echo "
"; - echo "".$lang['showing_rows']." ".$startRow." - ".($startRow + $resultRows-1).", ".$lang['total'].": ".$rowCount." "; - printf($lang['query_time'], $queryTimer); - echo "
"; - echo "".htmlencode($queryDisp).""; - echo "

"; - - if($target_table_type == 'view') - { - echo sprintf($lang['readonly_tbl'], htmlencode($target_table))." http://en.wikipedia.org/wiki/View_(database)"; - echo "

"; - } - - $query = "PRAGMA table_info(".$db->quote_id($target_table).")"; - $result = $db->selectArray($query); - $pkFirstCol = sizeof($result)+1; - //- Table view - if(!isset($_SESSION[COOKIENAME.'viewtype']) || $_SESSION[COOKIENAME.'viewtype']=="table") - { - echo "
"; - echo $token_html; - echo ""; - echo ""; - if($target_table_type == 'table') - { - echo ""; - } - - for($i=0; $i"; - echo "".htmlencode($result[$i]['name']).""; - if(isset($_SESSION[COOKIENAME.'sortRows']) && $_SESSION[COOKIENAME.'sortRows']==$result[$i]['name']) - echo (($_SESSION[COOKIENAME.'orderRows']=="ASC") ? " " : " "); - echo ""; - } - echo ""; - - for($i=0; $row = $db->fetch($table_result); $i++) - { - // -g-> $pk will always be the last columns in each row of the array because we are doing "SELECT *, PK_1, typeof(PK_1), PK2, typeof(PK_2), ... FROM ..." - $pk_arr = array(); - for($col = $pkFirstCol; array_key_exists($col, $row); $col=$col+2) - { - // in $col we have the type and in $col-1 the value - if($row[$col]=='integer' || $row[$col]=='real') - // json encode as int or float, not string - $pk_arr[] = $row[$col-1]+0; - else - // encode as json string - $pk_arr[] = $row[$col-1]; - } - $pk = json_encode($pk_arr); - $tdWithClass = ""; - if($target_table_type == 'table') - { - echo $tdWithClass; - echo ""; - echo ""; - echo $tdWithClass; - // -g-> Here, we need to put the PK in as the link for both the edit and delete. - echo "".$lang['edit'].""; - echo ""; - echo $tdWithClass; - echo "".$lang['del'].""; - echo ""; - } - for($j=0; $jNULL"; - else - echo htmlencode(subString($row[$j])); - echo ""; - } - echo ""; - } - echo "
"; - echo ""; - echo "&".($_SESSION[COOKIENAME.'fulltexts']?'r':'l')."arr; T &".($_SESSION[COOKIENAME.'fulltexts']?'l':'r')."arr;"; - echo "
"; - $tdWithClassLeft = ""; - echo "
"; - if($target_table_type == 'table') - { - echo "".$lang['chk_all']." / ".$lang['unchk_all']." ".$lang['with_sel'].": "; - echo " "; - echo ""; - } - echo "
"; - } - else - //- Chart view - { - if(!isset($_SESSION[COOKIENAME.$target_table.'chartlabels'])) - { - // No label-column set. Try to pick a text-column as label-column. - for($i=0; $i - - -
- Chart Settings"; - echo "
"; - echo $token_html; - echo $lang['chart_type'].": "; - echo "

"; - echo $lang['lbl'].": "; - echo "

"; - echo $lang['val'].": "; - echo "

"; - echo ""; - echo "
"; - echo ""; - echo "
"; - //end chart view - } - } - else if($rowCount>0)//no rows - do nothing - { - echo "

".$lang['no_rows']; - } - elseif($target_table_type == 'table') - { - echo "

".$lang['empty_tbl']." ".$lang['click']." ".$lang['insert_rows']; - } - - break; - - //- Create new row (=row_create) - case "row_create": - $fieldStr = ""; - echo "
"; - echo $token_html; - echo $lang['restart_insert']; - echo " "; - echo $lang['rows']; - echo " "; - echo "
"; - echo "
"; - $query = "PRAGMA table_info(".$db->quote_id($target_table).")"; - $result = $db->selectArray($query); - echo "
"; - echo $token_html; - if(isset($_POST['num'])) - $num = $_POST['num']; - else - $num = 1; - echo ""; - for($j=0; $j<$num; $j++) - { - if($j>0) - echo "
"; - echo ""; - echo ""; - echo ""; - echo ""; - echo ""; - echo ""; - echo ""; - echo ""; - - for($i=0; $i"; - $tdWithClassLeft = ""; - echo $tdWithClassLeft; - echo htmlencode($field); - echo ""; - echo $tdWithClassLeft; - echo htmlencode($type); - echo ""; - echo $tdWithClassLeft; - echo ""; - echo ""; - //we need to have a column dedicated to nulls -di - echo $tdWithClassLeft; - if($result[$i]['notnull']==0) - { - if($result[$i]['dflt_value']==="NULL") - echo ""; - else - echo ""; - } - echo ""; - echo $tdWithClassLeft; - if($result[$i]['dflt_value'] === "NULL") - $dflt_value = ""; - else - $dflt_value = htmlencode(deQuoteSQL($result[$i]['dflt_value'])); - - if($typeAffinity=="INTEGER" || $typeAffinity=="REAL" || $typeAffinity=="NUMERIC") - echo ""; - else - echo ""; - echo ""; - echo ""; - } - echo ""; - echo ""; - echo ""; - echo "
".$lang['fld']."".$lang['type']."".$lang['func']."Null".$lang['val']."
"; - echo "
"; - echo ""; - echo "

"; - } - $fieldStr = substr($fieldStr, 1); - echo ""; - echo "
"; - break; - - //- Edit or delete row (=row_editordelete) - case "row_editordelete": - if(isset($_POST['check'])) - $pks = $_POST['check']; - else if(isset($_GET['pk'])) - $pks = array($_GET['pk']); - else $pks[0] = ""; - $str = $pks[0]; - for($i=1; $i"; - echo $lang['err'].": ".$lang['no_sel']; - echo ""; - echo "

".$lang['return'].""; - } - else - { - if((isset($_POST['type']) && $_POST['type']=="edit") || (isset($_GET['type']) && $_GET['type']=="edit")) //edit - { - echo "
"; - echo $token_html; - $query = "PRAGMA table_info(".$db->quote_id($target_table).")"; - $result = $db->selectArray($query); - - //build the POST array of fields - $fieldStr = $result[0][1]; - for($j=1; $jgetPrimaryKey($target_table); - - echo ""; - - for($j=0; $jquote_id($target_table)." WHERE " . $db->wherePK($target_table, json_decode($pks[$j])); - $result1 = $db->select($query); - - echo ""; - echo ""; - echo ""; - echo ""; - echo ""; - echo ""; - echo ""; - echo ""; - - for($i=0; $i"; - $tdWithClassLeft = ""; - echo $tdWithClass; - echo htmlencode($field); - echo ""; - echo $tdWithClass; - echo htmlencode($type); - echo ""; - echo $tdWithClassLeft; - echo ""; - echo ""; - echo $tdWithClassLeft; - if($result[$i][3]==0) - { - if($value===NULL) - echo ""; - else - echo ""; - } - echo ""; - echo $tdWithClassLeft; - if($typeAffinity=="INTEGER" || $typeAffinity=="REAL" || $typeAffinity=="NUMERIC") - echo ""; - else - echo ""; - echo ""; - echo ""; - } - echo ""; - echo ""; - echo ""; - echo "
".$lang['fld']."".$lang['type']."".$lang['func']."Null".$lang['val']."
"; - echo "
"; - // Note: the 'Save changes' button must be first in the code so it is the one used when submitting the form with the Enter key (issue #215) - echo " "; - echo " "; - echo "".$lang['cancel'].""; - echo "
"; - echo "
"; - } - echo ""; - } - else //delete - { - echo "
"; - echo $token_html; - echo "
"; - printf($lang['ques_del_rows'], htmlencode($str), htmlencode($target_table)); - echo "

"; - echo " "; - echo "".$lang['cancel'].""; - echo "
"; - } - } - break; - - //- Column actions - - //- View table structure (=column_view) - case "column_view": - $query = "PRAGMA table_info(".$db->quote_id($target_table).")"; - $result = $db->selectArray($query); - - echo ""; - echo $token_html; - echo ""; - echo ""; - if($target_table_type == 'table') - echo ""; - echo ""; - echo ""; - echo ""; - echo ""; - echo ""; - echo ""; - echo ""; - - $noPrimaryKey = true; - - for($i=0; $i"; - $tdWithClassLeft = ""; - if($target_table_type == 'table') - { - echo $tdWithClass; - echo ""; - echo ""; - echo $tdWithClass; - echo "".$lang['edit'].""; - echo ""; - echo $tdWithClass; - echo "".$lang['del'].""; - echo ""; - } - echo $tdWithClass; - echo htmlencode($colVal); - echo ""; - echo $tdWithClassLeft; - echo htmlencode($fieldVal); - echo ""; - echo $tdWithClassLeft; - echo htmlencode($typeVal); - echo ""; - echo $tdWithClassLeft; - echo htmlencode($notnullVal); - echo ""; - echo $tdWithClassLeft; - if($defaultVal===NULL) - echo "".$lang['none'].""; - elseif($defaultVal==="NULL") - echo "NULL"; - else - echo htmlencode($defaultVal); - echo ""; - echo $tdWithClassLeft; - echo htmlencode($primarykeyVal); - echo ""; - echo ""; - } - - echo "
".$lang['col']." #".$lang['fld']."".$lang['type']."".$lang['not_null']."".$lang['def_val']."".$lang['prim_key']."
"; - echo "
"; - if($target_table_type == 'table') - { - echo "".$lang['chk_all']." / ".$lang['unchk_all']." ".$lang['with_sel'].": "; - echo " "; - echo ""; - } - echo "
"; - if($target_table_type == 'table') - { - echo "
"; - echo "
"; - echo $token_html; - echo ""; - echo $lang['add']." ".$lang['tbl_end']." "; - echo "
"; - } - - $query = "SELECT sql FROM sqlite_master WHERE name=".$db->quote($target_table); - $master = $db->selectArray($query); - - echo "
"; - echo "
"; - echo "
"; - echo "".$lang['query_used_'.$target_table_type]."
"; - echo "".htmlencode($master[0]['sql']).""; - echo "
"; - echo "
"; - if($target_table_type != 'view') - { - echo "


"; - //$query = "SELECT * FROM sqlite_master WHERE type='index' AND tbl_name='".$target_table."'"; - $query = "PRAGMA index_list(".$db->quote_id($target_table).")"; - $result = $db->selectArray($query); - if(sizeof($result)>0) - { - echo "

".$lang['indexes'].":

"; - echo ""; - echo ""; - echo ""; - echo ""; - echo ""; - echo ""; - echo ""; - echo ""; - echo ""; - for($i=0; $iquote_id($result[$i]['name']).")"; - $info = $db->selectArray($query); - $span = sizeof($info); - - $tdWithClass = ""; - echo $tdWithClassSpan; - echo "".$lang['del'].""; - echo ""; - echo $tdWithClassLeftSpan; - echo $result[$i]['name']; - echo ""; - echo $tdWithClassLeftSpan; - echo $unique; - echo ""; - for($j=0; $j<$span; $j++) - { - if($j!=0) - echo ""; - echo $tdWithClassLeft; - echo htmlencode($info[$j]['seqno']); - echo ""; - echo $tdWithClassLeft; - echo htmlencode($info[$j]['cid']); - echo ""; - echo $tdWithClassLeft; - echo htmlencode($info[$j]['name']); - echo ""; - echo ""; - } - } - echo "
"; - echo "".$lang['name']."".$lang['unique']."".$lang['seq_no']."".$lang['col']." #".$lang['fld']."
"; - $tdWithClassLeft = ""; - $tdWithClassSpan = ""; - $tdWithClassLeftSpan = ""; - echo "


"; - } - - $query = "SELECT * FROM sqlite_master WHERE type='trigger' AND tbl_name=".$db->quote($target_table)." ORDER BY name"; - $result = $db->selectArray($query); - //print_r($result); - if(sizeof($result)>0) - { - echo "

".$lang['triggers'].":

"; - echo ""; - echo ""; - echo ""; - echo ""; - echo ""; - echo ""; - for($i=0; $i"; - echo ""; - echo $tdWithClass; - echo "".$lang['del'].""; - echo ""; - echo $tdWithClass; - echo htmlencode($result[$i]['name']); - echo ""; - echo $tdWithClass; - echo htmlencode($result[$i]['sql']); - echo ""; - } - echo "
"; - echo "".$lang['name']."".$lang['sql']."


"; - } - - echo "
"; - echo $token_html; - echo ""; - echo "
"; - echo $lang['create_index2']." ".$lang['cols']." "; - echo "
"; - echo "
"; - - echo "
"; - echo $token_html; - echo ""; - echo "
"; - echo $lang['create_trigger2']." "; - echo "
"; - echo "
"; - } - break; - - //- Create column (=column_create) - case "column_create": - echo "

".sprintf($lang['new_fld'],htmlencode($_POST['tablename']))."

"; - if($_POST['tablefields']=="" || intval($_POST['tablefields'])<=0) - echo $lang['specify_fields']; - else if($_POST['tablename']=="") - echo $lang['specify_tbl']; - else - { - $num = intval($_POST['tablefields']); - $name = $_POST['tablename']; - echo "
"; - echo $token_html; - echo ""; - echo ""; - echo ""; - echo ""; - $headings = array($lang["fld"], $lang["type"], $lang["prim_key"]); - if($db->getType() != "SQLiteDatabase") $headings[] = $lang["autoincrement"]; - $headings[] = $lang["not_null"]; - $headings[] = $lang["def_val"]; - - for($k=0; $k" . $headings[$k] . ""; - echo ""; - - for($i=0; $i<$num; $i++) - { - $tdWithClass = ""; - echo $tdWithClass; - echo ""; - echo ""; - echo $tdWithClass; - echo ""; - echo ""; - echo $tdWithClass; - echo ""; - echo ""; - if($db->getType() != "SQLiteDatabase") - { - echo $tdWithClass; - echo ""; - echo ""; - } - echo $tdWithClass; - echo ""; - echo ""; - echo $tdWithClass; - echo ""; - echo ""; - echo ""; - echo ""; - } - echo ""; - echo ""; - echo ""; - echo "
"; - echo "
"; - echo " "; - echo "".$lang['cancel'].""; - echo "
"; - echo "
"; - } - break; - - //- Delete column (=column_confirm) - case "column_confirm": - if(isset($_POST['check'])) - $pks = $_POST['check']; - elseif(isset($_GET['pk'])) - $pks = array($_GET['pk']); - else $pks = array(); - - if(sizeof($pks)==0) //nothing was selected so show an error - { - echo "
"; - echo $lang['err'].": ".$lang['no_sel']; - echo "
"; - echo "

".$lang['return'].""; - } - else - { - $str = $pks[0]; - $pkVal = $pks[0]; - for($i=1; $i"; - echo $token_html; - echo "
"; - printf($lang['ques_'.$_REQUEST['action2']], htmlencode($str), htmlencode($target_table)); - echo "

"; - echo " "; - echo "".$lang['cancel'].""; - echo "
"; - } - break; - - //- Edit column (=column_edit) - case "column_edit": - echo "

".sprintf($lang['edit_col'], htmlencode($_GET['pk']))." ".$lang['on_tbl']." '".htmlencode($target_table)."'

"; - echo $lang['sqlite_limit']."

"; - if(!isset($_GET['pk'])) - echo $lang['specify_col']; - else if (!$target_table) - echo $lang['specify_tbl']; - else - { - $query = "PRAGMA table_info(".$db->quote_id($target_table).")"; - $result = $db->selectArray($query); - - for($i=0; $i"; - echo $token_html; - echo ""; - echo ""; - echo ""; - echo ""; - //$headings = array("Field", "Type", "Primary Key", "Autoincrement", "Not NULL", "Default Value"); - $headings = array($lang["fld"], $lang["type"]); - for($k=0; $k".$headings[$k].""; - echo ""; - - $i = 0; - $tdWithClass = ""; - echo $tdWithClass; - echo ""; - echo ""; - echo $tdWithClass; - echo ""; - echo ""; - /* - echo $tdWithClass; - if($primarykeyVal) - echo " Yes"; - else - echo " Yes"; - echo ""; - echo $tdWithClass; - if(1==2) - echo " Yes"; - else - echo " Yes"; - echo ""; - echo $tdWithClass; - if($notnullVal) - echo " Yes"; - else - echo " Yes"; - echo ""; - echo $tdWithClass; - echo ""; - echo ""; - */ - echo ""; - - echo ""; - echo ""; - echo ""; - echo "
"; - echo "
"; - echo " "; - echo "".$lang['cancel'].""; - echo "
"; - echo ""; - } - break; - - //- Delete index (=index_delete) - case "index_delete": - echo "
"; - echo $token_html; - echo "
"; - echo sprintf($lang['ques_del_index'], htmlencode($_GET['pk']))."

"; - echo " "; - echo "".$lang['cancel'].""; - echo "
"; - echo "
"; - break; - - //- Delete trigger (=trigger_delete) - case "trigger_delete": - echo "
"; - echo $token_html; - echo "
"; - echo sprintf($lang['ques_del_trigger'], htmlencode($_GET['pk']))."

"; - echo " "; - echo "".$lang['cancel'].""; - echo "
"; - echo "
"; - break; - - //- Create trigger (=trigger_create) - case "trigger_create": - echo "

".$lang['create_trigger']." '".htmlencode($_POST['tablename'])."'

"; - if($_POST['tablename']=="") - echo $lang['specify_tbl']; - else - { - echo "
"; - echo $token_html; - echo $lang['trigger_name'].":

"; - echo "
".$lang['db_event'].""; - echo $lang['before']."/".$lang['after'].": "; - echo ""; - echo "

"; - echo $lang['event'].": "; - echo ""; - echo "


"; - echo "
".$lang['trigger_act'].""; - echo "

"; - echo $lang['when_exp'].":
"; - echo ""; - echo "

"; - echo $lang['trigger_step'].":
"; - echo ""; - echo "


"; - echo " "; - echo "".$lang['cancel'].""; - echo "
"; - } - break; - - //- Create index (=index_create) - case "index_create": - echo "

".$lang['create_index']." '".htmlencode($_POST['tablename'])."'

"; - if($_POST['numcolumns']=="" || intval($_POST['numcolumns'])<=0) - echo $lang['specify_fields']; - else if($_POST['tablename']=="") - echo $lang['specify_tbl']; - else - { - echo "
"; - echo $token_html; - $num = intval($_POST['numcolumns']); - $query = "PRAGMA table_info(".$db->quote_id($_POST['tablename']).")"; - - $result = $db->selectArray($query); - echo "
".$lang['define_index'].""; - echo "
"; - echo ""; - echo "
"; - if(version_compare($db->getSQLiteVersion(),'3.8.0')>=0) - echo " ".helpLink($lang['help10']); - echo "
"; - echo "
"; - echo "
".$lang['define_in_col'].""; - for($i=0; $i<$num; $i++) - { - echo " "; - echo "
"; - } - echo "
"; - echo "

"; - echo ""; - echo " "; - echo "".$lang['cancel'].""; - echo "
"; - } - break; - } - echo ""; -} - -$view = "structure"; - -//- HMTL: tabs for databases -if(!$target_table && !isset($_GET['confirm']) && (!isset($_GET['action']) || (isset($_GET['action']) && $_GET['action']!="table_create"))) //the absence of these fields means we are viewing the database homepage -{ - $view = isset($_GET['view']) ? $_GET['view'] : 'structure'; - - echo "".$lang['struct'].""; - echo "".$lang['sql'].""; - echo "".$lang['export'].""; - echo "".$lang['import'].""; - echo "".$lang['vac'].""; - if($directory!==false && is_writable($directory)) - { - echo "".$lang['db_rename'].""; - - echo "".$lang['db_del'].""; - } - echo "
"; - echo "
"; - - //- Switch on $view (actually a series of if-else) - - if($view=="structure") - { - //- Database structure, shows all the tables (=structure) - - if(isset($dbexists)) - { - echo "
"; - echo $lang['err'].': '.sprintf($lang['db_exists'], htmlencode($dbname)); - echo "

"; - } - - if($db->isWritable() && !$db->isDirWritable()) - { - echo "
"; - echo $lang['attention'].': '.$lang['directory_not_writable']; - echo "

"; - } - - if(isset($extension_not_allowed)) - { - echo "
"; - echo $lang['extension_not_allowed'].': '; - echo implode(', ', array_map('htmlencode', $allowed_extensions)); - echo '
'.$lang['add_allowed_extension']; - echo "

"; - } - - if ($auth->isPasswordDefault()) - { - echo "
"; - echo sprintf($lang['warn_passwd'],(is_readable('phpliteadmin.config.php')?'phpliteadmin.config.php':PAGE))."
".$lang['warn0']; - echo "
"; - } - - echo "".$lang['db_name'].": ".htmlencode($db->getName())."
"; - echo "".$lang['db_path'].": ".htmlencode($db->getPath())."
"; - echo "".$lang['db_size'].": ".$db->getSize()." KB
"; - echo "".$lang['db_mod'].": ".$db->getDate()."
"; - echo "".$lang['sqlite_v'].": ".$db->getSQLiteVersion()."
"; - echo "".$lang['sqlite_ext']." ".helpLink($lang['help1']).": ".$db->getType()."
"; - echo "".$lang['php_v'].": ".phpversion()."
"; - echo "".PROJECT." ".$lang["ver"].": ".VERSION; - // echo "

"; - echo ""; - - if(isset($_GET['sort']) && ($_GET['sort']=='type' || $_GET['sort']=='name')) - $_SESSION[COOKIENAME.'sortTables'] = $_GET['sort']; - if(isset($_GET['order']) && ($_GET['order']=='ASC' || $_GET['order']=='DESC')) - $_SESSION[COOKIENAME.'orderTables'] = $_GET['order']; - - $query = "SELECT type, name FROM sqlite_master WHERE (type='table' OR type='view') AND name!='' AND name NOT LIKE 'sqlite_%'"; - $queryAdd = ""; - if(isset($_SESSION[COOKIENAME.'sortTables'])) - $queryAdd .= " ORDER BY ".$db->quote_id($_SESSION[COOKIENAME.'sortTables']); - else - $queryAdd .= " ORDER BY \"name\""; - if(isset($_SESSION[COOKIENAME.'orderTables'])) - $queryAdd .= " ".$_SESSION[COOKIENAME.'orderTables']; - $query .= $queryAdd; - $result = $db->selectArray($query); - - if(sizeof($result)==0) - echo $lang['no_tbl']."

"; - else - { - echo ""; - echo ""; - - echo ""; - - echo ""; - - echo ""; - echo ""; - echo ""; - - $totalRecords = 0; - $skippedTables = false; - for($i=0; $inumRows($result[$i]['name'], (!isset($_GET['forceCount']))); - if($records == '?') - { - $skippedTables = true; - $records = "?"; - } - else - $totalRecords += $records; - $tdWithClass = ""; - echo $tdWithClassLeft; - echo $lang['tbl']; - echo ""; - echo $tdWithClassLeft; - echo "".htmlencode($result[$i]['name']).""; - echo ""; - echo $tdWithClass; - echo "".$lang['browse'].""; - echo ""; - echo $tdWithClass; - echo "".$lang['struct'].""; - echo ""; - echo $tdWithClass; - echo "".$lang['sql'].""; - echo ""; - echo $tdWithClass; - echo "".$lang['srch'].""; - echo ""; - echo $tdWithClass; - echo "".$lang['insert'].""; - echo ""; - echo $tdWithClass; - echo "".$lang['export'].""; - echo ""; - echo $tdWithClass; - echo "".$lang['import'].""; - echo ""; - echo $tdWithClass; - echo "".$lang['rename'].""; - echo ""; - echo $tdWithClass; - echo "".$lang['empty'].""; - echo ""; - echo $tdWithClass; - echo "".$lang['drop'].""; - echo ""; - echo $tdWithClass; - echo $records; - echo ""; - echo ""; - } - else - { - echo ""; - echo $tdWithClassLeft; - echo $lang['view']; - echo ""; - echo $tdWithClassLeft; - echo "".htmlencode($result[$i]['name']).""; - echo ""; - echo $tdWithClass; - echo "".$lang['browse'].""; - echo ""; - echo $tdWithClass; - echo "".$lang['struct'].""; - echo ""; - echo $tdWithClass; - echo "".$lang['sql'].""; - echo ""; - echo $tdWithClass; - echo "".$lang['srch'].""; - echo ""; - echo $tdWithClass; - echo ""; - echo ""; - echo $tdWithClass; - echo "".$lang['export'].""; - echo ""; - echo $tdWithClass; - echo ""; - echo ""; - echo $tdWithClass; - echo ""; - echo ""; - echo $tdWithClass; - echo ""; - echo ""; - echo $tdWithClass; - echo "".$lang['drop'].""; - echo ""; - echo $tdWithClass; - echo $records; - echo ""; - echo ""; - } - } - echo ""; - echo ""; - echo ""; - echo ""; - echo "
"; - echo "".$lang['type']." ".helpLink($lang['help3']); - if(isset($_SESSION[COOKIENAME.'sortTables']) && $_SESSION[COOKIENAME.'sortTables']=="type") - echo (($_SESSION[COOKIENAME.'orderTables']=="ASC") ? " " : " "); - echo ""; - echo "".$lang['name'].""; - if(isset($_SESSION[COOKIENAME.'sortTables']) && $_SESSION[COOKIENAME.'sortTables']=="name") - echo (($_SESSION[COOKIENAME.'orderTables']=="ASC") ? " " : " "); - echo "".$lang['act']."".$lang['rec']."
"; - $tdWithClassLeft = ""; - - if($result[$i]['type']=="table") - { - echo "
".sizeof($result)." ".$lang['total']."".$totalRecords.($skippedTables?" + ?":"")."
"; - echo "
"; - if($skippedTables) - echo "
".sprintf($lang["counting_skipped"],"","")."
"; - } - echo "
"; - echo "".$lang['create_tbl_db']." '".htmlencode($db->getName())."'"; - echo "
"; - echo $token_html; - echo $lang['name'].": "; - echo $lang['fld_num'].": "; - echo ""; - echo "
"; - echo "
"; - echo "
"; - echo "
"; - echo "".$lang['create_view']." '".htmlencode($db->getName())."'"; - echo "
"; - echo $token_html; - echo $lang['name'].": "; - echo $lang['sel_state']." ".helpLink($lang['help4']).": "; - echo ""; - echo "
"; - echo "
"; - } - else if($view=="sql") - { - //- Database SQL editor (=sql) - if(isset($_POST['query']) && $_POST['query']!="") - { - $delimiter = $_POST['delimiter']; - $queryStr = $_POST['queryval']; - //save the queries in history if necessary - if($maxSavedQueries!=0 && $maxSavedQueries!=false) - { - if(!isset($_SESSION['query_history'])) - $_SESSION['query_history'] = array(); - $_SESSION['query_history'][md5(strtolower($queryStr))] = $queryStr; - if(sizeof($_SESSION['query_history']) > $maxSavedQueries) - array_shift($_SESSION['query_history']); - } - $query = explode_sql($delimiter, $queryStr); //explode the query string into individual queries based on the delimiter - - for($i=0; $iquery($query[$i]); - - echo "
"; - echo "".htmlencode($query[$i]).""; - if($table_result === NULL || $table_result === false) - { - echo "
".$lang['err'].": ".htmlencode($db->getError())."
"; - } - echo "

"; - if($row = $db->fetch($table_result, 'assoc')) - { - $headers = array_keys($row); - echo ""; - echo ""; - for($j=0; $j"; - echo htmlencode($headers[$j]); - echo ""; - } - echo ""; - $rowCount = 0; - for(; $rowCount==0 || $row = $db->fetch($table_result, 'assoc'); $rowCount++) - { - $tdWithClass = ""; - for($z=0; $zNULL"; - else - echo htmlencode(subString($row[$headers[$z]])); - echo ""; - } - echo ""; - } - $queryTimer->stop(); - echo "
"; - echo "


"; - - - if($table_result !== NULL && $table_result !== false) - { - echo "
"; - if($rowCount>0 || $db->getAffectedRows()==0) - { - printf($lang['show_rows'], $rowCount); - } - if($db->getAffectedRows()>0 || $rowCount==0) - { - echo $db->getAffectedRows()." ".$lang['rows_aff']." "; - } - printf($lang['query_time'], $queryTimer); - echo "
"; - } - - - } - } - } - } - else - { - $delimiter = ";"; - $queryStr = ""; - } - - echo "
"; - echo "".sprintf($lang['run_sql'],htmlencode($db->getName())).""; - echo "
"; - echo $token_html; - if(isset($_SESSION['query_history']) && sizeof($_SESSION['query_history'])>0) - { - echo "".$lang['recent_queries']."

"; - } - echo ""; - echo $lang['delimit']." "; - echo ""; - echo "
"; - echo "
"; - } - else if($view=="vacuum") - { - //- Vacuum database confirmation (=vacuum) - if(isset($_POST['vacuum'])) - { - $query = "VACUUM"; - $db->query($query); - echo "
"; - printf($lang['db_vac'], htmlencode($db->getName())); - echo "

"; - } - echo "
"; - echo $token_html; - printf($lang['vac_desc'],htmlencode($db->getName())); - echo "

"; - echo ""; - echo "
"; - } - else if($view=="export") - { - //- Export view (=export) - echo "
"; - echo $token_html; - echo "
".$lang['export'].""; - echo ""; - echo "

"; - echo ""; - echo "
"; - echo "
"; - - echo "
".$lang['options'].""; - echo " ".helpLink($lang['help5'])."
"; - echo " ".helpLink($lang['help6'])."
"; - echo " ".helpLink($lang['help7'])."
"; - echo " ".helpLink($lang['help8'])."
"; - echo " ".helpLink($lang['help9'])."
"; - echo "
"; - - echo ""; - - echo "
"; - echo "

"; - echo "
".$lang['save_as'].""; - $file = pathinfo($db->getPath()); - $name = $file['filename']; - echo " "; - echo "
"; - echo "
"; - echo "
".sprintf($lang['backup_hint'], "".$lang["backup_hint_linktext"]."")."
"; - } - else if($view=="import") - { - //- Import view (=import) - if(isset($_POST['import'])) - { - echo "
"; - if($importSuccess===true) - echo $lang['import_suc']; - else - echo $importSuccess; - echo "

"; - } - - echo "
"; - echo $token_html; - echo "
".$lang['import'].""; - echo ""; - echo "
"; - echo "
"; - - echo "
".$lang['options'].""; - echo $lang['no_opt']; - echo "
"; - - echo ""; - - echo "
"; - echo "

"; - - echo "
".$lang['import_f'].""; - echo " "; - echo "
"; - } - else if($view=="rename") - { - //- Rename database confirmation (=rename) - if(isset($extension_not_allowed)) - { - echo "
"; - echo $lang['extension_not_allowed'].': '; - echo implode(', ', array_map('htmlencode', $allowed_extensions)); - echo '
'.$lang['add_allowed_extension']; - echo "

"; - } - if(isset($dbexists)) - { - echo "
"; - if($oldpath==$newpath) - echo $lang['err'].": ".$lang['warn_dumbass']; - else{ - echo $lang['err'].": "; - printf($lang['db_exists'], htmlencode($newpath)); - } - echo "

"; - } - if(isset($justrenamed)) - { - echo "
"; - printf($lang['db_renamed'], htmlencode($oldpath)); - echo " '".htmlencode($newpath)."'."; - echo "

"; - } - echo ""; - echo $token_html; - echo ""; - echo $lang['db_rename']." '".htmlencode($db->getPath())."' ".$lang['to']." "; - echo "
"; - } - else if($view=="delete") - { - //- Delete database confirmation (=delete) - echo "
"; - echo $token_html; - echo "
"; - echo sprintf($lang['ques_del_db'],htmlencode($db->getPath()))."

"; - echo ""; - echo " "; - echo "".$lang['cancel'].""; - echo "
"; - echo "
"; - } - - echo ""; -} - -//- HTML: page footer -echo "
"; -echo "".$lang['powered']." ".PROJECT." | "; -echo $lang['free_software']." ".$lang['please_donate']." | "; -printf($lang['page_gen'], $pageTimer); -echo ""; -echo "
"; -$db->close(); //close the database -echo ""; -echo ""; - -//- End of main code - -// Authorization class -// Maintains user's logged-in state and security of application -// -class Authorization -{ - private $authorized; - private $login_failed; - private $system_password_encrypted; - - public function __construct() - { - // the salt and password encrypting is probably unnecessary protection but is done just - // for the sake of being very secure - if(!isset($_SESSION[COOKIENAME.'_salt']) && !isset($_COOKIE[COOKIENAME.'_salt'])) - { - // create a random salt for this session if a cookie doesn't already exist for it - $_SESSION[COOKIENAME.'_salt'] = self::generateSalt(20); - } - else if(!isset($_SESSION[COOKIENAME.'_salt']) && isset($_COOKIE[COOKIENAME.'_salt'])) - { - // session doesn't exist, but cookie does so grab it - $_SESSION[COOKIENAME.'_salt'] = $_COOKIE[COOKIENAME.'_salt']; - } - - // salted and encrypted password used for checking - $this->system_password_encrypted = md5(SYSTEMPASSWORD."_".$_SESSION[COOKIENAME.'_salt']); - - $this->authorized = - // no password - SYSTEMPASSWORD == '' - // correct password stored in session - || isset($_SESSION[COOKIENAME.'password']) && $_SESSION[COOKIENAME.'password'] == $this->system_password_encrypted - // correct password stored in cookie - || isset($_COOKIE[COOKIENAME]) && isset($_COOKIE[COOKIENAME.'_salt']) && md5(SYSTEMPASSWORD."_".$_COOKIE[COOKIENAME.'_salt']) == $_COOKIE[COOKIENAME]; - } - - public function attemptGrant($password, $remember) - { - if ($password == SYSTEMPASSWORD) { - if ($remember) { - // user wants to be remembered, so set a cookie - $expire = time()+60*60*24*30; //set expiration to 1 month from now - setcookie(COOKIENAME, $this->system_password_encrypted, $expire, null, null, null, true); - setcookie(COOKIENAME."_salt", $_SESSION[COOKIENAME.'_salt'], $expire, null, null, null, true); - } else { - // user does not want to be remembered, so destroy any potential cookies - setcookie(COOKIENAME, "", time()-86400, null, null, null, true); - setcookie(COOKIENAME."_salt", "", time()-86400, null, null, null, true); - unset($_COOKIE[COOKIENAME]); - unset($_COOKIE[COOKIENAME.'_salt']); - } - - $_SESSION[COOKIENAME.'password'] = $this->system_password_encrypted; - $this->authorized = true; - return true; - } - - $this->login_failed = true; - return false; - } - - public function revoke() - { - //destroy everything - cookies and session vars - setcookie(COOKIENAME, "", time()-86400, null, null, null, true); - setcookie(COOKIENAME."_salt", "", time()-86400, null, null, null, true); - unset($_COOKIE[COOKIENAME]); - unset($_COOKIE[COOKIENAME.'_salt']); - session_unset(); - session_destroy(); - $this->authorized = false; - } - - public function isAuthorized() - { - return $this->authorized; - } - - public function isFailedLogin() - { - return $this->login_failed; - } - - public function isPasswordDefault() - { - return SYSTEMPASSWORD == 'admin'; - } - - private static function generateSalt($saltSize) - { - $set = 'ABCDEFGHiJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; - $setLast = strlen($set) - 1; - $salt = ''; - while ($saltSize-- > 0) { - $salt .= $set[mt_rand(0, $setLast)]; - } - return $salt; - } - -} -// Database class -// Generic database abstraction class to manage interaction with database without worrying about SQLite vs. PHP versions -// -class Database -{ - protected $db; //reference to the DB object - protected $type; //the extension for PHP that handles SQLite - protected $data; - protected $lastResult; - protected $alterError; - - public function __construct($data) - { - global $lang; - $this->data = $data; - try - { - if(!file_exists($this->data["path"]) && !is_writable(dirname($this->data["path"]))) //make sure the containing directory is writable if the database does not exist - { - echo "
"; - printf($lang['db_not_writeable'], htmlencode($this->data["path"]), htmlencode(dirname($this->data["path"]))); - echo "
"; - echo ''; - echo ""; - echo "
"; - echo "

"; - exit(); - } - - $ver = $this->getVersion(); - - switch(true) - { - case ((!isset($data['type']) || $data['type']!=2) && (FORCETYPE=="PDO" || (FORCETYPE==false && class_exists("PDO") && in_array("sqlite", PDO::getAvailableDrivers()) && ($ver==-1 || $ver==3)))): - $this->db = new PDO("sqlite:".$this->data['path']); - if($this->db!=NULL) - { - $this->type = "PDO"; - break; - } - case ((!isset($data['type']) || $data['type']!=2) && (FORCETYPE=="SQLite3" || (FORCETYPE==false && class_exists("SQLite3") && ($ver==-1 || $ver==3)))): - $this->db = new SQLite3($this->data['path']); - if($this->db!=NULL) - { - $this->type = "SQLite3"; - break; - } - case (FORCETYPE=="SQLiteDatabase" || (FORCETYPE==false && class_exists("SQLiteDatabase") && ($ver==-1 || $ver==2))): - $this->db = new SQLiteDatabase($this->data['path']); - if($this->db!=NULL) - { - $this->type = "SQLiteDatabase"; - break; - } - default: - $this->showError(); - exit(); - } - $this->query("PRAGMA foreign_keys = ON"); - } - catch(Exception $e) - { - $this->showError(); - exit(); - } - } - - public function registerUserFunction($ids) - { - // in case a single function id was passed - if (is_string($ids)) - $ids = array($ids); - - if ($this->type == 'PDO') { - foreach ($ids as $id) { - $this->db->sqliteCreateFunction($id, $id, 1); - } - } else { // type is Sqlite3 or SQLiteDatabase - foreach ($ids as $id) { - $this->db->createFunction($id, $id, 1); - } - } - } - - public function getError() - { - if($this->alterError!='') - { - $error = $this->alterError; - $this->alterError = ""; - return $error; - } - else if($this->type=="PDO") - { - $e = $this->db->errorInfo(); - return $e[2]; - } - else if($this->type=="SQLite3") - { - return $this->db->lastErrorMsg(); - } - else - { - return sqlite_error_string($this->db->lastError()); - } - } - - public function showError() - { - global $lang; - $classPDO = class_exists("PDO"); - $classSQLite3 = class_exists("SQLite3"); - $classSQLiteDatabase = class_exists("SQLiteDatabase"); - if($classPDO) // PDO is there, check if the SQLite driver for PDO is missing - $PDOSqliteDriver = (in_array("sqlite", PDO::getAvailableDrivers() )); - else - $PDOSqliteDriver = false; - echo "
"; - printf($lang['db_setup'], $this->getPath()); - echo ".

".$lang['chk_ext']."...

"; - echo "PDO: ".($classPDO ? $lang['installed'] : $lang['not_installed'])."
"; - echo "PDO SQLite Driver: ".($PDOSqliteDriver ? $lang['installed'] : $lang['not_installed'])."
"; - echo "SQLite3: ".($classSQLite3 ? $lang['installed'] : $lang['not_installed'])."
"; - echo "SQLiteDatabase: ".($classSQLiteDatabase ? $lang['installed'] : $lang['not_installed'])."
"; - echo "
...".$lang['done'].".


"; - if(!$classPDO && !$classSQLite3 && !$classSQLiteDatabase) - printf($lang['sqlite_ext_support'], PROJECT); - else - { - if(!$PDOSqliteDriver && !$classSQLite3 && $this->getVersion()==3) - printf($lang['sqlite_v_error'], 3, PROJECT, 2); - else if(!$classSQLiteDatabase && $this->getVersion()==2) - printf($lang['sqlite_v_error'], 2, PROJECT, 3); - else - echo $lang['report_issue'].' '.PROJECT_BUGTRACKER_LINK.'.'; - } - echo "

See ".PROJECT_INSTALL_LINK." for help.

"; - - $this->print_db_list(); - - echo "
"; - } - - // print the list of databases - public function print_db_list() - { - global $databases, $lang; - echo "
".$lang['db_ch'].""; - if(sizeof($databases)<10) //if there aren't a lot of databases, just show them as a list of links instead of drop down menu - { - $i=0; - foreach($databases as $database) - { - $i++; - $name = $database['name']; - if(strlen($name)>25) - $name = "...".substr($name, strlen($name)-22, 22); - echo '[' . ($database['readable'] ? 'r':' ' ) . ($database['writable'] && $database['writable_dir'] ? 'w':' ' ) . '] '; - if($database == $_SESSION[COOKIENAME.'currentDB']) - echo "".htmlencode($name)."  [↓]"; - else - echo "".htmlencode($name)."  [↓]"; - if($i"; - } - } - else //there are a lot of databases - show a drop down menu - { - echo "
"; - echo ''; - echo " "; - echo ""; - echo "
"; - } - echo "
"; - } - - public function __destruct() - { - if($this->db) - $this->close(); - } - - //get the exact PHP extension being used for SQLite - public function getType() - { - return $this->type; - } - - // get the version of the SQLite library - public function getSQLiteVersion() - { - $queryVersion = $this->select("SELECT sqlite_version() AS sqlite_version"); - return $queryVersion['sqlite_version']; - } - - //get the name of the database - public function getName() - { - return $this->data["name"]; - } - - //get the filename of the database - public function getPath() - { - return $this->data["path"]; - } - - //is the db-file writable? - public function isWritable() - { - return $this->data["writable"]; - } - - //is the db-folder writable? - public function isDirWritable() - { - return $this->data["writable_dir"]; - } - - //get the version of the database - public function getVersion() - { - if(file_exists($this->data['path'])) //make sure file exists before getting its contents - { - $content = strtolower(file_get_contents($this->data['path'], NULL, NULL, 0, 40)); //get the first 40 characters of the database file - $p = strpos($content, "** this file contains an sqlite 2"); //this text is at the beginning of every SQLite2 database - if($p!==false) //the text is found - this is version 2 - return 2; - else - return 3; - } - else //return -1 to indicate that it does not exist and needs to be created - { - return -1; - } - } - - //get the size of the database (in KB) - public function getSize() - { - return round(filesize($this->data["path"])*0.0009765625, 1); - } - - //get the last modified time of database - public function getDate() - { - global $lang; - return date($lang['date_format'], filemtime($this->data['path'])); - } - - //get number of affected rows from last query - public function getAffectedRows() - { - if($this->type=="PDO") - if(!is_object($this->lastResult)) - // in case it was an alter table statement, there is no lastResult object - return 0; - else - return $this->lastResult->rowCount(); - else if($this->type=="SQLite3") - return $this->db->changes(); - else if($this->type=="SQLiteDatabase") - return $this->db->changes(); - } - - public function getTypeOfTable($table) - { - $result = $this->select("SELECT `type` FROM `sqlite_master` WHERE `name`=" . $this->quote($table), 'assoc'); - return $result['type']; - } - - public function close() - { - if($this->type=="PDO") - $this->db = NULL; - else if($this->type=="SQLite3") - $this->db->close(); - else if($this->type=="SQLiteDatabase") - $this->db = NULL; - } - - public function beginTransaction() - { - $this->query("BEGIN"); - } - - public function commitTransaction() - { - $this->query("COMMIT"); - } - - public function rollbackTransaction() - { - $this->query("ROLLBACK"); - } - - //generic query wrapper - //returns false on error and the query result on success - public function query($query, $ignoreAlterCase=false) - { - global $debug; - if(strtolower(substr(ltrim($query),0,5))=='alter' && $ignoreAlterCase==false) //this query is an ALTER query - call the necessary function - { - preg_match("/^\s*ALTER\s+TABLE\s+\"((?:[^\"]|\"\")+)\"\s+(.*)$/i",$query,$matches); - if(!isset($matches[1]) || !isset($matches[2])) - { - if($debug) echo "SQL?
"; - return false; - } - $tablename = str_replace('""','"',$matches[1]); - $alterdefs = $matches[2]; - if($debug) echo "ALTER TABLE QUERY=(".htmlencode($query)."), tablename=($tablename), alterdefs=($alterdefs)
"; - $result = $this->alterTable($tablename, $alterdefs); - } - else //this query is normal - proceed as normal - { - $result = $this->db->query($query); - if($debug) echo "SQL?
"; - } - if($result===false) - return false; - $this->lastResult = $result; - return $result; - } - - //wrapper for an INSERT and returns the ID of the inserted row - public function insert($query) - { - $result = $this->query($query); - if($this->type=="PDO") - return $this->db->lastInsertId(); - else if($this->type=="SQLite3") - return $this->db->lastInsertRowID(); - else if($this->type=="SQLiteDatabase") - return $this->db->lastInsertRowid(); - } - - //returns an array for SELECT - public function select($query, $mode="both") - { - $result = $this->query($query); - if(!$result) //make sure the result is valid - return NULL; - if($this->type=="PDO") - { - if($mode=="assoc") - $mode = PDO::FETCH_ASSOC; - else if($mode=="num") - $mode = PDO::FETCH_NUM; - else - $mode = PDO::FETCH_BOTH; - return $result->fetch($mode); - } - else if($this->type=="SQLite3") - { - if($mode=="assoc") - $mode = SQLITE3_ASSOC; - else if($mode=="num") - $mode = SQLITE3_NUM; - else - $mode = SQLITE3_BOTH; - return $result->fetchArray($mode); - } - else if($this->type=="SQLiteDatabase") - { - if($mode=="assoc") - $mode = SQLITE_ASSOC; - else if($mode=="num") - $mode = SQLITE_NUM; - else - $mode = SQLITE_BOTH; - return $result->fetch($mode); - } - } - - //returns an array of arrays after doing a SELECT - public function selectArray($query, $mode="both") - { - $result = $this->query($query); - //make sure the result is valid - if($result=== false || $result===NULL) - return NULL; // error - if(!is_object($result)) // no rows returned - return array(); - if($this->type=="PDO") - { - if($mode=="assoc") - $mode = PDO::FETCH_ASSOC; - else if($mode=="num") - $mode = PDO::FETCH_NUM; - else - $mode = PDO::FETCH_BOTH; - return $result->fetchAll($mode); - } - else if($this->type=="SQLite3") - { - if($mode=="assoc") - $mode = SQLITE3_ASSOC; - else if($mode=="num") - $mode = SQLITE3_NUM; - else - $mode = SQLITE3_BOTH; - $arr = array(); - $i = 0; - while($res = $result->fetchArray($mode)) - { - $arr[$i] = $res; - $i++; - } - return $arr; - } - else if($this->type=="SQLiteDatabase") - { - if($mode=="assoc") - $mode = SQLITE_ASSOC; - else if($mode=="num") - $mode = SQLITE_NUM; - else - $mode = SQLITE_BOTH; - return $result->fetchAll($mode); - } - } - - //returns an array of the next row in $result - public function fetch($result, $mode="both") - { - //make sure the result is valid - if($result=== false || $result===NULL) - return NULL; // error - if(!is_object($result)) // no rows returned - return array(); - if($this->type=="PDO") - { - if($mode=="assoc") - $mode = PDO::FETCH_ASSOC; - else if($mode=="num") - $mode = PDO::FETCH_NUM; - else - $mode = PDO::FETCH_BOTH; - return $result->fetch($mode); - } - else if($this->type=="SQLite3") - { - if($mode=="assoc") - $mode = SQLITE3_ASSOC; - else if($mode=="num") - $mode = SQLITE3_NUM; - else - $mode = SQLITE3_BOTH; - return $result->fetchArray($mode); - } - else if($this->type=="SQLiteDatabase") - { - if($mode=="assoc") - $mode = SQLITE_ASSOC; - else if($mode=="num") - $mode = SQLITE_NUM; - else - $mode = SQLITE_BOTH; - return $result->fetch($mode); - } - } - - - // SQlite supports multiple ways of surrounding names in quotes: - // single-quotes, double-quotes, backticks, square brackets. - // As sqlite does not keep this strict, we also need to be flexible here. - // This function generates a regex that matches any of the possibilities. - private function sqlite_surroundings_preg($name,$preg_quote=true,$notAllowedCharsIfNone="'\"",$notAllowedName=false) - { - if($name=="*" || $name=="+") - { - if($notAllowedName!==false && $preg_quote) - $notAllowedName = preg_quote($notAllowedName,"/"); - // use possesive quantifiers to save memory - // (There is a bug in PCRE starting in 8.13 and fixed in PCRE 8.36 - // why we can't use posesive quantifiers - See issue #310). - if(version_compare(strstr(constant('PCRE_VERSION'), ' ', true), '8.36', '>=') || - version_compare(strstr(constant('PCRE_VERSION'), ' ', true), '8.12', '<=')) - $posessive='+'; - else - $posessive=''; - - $nameSingle = ($notAllowedName!==false?"(?!".$notAllowedName."')":"")."(?:[^']$name+|'')$name".$posessive; - $nameDouble = ($notAllowedName!==false?"(?!".$notAllowedName."\")":"")."(?:[^\"]$name+|\"\")$name".$posessive; - $nameBacktick = ($notAllowedName!==false?"(?!".$notAllowedName."`)":"")."(?:[^`]$name+|``)$name".$posessive; - $nameSquare = ($notAllowedName!==false?"(?!".$notAllowedName."\])":"")."(?:[^\]]$name+|\]\])$name".$posessive; - $nameNo = ($notAllowedName!==false?"(?!".$notAllowedName."\s)":"")."[^".$notAllowedCharsIfNone."]$name"; - } - else - { - if($preg_quote) $name = preg_quote($name,"/"); - - $nameSingle = str_replace("'","''",$name); - $nameDouble = str_replace('"','""',$name); - $nameBacktick = str_replace('`','``',$name); - $nameSquare = str_replace(']',']]',$name); - $nameNo = $name; - } - - $preg = "(?:'".$nameSingle."'|". // single-quote surrounded or not in quotes (correct SQL for values/new names) - $nameNo."|". // not surrounded (correct SQL if not containing reserved words, spaces or some special chars) - "\"".$nameDouble."\"|". // double-quote surrounded (correct SQL for identifiers) - "`".$nameBacktick."`|". // backtick surrounded (MySQL-Style) - "\[".$nameSquare."\])"; // square-bracket surrounded (MS Access/SQL server-Style) - return $preg; - } - - // Returns the last PREG error as a string, '' if no error occured - private function getPregError() - { - $error = preg_last_error(); - switch ($error) - { - case PREG_NO_ERROR: return 'No error'; - case PREG_INTERNAL_ERROR: return 'There is an internal error!'; - case PREG_BACKTRACK_LIMIT_ERROR: return 'Backtrack limit was exhausted!'; - case PREG_RECURSION_LIMIT_ERROR: return 'Recursion limit was exhausted!'; - case PREG_BAD_UTF8_ERROR: return 'Bad UTF8 error!'; - // PREG_BAD_UTF8_OFFSET_ERROR is introduced in PHP 5.3.0, which is not yet required by PLA, so we use its value 5 instead so long - case 5: return 'Bad UTF8 offset error!'; - default: return 'Unknown Error'; - } - } - - // function that is called for an alter table statement in a query - // code borrowed with permission from http://code.jenseng.com/db/ - // this has been completely debugged / rewritten by Christopher Kramer - public function alterTable($table, $alterdefs) - { - global $debug, $lang; - $this->alterError=""; - $errormsg = sprintf($lang['alter_failed'],htmlencode($table)).' - '; - if($debug) echo "ALTER TABLE: table=($table), alterdefs=($alterdefs), PCRE version=(".PCRE_VERSION.")

"; - if($alterdefs != '') - { - $recreateQueries = array(); - $resultArr = $this->selectArray("SELECT sql,name,type FROM sqlite_master WHERE tbl_name = ".$this->quote($table)); - if(sizeof($resultArr)<1) - { - $this->alterError = $errormsg . sprintf($lang['tbl_inexistent'], htmlencode($table)); - if($debug) echo "ERROR: unknown table

"; - return false; - } - for($i=0; $i"; - } - } - else - { - // ALTER the table - $tmpname = 't'.time(); - $origsql = $row['sql']; - $preg_remove_create_table = "/^\s*+CREATE\s++TABLE\s++".$this->sqlite_surroundings_preg($table)."\s*+(\(.*+)$/is"; - $origsql_no_create = preg_replace($preg_remove_create_table, '$1', $origsql, 1); - if($debug) echo "origsql=($origsql)
preg_remove_create_table=($preg_remove_create_table)
"; - if($origsql_no_create == $origsql) - { - $this->alterError = $errormsg . $lang['alter_tbl_name_not_replacable']; - if($debug) echo "ERROR: could not get rid of CREATE TABLE
"; - return false; - } - $createtemptableSQL = "CREATE TABLE ".$this->quote($tmpname)." ".$origsql_no_create; - if($debug) echo "createtemptableSQL=($createtemptableSQL)
"; - $createindexsql = array(); - $preg_alter_part = "/(?:DROP(?! PRIMARY KEY)|ADD(?! PRIMARY KEY)|CHANGE|RENAME TO|ADD PRIMARY KEY|DROP PRIMARY KEY)" // the ALTER command - ."(?:" - ."\s+\(".$this->sqlite_surroundings_preg("+",false,"\"'\[`)")."+\)" // stuff in brackets (in case of ADD PRIMARY KEY) - ."|" // or - ."\s+".$this->sqlite_surroundings_preg("+",false,",'\"\[`") // column names and stuff like this - .")*/i"; - if($debug) - echo "preg_alter_part=(".$preg_alter_part.")
"; - preg_match_all($preg_alter_part,$alterdefs,$matches); - $defs = $matches[0]; - - $get_oldcols_query = "PRAGMA table_info(".$this->quote_id($table).")"; - $result_oldcols = $this->selectArray($get_oldcols_query); - $newcols = array(); - $coltypes = array(); - $primarykey = array(); - foreach($result_oldcols as $column_info) - { - $newcols[$column_info['name']] = $column_info['name']; - $coltypes[$column_info['name']] = $column_info['type']; - if($column_info['pk']) - $primarykey[] = $column_info['name']; - } - $newcolumns = ''; - $oldcolumns = ''; - reset($newcols); - while(list($key, $val) = each($newcols)) - { - $newcolumns .= ($newcolumns?', ':'').$this->quote_id($val); - $oldcolumns .= ($oldcolumns?', ':'').$this->quote_id($key); - } - $copytotempsql = 'INSERT INTO '.$this->quote_id($tmpname).'('.$newcolumns.') SELECT '.$oldcolumns.' FROM '.$this->quote_id($table); - $dropoldsql = 'DROP TABLE '.$this->quote_id($table); - $createtesttableSQL = $createtemptableSQL; - if(count($defs)<1) - { - $this->alterError = $errormsg . $lang['alter_no_def']; - if($debug) echo "ERROR: defs<1

"; - return false; - } - foreach($defs as $def) - { - if($debug) echo "
def=$def
"; - $preg_parse_def = - "/^(DROP(?! PRIMARY KEY)|ADD(?! PRIMARY KEY)|CHANGE|RENAME TO|ADD PRIMARY KEY|DROP PRIMARY KEY)" // $matches[1]: command - ."(?:" // this is either - ."(?:\s+\((.+)\)\s*$)" // anything in brackets (for ADD PRIMARY KEY) - // then $matches[2] is what there is in brackets - ."|" // OR: - ."(?:\s+\"((?:[^\"]|\"\")+)\"|\s+'((?:[^']|'')+)')"// (first) column name, either in single or double quotes - // in case of RENAME TO, it is the new a table name - // $matches[3] will be the column/table name without the quotes if double quoted - // $matches[4] will be the column/table name without the quotes if single quoted - ."(" // $matches[5]: anything after the column name - ."(?:\s+'((?:[^']|'')+)')?" // $matches[6] (optional): a second column name surrounded with single quotes - // (the match does not contain the quotes) - ."\s+" - ."((?:[A-Z]+\s*)+(?:\(\s*[+-]?\s*[0-9]+(?:\s*,\s*[+-]?\s*[0-9]+)?\s*\))?)\s*" // $matches[7]: a type name - .".*". - ")" - ."?\s*$" - .")?\s*$/i"; // in case of DROP PRIMARY KEY, there is nothing after the command - if($debug) echo "preg_parse_def=$preg_parse_def
"; - $parse_def = preg_match($preg_parse_def,$def,$matches); - if($parse_def===false) - { - $this->alterError = $errormsg . $lang['alter_parse_failed']; - if($debug) echo "ERROR: !parse_def

"; - return false; - } - if(!isset($matches[1])) - { - $this->alterError = $errormsg . $lang['alter_action_not_recognized']; - if($debug) echo "ERROR: !isset(matches[1])

"; - return false; - } - $action = strtolower($matches[1]); - if(($action == 'add' || $action == 'rename to') && isset($matches[4]) && $matches[4]!='') - $column = str_replace("''","'",$matches[4]); // enclosed in '' - elseif($action == 'add primary key' && isset($matches[2]) && $matches[2]!='') - $column = $matches[2]; - elseif($action == 'drop primary key') - $column = ''; // DROP PRIMARY KEY has no column definition - elseif(isset($matches[3]) && $matches[3]!='') - $column = str_replace('""','"',$matches[3]); // enclosed in "" - else - $column = ''; - - $column_escaped = str_replace("'","''",$column); - - if($debug) echo "action=($action), column=($column), column_escaped=($column_escaped)
"; - - /* we build a regex that devides the CREATE TABLE statement parts: - Part example Group Explanation - 1. CREATE TABLE t... ( $1 - 2. 'col1' ..., 'col2' ..., 'colN' ..., $3 (with col1-colN being columns that are not changed and listed before the col to change) - 3. 'colX' ..., (with colX being the column to change/drop) - 4. 'colX+1' ..., ..., 'colK') $5 (with colX+1-colK being columns after the column to change/drop) - */ - $preg_create_table = "\s*+(CREATE\s++TABLE\s++".preg_quote($this->quote($tmpname),"/")."\s*+\()"; // This is group $1 (keep unchanged) - $preg_column_definiton = "\s*+".$this->sqlite_surroundings_preg("+",true," '\"\[`,",$column)."(?:\s*+".$this->sqlite_surroundings_preg("*",false,"'\",`\[ ").")++"; // catches a complete column definition, even if it is - // 'column' TEXT NOT NULL DEFAULT 'we have a comma, here and a double ''quote!' - // this definition does NOT match columns with the column name $column - if($debug) echo "preg_column_definition=(".$preg_column_definiton.")
"; - $preg_columns_before = // columns before the one changed/dropped (keep) - "(?:". - "(". // group $2. Keep this one unchanged! - "(?:". - "$preg_column_definiton,\s*+". // column definition + comma - ")*". // there might be any number of such columns here - $preg_column_definiton. // last column definition - ")". // end of group $2 - ",\s*+" // the last comma of the last column before the column to change. Do not keep it! - .")?"; // there might be no columns before - if($debug) echo "preg_columns_before=(".$preg_columns_before.")
"; - $preg_columns_after = "(,\s*(.+))?"; // the columns after the column to drop. This is group $3 (drop) or $4(change) (keep!) - // we could remove the comma using $6 instead of $5, but then we might have no comma at all. - // Keeping it leaves a problem if we drop the first column, so we fix that case in another regex. - $table_new = $table; - - switch($action) - { - case 'add': - if($column=='') - { - $this->alterError = $errormsg . ' (add) - '. $lang['alter_no_add_col']; - return false; - } - $new_col_definition = "'$column_escaped' ".(isset($matches[5])?$matches[5]:''); - $preg_pattern_add = "/^".$preg_create_table. // the CREATE TABLE statement ($1) - "((?:(?!,\s*(?:PRIMARY\s+KEY\s*\(|CONSTRAINT\s|UNIQUE\s*\(|CHECK\s*\(|FOREIGN\s+KEY\s*\()).)*)". // column definitions ($2) - "(.*)\\)\s*$/si"; // table-constraints like PRIMARY KEY(a,b) ($3) and the closing bracket - // append the column definiton in the CREATE TABLE statement - $newSQL = preg_replace($preg_pattern_add, '$1$2, '.strtr($new_col_definition, array('\\' => '\\\\', '$' => '\$')).' $3', $createtesttableSQL).')'; - $preg_error = $this->getPregError(); - if($debug) - { - echo $createtesttableSQL."

"; - echo $newSQL."

"; - echo $preg_pattern_add."

"; - } - if($newSQL==$createtesttableSQL) // pattern did not match, so column adding did not succed - { - $this->alterError = $errormsg . ' (add) - '.$lang['alter_pattern_mismatch'].'. PREG ERROR: '.$preg_error; - return false; - } - $createtesttableSQL = $newSQL; - break; - case 'change': - if(!isset($matches[6]) || !isset($matches[7])) - { - $this->alterError = $errormsg . ' (change) - '.$lang['alter_col_not_recognized']; - return false; - } - $new_col_name = $matches[6]; - $new_col_type = $matches[7]; - $new_col_definition = "'$new_col_name' $new_col_type"; - $preg_column_to_change = "\s*".$this->sqlite_surroundings_preg($column)."(?:\s+".preg_quote($coltypes[$column]).")?(\s+(?:".$this->sqlite_surroundings_preg("*",false,",'\"`\[").")+)?"; - // replace this part (we want to change this column) - // group $3 contains the column constraints (keep!). the name & data type is replaced. - $preg_pattern_change = "/^".$preg_create_table.$preg_columns_before.$preg_column_to_change.$preg_columns_after."\s*\\)\s*$/s"; - - // replace the column definiton in the CREATE TABLE statement - $newSQL = preg_replace($preg_pattern_change, '$1$2,'.strtr($new_col_definition, array('\\' => '\\\\', '$' => '\$')).'$3$4)', $createtesttableSQL); - $preg_error = $this->getPregError(); - // remove comma at the beginning if the first column is changed - // probably somebody is able to put this into the first regex (using lookahead probably). - $newSQL = preg_replace("/^\s*(CREATE\s+TABLE\s+".preg_quote($this->quote($tmpname),"/")."\s+\(),\s*/",'$1',$newSQL); - if($debug) - { - echo "preg_column_to_change=(".$preg_column_to_change.")

"; - echo $createtesttableSQL."

"; - echo $newSQL."

"; - - echo $preg_pattern_change."

"; - } - if($newSQL==$createtesttableSQL || $newSQL=="") // pattern did not match, so column removal did not succed - { - $this->alterError = $errormsg . ' (change) - '.$lang['alter_pattern_mismatch'].'. PREG ERROR: '.$preg_error; - return false; - } - $createtesttableSQL = $newSQL; - $newcols[$column] = str_replace("''","'",$new_col_name); - break; - case 'drop': - $preg_column_to_drop = "\s*".$this->sqlite_surroundings_preg($column)."\s+(?:".$this->sqlite_surroundings_preg("*",false,",'\"\[`").")+"; // delete this part (we want to drop this column) - $preg_pattern_drop = "/^".$preg_create_table.$preg_columns_before.$preg_column_to_drop.$preg_columns_after."\s*\\)\s*$/s"; - - // remove the column out of the CREATE TABLE statement - $newSQL = preg_replace($preg_pattern_drop, '$1$2$3)', $createtesttableSQL); - $preg_error = $this->getPregError(); - // remove comma at the beginning if the first column is removed - // probably somebody is able to put this into the first regex (using lookahead probably). - $newSQL = preg_replace("/^\s*(CREATE\s+TABLE\s+".preg_quote($this->quote($tmpname),"/")."\s+\(),\s*/",'$1',$newSQL); - if($debug) - { - echo $createtesttableSQL."

"; - echo $newSQL."

"; - echo $preg_pattern_drop."

"; - } - if($newSQL==$createtesttableSQL || $newSQL=="") // pattern did not match, so column removal did not succed - { - $this->alterError = $errormsg . ' (drop) - '.$lang['alter_pattern_mismatch'].'. PREG ERROR: '.$preg_error; - return false; - } - $createtesttableSQL = $newSQL; - unset($newcols[$column]); - break; - case 'rename to': - // don't change column definition at all - $newSQL = $createtesttableSQL; - // only change the name of the table - $table_new = $column; - break; - case 'add primary key': - // we want to add a primary key for the column(s) stored in $column - $newSQL = preg_replace("/\)\s*$/", ", PRIMARY KEY (".$column.") )", $createtesttableSQL); - $createtesttableSQL = $newSQL; - break; - case 'drop primary key': - // we want to drop the primary key - if($debug) echo "DROP"; - if(sizeof($primarykey)==1) - { - // if not compound primary key, might be a column constraint -> try removal - $column = $primarykey[0]; - if($debug) echo "
Trying to drop column constraint for column $column
"; - /* - TODO: This does not work yet: - CREATE TABLE 't12' ('t1' INTEGER CONSTRAINT "bla" NOT NULL CONSTRAINT 'pk' PRIMARY KEY ); ALTER TABLE "t12" DROP PRIMARY KEY - This does: ! ! - CREATE TABLE 't12' ('t1' INTEGER CONSTRAINT bla NOT NULL CONSTRAINT 'pk' PRIMARY KEY ); ALTER TABLE "t12" DROP PRIMARY KEY - */ - $preg_column_to_change = "(\s*".$this->sqlite_surroundings_preg($column).")". // column ($3) - "(?:". // opt. type and column constraints - "(\s+(?:".$this->sqlite_surroundings_preg("(?:[^PC,'\"`\[]|P(?!RIMARY\s+KEY)|". - "C(?!ONSTRAINT\s+".$this->sqlite_surroundings_preg("+",false," ,'\"\[`")."\s+PRIMARY\s+KEY))",false,",'\"`\[").")*)". // column constraints before PRIMARY KEY ($3) - // primary key constraint (remove this!): - "(?:CONSTRAINT\s+".$this->sqlite_surroundings_preg("+",false," ,'\"\[`")."\s+)?". - "PRIMARY\s+KEY". - "(?:\s+(?:ASC|DESC))?". - "(?:\s+ON\s+CONFLICT\s+(?:ROLLBACK|ABORT|FAIL|IGNORE|REPLACE))?". - "(?:\s+AUTOINCREMENT)?". - "((?:".$this->sqlite_surroundings_preg("*",false,",'\"`\[").")*)". // column constraints after PRIMARY KEY ($4) - ")"; - // replace this part (we want to change this column) - // group $3 (column) $4 (constraints before) and $5 (constraints after) contain the part to keep - $preg_pattern_change = "/^".$preg_create_table.$preg_columns_before.$preg_column_to_change.$preg_columns_after."\s*\\)\s*$/si"; - - // replace the column definiton in the CREATE TABLE statement - $newSQL = preg_replace($preg_pattern_change, '$1$2,$3$4$5$6)', $createtesttableSQL); - // remove comma at the beginning if the first column is changed - // probably somebody is able to put this into the first regex (using lookahead probably). - $newSQL = preg_replace("/^\s*(CREATE\s+TABLE\s+".preg_quote($this->quote($tmpname),"/")."\s+\(),\s*/",'$1',$newSQL); - if($debug) - { - echo "preg_column_to_change=(".$preg_column_to_change.")

"; - echo $createtesttableSQL."

"; - echo $newSQL."

"; - - echo $preg_pattern_change."

"; - } - if($newSQL!=$createtesttableSQL && $newSQL!="") // pattern did match, so PRIMARY KEY constraint removed :) - { - $createtesttableSQL = $newSQL; - if($debug) echo "
SUCCEEDED
"; - } - else - { - if($debug) echo "NO LUCK"; - // TODO: try removing table constraint - return false; - } - $createtesttableSQL = $newSQL; - } else - // TODO: Try removing table constraint - return false; - - break; - default: - if($debug) echo 'ERROR: unknown alter operation!

'; - $this->alterError = $errormsg . $lang['alter_unknown_operation']; - return false; - } - } - $droptempsql = 'DROP TABLE '.$this->quote_id($tmpname); - - $createnewtableSQL = "CREATE TABLE ".$this->quote($table_new)." ".preg_replace("/^\s*CREATE\s+TABLE\s+'?".str_replace("'","''",preg_quote($tmpname,"/"))."'?\s+(.*)$/is", '$1', $createtesttableSQL, 1); - - $newcolumns = ''; - $oldcolumns = ''; - reset($newcols); - while(list($key,$val) = each($newcols)) - { - $newcolumns .= ($newcolumns?', ':'').$this->quote_id($val); - $oldcolumns .= ($oldcolumns?', ':'').$this->quote_id($key); - } - $copytonewsql = 'INSERT INTO '.$this->quote_id($table_new).'('.$newcolumns.') SELECT '.$oldcolumns.' FROM '.$this->quote_id($tmpname); - } - } - $alter_transaction = 'BEGIN; '; - $alter_transaction .= $createtemptableSQL.'; '; //create temp table - $alter_transaction .= $copytotempsql.'; '; //copy to table - $alter_transaction .= $dropoldsql.'; '; //drop old table - $alter_transaction .= $createnewtableSQL.'; '; //recreate original table - $alter_transaction .= $copytonewsql.'; '; //copy back to original table - $alter_transaction .= $droptempsql.'; '; //drop temp table - - $preg_index="/^\s*(CREATE\s+(?:UNIQUE\s+)?INDEX\s+(?:".$this->sqlite_surroundings_preg("+",false," '\"\[`")."\s*)*ON\s+)(".$this->sqlite_surroundings_preg($table).")(\s*\((?:".$this->sqlite_surroundings_preg("+",false," '\"\[`")."\s*)*\)\s*)\s*$/i"; - foreach($recreateQueries as $recreate_query) - { - if($recreate_query['type']=='index') - { - // this is an index. We need to make sure the index is not on a column that we drop. If it is, we drop the index as well. - $indexInfos = $this->selectArray('PRAGMA index_info('.$this->quote_id($recreate_query['name']).')'); - foreach($indexInfos as $indexInfo) - { - if(!isset($newcols[$indexInfo['name']])) - { - if($debug) echo 'Not recreating the following index:

'.htmlencode($recreate_query['sql']).'

'; - // Index on a column that was dropped. Skip recreation. - continue 2; - } - } - } - // TODO: In case we renamed a column on which there is an index, we need to recreate the index with the column name adjusted. - - // recreate triggers / indexes - if($table == $table_new) - { - // we had no RENAME TO, so we can recreate indexes/triggers just like the original ones - $alter_transaction .= $recreate_query['sql'].';'; - } else - { - // we had a RENAME TO, so we need to exchange the table-name in the CREATE-SQL of triggers & indexes - switch ($recreate_query['type']) - { - case 'index': - $recreate_queryIndex = preg_replace($preg_index, '$1'.$this->quote_id(strtr($table_new, array('\\' => '\\\\', '$' => '\$'))).'$3 ', $recreate_query['sql']); - if($recreate_queryIndex!=$recreate_query['sql'] && $recreate_queryIndex != NULL) - $alter_transaction .= $recreate_queryIndex.';'; - else - { - // the CREATE INDEX regex did not match. this normally should not happen - if($debug) echo 'ERROR: CREATE INDEX regex did not match!?

'; - // just try to recreate the index originally (will fail most likely) - $alter_transaction .= $recreate_query['sql'].';'; - } - break; - - case 'trigger': - // TODO: IMPLEMENT - $alter_transaction .= $recreate_query['sql'].';'; - break; - default: - if($debug) echo 'ERROR: Unknown type '.htmlencode($recreate_query['type']).'

'; - $alter_transaction .= $recreate_query['sql'].';'; - } - } - } - $alter_transaction .= 'COMMIT;'; - if($debug) echo $alter_transaction; - return $this->multiQuery($alter_transaction); - } - } - - //multiple query execution - //returns true on success, false otherwise. Use getError() to fetch the error. - public function multiQuery($query) - { - if($this->type=="PDO") - $success = $this->db->exec($query); - else if($this->type=="SQLite3") - $success = $this->db->exec($query); - else - $success = $this->db->queryExec($query, $error); - return $success; - } - - - // checks whether a table has a primary key - public function hasPrimaryKey($table) - { - $query = "PRAGMA table_info(".$this->quote_id($table).")"; - $table_info = $this->selectArray($query); - foreach($table_info as $row_id => $row_data) - { - if($row_data['pk']) - { - return true; - } - - } - return false; - } - - // Returns an array of columns by which rows can be uniquely adressed. - // For tables with a rowid column, this is always array('rowid') - // for tables without rowid, this is an array of the primary key columns. - public function getPrimaryKey($table) - { - $primary_key = array(); - // check if this table has a rowid - $getRowID = $this->select('SELECT ROWID FROM '.$this->quote_id($table).' LIMIT 0,1'); - if(isset($getRowID[0])) - // it has, so we prefer addressing rows by rowid - return array('rowid'); - else - { - // the table is without rowid, so use the primary key - $query = "PRAGMA table_info(".$this->quote_id($table).")"; - $table_info = $this->selectArray($query); - foreach($table_info as $row_id => $row_data) - { - if($row_data['pk']) - $primary_key[] = $row_data['name']; - } - } - return $primary_key; - } - - // selects a row by a given key $pk, which is an array of values - // for the columns by which a row can be adressed (rowid or primary key) - public function wherePK($table, $pk) - { - $where = ""; - $primary_key = $this->getPrimaryKey($table); - foreach($primary_key as $pk_index => $column) - { - if($where!="") - $where .= " AND "; - $where .= $this->quote_id($column) . ' = '; - if(is_int($pk[$pk_index]) || is_float($pk[$pk_index])) - $where .= $pk[$pk_index]; - else - $where .= $this->quote($pk[$pk_index]); - } - return $where; - } - - //get number of rows in table - public function numRows($table, $dontTakeLong = false) - { - // as Count(*) can be slow on huge tables without PK, - // if $dontTakeLong is set and the size is > 2MB only count() if there is a PK - if(!$dontTakeLong || $this->getSize() <= 2000 || $this->hasPrimaryKey($table)) - { - $result = $this->select("SELECT Count(*) FROM ".$this->quote_id($table)); - return $result[0]; - } else - { - return '?'; - } - } - - //correctly escape a string to be injected into an SQL query - public function quote($value) - { - if($this->type=="PDO") - { - // PDO quote() escapes and adds quotes - return $this->db->quote($value); - } - else if($this->type=="SQLite3") - { - return "'".$this->db->escapeString($value)."'"; - } - else - { - return "'".sqlite_escape_string($value)."'"; - } - } - - //correctly escape an identifier (column / table / trigger / index name) to be injected into an SQL query - public function quote_id($value) - { - // double-quotes need to be escaped by doubling them - $value = str_replace('"','""',$value); - return '"'.$value.'"'; - } - - - //import sql - //returns true on success, error message otherwise - public function import_sql($query) - { - $import = $this->multiQuery($query); - if(!$import) - return $this->getError(); - else - return true; - } - - //import csv - //returns true on success, error message otherwise - public function import_csv($filename, $table, $field_terminate, $field_enclosed, $field_escaped, $null, $fields_in_first_row) - { - // CSV import implemented by Christopher Kramer - http://www.christosoft.de - $csv_handle = fopen($filename,'r'); - $csv_insert = "BEGIN;\n"; - $csv_number_of_rows = 0; - // PHP requires enclosure defined, but has no problem if it was not used - if($field_enclosed=="") $field_enclosed='"'; - // PHP requires escaper defined - if($field_escaped=="") $field_escaped='\\'; - while($csv_handle!==false && !feof($csv_handle)) - { - $csv_data = fgetcsv($csv_handle, 0, $field_terminate, $field_enclosed, $field_escaped); - if($csv_data[0] != NULL || count($csv_data)>1) - { - $csv_number_of_rows++; - if($fields_in_first_row && $csv_number_of_rows==1) - { - $fields_in_first_row = false; - continue; - } - $csv_col_number = count($csv_data); - $csv_insert .= "INSERT INTO ".$this->quote_id($table)." VALUES ("; - foreach($csv_data as $csv_col => $csv_cell) - { - if($csv_cell == $null) $csv_insert .= "NULL"; - else - { - $csv_insert.= $this->quote($csv_cell); - } - if($csv_col == $csv_col_number-2 && $csv_data[$csv_col+1]=='') - { - // the CSV row ends with the separator (like old phpliteadmin exported) - break; - } - if($csv_col < $csv_col_number-1) $csv_insert .= ","; - } - $csv_insert .= ");\n"; - - if($csv_number_of_rows > 5000) - { - $csv_insert .= "COMMIT;\nBEGIN;\n"; - $csv_number_of_rows = 0; - } - } - } - if($csv_handle === false) - return "Error reading CSV file"; - else - { - $csv_insert .= "COMMIT;"; - fclose($csv_handle); - $import = $this->multiQuery($csv_insert); - if(!$import) - return $this->getError(); - else - return true; - } - } - - //export csv - public function export_csv($tables, $field_terminate, $field_enclosed, $field_escaped, $null, $crlf, $fields_in_first_row) - { - @set_time_limit(-1); - $query = "SELECT * FROM sqlite_master WHERE type='table' or type='view' ORDER BY type DESC"; - $result = $this->selectArray($query); - for($i=0; $iquote_id($result[$i]['tbl_name']).")"; - $temp = $this->selectArray($query); - $cols = array(); - for($z=0; $zquote_id($result[$i]['tbl_name']); - $table_result = $this->query($query); - $firstRow=true; - while($row = $this->fetch($table_result, "assoc")) - { - if(!$firstRow) - echo "\r\n"; - else - $firstRow=false; - - for($y=0; $ygetPath()."\r\n"; - echo "----\r\n"; - } - $query = "SELECT * FROM sqlite_master WHERE type='table' OR type='index' OR type='view' OR type='trigger' ORDER BY type='trigger', type='index', type='view', type='table'"; - $result = $this->selectArray($query); - - if($transaction) - echo "BEGIN TRANSACTION;\r\n"; - - //iterate through each table - for($i=0; $iquote_id($result[$i]['name']).";\r\n"; - } - if($structure) - { - if($comments) - { - echo "\r\n----\r\n"; - if($result[$i]['type']=="table" || $result[$i]['type']=="view") - echo "-- ".ucfirst($result[$i]['type'])." ".$lang['struct_for']." ".$result[$i]['tbl_name']."\r\n"; - else // index or trigger - echo "-- ".$lang['struct_for']." ".$result[$i]['type']." ".$result[$i]['name']." ".$lang['on_tbl']." ".$result[$i]['tbl_name']."\r\n"; - echo "----\r\n"; - } - echo $result[$i]['sql'].";\r\n"; - } - if($data && $result[$i]['type']=="table") - { - $query = "SELECT * FROM ".$this->quote_id($result[$i]['tbl_name']); - $table_result = $this->query($query, "assoc"); - - if($comments) - { - $numRows = $this->numRows($result[$i]['tbl_name']); - echo "\r\n----\r\n"; - echo "-- ".$lang['data_dump']." ".$result[$i]['tbl_name'].", ".sprintf($lang['total_rows'], $numRows)."\r\n"; - echo "----\r\n"; - } - $query = "PRAGMA table_info(".$this->quote_id($result[$i]['tbl_name']).")"; - $temp = $this->selectArray($query); - $cols = array(); - $cols_quoted = array(); - for($z=0; $zquote_id($temp[$z][1]); - } - while($row = $this->fetch($table_result)) - { - $vals = array(); - for($y=0; $yquote($row[$cols[$y]]); - } - echo "INSERT INTO ".$this->quote_id($result[$i]['tbl_name'])." (".implode(",", $cols_quoted).") VALUES (".implode(",", $vals).");\r\n"; - } - } - } - } - if($transaction) - echo "COMMIT;\r\n"; - } -} - -// class Resources (issue #157) -// outputs secondary files, such as css and javascript -// data is stored gzipped (gzencode) and encoded (base64_encode) -// -class Resources { - - // set this to the file containing getInternalResource; - // currently unused in split mode; set to __FILE__ for built PLA. - public static $embedding_file = __FILE__; - - private static $_resources = array( - 'css' => array( - 'mime' => 'text/css', - 'data' => 'resources/phpliteadmin.css', - ), - 'javascript' => array( - 'mime' => 'text/javascript', - 'data' => 'resources/phpliteadmin.js', - ), - 'favicon' => array( - 'mime' => 'image/x-icon', - 'data' => 'resources/favicon.ico', - 'base64' => 'true', - ), - ); - - // outputs the specified resource, if defined in this class. - // the main script should do no further output after calling this function. - public static function output($resource) - { - if (isset(self::$_resources[$resource])) { - $res =& self::$_resources[$resource]; - - if (function_exists('getInternalResource') && $data = getInternalResource($res['data'])) { - $filename = self::$embedding_file; - } else { - $filename = $res['data']; - } - - // use last-modified time as etag; etag must be quoted - $etag = '"' . filemtime($filename) . '"'; - - // check headers for matching etag; if etag hasn't changed, use the cached version - if (isset($_SERVER['HTTP_IF_NONE_MATCH']) && $_SERVER['HTTP_IF_NONE_MATCH'] == $etag) { - header('HTTP/1.0 304 Not Modified'); - return; - } - - header('Etag: ' . $etag); - - // cache file for at most 30 days - header('Cache-control: max-age=2592000'); - - // output resource - header('Content-type: ' . $res['mime']); - - if (isset($data)) { - if (isset($res['base64'])) { - echo base64_decode($data); - } else { - echo $data; - } - } else { - readfile($filename); - } - } - } - -} - - -// returns data from internal resources, available in single-file mode -function getInternalResource($res) { - $resources = array('resources/phpliteadmin.css'=>array(0=>0,1=>4047,),'resources/phpliteadmin.js'=>array(0=>4047,1=>4169,),'resources/favicon.ico'=>array(0=>8216,1=>1448,),); - - if (isset($resources[$res]) && $f = fopen(__FILE__, 'r')) { - fseek($f, __COMPILER_HALT_OFFSET__ + $resources[$res][0]); - $data = fread($f, $resources[$res][1]); - fclose($f); - return $data; - } - return false; -} - -// resources embedded below, do not edit! -__halt_compiler() ?>body{margin:0px;padding:0px;font-family:Arial,Helvetica,sans-serif;font-size:14px;color:#000;background-color:#e0ebf6;overflow:auto}.body_tbl td{padding:9px 2px 9px 9px}.left_td{width:100px}a{color:#03F;text-decoration:none;cursor:pointer}a:hover{color:#06F}hr{height:1px;border:0;color:#bbb;background-color:#bbb;width:100%}h1{margin:0px;padding:5px;font-size:24px;background-color:#f3cece;text-align:center;color:#000;border-top-left-radius:5px;border-top-right-radius:5px;-moz-border-radius-topleft:5px;-moz-border-radius-topright:5px}#headerlinks{text-align:center;margin-bottom:10px;padding:5px 15px;border-color:#03F;border-width:1px;border-style:solid;border-left-style:none;border-right-style:none;font-size:12px;background-color:#e0ebf6;font-weight:bold}h1 #version{color:#000;font-size:16px}h1 #logo{color:#000}h2{margin:0px;padding:0px;font-size:14px;margin-bottom:20px}input,select,textarea{font-family:Arial,Helvetica,sans-serif;background-color:#eaeaea;color:#03F;border-color:#03F;border-style:solid;border-width:1px;margin:5px;border-radius:5px;-moz-border-radius:5px;padding:3px}input.btn{cursor:pointer}input.btn:hover{background-color:#ccc}fieldset label{min-width:200px;display:block;float:left}fieldset{padding:15px;border-color:#03F;border-width:1px;border-style:solid;border-radius:5px;-moz-border-radius:5px;background-color:#f9f9f9}#container{padding:10px}#leftNav{min-width:250px;padding:0px;border-color:#03F;border-width:1px;border-style:solid;background-color:#FFF;padding-bottom:15px;border-radius:5px;-moz-border-radius:5px}.databaseList select{max-width:200px}.viewTable tr td{padding:1px}#loginBox{width:500px;margin-left:auto;margin-right:auto;margin-top:50px;border-color:#03F;border-width:1px;border-style:solid;background-color:#FFF;border-radius:5px;-moz-border-radius:5px}#main{border-color:#03F;border-width:1px;border-style:solid;padding:15px;background-color:#FFF;border-bottom-left-radius:5px;border-bottom-right-radius:5px;border-top-right-radius:5px;-moz-border-radius-bottomleft:5px;-moz-border-radius-bottomright:5px;-moz-border-radius-topright:5px}.td1{background-color:#f9e3e3;text-align:right;font-size:12px;padding-left:10px;padding-right:10px}.td2{background-color:#f3cece;text-align:right;font-size:12px;padding-left:10px;padding-right:10px}.tdheader{border-color:#03F;border-width:1px;border-style:solid;font-weight:bold;font-size:12px;padding-left:10px;padding-right:10px;background-color:#e0ebf6;border-radius:5px;-moz-border-radius:5px}.confirm{border-color:#03F;border-width:1px;border-style:dashed;padding:15px;background-color:#e0ebf6}.tab{display:block;padding:5px;padding-right:8px;padding-left:8px;border-color:#03F;border-width:1px;border-style:solid;margin-right:5px;float:left;border-bottom-style:none;position:relative;top:1px;padding-bottom:4px;background-color:#eaeaea;border-top-left-radius:5px;border-top-right-radius:5px;-moz-border-radius-topleft:5px;-moz-border-radius-topright:5px}.tab_pressed{display:block;padding:5px;padding-right:8px;padding-left:8px;border-color:#03F;border-width:1px;border-style:solid;margin-right:5px;float:left;border-bottom-style:none;position:relative;top:1px;background-color:#FFF;cursor:default;border-top-left-radius:5px;border-top-right-radius:5px;-moz-border-radius-topleft:5px;-moz-border-radius-topright:5px}.helpq{font-size:11px;font-weight:normal}#help_container{padding:0px;font-size:12px;margin-left:auto;margin-right:auto;background-color:#fff}.help_outer{background-color:#FFF;padding:0px;height:300px;position:relative}.help_list{padding:10px;height:auto}.headd{font-size:14px;font-weight:bold;display:block;padding:10px;background-color:#e0ebf6;border-color:#03F;border-width:1px;border-style:solid;border-left-style:none;border-right-style:none}.help_inner{padding:10px}.help_top{display:block;position:absolute;right:10px;bottom:10px}.warning,.delete,.empty,.drop,.delete_db{color:red}.sidebar_table{font-size:11px}.active_table,.active_db{text-decoration:underline}.null{color:#888}.found{background:#FF0;text-decoration:none} -function initAutoincrement() -{var i=0;while(document.getElementById('i'+i+'_autoincrement')!=undefined) -{document.getElementById('i'+i+'_autoincrement').disabled=true;i++;}} -function toggleAutoincrement(i) -{var type=document.getElementById('i'+i+'_type');var primarykey=document.getElementById('i'+i+'_primarykey');var autoincrement=document.getElementById('i'+i+'_autoincrement');if(!autoincrement)return false;if(type.value=='INTEGER'&&primarykey.checked) -autoincrement.disabled=false;else -{autoincrement.disabled=true;autoincrement.checked=false;}} -function toggleNull(i) -{var pk=document.getElementById('i'+i+'_primarykey');var notnull=document.getElementById('i'+i+'_notnull');if(pk.checked) -{notnull.disabled=true;notnull.checked=true;} -else -{notnull.disabled=false;}} -function checkAll(field) -{var i=0;while(document.getElementById('check_'+i)!=undefined) -{document.getElementById('check_'+i).checked=true;i++;}} -function uncheckAll(field) -{var i=0;while(document.getElementById('check_'+i)!=undefined) -{document.getElementById('check_'+i).checked=false;i++;}} -function changeIgnore(area,e,u) -{if(area.value!="") -{if(document.getElementById(e)!=undefined) -document.getElementById(e).checked=false;if(document.getElementById(u)!=undefined) -document.getElementById(u).checked=false;}} -function moveFields() -{var fields=document.getElementById("fieldcontainer");var selected=[];for(var i=0;iK=_ogN*mv zU%nwqTk5KM_3G7ouU@@ZU2o&dFXk5Kq--zPvpcIe#jLnbK~ailQ&JR)^i2wd;spL5 z_-Di~bl?yCmy-NG!LNXkzWpEc#@{J)3AYr+1;)QH{E2}!)Fl4B{+o%#coq8>qd<%T zF$%;e5Tihh0x=52C=jDSi~^HVfLo-~%*e=~4$LXe+M1VByt^hbBptG-byLXd9Qdu%3DR-vWg{t6%}Xg zDIO~l1=cEd-=k3yJX3U>Yae5i@ zejowV{D11gBknI1(9X}=J%*>hATxKH*#A5(N3EHWno1qi3BAe4B>O`n?@3nn-$|YY z*#-GU#e1@H^NUl+&@u~mr4;VT-JP{(f6A_${V7lRhqyqPpan(3#LS!L)Tn2yOQjUK z`P*{dD|#mnySmJ*y~PE>-*WEAWMqTWaw=LgWAiruv3ho-A^3X~2jKrhy(3ODW7aH+dqluKD?2-f-b0-&B- zn3=V0+a9#>Grqr+@T>S{@18u7Z@CmoGh_O6>cDKFr@Y*vV)B2b96EVL;1=iX_Cplp z%Ktkk>i;bOc0o!m#@ohT z;}v6v@uacE*l4UZa>fsg<;K0n0%NW*+qlK}nsKdhrE#gzX*3(tjH$+1#w6o(!*7j7 zqs|y-_`TtmhMyUD!;cL=FnrhWZNt|Me{2{u+%$9>E*Z`m+6~QyQbU8`%Z6&hn}+>{ zBExRO4nvmVRl_X(9~qJiFX?}z|C;{$`v0vzr616LOMhJ7q_5Lg=nv>W)bG<5rf2WW z1-BJ!&CSb6&o0=VvEju{n=>5#e;F)m$uP4l!?HHUY0qHNcboS*X74O6E?k&_zZj=A zone@C*2*lzf1Rd`;-c+=a;4fA&E&SUpInHH)lsukfy zKj+;d;TK`eBX2Tx=j_>$lSzJM%)&Bf*sCW*;?~KC#70FVtc5ZnO|EAd)~{#vdlSQS z8=d&G>|J-u_`6NyRwW4hTO=EFuVmgm7!Sew!m@{7>blSQ{h+%NHzC@YW$={yFlIJh12W| zEKq@wMloqt|D>t7=V@Ui??`n*bW56ZVmXr17yGRCBm41eJ+czd<3}FH^H|d!Je!-= z;(4?w4bLM@)9|csd>_x6#tnEbPQl}S^4oz|@z^^XkEX_rcosF@k7s4$GCXS=zl3LX z1HGRXYHtMS}@ zm<%lM@B?_h-B65YVFMXSPQycZZgUmjxub#9+3ETi&urJ5cqY1D!E>#P^!uiZ40J>N z+jxGVeleaK>z}}LeZ2PX*Fg%pQ$0G3#)hFX|E>GmQ<7XORMML`CPRQ&lOd9c&@BkkLS87 z2G7-1WWrvo+=XYxK{DQ#DwpEM*R@C70>j8DR^2A z5Nu~~goY1tc04(b(B}{#=V3z4_XwZq$-4wv8K0y`(H*zqkG6zIbw5n_NdMi$ZzX&y zaYe#X!{)^I5`U+EOuyLRGt4(ohHLS^NqjuvlJ2-M-na^T`P2Gy@pd6Ni#rup7WWFRrGFOpS8>l! zuTfv8zDzBPGbroh<|uza{iE_S5JyR6kaIL)ELkpl(oqpw3ah zq;{%jtM#g8)kmsq)oPVV!)RVm|4jW|&7&IPI~n^oolcsmbRTW@^$sn-MvSj3byyTf zQ|Y8-!MF9tJQr$52L{Bw)tgu$O;0l>hiQxA$ZR^v8LW4-jjy~AsKh!j#|!u>TyyB8#quU19a!l|>nEzkNNd$e$Kf8j z!e8V9V;vhut+bN2x6IRc7JF*GqD%^@<`Ft+P5>+EU=`Jm(n+bol8zIgmDmTXsCtM_ zN)8mchno1N-qE4sic0Bg&w+k-XANK9qo|Nh{kqM*lh*-CQ7&}M_cZW_MizK#uJDIz zyd|7(=#-*NTH?NW+cS8R?`p@7qEuSqsqW%CU7osXzO7nuNLEr-#h<(2DXSVCs8Jl0 zmhknp-r=k6V<$bXgNg&v5?|{zciT<=dlp z%2#q6v+Zdb{PM#fWuT02tiX@wz!j8zEG-xvIz}d}_B7gk1j-}_TDXt)pf1WjlvWpC zc`lUjZ37=XMkl2Os;}O#X|srj*!%mkRsdgmTP)s>S(z1RwRYLsSH;)w$?6}g938$c zBK5Acz*pYj>+cZ@_B}u+JrV#UZ2B#Gg}NSr4huZhSK(*zwBB$Z?ktuS2<6`L%Y4PH zB9Jzf3bYUk&<-sudnPI|zcWz@TR2e(Qy`35)(^ZCmi(}<+1+7ZGkIZOn|2A)76RM( zcDT2W+;DI0JHx%T?FjeQx;@-mOHR1A=568Lvf1I@GFxZRNwb49AEHvBhR-fv>!lAMkhns?WZ1}o5LU#;3p~Tk?&e#geLeih!O?+g z)tR5f|5P#aVRF)R7Buq=r9XgTS^Mg$6}mcOyYeO76%;-hw#VmkRgIf&4l+955BHS=4Or&;uAEVnM}``uY4or4J`gdJbkT~NBcV62Wt6>67T66B{8>+ zDRgqiShHa4^)3NnxPWzflFXL6r_7k+tcj3c4Lpg^FJ z1d8z&d%#r^E%Q8j)>28o7>DO$-#4`%Dh0HEH zhn{7Z%m9?fXy0YN<2ptSx{=>oPtjk~?@~OOOsByv3t=u_`x(Bb6l|u=EYoftQIh?Q zQ<&AU@w+P;MhCBgsR7V^>b836ZMCaT^&{1vqAnA{0eo4jyO{)Lzz#6PmH&V`Pd!G@ znj^uHZykmn7j0qsc~nRh20q3{e8=!;f2k-%Y3|PRM2DR_Iy!Vp$>_hTFq-Mqb%g!V z6948rNvF*lH?B>at?OP|zhY&|#!YX$xKfu|gqjaOMyG-TQn`UC2&Up){i??duP6)_ zI{7t`k5GO2TzZyMG97&F5%0hiQT{W1gNNKLjePkzb$*NLA5r`9kcsddfQ4D@sqge0 zKjc0FCahk)dUaeTYR-Owp2bMWfqf4VUp!CU5G^|8uME|K+L)h4PlH%&Uf^q~;5&|Z zM@rM&-Sy(Ux{uXCGf3n?^Xa$MTMa)^%t@h>%t~)dou{&8f%u;^UuTp1`jOGTqn;x* z@t5Nk0*&MlqI-n>i0|qUc10uK7f+-VvJ0iRfK#T%03dAT7qd<%TF$%;e5Tn5V zbP6mr(5dF-h_?x+ZE=j&YGzHWCC$X7F}4)OvJj`1Sc|0GY|Yq~yT4F4Je6L!v(T=m zlg*15){bMjrgR*}X3c2~n`W}7-~gN1zL2p5%QA{^EO)G7V&sM_$v!7{N+oG2#^muBx=OoA8Yx#YWz#iSkZb*zt{1fIn?F+6fOj17UO zn+%@yZs6HAY60(^2;*fYh9`VY>ff%k=7N=5K zhjXq{QZHQ3q#k;9QsB0wLAsAakQ`|Dv#`iB;$R5dko`YC`j7pKQ6NTv7zJV!h*2O$ zffxm16o^qEMu8XwVibr`AVz^dU<$;OvBmcPf50;w8(NG4F$%;e5Tihh0x=52C=jDS zi~=zV#3&G>K#T&o27nMDw*QZ@LW}}23dAT7qd<%TF$%;e5Tihh0x=52C=jDSi~@hq z6o|$D|DdNgHn0NMZ3RJ9`U8BMM#9>2u?{lB6>*@v_yX@G zF3iXXBq>2ElZ6%&%VzA|R+zz>o#_q+nMs^BytLY8`zzx$W45HT7UVr)Gq!EbMQW1t zqWtviow@m0y9>7F=H;Yk7wpd1@ZzS;84mxy43@QIm`SP#*2XxQ3?_ZId9Nb?l1XQr z)^vtp(pf9B5dU?WGK!0~1Co&QB*SDfSu*8K04kkj%;^?$x`SOvddbMoc{eY2pTEh@ zyrK-Nm@!4#lN5O-I^=;%2=cl4+j8C$2Cy_R0x8@mi4qmuH(86xxzJ&9*cX}|Hu4(_ z0+~$A!i723EemZn#xxt**kLi*GYX1}(=p*$xmyd~8=G>ogj{y3#VJ8x zX>N95?zY9|xvy;6xR|lo99E}=wX<`#?7lD8o**itp zPLtCq{sum0Bm<`peKC%RU*$}x_?e>;Kcw1`$zK%0VxEGqSjG#BWaLv|KC@*q=9>ag zi+wVn;W?T$ZJB^wfn`uNIV?^oyGG4m=DTMvk$b_s5+dIPdod21guUV_Hz)~vHL9fS z#YV+m3}cnC*Az4vbnh4qq28?_>isi=B+%vRKMEmWryvC8@j@^K|^ zJIxlX;8yDdDkx;dG)oW&w_=(cj?a6=WT&!XvSFs+E>s%Jnj`~PmM^1-N~_D&Neosd zI+bQ(@2N_&I!vMZCmQpU9j{D2qZmQYN=Ouj+*1%E^Q0Vq_du<%iS9k77WUo)wPOo& z&oOl}lTK7nE-b{9Bv$;yrX<;rjT!Oc0uqhc%S=UxnJ`=xM0RqsSB@*$|EDNkQW)!v zvkcb_EA)S@-=6qyiPedZC3Ge%iT{iEw{*YM9nekFp3_=2U(;l36zVp$Q}sR79@PW% zHTvbaU&K|%r2>FL@dEx|y2Y3+^-;#R=U4rDIeS&);T`(E}=88o;=;LCt>#GY=qEkp)Q z$gbd&*q)QWW9Qzi{2lM+wxJoj^S2A==~~`$ zZ4mmHCGBINW=ehJ> z<$6IrjM0IbsrC_G=<45cJs;9VU&&Ov2rqPXd9Ib3w8eTZPU*dQ&U2{8*L2={`Yd02 zWkJZ_DW0oWS(C4|jPM$Xu?R|wBo8)OSR3&dm>iioR#T2?d$x4# z)Yay>Rz%+&X3MlWaz*^IXr~MR(RHx&tvyc8e*~!CJPn&g|{d?ke(JOYfpP%jDfLASSFnQ>N4DV7EGR zWOG-Z=UQ?X-I*uv&V+q}3H@c}WZM~wbE`u-y0Sdi;=AaMjiNimU7R+I&V&sI>##{( zh`Q1|*E4s~9W!Zn#PngDX4aC)+AZ6h4(znXb}_m`d9Fow(cR=)1?Fc4<8WGSnO3KD z>o%)JHg^Z}TnnS`&NR7JVKH~GEg5H~#c8)~-wq`s8QpIc%@?7@2=x%Zuhno!D zF;-_Lf=Ui^c8;vOFXy>zchTMCGR_cRj?IqlEZH`z)nt|t^W$AEtI!=4&0=Q?FXPU@ zT8D6_8H2Og9i~jsaVs`~G9mbAm&QU2unC~)c(w6JF z@nidRa3suHZVE5tVLHT8ZnxQNR#{X+_kmt_LJ_B!rilBRVp`&t@rOcDZc-BixNf;L zQemC%w@xDmq8Y?0CyGSdq6_BALKRlKEi@861^4-6Afs^=+Q+*Jr+|qp?jQ_qOeNj3 zxWhznCwI5lCJMp9SvVGgW9?FNFt8JsK)-u;qzyr6sodQYpmr0iScx7MfJWn%vldRp zFJ~UHz(xc;cIlGLel+Vp;RO^~BrEg`s@H|B2#7O@CB{sACU7d281_-vEXqCUlb;E+hv@Za^rUkNdXk0ZB0CP}bXZsi zYcrcN8FGHjV#D7PaEdgx?_eF1#r7=@b3{eSI?bP}qJ$kbj+y16a`*CQvwRLf$w{qo zn1+a5*~c1UxYTAz8Qd17;bOk0TMZa4=DTNbL?LA|5e))z+Vs1ufe5JnGs z>eV)tZAS2vw`9e=s})A-!qkxXe_Y%`MPj+85&wz(i%}p(fv6}@u{oYBT@Ck3mo8^i zOBch~CtSLs+?C2)TCmORAxoEZqdP@&FBD`H+j!>`Rzvufi9bWOib}DMk{~kAnm`cA zG8Zt)rEsU@Rv?591DAXkV|Aw6%<1r^-~$6j_H7KDqM>GjM0ZcH@G$cA-ojdOhzEOq zSkw-jfyEIhb2Nul9cI&H1}*lU5f^;ciO)VJ{=DNeFZd+ZEFo%Ot|TOyia{F&Xf#W* zb1F-+GYrmmu_Uu*DO1H)zM~_GrSS!+VsS*JSXi^=-YOOo6T0b>icplIDc4ozao?6n zK~70mMaFVUAje}Fh5B=Zs6XkzrlfAjz{02-DcmUMK&~DqfGZKX@LDPK3_YTOHte*8 zZ~quG)Dr-kquGX7?2~CF1gauxrAaFRW5Ih{5mk6FVUj3NjZN-ljR3^1ZHKO{l>MzuV>I3Qy#jh1V zR@YMrs#fYn^{}dwny38RxX0tv%0E-SMV(V+sZ!~mD{GYd>6cWW(oa$E(`V@q}$_ zq#xD)k@AwhLI1Y?dHs`mZ6cre^~CnX!o*h+=O=t6VROQwgxLw2_{;Gh#XqR~jqY2z zF5MyBYq~V;Z?)gip4EP+eO3E}=69MOY5qvlt~r1&6kgV(X^iS$s=tG6+;n={9HnLL z0{-x2{_v5};YRO)Yw?c--_|zst;4>9!+hU?_@tTiG%Km=?mg+PuJ>FR<7nS7?`ri7*7K!( zVtdcEJHC=iM*Gww^z`{cOYiV`@9^-7HQozlzB3J0ZR!Li7VX>#O3d0h6O^#pCnqRj zw6h-+E?=YsukJ?X3@zgTqC|*fK#e0Uw+DW{%8QAX6Qb8`XfT~b(=Q7Q7}vUV35Kr zgY&j4)}VjSz!}eQgJ-bKeWTfXsKL{50_4`tm_biZ4K#f&uONHZhO9ls`?U|r-skSv zfzQ@A6clQwhm03E@;&wL=3Ck)f-Sri1hhzRi*{Dn_hxNM*!Qe9IqZ8z`}o*jtae^N<3OE^_EkZ_Ob@;p=pG%of;SHu>1mG;{X(t^VQlf!q<=fs z#y=qa8};vxG(YY`CyCN&tMs*>;;;2-S?JGAVxwa}kn{P@R%3b*AB5rmTC@iSBCVO*bYQ?!S)rLflTL<03h0qw1y==5%W7=lOGgLJVYnL8Y&zL0ZHwW75`29J`Dwf8 zag}L~+)pRpFRi1w^*EgjB^>B+ZB~A9?yj_#_H56|E7-ALQ}rmFJbSG8g`9#FSsQcn z_GPWnls!Qwn;Ue5hz}fW}p_CwQDS$yir*-60cruA{DKUcP)(4ETK-NmKY}l@YP}V;q_QGBOm|x=>hrZX+?^c+ z!{1ryjcUy(8yawdLg5hhuNWlI!JXnxxwC^(5)?G8;N8sP&v%O*sxYB*|GGBU#A3CYg zhQe{Tm3Z#d5#o%Li|Fxpx*%2>%{Vv$BSXu021Yc!J5|ZtVkvb*i5FLH%#f$~26@9( zgZVK4@@C+S?@Sx0#^3H0-;54akM`BM4~=+7+WmEgj`3K4Tl;)mIo_;Vp~(xSlGqP{ zCoqY3C;cJ?GX9+i9gaR*=qZ;4c zPv-OH?I7yA#?98~&^f4bunh0II<>hWtxk4eoczd5agITw{7}(CEnitBc#A)GobPGi zTTcKfjVhG42(Zpd%qS_PL#G_2L^TXvC1O@q>ps>!I#|b75@A;VK9r$R88id&ytl6t z?4WWFULZC9N#5ym1zTUp-IG_8w!Yxqto@oV%k`)evkJt?f&i8gC-btL0j#JZPT97% zHIKN@aKBHeU}Mq4xjpT zs8YkF)5+Kt1UP3B%T@gk@}7xVEaDb0i-CWgjZS`30urAAi^a!!YrYt$rg_*zC%+T|n7abl;~@H}yjgB05RlMOBBzQ~(C_=Hbh1SI z_$!SLUzZXc_1=>&Or#$9s!p)(vAh5cX#+u&XFNqG!;}mXS8PJmBzHxuEN(9}4?RsM zOXSxNJBTZ$D?ne(1LM*4_bb_90NwraC5M2-N0}n|`LjJ@n}Bk`299s!&?+~LPF^j? z7`lLHJCV@-Es&^KG@BSY8RoZid_?+$-5_CG7}dP%0(ODI-h{~GtMQ5-DxO#LD-^#{ zHRGH97wBJ5Z%}6ST4QyQpG zsXwRAQy)-UC}>>y!5D(BG2&N0A5Ckd)nWMBu#ObFW}XLX^LV1r`ihYCB}Ln^i9 zVV%IXDllPWvcj24s4L=uKCmXhZU9dBT~r(X(uj*7SgG(;bT&iY+2v;b96^_$=c;j^ zCWc9HB_ep9yX+k%%P*;b)k-i}$nQP%-YP;8&3d_{pbVPccl?gK_W(f_zZ~uSX~}s~ z_0e!u$y!{|LnO-uOQnRb7(`X|zZU}6buwJtw_1sq+-Y|=6P1sSe64qgDb-euC0Bgo zk&Z`-uInnW7wfoNj(aYkIf3Brt{ok?hTk>oveBW$)*kIUh=~k{BdJ?g4? zmSSJ~84wJ_;4irF;|F^1ItB&vgS>C-zz^PI1=Kj@3Kd7@5g zBbWm4M59P^OwPWf(t&>L!`wYLpzPn26Pb`Spe%Al-53ym&2+i?{-ng^E#a`-3vB*L z35Mxc9RZ%+Xr_~2l}?IFbUKO6&|<}!acy3H9fXybPpII#G~{da&jw%H=&2){2E6Cb zUGm=P7k~Hljrdx*vG;-v=&h}Utqly}SkbJJZ>!MWTixqxJtXc(HG}Fp#q=>;u~YM5 zaO067oeIE15R)P>+TRYVQAEZwcsR&zV^XkMPIWSv&%RY2!yfQptzc{7K3E0B_^vZR zM*W*ykXEvsp_aS70~`Z8imw}VS9iFrf%edZz%_nkcfu_T)cVdIV_Ue_?h8f-i! z6=%*9yRP;&fBG2uf$G?|13gK0bfl-xCJ$sp*bcT4M-b5Bhf2_shMYeu8yhwZLr>F1 zxKgpJ0D|tL{rpfpqyS^moRv#~yY!5^p**0 zzu|4aMR0m%Bj8R854WUlw7-I{hvD3Takx9r@nyHYrwKs?Di45Se0?+DGmPQ7OWHld zWZ#2XefwcLIava- zve3z|je)|J+}qWIY4Wv|c+Yd#AB^^wK7}0;_Po7AkR`06^E8GxFeV8C{Lrb<{*wTW z-8yk|UmD05?HeFFz#c9`Eg zU(4~OSNI|S^5{Ntl&>iTiQzsVIJ_8wgD`Y=U4^^-pysWYF><4XUR~vU7kICVuRTb1 zguN%xg|Ioez@Mo03|!`ik9aDvYp(L#xZ(jp1<%N6-=OczF<^zcd{@queCK)SfuJ~; z<>J71ws>PcgTQ>n6>J%$Rx<{o{^cS%IY)wP$1u9YP97def{>ptW7T=?U%&u&_$3W6gu|U5r=_7PhdF6)CTIU9RuRo^$vTnX1ML@0~lE z3nAo2Sf{1bzpPqAh|}8YzIj_L!-|krD z6iV!%FrJ=4tlVuxQX%hUm42ZCE5R=}P)6Jw*rs<@iVKnGZrL3|j*50TlSCfWoCsG2 z9>9<^Cqq^|Q5i{%5K#?d>fBXV;GXu}f!C)CkUiByB4Ti?VDe?sTy_nkL>>3ROP*mO zyI|a6`L0gd5hw*kDDu7L`7NMVszf>j^(c+S5nSY|0dGREAmr(5^xkO@_aLG@1uXWw z4d@a#?RYfo5WG)`!U+W#wp)>m7$GkoGrB60o1XrjumnlyrMWG4$cOm$@gu6 znxF%yiy^E3L#{wj0eb?%8f`+EWjt)fR%UT82Db~xn&Oc#?YB}_^SI*z4%V5TCg}lyLg%f=lMT|&_j?ew8x?d zk;)Ic3I$L~g*wb)WPKjX$&knqAVsKbk$VL7o8XMETH(v3d zicN~YQYe3k9rua2k+?%~*>UM{M*0+8Md#D&>0~-CZd7|j`;m5wmendXf1^38$<;ik zd0IW9KCS*hy;40_txE4?h937?oOYL>#2IYg)KTzMIu2P4oJn9+hVa0#y3*mE^r%z1$B=K8` zZK?t}&xjl;`dYxBO}EK5QV2q85)}&SloEj_@R0X(4dP2x-kMwd*<0$5X4A9G@)ErE z4D_b+6~{dF2RtXwsz1!2XRVdh5ex!BtBb}hEZcP7;ge(|Sk|L{bPhesF0Eg2#oK)Y z#*OFvAXzPjO7OdSRq-Ukd%FEo9)#Ggd#ifS$Ed+Lu@#6@*ZcTnm%^ zfZ#qM5t_jZp21E}>kaqePR$|t_Ukk38{|3yyT;MJqp-jHhD3(k%yrjY^wzqFJ2|jB z$i(mX@ietTZHPW*_0Q#s$z636PDb(I0dC?te^l*RNGE5HiL}3hpi`i|_;VNF^5I?m z^Rdc`KklI`z9VEms<~gTwA_`A{Ou0!omL-Cf?U76Vhs!Un!_Q3f;+3D0)!-cfx*j~ zbMgh(zf*?q=3t$gmwThdc&8X9%H)r9K$Un$TFCB0@PKJrlj-C%$w(woC9+Uyj*jaJ z5d2Z6o73rJ9N!4I!o;pL-SQv{dF$VfX>im+8kZ5p94a!|NhfEG0g^iY-~p5`%`R*T z+(&K*al8i28*($$gGl(<6W+>enEjwBy+BTJgu=kd;BCTlRo!HzXll`P$#pn%4(2-u z;wd?|k|j(q_}#5H@H>gvVXrSbBe%!}fK(N{em*$5I$h|~*W3kJ(VUU0>fg}zgB^u5(uvTwcL-2R-;4b`HO97-jU1hY8aHnbET<} zlhS>?hi^a6_YCo+)$2BEN<$1JcXz9}ks9wUl=}UM#tXPI-N!lv`GN{2ktocd_fVg> zMnm+Vqi{luh}v2?y9G`yseSS-4uX#W;Tb9QmX%=F4GS3h5r&LQ&Xqwggw%K?wu-QS zgo*?lC}q;|Qu+QQq@_5?VoM0Lx3`S6c~;J1V{MKfA~OP;{M=>!0CBZy`sG`hU{%!f z4V-toxY0Xh5OThw8MR?CyfXo4)c4*v3Cd#lU`YacNr*ZKcwW*76N4#Fhmf?b1o90D z{zAx{H+T3>UJ_L>C~1+Gq6jmDEhFE025slbheJy1yYWMY)6_CLT#Fb#JPSZi^ycg3 zGVg0EcOM?|40Pj^9@O-TJq7RPtKD+7D*sQw;!goV+Q660LwbbG+bkVB`yPObC z2+@c}7oobaq0(#!=~fVT(e4+wFc=Ce*L}Y7I^w`P--4pYLogEJI-n59pqUc_S|}6! zV}WH#(-J~MY+kWE3&#jR;YPXE@geGW#O3QdOK4bL=We*TieUmug+jhjKqS{IVqI(RP_QF9qIFd*{>1lCTJ<2pHmukV*6ccC0<*OqA!?9nEpM z>Vw_wzIGZhb*MQ09Co{!db#pKP!^L+pa>`SG}}Tv|NfxuNGX4=T=d&@mE$}L#*5** zhr8VUBfwHrXM`Z*e06w9oD=;wh(FFn0{H4r$DtrOjA_&4ghe4RSpq!24dBN@(5SxV zYu@g_*^0VW=){075HP*g0;|t=xeVTRw9+`_MseUg=y+r`I=KW%YGSt|-Rb*}bs6Pc z;Jta%d*lv&2yu)8S_?6qxlvt3kU=m9gHZG(|Q}P&{Eb$D8*!s_dYO*ITG;6j_T*zp$Lg*$r zW~%v;TyTjE3hA#p#UDP(A35#2)8adO3_qHca`_TX4(wtHj)GqlXc^VfIZP8S|iH+%OiPqKpIYgH8W@Hc&C?{v*-Bm$CW)xA_|i^j8_g>rv01UU zXibU=4#Ofg1FW6FOCs*RMr5IKg^bw(2}7hZ8hWD)FYA050b!WFS+ z$lgPJs)Oyq;iAcqIPQ`0vNx zi9Z+rZv4yf_V{VK|Iq!Zu1D9RE7iTNdr4>3J*@q`_7m+lv|ZW;?LO_B+GX0A+BnS* zahAVX^R8yI<{8Zs8d~jEe?#4+Zc@LmehdDFRJBg^Gu5|M*HtdnK6o6SQ9Ys3(m$jB zjJ`l0qPNj&Xfquj_fK)(jq8s)gX{$F#%+mvHg1OU_sUO{-&9^z9#+1m+^BRa)zn{6 z1Jp@sKlLTbL5>vM-9PGz(k+}*U*Nsb?y0zqL#cdSDf=ew$uT{R`*%%S6!nkNNvUCL zDNfI!lNN_7Vx$1-CIY}HPCY^=%?Ss9`Z7Z&y(%wRx9oM`=7DRXpM2FYI@~6*0)Mm( zXKbmbSUTyoa4pg%YNBwB?_TUgaq>wzX;BbZZ<(j@ED6z6lt~9xBWo_HL^X{s5xf zyXrd4R~-Iy2+^e`$gQ{Pz$aW6KXL^hC(wT*!|B3VAS51623ZwE-gk-c`+cq&`@j$71f8SMHtzO|D?*E)u% z)}dt z-x#D)WC$HN>OI(IwwkCFGRP%Rgcm^xU&|RPHw>|oBkC;Jhp9FhVJ- z_m*%Ug-9GnPz z$51}tE$#OnsDbXq2u)O~j6ud#Q2bUZjGikU*iG;q@a2vkbP+XL8MaK!KONbPNfK}j|hp}}L(iALW6ena-+E(qZs3*R0VIx7Umvz>3 z6V|ji#nc8FL}A*!UHJOyEUV}XX+-q1P^7pXrjbBAr{ZrXDzYoSn?xtg3r?=smC%Z1 z72lhv8LPNDQ4yoKB3%tU4Y%+^y(!hQp1Nvc5Z8B8dt`&Dxq<_Y@EZ7rPEmU4s_&^j zG&;z++k4=Ha38$x5Ah1#E%y;@h^l#4Gc{k_=EqROD|mNI@%D`-%n` z8j?DSYN=gA)~fm@zVAFNeXtswtyurS0gC@zKqsvY(om?i9u@+Lm5i%QEs%94xIp>R zt9*B(;(y6Xa0(8gS=R|z)rx-E*n|?8(Ta+BbkfRTzj%GP6OKHbDoSH5tMJW{@V#Lz zjx17IDQL(nf06TB4c$`vMl2EeT58|aj&Ckjq8g;^BQ{^L+|R`}Db`pWafl3|4n?I5 zSYIDxLKI@ELta9>R^nVyo25z(iwjwN1c8BcGK%j!NGBx)=pdGw6<-_wl2!cC_?L`g zIHX&^6eBUzi&F8$5qNh?4?K$Q&a*h2N9~XePq0bA*%T#R^Ma-d%nlJIl%3)eDOaJ2 zXYeMzE&(%Sld@k#|bQR8g5XXJG0fz{w88SqB zPr6~i-)?uGgv+~`GD_96$QHgc2ZHodw8+MPsfGBr1>LF`kPYz+heJZJVyJAXg!?-& z$Yv-&Byk2=>S%;ghB_kaCeT*VE5i$~Pc-}4!6_SV`yIGGKwt#_Oz9@-Az3p?p~5Sp zyWpP{*9H+yKNl)wbjMNNj$ueUfiDQ7r@PDJIw&rE6h4GaniZU*mg8{CZ_eG9OMOwQ z5y-5bJd=hX1HSJ-SW)!L6BS4fO0`haW#kkpD?D@Qq@_W?$4(M1IeZYy*k&0g{aUIf z(GPxr8CFwql_gG)(A@~2O=}txBdhOe)4^@lk zf2BKd)_;23cjC&GHtJuf^%OwyqOV zU1sEzrxK9d`w+bDAd1wC$YvzD?_g;P`BE02lKL^o%fBRKN1dc&s8 zqU1z{DK2*xu3g&8J@J?(X_o##@_2Aj0b-F!UYb53@)f_h2>dQ;Gpu+w)ShKYYNU4v zj+l%!+UyQy@ygYA4y=DvgULNq6c{It`+IJj5l<>cHBw|El;JL!U0j(jB)k`|%y%LM zq>z16%-W7J{E}e{{Du2+ke-J%;Zp9gn{Sq8??k$A*Z ziISY+E&c_|A66&LB!JF!5urmA1U^d3+US6=;+#CZW`;Ux{uq$utCmZzu80a2l7|WN zJ7dj5p|JR_Tl_%hU5FQJ7Ww?4HPgqz5}jFs*%KXJW>LbXKl`8>m#hT|wR|PiLR1hK zhltICOQ#VCIRR1=2+<`!c8YT~t#sD|B+*K>>~?P^x?7Ks^;9N5lifgwdxGT`6-xwe zf;*=|ZXCwF*G`j}TxFPMvzx6*Gv=J&PAb`j+7^@aa=USPM3D)KwMR~t%{rOS^Zr36 z5R@v9FxTtc{XIiYk~d7Ek?s-D$uHCnd(RMfYTMmkWzT%pn}#fmgaQwgXWdV@y?#zm zV1zp>qLVqxJx)^MMA{6wJbdOm^$1AG5)_zmDcmXD0XPBNN#)nHHRJ|SEAq-Yt#)fB ztPHG2NPrv7RecTyS7u4ZHU7qMD{EyUUe#wZJE9k0EV5$4oP}AY?F$)Zp>v8WtW|bZ zYhXGiB^!ekJ^WRBGPTCY(n$-@qq%C2!Ij^ZT^S5+a3%lls@-@AmJB9n5(hF2O`NP8 zSz{y<8ip`;1IsFfb$@xreM0K6WilDJMkV7g)MYE0RB)oa~W#km@NXJdD*e#{MxBvZ&Z3TPx z@6AAl6_}sq0EdUK117UNskh@>l!l}<{lrJQyX91j1^v*+jqSG{(if|IVSl`dg0E(rEuZ+>rqRWaCRA$c-KjU zf83Ra5$}l95$kl=;YgwimvT0B(mV+tN|`-ixP+Bkm{AxlRj`D!%2609A?M4R&fzB# z3dj=RV4Zd<|5?sLP#7b$1O+ytz}YQMAi+?(mvCko4u1E%5ax`81JW5dS*xAOTfwpF zBxVc;1QkP$X+#2JM+zdqp>{3hOcRP`z^@UOm;%?bHY#@smmwR8H1rk;1tHs))k5uD z!llaqc)Q0={6qr4T7ZMoMD19@rO5#ZLM&1=5`ci@ZePkRkP$%|D~Tw0X2xlO_)s}Z zx%m@9h`3_0b}Mp2TB&VIxTj@<5To^Cye85haFPcZBP>+*5^kOh0Qn9yaC|8e0H+mP z4FFr0a8Jnqh=*pxvjLF+m`TP|)K{u9!Kt4npE_aMlrs41}F-tHt7gSxc>dkwbi9nWS<3G0z3u zFf|}DjpTetBmn}Y8KQ#Mt>O@(a7w@lhjjz60%vg|f?}Pl1(WvTDh{y<2`FD%t^3pv z1_y02cC057C9V%DtU?w27YwQ!?DDq!ob-o)LfPI^th zE?{g*mBoZ-m?I6B82r?#Rh*IVR&cCRB_=)S9SM@C4_{c#83?HG`Y>9$iK_AW)tp|o z&6wa2QY5Tw48qJ1!_`=EYn)&?THV)z~( zg!)Ppio}H|JH0wkCf>d$#`*odP7=9htTJC8q88?KD_gu(u=R8Ew-*pAAAX(Uf?YZJ zi*Z?^88=(nvvP{|c&TtwpB#Gp=`y=8L1()sESx6u*Ey~%mFE=}@Z?9gqaTPTE z#+;&}+=6_Bx?g$40;>fyhFqGQjM-vmkXY2o*u$lGxm#RpPOCK0%e}<~$%hugSYQZI zn1u^-0!IZVB8=6J7|mp1xe#JI{|6C!GF<+L5gR9OCL#7+L>gd~OL%%;g+}n?)Fb@< zKl*slzMO)>^z3YMLL@(9XI@c;W$mgJ8HIUS`}1;(ie=G>$m(UvCr!*2sQ}&s^=jN0oY8O5KbrVAiANG&PK;0ZI&S!1 zLR;c*#qWtX>3q1c?^Rub_Kx;_dNchnat0iVvnl^sc}4lQ@=@v=i2rY(rlH%Ae@^as z5)mE?g9#Dgi19D0&4GA>g(`{v_qcp`SAuOP`tZ!J`NF#K0)UNvlKs zOR~@RxjVRypL~5=IvfciD|(r3tmF0*h#@{T8ARdBX7LVzNDu{Q+Vv&ed$NdzcoIVl z3q@)j2nbzU!M!VsQ6kVA@?mWxFb=cBWH&je-eufA`5B2ujz4#UBrCdf3?Fhug5k7S zO-?wSd)9J$)k#aoW|@3Q6!v?gh|sJ!M-9Jm_ZqI4_y&VKr`=|?!mUc}UBNAq zNvE50xl3?gDEVwx{3<;X7>C1Vci?PK@e*#K3=g;D8`MYuELMw?u{o)tC7e?RfPB#y z_;@-J07SP<Mm9>3QN@Mk?@Fkehgm_ zAZpA~hnI1$O-vATM1nXlw-%foZFrX3EIUKy7f1iS6cK4^!HFT(Nx4>VugVyNKiQA_ zUHPU{d~?I(2ZyYP#@k`c)Gy;UO*|SV;we^(&CK8+8CAEG+c+VUMLb64fDL3pShMz7 z?iGSXFx)C*GA81@u&mjNm8Rxd?qwMWkp@Ih2Tw~(bN~bdg;t@epW`;j*dz2FhDh^b zwGu=as%jbcl8m6R#BjSU77KBXBf-G21gizRgUVIhdReF)moJSD-~w%uG8|yU5k*`A zvG52hSj94KoeUk>0&KHILdR-#Fyyph`7-WB84TQeF1^ev5)7+dIq)3!f{eSQ5OAC);wp@T?f8I`r8x5a|6|%06~^1f zeMZ*s3&VBX_?M>l>D%>h=+%k+iSH$*B>Zi{iG zF!nD-ffxm16o^qEMu8Xw{=cTc8t!A+el_NW7Y~feeC9DPe9Q}fPrUGj6YV~o77OlF zaZ*>8aqq~sNFg`oM%p4_D{rx5t9Ip8u27w{QQ{O6ZZKsnWEa|e3s-aE;yv7#D7vPQ z#11!qMucm@x4ZCdU0%W!$Q+R52tfN8T)~eVMv(yEdr9nSE!3qoT)s@%h&MOGiHKVV z{WrQvZv_e)^0QeiP6wQ07dLRbNvtavYKVL#TqOMP6`9j%c2XCXad|T0`zaKN#zcaF z5R=ntu~O$(bGyhGgS$%+hImIEKT-=fAo7snTEj@dSd$GO-BTUQxVPo_AS=hUJHhZ$ zBoJ1o&1AROsB_D>Tp5gzOBEx*08tzkGeezS%Izc*AN&r*ExB(n5&#D0d`$@WQfD08 z4q1p*ye%+NTZaWcKf8%Ky^Px~8vw4w$9GZ4wSy!H?rZ&#U^wB!w+%>+%`G)mtOR8HJ%!h`Y93sauFIXPoPdb&t(%|b&xaQ zq84xX4o)cKG7==G@Z~4fPVWEzf^sdn|NooDZex|P5V!v);P(IT8F~yy39PzTN76$&QJI`z8)A#IFs;k!j6PB38sW; z@&6Ui$NyP;M|?&6JMpg}o8P>6jqdMsw{$hSFDduw616|jp4R4T7ikkTKhkt*sx+@@ zo>c!{{T=lwb&>jcb+YQ8RbN#dQDv%Fm5Tm8eTDv*emQP5t}pII<=VK%aGKz&$`i`R zslTOqs6)8FpP>wjZ>x~b?=O`kj)A=DLb~Dw2w0MAM?&IOkOnFXIqaYZ$=7g$BtJHi zgyM2q-@yj=fJ?Rf2|5)w%*y}_o$?^HUF`_+pdc56>gWPG71vD4s@z7}+-~oUb7{!N zz_*?PJTcjcs$dSC%7j$zt@fS1g&w>eA&~qC6R!FCe@HY}iy4x>;o%rF) zsufl`6)Yyh>_VHTuF`kxdKzCb=({ZBO%>7xzG-`!PQ|_dvdXo{s(d}=r=_P-5X~l8 zQ-uuFs;jAVs#RWfbfC_Cv>ZP|ZQqq9tOlx!bLmvGydLj5ff;5_{cjnQlxJq7z=2+#{JDyvOB#BjXt7=aMor=qX zC#Wf0rc9Cyb@yY!A^57IU8+=MNtZVe^T7gUX`eK`6G@5k88XzW9AWrC(iOoWkfT;* z&jVhe3^uOvy~!l2vW1xo!ks;%Lr6PVp5{e1u5+!aW@>ZwU9 zmwQM0$;p!=HL8p-0w}|zw9;F3SjA2PQ%t5ymZqU&s(F)D7E$j2p-(P?cuo1Sd|h6xLDuQc9P_HI@axL?kDQE?vg4w%;?0*WSuCjBynHv ztm<)=PQ_=)GCkn0HbGib)tm{NAT=0C2!uRmLW*#2cL#JLa=5DI&Zbk5ydg|4eEm5w zfs<$h3qYbWNxXKx4B8ifv1b5Mo`Y4smI~x*tJab@|gJATadX#wRk+^Vs-PJI!d06=hLu)^NrV3HQ@jvD`f{@;$HbQ zPzxy|`L0TpYZje~oCZ=V7wyc+DTLL5yc>M!4b>~sE4Rfcm*Sh!o3VX^b@(Bf)CS6^ zHL{X{M&$VNj@aOzi4pXnoP>~z=3SI_Eawmi0tgM;*wt0n5HfpRT zNCR}iMLjP~wGjTBY(=B2N6B~F6eBA+HZqDNbYjMx*JRx_cOfAjri?0FOegIQd?Jlp zWzu7hpAJ>HyX*Oei^xKYOp9P7FSK79Z!;%40a;SX{FAFeQ%-8 zgne(Okal$J3i==%?Ciq6XQ-1>Y`r6`eEA^s4>%n;k*ErJp)75Y;+ImYc!#?^*N@`j zeVCWj2hv0o;spg0B%;vCI*^}{Qv6h!sDK=xDnBSHAu$$AB}s4Q595rK9N<;_>m+q0 zj!VVA+3BRL04GVmiuWHWkR}?Fw4>%pC0W`|`ZawlZQ6nfE)G-N`?P6f|G$fxub{8f zAJL0wW85ck!*MR^Q)LQO6SrGg7`Gr!Yy4AVh4G8V=Zr~)e>QwWxzcdP@UdaN;W7Ou z`g8jC^>67{>Yv6Pfxk-pLE@dnvxybR2>42(BXMS;GQpGZt%Tl$qX{1*yp^yr;pv3? z;(s0g!}t+o1gwnDkKY*Yh@Tm+)OmH^)?L#z>ps+F>7Lik*WIW6wf2YFKhkz+tF#5$ zO z9sLvPHEKSk#a)B{K4DNMjt{PR)S%)}@Q(&;o)(Zym&C)_19?Tp9MzfeTdrUgvbXFy z4olQs;o_@Ks?J*IRNNXNT~Fa`^OaQkPB!{eF^U!gYP4PxQZYWST9ZzvBI%s85!PSN znG5cgiy26(I@&kvJ9AXnAG_OHRX5CZDh}sMtK(>($8}k#0bd2Nayu(w^^k09$g|mh zL)B}dQ(us`5giLc8zj{Y@j9rG>?Sp1!Upb}UEc0iRoD2Pzq`GT9~=;%655Oa`4WOa z=XlE{Xk!Sq1+znS={Y)em%Q8m%if!S$5CASqnhrX(R7byhOh?AA_2yL8KYUWVQj}6 zV2o|R#^6f`7;L~SHrQq-i8QkI-IlH0vSh86wcFM%kv%LSfe->o$O7t~8M2U&JvYny zRo6)Bu9+U^eee6fm;0`B{rQ?XwVtjzb?VePzk|6UjVJ!7#fZ|kZ%Wx$CXWotc}+wg ztRZ(fqHd0MDOFkK_DJ0e*}>H-zyY-hBpoIiAyN-RGi{5aeNS{xPYfzK?Jk%Na2+u} z^*Ld|Bl5Qli7h8fHJb9$tAz!~ zEvVZh-9sc_kDBb7m~4wil*9Gr&5^AJDuU$R+9IkonmtO~JvpY`~=;zGY&lv%`qwHrtIz$!6p?jmjsV5HzUd%`n@HNa<$Dh?Hg) zjYz3xs}U*19B)MOnJq>nui0!w@|Xo9lH1H1k&?}v0iV1=z@U;R!)!7lrJLi7NNK{q zj7X`%KaEH!!as~iKH=|1B(Lz_MkJ5$HzSf;_^S~qSwQaFsO!liC8N#29Na@0# zj7Vw1AB{+6xG!@D#M%wtB%(tWq z3y|DfC&cyD(Id#TIt+rie5w`KxP=8srx>*&3WrA9l=7_U$=u*njoey=D(2fGO~{xA z9Vu!APc)LJHK>OZN7No}j#QA8hI&|trpFsyln>_nBHvJPxd@aF;29Fi4m30rG~XSC zo4A716U(v-_EXaDSOcuZW~BCJHA38`X0KOJC+LmK{P`$~Nqs(^1p;$A(9ceOejl3`_6`g^aF{*nirOhNkX5R^AV9!`YNDnf`VxMFtiJe>?>4qCP}&u!=p$e326F#jWhL+bR=@Mx z&g0H<=N{)~=MBzFohFCuc-3*-QEpx9*z35*vBZ(&u-JcT|DOG%z1I4O{mb?T?W^op z*{um5C%lo+lTe87t36Vptu7!y-XQ8Fphf!?wz z#WbnQ$*pGTm?6S3^rIM5x9P(e)MS(HZB;*2pJ~FlDjbb}9)p^0`dJKWn(3!8sHvt8 zVo*~|KZ!y0nSLCD>NWi+2GwJFKL*updM^ew+4Mu>kLxv!8&^dD{JSxz>82mVpr)DL zi9t;@eLn^@#q@Rzs?YRR464`ky%ANwgZqu7FsL7@%S;J@6y2mtTTos8o-iSd> zH@zN%nr3<}1~t|6Y7ADw`=KGU~iP`##a#-Msk--tnVo4y`{nr!--@rrbtMvdfR zhN;(xlxFHNBBh$TjYuh`<3=Q(smqAuH61gO>YilNuu(OSsne($*2j<`E!}j=kd|sX zX~aon(~SGEVZ{{F2}7DM?tQ~Xy~%MuG_2?~4I0usrUAo7-RW`f7!yf{)83QFD4}8=Kn8S(Ds(C)mCKN z3&emMY**M4q`yc%mA)diOL@|h)>{w@aHDjUlpy{}d|R9p+r>ihF>#%kCSD@))r(54N# zK~s21)y>ybryD^8@MPRrl$vS?wW&lmT{X%9nKB!+I;RdgEABOI1(4JnYH^3O9cULx z+)3@wA~V6oRqJXFwFawN4)@>}&_Fzc9U5A!pevgEcA(@uTII`FZ$*BPP~ur2PpOoQaDwxPzf zg&8bHFg@BGIyhy@(Rya%XSs|3@dmnDNwz%d!mTb#;GdbUU>c`o<3447E@(%jzG)ZJ zC!#UvE#GvQsen)l!tSEa2=mUHS@;;rU8ehWQ`N^)$H5t3-h$cUJ$Xn*edqQEckJH# zsA;3FgSNxdW0mW7JY%{+w-WR*>Ii8zU8w6$PmlXp8#;jCnoxb&^4&YOKVf=M*J?!O z!?;>K{Zz1~ON-2E^5}YPJry``ih_C&me=TsVbJa{AFCD!^AG~08Vj$RMf6s)i7JP) zf_W!`2O99EY`Rv*jv3_dxc|Odm4_-<)w(|nxDY_F#{O=?my5KQLjr-9 zTNubXzGv?XPi!~syIhzDC&-yb+7TYjpqj@0T(=Nf4#{Ohc-#)vm6?|5SQCK>8TSL- z?D61!s7gNCMPu?!oYvpp2%#bFH&IGyvi8#Oh`1`<5Y;S?6c521kcdG_NBS(#g7UMa}paR~e-?71Vom-65E#0dco&rcJsE__@9-9Bi{l zGEK)lV>;LDT5Ha^oQn0g)(@<&S%<8R);#$6-)&uHU0{{se+@tXiTIR54mr1y<8oa#XZ8U}5K*3}=t}^=F1RUQNd)*_;oUI%X2C zU;!#4lXCGWEq0rB2y%U&I-_PBDxwToI)AoSU7bACK&#LPn{Y33H3AF8qwFCL`f&75K3maRkQjh2v%Kl^W{)6K8bb~4{ATHTz z`nM}|9h9{MkLExb!VxEaT}LTx3srT{D&l~S0{oerA)-L+n-Wjxx+$q5(9dc&w_YmD zbI&rRq)P4~LCEmyr9jL#M3NCp7pfWyi~%DgKO>S%)h4+Ep}6IXnO@O2yxQfQ{u}iJ zEmaQoAssZFhr~WzmEtNAv8;BrM3vez%qy;%9z7lyJtp@YhG0|<)`-7lDuPZ6U#{c2 zs#b^}>H1dzfCwfAm|M-1MkZ46YfNe4ldnoAaY9E?ta|F39udb2GzLDZ!Kb zf<3+B$B`6xUjx`d4C$tjTR*!Ns0KXKSZ=;p~Ua z%?a+WAz|0*N55CsQO-%Zu9*_n>zV_hrh~AzFjH*P?nF7KgYsT{OIv|%+wcZaA}Q13 z@W&qz2Xz$9h8Op1$2C1#A!9wN1HN5X1(&Yj;ZSo0!s*2Z9Yqba$6i-XmWuC3QgBOC z`YOdAMWGZn0!=`CkEN89BKjh9v{9sYs_-Yk_mV*=7{Tc)2K05P2vr5nXe5R14zWTv zQB~~Hrjr=LEC&*qw&da}pe8{gh=0>l2+9G(UZ6Zz?9fvRNfd&*x5ZPD6uPa&p(vDt zH8?87KSxramH_2gJgHq9)5D~nH7hrYf6~vTKpCi^le|;kQZ|A&=v7awIa`=_;mo34 zbNi;vDGTSR+E|$JD{omzk%@K zxkx7VcL3bW69>hAMEu^WmXC}0y{Mn?FLj-~Wl3UoaytR<7Q( z*(ZL&{^S*Z!~WzEf6e~n77-XRCwnv}w_AcUIH9Nl@4DHG7GxY}rOcufgoP;iLpUFm z#$K#I&UCIYZ{AEb`kR;IsH6fwYKR5!u z3#F9Oj$lc-+*6I?cJ^Y!Nm|Cy@?66CLehoYmc%VoKwK9ZtB`a1_~9#rB(Lu0eMH}G z>v3TNP>gf_qpO6Z3~iZ_snB>SmaU6!6$tB4T`t#RT&yM^_g-8f0tNZ}v|%w4Ne>jN z&OQ|5piw4W7OhkM&WnYl`C3YMr93hQBon26l)v&iA!#*3Y;07TvVm0v_@!z%N<*+t z505G1l|tOrLedg#;p5{35B+2@{-$e}N&)V`^+M9xh=SqkZb4omL^$rLu#=GJ$oe8~ z%auY>N<{fZN_L^*uU$kT?YZw?BP1=0D3mzcDpmjjmq>G8xm-wcYfAz|AwO3)!bj!{ zNokQqv_a(sc|5?nqBJxMv5%#}$?R0szOaZO*~lHaAkP&B)5{x0R6k$F&O+5rLN(2S z(W!8Gr9Km~pWn`Qu9nocES$rBkhUU#RRJ9Xrca_wR}2C|AlTf^%j|TI9uC%&PLC9Y z>V`t~xiAwb`PITbMx~UA`d||*f}|ARz;=4{Fl;WMgm6z7DaRjb0OKLS^b7Ck0iZAh z%UfZz?=Ww;2vMeZp5Rdf$j$G>k(ru#dPJ;MrZ)!k}=Vv z^dIDpL=2%6KzhV<*HXs)ie>OoVB=MU>h=MU0*cA>aFNiMC?vVG%cN;k?x=QAnSiri z@Uk5=91ix@%0*L3K_CCO4C-fi2jFkLj$+L=yK|otOiG1suWM&{~wNfFV6WB=PBoY z=T7G>&Lqbl9N%)ZIPx6#0sZeRd%)gne;N7y=G#s1^KVGln{aEwrM7?Cerg-C)xrjF zuPwzEF9oF6q;9E1dRY3LbiVkp_?lRYc>epv72?I#zgmB69k3QyAGEHpo*(~<_~H12 z@w?;ij8C-u&GNeCu;m%cZIX-pU7=N|5S|k@2-gcD|8stv zZ{%O*xAQCb^SBSVey)^znp?$v#`Fi%Tc#mXq3IFRt)?qXmbmxEYn6PLkaV;5>(-S3 zW(Xm(N_|5jmGp^9VN0MMLNcHGuZT}LSDM?v%J|wMxw1T1)Q`mo9J54fz~h#%ZK%Z{ znWskzghX~VQ<0((MEnh`u&*gm>Ptd653mdoY>FeH=cG#+?8D0DVL#FzC_wT-*w9!D zzl-guYCx&Y3%2_qdvP@cnvXEfjI@K<<*q&u{XJ8%l|DPR@WCS(X= z;U{LzYse)CK`O+vBR|kh)WFhQ8R5x+$^p3~AHoxAE)h_Ew)6dsp*F-W6FfM+n;m>! z1-Zz>_<;HaB``n>``B%pSAjqvWvod);{Rm47AOluKL(f#_Wy-xLejn3xd0Qgx-qz~ zUoJa}3oMEg7=eS$6s8LQkjszDvG6F%t-Mktvt2pfuACSUu3^=kyi(vSg+}`3L?HJQR+8tH zz*K>=g{WkjY+L-#SdpFCD32o0xm20T#L^0@MNeHOBrVi(G_w|xYc@fquy}!xv{*+k z3LQQYsH;jO3x`O5)uPG$lU=_+ojl%*(~0}eIYQDonilZdB0R?&%fYF7xs+h=AVgd@ zT|S4|t3d0)A)7d>%uqd$`{HSeg@yNXi-e>#+ObSdz$QacD8Lz_AE~ieN>+zbQ_KB^ zSvJ9;L5vjamMbQpKp^NJ7P*e_+C0T*Rl!q*fEmQ!vI-F7^|^d0LQm{M9e4Sa3SRzP;BLh>Uu^VR=ObEgdvmQwiA_$?s9pG?Rp zse+R31ge4Zhocr$s*WhQjF$t-Z4^6zs26E0N7Y43ivV^PMdmb2?nd@&p|C0qpl{Lc zsd^S3#J`vYPex0HM|T_Wmvkc-lQtiuk*57L3E%;O|B6pYx=TL+ zx(A_$L5Z3kZ3$)860n#`qS6FUOa@P!OU_cS$+henm@QRas!^dD z*eU3XaldD|*^~)jSO9mxc)-JQq5lr`t-*Sv^(7WQp^I(#P#rSj%ELM6U2e_e`WbZ* zIvr`bx)EBp3-B+2eWzTrlNPRKCtY4lAPb4dK;uR?IqArNzRJqnBIq5Ja`s8NZ#dDL zoSYoW?%;srp;P37MQs%8Q+SD;Pf;7rN2Q?x1`^>;mZ63H5#D0gOg?~W0Ww(#AwaCUbrXT(fZfTIyN?QM*fkTatOq6eFS0v0 z?}T#jIAM1F5FW(wZ)y$Tf5b}keHF@y!w`~~D3NojxTa!}ti@ljqAq(Pm|2eE;X60N z%10{#EtAm6VWWrmQI6IMCG6>`sf5Y7$;Pgjs++*_hr0^2{@{K;-Uo!sm?aSyAC-G@2&_`;pnhJLGK*bXQrOFg>cIG+ z;A91M59X~P)PA%`Sj#91f$;+P|Gu=l%kT^ zg-yOa|4)`7C|r;qRzAqVr20|uK9(VBG1?(Yg>7E}X0ZX10FBX7iNxr3e4M)@R+&^P zHC9CQRwH+JV(kT+TJc9|tA`NaMN(m3>S+3Mf_Ldn}EA_NBouXyt&x&bD`HVYN<8P7ye>-(z4EStwq2) ze7EUr=lifClnYNHi@@#9M904zKXpv-YaK@&Uo>Sn9&p^?xXAuD`v>+udmeHL+-!Xu zxPb`?ze;$+ydj}YIGB)|@BlZJu+pRmw29AK*{&)pP!urdQ&w z)NIHw=XEmge&&PYSrK$-xrtONQT}m%XLb~>FTp7Se=Fzrg*6-X{aM(;T@x3NKAA-f z1u0N70ecm`TKEv!#(Y&2A-3K9-4F>%zdw-E9%`E84l*Z(T8bQU{N2$g1=yDy920eC zqcYTwjUnfE$^{j|2DaPbUP#lhLAGWRc*)pm!g~IxI8kLC+m@=f(~E+zkU3DOP9MlS zD3=vOKynC%(hr2{{H0UGbg`e2hmkCD5nBkf)RQMebvePp2Ck8jFv`g+z+K1#S-^~U z(J6%QTPf_w>H&mIAkZL0aN*z|^07l3?}85x%>^nXvtO_J01*>_ojZX0AmK5;*~Ogq z^g>JTMsTM}Nq40s3)fon;~KOpP_;-!su=T`(S%PqD!>5DqPvvL9)aX80$5sDdRh-d zts&hvGAP>wTe$WF&S>)5**bxRA=l>$b<7z6NSR>qDZ((kGPLCb!H>Z7hDOIQFW~^Y z${O(K0^gHkE~T&viu0Vsxr|+9@T;#7}w*Ve5 z@}LJbl2xKY`Up;T_Uc-kp6WqfgW$+M;l?OTSFbUEOohG>7O>QG#{GqD3>Wg|K5#qO z-R5?Ah0n61#!{#s#aWBnG>XW@$H+}4i5+!)KNSDK{vwEe`Xb1!kIi;Bzm*-fdVQV! zE-vjwRyZ$W*yOG|TbTa~bFG6b9&88HKH-98mFU#!E~nd$2Na;r;-&!ObR>IvypUSt z`1uj^Oeiz>Ak@#1UmMY1Ch&wn4;1y_=y6g1{n@(>{~dO%t7!;83gSN^TqarRxVtG)IF=TauG(B{M=cq3HNJO zfy(j?m6Oq0A29!{5&wK!GTw_#Nz+A`0<8WEqhQfE?4#U% zW)%gH+^V;Syt@<>CF;b=O0ASbF7#;aX zSaGNpM6wCE&*RP&7$^XcJCq?DowzCTeY3}*n(F;JW%vXD!uULfar8{15|=I+?&%ms z!Upsl<{Qyg=qvrKQJ{obdbAMj1j~VYh~b%*&OIEpheW#Y6Y1jPeiS)UJeVl{lBrhKlMWv}|CLh!>n$8q$@!}-WyKn!w#T+r|9lcjK5q*fqqJF{Gr6UT^x*3$r% zlY>KjLgoIOo$v{~MYY4&M(O+sww1xAU}25cs!v|~zr?npJA9k@cVp6hoV_dDy#OIW<6RZh0s0C?NOb<6#YEH9nIq2pcq9TU!p{ zY7jnNayoFlaWAuHk*1)FTt{Kj8ZHX85??od9Xn)AVJ@BJ2F}bOqDO^qBdqNx{Gv5` zY<_|LCf!F7FoW%h{)r((#UbXt88L*pQrt?miQ|a&>Le?b*rv0m$ABw1$TzXtp!!f0 zYWDNzuqQXAsIL*wxPAOZgtLoutK+rx5IKP3L9 zsC1anXtoWW_42?@q;_~yYoE_6D$UdOK;V~#pUmSd}9x#LRyYU^W;IAH#N&0cCxQ#lFmb zal#+?O$o0j^l)VfB?*tfGvEqf0Q`h+<$hv2Wy|GXvaPpWX)^%<;3T(A+AlpJ-G%6X zQG6Fs0f)qA#k)kGc!3ya{m9yHt+Xb_|1JLK@n4H?h<`qQWBhgTPWb)5Y3a9=SRS)1 zwVY@E)cm%&%lswtHuEa;0<$3eLYNflglFO7pDdii|7z}@f97BRNgTLVNLsGdUh0PB zqkVWf#otPKy*E9@lTQ7Ug?E_kfhQT96|;g~_%o_jRf!;i!nk`ugOZEVn zNPfTG%2C0HTd0#HR!n_#7xLM0sS!t15G3ONg*_xA+Rzl^SS@JQ#zIU+s^ZMO!U!jA zk#uUmyq(cev_)pMpf{qoQ+}Ad8meJf{O6+=(W>$Dq85R6fdPlLYe)1V8vkeEVwSHe zPms3{DzESiyJ$y`DK!V=fm-qi*ngPY#~fg|Y*9Lg#C@yf*^(#IO!g$ zB3V!H_mLC)HSDfX+tOZerboNz$;bzy_Ny%`aIC?4pfPw9m&A6tFE{-7zykzGr)?7L zeY6>S0f`fN58H?OI;D)A2sUMg74SbXN*-)Z=_J^3;y~!YDE}w6bu6``;nbBv0{a0# z^bZj4?~y}u9>&7U?BdoGBPK5L1}1DhO(E3|wvH7|+LnB4sk+B)j56k#VR6UVwWl^A z5BCTbw(-s>c#a_BO`vm>$Tehh$SUH4Y~!7y!M-7RWJ1pAd{8`9uK2^=^qz`-8GH6M{jhA};1GrNaTs^>8D;OVhb z;p<{0E1!URJ~{wb7Ni8GtBtA?ToKz=U6qn^FmSvQmLjt9vU>T;q86dAdT?$O(^y9$P88f&ynde#9%Vv-C4>J$q4^dUBOXZehf!0IHj4e{w#N0Bp^<1bz zj{4d>+`!~~q;c&Oma?40OHxZcHN8Q?gkR)Wuv1gdXVNwT*x*o^U(NlQmAGmV-J}He zL5y-Z5#e!4HvC{J!-AEKWC&FD$#vaOwU85s?_dX9*%-=f4rEOQvi%S?u)4t($=}89 zo3fHX*%7QkB3;36{t&xJOZ%qBj>>9?AO8%yDv%#1Glz;IEDr*wK3*9ZD-}{1GdlGO zj`9Y>@~>#$^cb>Z_tC6c@_{xEh!#5cjkzuSD0|Kn`9nu*W}JoV*d3x$`QwZS17hZ= zK*bse)sKYg24QX^h$;n8U-GHBO%PaNkbg?)EeVV8>>NIhWg4Zc*?PDm>;h09#DY^@ zp_&p`s1Xl@?SdOnvU|h?@V8O~UN@nlU2J z+!)w5K&a3Eb8W`#mZMhzNdDZMuyr2qBe&aeQB31*j&n{qvz$wvaftta$+5)#FZ+c3 z1$#!qUlNAl@1JV>BYgdzv|W!#|3T>)$tV6=JT5*VF0h8I9o9#zSH;Wm?eP!C&$mol zj#-|tTxb5BdBD8aoMGmKR|U9d2zLIvd-?rj1+>J~8Pg>?(F*j{oEJBqzNYA=sN38nk8E$u4iicag)c=HK z-u$`x;oE>JG-EZ8;Y;zkJ*nIcOZ|`Q8&Fj)xit@pSIh=7(tW8OAD5Btf6OxP!nqNI z)I_f_t9mlPxeP9SsegyAZ|VjGagVsGm<^=Ea^Own(w6!k)in^(FQDR2u`uua3?3Hq@|>~ zIo~q>b~2N>M&JQ5R!IS0PSZkaa=JT(^Dg#p)2+kXcDxAP8jp6ds;7BUe1wyp#r}tM zwUy>9Jd;43h+P|t*ptS&m-rvltzr!TPptYGsVNz08EIVdV*ge$d*rm7-GH-zO|csA zW_Z%M>r?#?kQF$GCzjiXn9x}D(tO@DAGgTozuz+NJWWNQ8pW!H@usD5u5|wwbSoY^ z9w1V&D!Q>)yxuhKy2bwcbZidp9|+d^gSGv!YNsYcN~NT53vcv)-ZC#qvs!Cv;j_GX z$Fs3zMS3cPMFw|my8m9?xC0fZ@F!N!o(zl|Yy6re{{JE$XjVc7dq?r-^y|x$;vviH z>c##ox_N_T6#FV>@1FGZ)U;G?L7M*_GVs~nLu$J2SXEPeK2NHbyK1TbZoPoelz>rZmMuSt%&lZg6-UuOZ|808lXAuX&bRd;P!Y@(|m63ipBm- zde+Tg`^2i9mf}tGWTbMJFZFM<%v&(WI$4Xv6{`iG+nbW+<&u{A?<8A$RxoMOa>uF; z$>zq=adU}F{dedXK#i-^4JlR&-i!RgGI#M3|2i^< z*%dr%_Jp1htA&gdUm8TtyrurzbUdK9bLy)dt3FQo40mbwLK~B4CpJ|xr_Zb z>1vb2p0H20m&dA|k_t5ga^#$w{i`kW(jxfZ-3H4N)&K=Mi`7y_MoJoK>FmY+Rl0Em z{fC0t_1=`^Shdr<-gKx;+-H{hSL!}su&f?;_0ykVX=%yi5aZ5T>|deleio84R`==d z)O4IAoO8KU?@LuF!r}dPESF7`%?ch z9Sex-)ePoctN~;|9;9FuCM@wU)eV4JA*f9)Rs%k-+n1Wm*_Qj4=$HT`2Uz)uuGd{G zm&H_EyzcZ=k2{T%miccaW0)1oaC?D!A9eDJH3o>J)Ko8KAujeW)_us($P}uFa$>3? zX>Ko$#Wc>k*nfkrwmbvl7_0MiT;DRF@5L|mXXriwQMlpsaC*g`%4N>7+@G#vp~v?q z40kYt;#>)2O~x98*Xv95CZ}-b#r`zi6oBd$nkbjc>tfYT0|!#l(>dXD{#47nYvwjI z^+8&-^4~d^l5w{AIDWA|#WL@bxo?<}47Vg$wPN*8z8|i<9*$e;_vv^DS7yX|6CT#( z#%duQZ$>@{G+e;r;xhSjw z@P>21S?&C?^I_*Yr`LHQ{QG6c>y7~+24*^TIBs)z9Tz!F_79OKpwC`q|DydN`)ziQ z{j&-GOqhm`Kz~AY!V3xim9RJ=DIwnWYvc(S0)}9=ZHH}xE!B3hjh8-_-jar;Mkxn= z0vn|aDN(Y(((sNrDjpGw#ogjY@dhzb6s@0F-?L6xTdhUbr-2%{#Cio#1AiO;Zv1$B zb9_PkuK3OIY4MlFOP1eS-nEQa8ZEi7N!)44uv}&_n}22gzIhZV13Bg=%y*j8&6mQD z;A7!?+)ubyxE3y-dxE>2^KloN{$ctBY!t^#Wv0EREvBWWcCD2nZk~{I1t&Mg#qs;` z|BB=zx%hM4?7z~b)fWj#Nzq7Y(kdfTszY-E^RTSrAhY~(o&_n4QVOTW<#1!y33H}l{OjDJkmxjS_Uu? z5MdQYQk1k9T`(=pL3Zfi<6v7q1F_fz_5A+>h(+zU11waq^Z<@z1agSq)KN63D&nw? zq5>;Y`7I(4VGbIMx}Am^2l2utHb+t@MvK@QNug#$u}Qmnh?m2u}B!L2VUaA{1FgFSY zWV|&U@rwvH(l7u}8wJG_L_~a5-&hGiyXlzk(pAaLg9iY8s1_-{I4yM@h1Lsm=76@b zpo+3Ui+Qw-QPbvQ}56_!Qna z!(fheI!ab;XrKe08llVr$*!f)j}MiI;C_}zQlK&rIL*V_0faq1)F;jhbyeWuaUhGt zcLU|`!$=AZBoN<-q>yV8@E2c?q=Y}fFLV_36%+CGxT1<9k(BVlIjS3U&7|r*L!ee~ z(Sj`E$rJAKz&Q}Vt7}PJFG_J9K>Nhwx(c%^>8tt*(1m|dWEEoL>TVN{M4_l}<6>hZg&bK0o#MET z0_W}eUW#WR{+OZ2C2%$)L7?LIRUG*6H-fh^ah6kGv3zUApstpNCe|_(9C6_t_TM^6 za|i4MVe#`5?K)SQ+act%>wKk-+~jAr!D=13ageFKO2=VD)%Hx%55Gb;9ssXYBXo>7 z^ND}eRY7>|q40_HU%D!X^5o(}M7|x!5<7Ji70{5zK!~sDD49*u<0pV+A&(A;@9HU; zN)?f7c*+(LM>+4Z8Bo%2#Mg;#=`3vp`m=o4AKHIFtk+S-^WpeOa3$M|#6N21B9EN{ zwhaBG>vV)sppKrPgiSgEG}hKBdc>w{8BJ8#)+u^~0u~uT8flUB=vPdQB;WwW&QFO# zP(=b>&*!;j;Am-21eBIu=q~|tk|K#0GmYW;P3N;fN9gaL-L7{tgxMNb>A2Z*N~tdh ztL;vP0?=Ck{^D>Ee;-Mq!xbl^Q0Qm=7E6KCt_lJ#IdntoDUhMbsGLb=2`#mhuu)IQ z0`egx&}1O=-$)w)Kf11PCkeXlTL%dq7(J0%bd;7Jd@Dp;1tuy)I9bf8ak$Zd0uvJg zgT-Uy{$FZ(H_q`{`#6Q0GreQCnw2^QPO zwl{49wkq38w)<@>Z40Cw(mKg4ohSZP{J@qVeno5*3&bbIJH!<6LhC=Qzp#Eo`kl4Y zT7sMUUDgciB~}xB1zwHsmfqzYrcX`pN@LOyDTlijx9%m}UT!N_%jI!0_ck}hb@R#m zrM$%bg+C0`{ulX2`Az%^^F8L95b5s_J{3L?UK6^7L&D3#L&6$F0G!YNgZ~Iti+<p=3E3$*=txQIe& zXGi>$`k9EIQqE$VN-m09~mZ50FoEA=O##Nv;XMh^=* zR_dGEd?BdJ`nPMarMWYbQ^*r>ZjQ7t%I~3? z9O+tZFX6`%H7Y~8MoS61LIDq>pk2Bey3q9;Wz=;MIhdpcx{A~VN*#}M6~#2Cg9|rF z>2wujO@?YGrTMy2TDm$gdd-urq!8=0EkN{Z7nyVgL!?l()Ep&UZX}*lGNk7XY3b5) zhO{*4SwmW?^o$`bMcQjf^GSOQXCv|`cHXb@k(DXoY|SzmuL@Qp3}U(7_rmimhLp9B};c0 ztrU;6%&3|>L%Q9NmM(2Dq@_vg4QZ*;Izw8Dbekc~C#^N4d8JzoX&z~fATUtuB9ct>sI|`hrXU%n9=r-rgxKZtfUyVu9ru$sCnZA+4<*D|NurueZBdTee zdZ34YUbAlbJvfh%AJmks9)028Z`!eY`_66fDw-ajkgMxVer*rS5N#C5Zd_){)&4s3 zaBd<7iYsQur=IduF^Ox{4&1jk@lKO&h+c07EodT&=E9j47_S18PF)Mt4a};oaameT z7cdtD5>nN4ambQ)9IBhb8clBIK+aYlroK#-jxdd+do6|sbZGoYT&|8XtNqm%#UY}U z+~>n}RE?2DLXQ^5Wos#TU-hbI0qx&NnHH^(`Dj@*5v z&c~e@PN(BTN1x+>W4B|2<7$UspSFM9-i{0aciOMBI}<)Z4uGRT>ic}cvV`+(itSZf z8*%_VV7uOSwiJ}UA$3X>(&N(2$o?maABtnh{r8M`k9D({E`HYfN9(t(&DNa%5m)Fl zgFM55GaNX>fioO9!+|p#_`k^kCSF{rs0dt1173Ip~BQ!t3ToO56Vgi9F z7NXpm2iNpOq_+l)40j6?tBW)lfubtqXbJZ^TU$i}Oq0t`z;qnS%#UJ;x{t* z0wnEGZzV7n6y%T3^9Lu|5(xl9771vXo@(NM$b{09X7(3T)L1;LP7faoAUDu>Eq7N$ zuVnSnP!fJA%k$ihV1F*aa53>PY!Nky3JFL)BX6GVm0U6zp=!gF< z%Ow=dDhJMkl6ed%h?LqMu9f{900ltmC?uEy&}L0Dw}u^vitbK9O1KDYHkC-AXV67M zt5PrtCh}G6tTT_v#bfZWA~?|vRdYL&|2cz;rDPJ9K&10S>es}pLU|=}d2bk8;azrI znX2CbrhXucXEU&bGl?SIB3;oeCY?NW1c_pl27nI3lPQ?hnv| zKJF+pS8A@OuMYgJ3=XV3(H&?Tl}k_2&kT7*pkihqk5HBS8FMmVKLzUQU{@#H9Us+W zUEINZJV;7;1PDZ(fXqmwz={M~8wXAbI}juishbFv97SR%8Nqp{+6ZnRwz|5N0Y1SC z%<`1SGlA0x#8D!JRBtctAI$PZky#Y#U{jUgkLZ-pDQh5nRM^D1ls=F@{AZ)KI6X!3 zjT2b+U6RQecX!+$;~e`O_c}Zd(f&ht06cHM$$ojlAK|m#l<-o*x`fLS|NpA3(e|M2 zM%%^GU!*srX6Yp$`CTE!iEoN6;&bBd;w9F|{^f!z z%1F1*mdddH_;f|mtpIY3-AbDE{nHgmwE`0?b}K2?AD*s=&-(7^ig>I)xI%C(h{YPW z$NJOLmT_A@IBl6^>rYNM9JlqIM8TC5Ih;-5@8q@qGj;)w^&hbdxUK(+KGGE{6K~t` z@b*1>UwC4>c;#h+>$1pUpv>y!cW$~x1jct1I$d%bpGpzu#iaYhi(=9}B7{VY_T3_$ zzFikYjBhzCv|B}Y^t$(~$G$@pg!P$A1=l5!bvJIj-E%)&NG>!ay9xP%s5^D}x|LQq z=0@4W%U7=y@yHxyv~Hlh^;!Fu2n)7yh_HhW4+E`IH*g&epU}~2{0W>ofb=L(r$8pc zw7gXDS5mJ5oa+##<~yzz7OXa?jT$6y4~UjoMUeI=ev^6Kb;5#WG0H;=8)ypU7N~{S zUL!2XFfJ@lX2OSAEqPmvk~q%h24SwcLRjF6Xj5s)*OB;P&JpC|!{IZE6Uht+%mrSiC~`FpHxlc1 zLxF30Yz!&2%!{LpudV|r7XpogF6t3tE{Za~I)Ds!V{A%hgA3nJF3E3%Q{6)iwqcGYe zCA;Blnqz+1Ei70Q!CPghB3LvM8iVbkjNs2{mwCF?)vA2(*pihG4FZ(J1{= zSUmUy_}o~)_~Pce`N9HsWTTC}z@5N&+9*7ulie8qC1_MAYq#`yomD2JbI~#ttC^`DpNDpZP!($y1XrXLjO`OYS@YJOJ~K z%Y+5c&~&`XtC&3_%qdZ(nOlJIz;%n{lW8Vcapo;I3JdOMTJa-$&;(+PiL}NUM5A^{ z+;!WbM0yNSg4q{2`QT(7&|?GT$6V7>o%lm=l&7lA&qq!^*w-BxJApqqn@B>#(g8?T za*h>7uD)Q;aIknJSUBvG+u*8SPgthzUGp=MQlAtqK(6(ARqB%p&232FWbSea3zqAr z8f*i6Pzm{aqz@1UT#FN2AO?+-3_wJq=Z#44mphQp`YIqj`JeN|_k| zOgR1#a@;)m83P39)^`p5whi)z)W>ES+l&=3LJUp05$9l2Uq zkftBdT#fwxkRSNk`GKlBb3^Qc_#|jLIMi!KmS4jbNnSAID~B*@ZZkLCAS}4opljto zn^FqL!g0B*l?WRZcKhD6RGiXY&wXaZ&P3A!?^!RxRvC?Q(|U1rRLY7C8^q7S%Kd(X zuDWvhrj@tce%tab)~|s+5<0If*}JA!JS+O; zVXi}WiuGrwE#tEy9x@s;HmnktN~Ywvr%mU@32zBKKzhl2+uVa%Vo!iVMJI=TN!Tz?r+g@(pW8Y}^ z+8qfY&YAG7gjUnn6S5PwBzO|evi-*P9or!Hp{>&PyzL9N#kNbNze_)sMx`1lQ+h;N zEiIHJ)3o?2@on)Wyat}<{x04pE*CEs&DJ3N2HLHK)+enua}Cz{RzCh0urJicKO28n zyf6M7#QDEz=|YtMW0rN?%NDog0`s5DZvuhvkoiUP7tAZnS0i5F51e39OkX!0HGSE1 zHzpnHe-{ZZIJht$aOL_HE5+@oRvAIs^Y{yidx(8tPvTbfRusQLa9tm>*h71F?Aj^X zqJF$5cRjg_fZBAITbnT7W7n(|3w_)>|)f>g9=L;_A3k+*k-?n=5YFIaJ-*D%qjfo!d zsehxCTig}3vyFSV?oPaW*X}2_iBCk`NECWXVSBFhnWOwbcz7=)nZMtn`;>xW%w{F`i z!i7HCbZ=WJCPnRj<1@Q=Y!%PDSa4k!vCv^S-TSP^8jN0%5UqizJ4Cg(uHU|wN(1X( zqAs-ALK}8&xBfY*ZFa86dh4HJH{wlAw*ECLbJRu>Av3*VV(bDQ@v_(j+~TEC#s0>b zQzY@3ox8+y49loP*^_vaTjZk82JM8)xW%~WESV{i=o5w0l<C3e?F z>u;hCiPFVO42dh3TmKey>!POh*HO>Ob$6}21)YlbMP>224eK^gRm55ywc)jE?h#X> zu8*}VAOq<-v?`w!T%U=M47Yl$_eLkUts_x~bL)(b;j_xI3wW*5u?u*tAH^=W{j9S0`@Yxz~zpj#2dL zRckh`+^~7|om<3>QMc8~9Xq!}U$<_Hy82f>x^?Hy?N6kO-dN-maaGijhifO^yZJur zmZ+nfDRGy0Q}of@xn||s)tkhO=-scUe*V_Fs9$L18j|E08B8YIl*U%^il~PrA_29* ze%7xWmD0uwTEA&nO5^Zm{YF%gv2x`)aXIn-PqDrnr=t6{0o!l0^9rZv_?6=a$o+Q! z5%B9ANx<|A*r)7`_Gj$t?ThT^Cj1$w07no5aCd?);R3_}eA9N+R&3jCyUjM=#!1t- z)7MH*NvotJ@h{?c#iQa=@cvJ*{sfqP&FJdP|ITpW3n@ET4$65=@<0|I5cx#L>sdxh>ESFF z4H}@nv09&huA0eaDGzlj{VIH4bt^J#5J%$!Su|&;(8OeVlLrRzWEvVNlY7+c*F6o> zBaOr}04c{*FI@Nvd@|lBT)<@Jo2}=P`-`WCNv$CKa^QQL--q`-xIXYj?6CR>8Wcsx zpg4`xnH?Bt!i$WrGzk&KV{~^h-W)&5EXOM_JUBketl&;XEhrb~0GAX_5^55;0yv0r z?X1_T+Tv_M_%ra2MGTO1I$H!et7*STS;nnn9c=Z@x#mjNvYxB@l3Z^@OJ(o@MjlV- z$F4wED;YxFVRF`ih@q^LaMs=2p-n?84Xm{ z<4>Yol!r(Yl*B7Ae;>P^k=|q=A8)?^b(>v3{MVQu3XBHt32=nx6PToMgmSQq`!sTZ z1fTI(2Ru4L#HnhEKN!KQGE@dJSW}8<6#m;x*aC=%ETCx@;Rqa_D&_91^J>;j>>eQ@$7>Fj_a z+LSpxOy19Vppxp+=*jRLLQ2fGdhYY=SMD7Pw6{SnxB_avQe3Dh919m@{k(g}Tk5&abyv8Ox)XmqH&qn%-P8v+_E=gyl1!-wFXMR0_v-{DV(r z7mA8P2geRMuVv2hU$~E*6pB@q!FN2EnHi2(g5d;H6S^ZhRP$ydzGb2c8N#^DOe#aU zr;B*v^fb9>11@A~3?9u95K69R@Ju=W+=w2CqX;r%B1Q#YicexU_l$hgE@~m-hlLhaWP^f)+C2?{u?C1V8XTev zBjCGO>Do4e6+~hV;5Viwu%?FsH_R@WwnL%rN*c?M2vlPr{~^;1e+kRjwnNw-*ac)G zja3AS`jIA_A7mLaQ;H9LC1E&R2fhElNaFuTomI}A&O4looHoZV9p83zIZ7Qn z9jhIe+dsCyVn2d>fcMx_faX7)@RfwahzqzUVNrqvJiu4*qW`#Uz0C~-fZt2+NIlY* zfC=c8?BaXkq}U|Bh_*r-!A zjy91hRbln$r>rX2nuj$N4rv8N>j-5)lrGKlm&ZBgcA{~upOofL}8IA zm--@NZlIUG_J~y&E=YoC)Pg}|XDL2LF0yR2IhZZCAlkjcwfETv!)sf;0`fm)uU#lv z2?x_+tZ-cPgq7@m1iie@rIeKg#;P$y_-hLz?8Oyj3X!*Qkf6M_7T~fy6A0cMu{#c7 z_t1Qw7$b(xBLFtZt=nvBk$g3|JT6$c{*Fd15;k|Kn5sf)j3TrnVUbrz+NkTOOgT|U z(229#l&oJ z^?kUQ%cZ%Ynoiu?JVGbC{q+T0lvP4M`_&M-G&~pL&3%vkA^^?p$f9B~kwnx_9too{ ztYR&eDA{s|q)0-xAC=t@3Ucm{JTeg)t0s3}6*ZWjWG74Osdw2hgEQEbO^ehZDaI59 zUI`au;TMPz6TllPQZ88%zh$|uq4PIJCDO$p?1(x_IxqTVg_A5R)yBiXFxX13MQ=iV zM-Pwx?x;n`vpx`9R5P#eM$}Q#BEr2<7=@Kb=dad>@eRfl{%=t_(iarcSXqea%oZug zgY7xk+%23PWzw2b!V?t#Z%dr>Bj>ntzjLqiR_B$DKRVu2@$a`fZgpIW*Z;Td_4Y5@ zx7btdX9E@By@W~J{~t)WA>on)-uAxjgssf>m~Dye9O+Net5TcvqV#~YM7l)$oA?1T z_f?5I#kJx>(Q5sr^{dF)_p)`%|9aKu3{U8ydLPL-Pz*8J+DwgR= z7>KG$&FPPPj3(%G_>ZHGRjWUuAa3YFWn^2^qqy0Ti&I$9yfS(bRg@SZ?Fi{@@;jBmW?bT^L4*H0`}|um0Za&G5Flr@vw_1dWw4Lj zD?3=mlushyUoPuKicA3!=Sj=7>x6H* z!+xUjY(SjAUxgcD*;IB4Vd<3NTqb+}C>sd&Rs}}ewHsJCcZrbnh<4VhF@i2Zx58W^OPuN4Ozk=+*K> zGa!HD{8~saRt%2@JhUSDZuse$i`YA*jdHt+eFFnlaRoTQD=d37 z7bc)7JzIn)b}cdhpnzn6V%J^Th>;&pT(SCqf5{&!0sxZfvu|}0bSRcEP6IDJo zsPVs8#d@a{bi#%O$PSWz4^9XK8o^JX21beiWWblQedmuVQ<+$w)O-;>hi+vjn%6|& zP+$={kfj`fl}R;x66sUU`Xl8Iz;;C3$LjZagvZ!+G}JI^X4p<>XJ?z+C+Cg<*$T!e z*Q~D#Kfv-e7tRX+ek=nX2e0P;yB(-^&UbPDKM4H)H0MQ*j~%Z#N*oV4mO0M0{}Sl` z2N2cov-1gWB{U{HnQ(K$dB_2{-?qc%ll~=rUn-ThODm-F#ovqH0Ty7Ec(3RYMe9e_ zA#0`eVXM~~7yq631M!>UFSGo~@}A|0Wv?a0a-R8J^HFoI`4;m9!jFWb!cO6OpbmVS zFX8Xy-P|9!*SU7?OWd8@Ri=Qc!}KK#@PE+%)Gvtm`ao$P@`7F$^7oOQ(sL4!Rs+P? zi!}lBT6d?VlPRgec410(EESS=aC2<}+eO}A78-3_NS19*kzCZ`0%)g_JxK5;fz>)P zcr|FV|QO{~Og+5SJ3bF9B6ZIWnZJPS0v>@6Et>QVL336y8!>c2t!anzB8^ z@=ytJ?4tlQ+Oh{!eJG+V@=_?>t=fW>s!-MxME;7l9vAV?8)*VRfw5wlVwg#M0DB6^ z)`O!P@eHb%ATUXpHI~7}LefJTW(JN`L0@#q<;6-90k?wI0dyH8M>`gr=q3L`^DeSs z3I{E(vb~hTm91xbw8uq&i1I1`*8(7Bd}T|Q3f4I{W|FyWq7#|Qs4<<48vPQ)<_Ze- zV)@_(A!(~-TuT2jye$MvvR%`|c>o+E&_ezFN+$MrFU;{;230eip{hLC=OU1@K&}Qr zlsbQHjTZHEnHwJR^OB>dwUta{dUOgPzwqjV-=elsFSCwjD=iH6HG|t>SRz34AU_L6 z46rb5^#-<2tlgeGc#^q7b*F%(Gd)^Kd<6BCYEy-zEn2P=b_E(TRW$A%GP5FlU_4O) zITvU^-Ni0BcK}Mc<=Zz3N!zv63W~^=RME?n;ZCKoQeREcG;8^m`jVw#PENB@kw=nm z*9~CJcPM=oftE>ZE&O`*s#~wIbgO!frh+<_Ky4m@5j%xRSA~hl+#wHfWn#{$B&RCk0nz8iVk$uSbi4S zyizk7sz0<4$WTaMtYkL1$VCNK=)+xd*(qkN()TT0^WKgusk0V$%bkMsBfjPFj(l<*6UNxSWP{=1b4T&f>VufakY#ya)*fHycYbS zTN45h5K!<2wfvM>uo|Y9j**Um2A@@gTH3ykvFw@oQVZdYDGznXjiWBGWO@Wpa0EC_ zZqV(q{tO}Me$B$gwnBnOxDhW@ItrDh@?d^r6nQ`-&MWLn>25^&%3x8Ri+Hx;HUybn ze-gq>&Z@=Yg2rKa!?22+dmI`nxJ91Xi>vUSfSVYRv#%Rg!Gb0j$!Nc?U(Oqa{KTk% z;b!@cOGvs|JEiU#rS-_dP-7=vp^0-YP`}7(hfiZ~gQZcu?P|`8NbQ8(W_jDFUmUcd-2K>m@CLQ~z-Y2c12SP}$sN^}_YHfjIuh*2B#aw7 zAopiler(v|fi`($AW%OJR7ne9dhzZWg&#^ufil<{8qBf$(1^W6)D-(6n*iV?x8PLi zuzb&`IXS09^~0#Lyk#^2HFtLvN$p)+MYh}bR|!eaXoptVf%j$XGYFoA!Kq_VbOHr+ zxc^}T5FG_mhXBAw)^5MAu!GO9h6^~(T~`2dZ0w}A?AO@+JzJK-;91aVaCT>4qE>t2g*wMW2eQ$h z44!PZe3xx^ykvR;p8V?m2UrzlpO$M!3~C(90(>l(5zIRV z^+{V}IC>4G_!!>B3Hy%r;5^pWXl2fNVAH~*Bs5X3s@6SKK#O<5pc9-L!s-tkE3r&6 z@_nv?T+xAbCTBs1YU#wh12q$YsuS4n+Wx9kqsH7yK=KH3{Fzb_ zH@fICgWE7k4Xj^}HR?TZuE79aX*>YVU;~Eo z@+|vRqZV3IP9j31nBXG^io58Ed;g3ugt$4ZG-O*A&FJNGg(RY#fn57%jmt1w?Dr zDT_-rj6@p-ktIDRsrE?!4M0=NH8VQd%wW1JmBE8B0?9|3%s*FMN;HjiRU;f|-DZ&0 zWXyf!xWr;RSTjA+MqTYK05aC|0WK7{pEPvK9eMYoU#RE=7SUg6xqs$M&2-&X16`V& z-o5+pSDO66(h>Zz*j4M7W)Me91Kkb5-d@XQwk!4c$H9rSS!o?#gcU2d)d2a;@}M2} z>PzF^k8=(??{^B0Q;s|BAK6RnX$iv#57>Th+b#WBdQSYM_@MQD>+SJV@e3^#mN@ec zVLd;@U%{1`{%Lv)mH!j}mt`;65})L@XWge2h%=}9?CJXG-n~!VaQ*eqZu2gBaNC}} zTlemGXwgHvp1l6aZChQBZGU{v-jqGwhrB-b^UuAoE$WYpo_xx;?5QWVzVHNaVV2BK zSux+^d2}28n(tYOzxO;u{+Y7Mnv```$vyE&X$Aw*DkCw+^zb8(?s@33^le-BKC^en z&d2GPm>>V$F(raYcgJATj6x85K&g+XKbz)$boZY0JwBg1JRtp#|L%Y;1CurzGYM#* zvwBR-F>QZ(oA2?b(|0`gXlmM4cbG}ckN@tNF2$JciZLdQHWzzLJ9obDP|8C)+|N9+ z`}r4lgcpt&vMD}kiP2(G-Sr?-=rtzhupUl%c=z_S$DZAm{IqxX!_S02 zpZ>>xcUTwuFDThahLx?odCw~6jJg+lSQ!uRd2w5cd(WdUJo(5|so`PifBZLxHQRr% zzUu#C?>*q-s;>NTO;;O<1V}<0f)&6(V5E6%W**=o* zZ9wi4uCj5FyRjv?goHFwm-J*wA)2CWcC)+L^!EGS_olpgGkW%9v-|&l_G3pe^2~ep zp4-kn_uO;7Ut&HYT@RU)V_v|~KcFl_Rju7w@2Ryk(v-{XjL4Aq;dRQ8IRhj1`1B(t zJ3J_fRasM6?x}8e0oBRf;$o`=vE(0KuUH?323R@028h}4N&;26YRg+)6>MXRxw5gX z#xC}g?8EC7=(g?;46HB|%%5gvCm%o*CG%95w_Dq}^6E;yy}rCDGJ=U8Uaw>yf*x3& zqz6)3y2>&&x?9TIsCs9o-PYb1)t8AMUaw3a#PBVfe)wVsW@UkF9!FJuW37kswAQyr zwmwhdhu1662fB3wrG|o)#%_~z+l@IQrgITQ1awq(V)L!3t1Yyzt#rC-g{^okUAv&6 zzO<&+vS8t3wNG|Fv$D8oZH4_wtF@SZ{PDKR#f=r_`IU?BX3hAia23`tEw;>CA;?k% zL8kMFq$|k$a=u{^S6NfKsJ4DZ>k_WCwkA=KTOi011wp3sv!pA?3YV>6^?b(0H7r^D z#8dXCoJ*<_1-ZF9b6~Ndpu^amBORK*>xf8%YZA<+CU>IUROF=GX4cJ8HWzJnxy^3c z>fjt6GjFA77jJP}$xO<8|EC8Q848?z8_fVZ2Y{SXQXo;c+<3HY??JnJKq}VQ3r6TRnEW+hVtI z4CN52zUjq*g@yvRtm-tJ(+UF69*(ittZtU3IGS~P9CqGeryU$^^H?1&iWUUOuNrt% z*oYFQ!8Gm&h00iu(`l!8@?%FkS(-6BIk($twmUeFo#TYc^41JIqA$4H_=0rGNxa*n zd|@8dwbd3@x3tw2I%|s>-A#2ZjZSw_Q8Qaa(?u*_^i1*ERc&RiCmN`gLb=9I4J>R&FsT6A#O3hw7P^>R#NtE^PaI7g-$1yfaY($oQV4l99EU~)lbzv*k!Sl44 z5}K5`WMHnofJvw$oO~sySQ^DcCkdq)o*I~=FDOkYE$-7H_p8ZHplcM(nz7a}qWUKW zX6p+UB@~TWO0HinjpO3xJe(iFZmD-sv0#R_Si~OCJu>jHzTlpOg5gDq-*G6GL(x_% zF9@h5@&8X`ypxgt!~9cV(R(!ieR-k0i+R4hr}OSI28;@ZPiQyJ~P=8UsQU9F2Q1=(zJGz6qR>S~&K>IJ+%i348F0DnIrTMYu zw8p1d1OLMB)o-hZ)GqY{@H2co%A+;$mvH^5N zy||-AKnEf%GT&#?-n@o9GUXc$ob;2xp5PEJMczQh1j*mo;*~R977P@!$|$O(Hl3^g3Y+Ubk6V%X`UBqvgTvBgD0Ks2iL%(x-nJ>(W#E2}2lh zlS@41(nsH-v^T?tM4C+=CAX-d4O^8Od{rV!cw7

fLqyQkz?t2|fsD)g-DmE7Y(YHi!|?T3E5(P&t)mc= zBo-|xH&Z1mS3aHzdr~LZUp75_w`X zc^ct3;r+)*Qr-Fq>C^ufeL5cD5xWExZ!M)y2a=zbkB(%_zZ7j|@Fc|OHbD`^DAh3R z(t`gKRYdT|hx^VVyakb=eUZdqvc`x{TKd9gW0J&QfQ$R`W>f-^5`#qyKTdu+ICLoN zLmcxE9MOqk9)@2eKdsQpE3v2doF$QUJI9ok@E2lFBgp0IdITaVO%#pvX)z>5L5Kc_ z1r^pqCT_uH^3- z{y8Sab%fLyzQ$;8MxfCX4~T5>_mj9-#BOg}C%=oox59;pMXbF048dp(fh$|YcnQf-g23Qti{v; znNkVYeTJ#1atbI#QAni=#oDqNmu5%E4ui_3*$E84i?t>C^!+ed10$f4>`{8}w~|_5 z6iiNlp>BGk;4@L(gIKND9X|;O#$+S?bY^Gp(q2g;GC>$E8f`ddh5JVkCziDLNwgri z;3HOG{8SbVGZDMg5KewXZrA-xQfDNF05_@R8W`85V0Jq?ERoRg)f7()WO}Kh2r@wj zE|)NN6H3IWcbv9%$rhH8W`C>b!aD|y)msb4bwcb0c@yZkU?f{>PK*U ze{eHwY}`v{>OZ2rnMoE0VG|o)$;?mrKFk9W6b{_M?pHJOV)LQrEEqL|h>F84K4u>g z0sf_gs4>I4(FHL%<`49o3hcfzwYx_Mn*~Y-xk@IXuF~oDt>`6hG|U)5amYT|GGZdE z!XjVa2}JE})$fx9Ea3Ws1f`E}xj%Nyg_1fdKpA!+LJU8WiuAi>@h;?bkscW9Pz)>; z18b!(os&y<3^^V{P-{euf`Jo%qg6OO=?}?^-#-*OgfZA-!sY_|9Wh!&k0dBT{eB^Y zA9vr;#w#AG^_S(+#2-&I{Po-9(!`#eUYY5)CchMQL`}Oz>W8L(Dbaf+?bZv)4T;v2 z_>vy{0R>ix*KKP1<-ovpf?p#fkcd3j`uE8F|D73EGxB@#Z^}EIS7bb8EXjQrB?l%wJ@#%gi_IH$0^Os(!VuUpGtp4Xs`CTTPE9OTAY;TlKE0P4#{h z^S}LP#lZXYxa1eE8za#YLk87jK+671G$ER`xC3c);Z z?xIYr)#^0a>>jtt%CL5hXFV>)E)M&*I|gzL1*;N=9d_ll!g>-bPncT_=dxOOo6W@0 zF0_=R-6p$*ahPnZ(`M#9jKgjh8~Lr;fo#DeFP(CTheKdIx{_eA;%tBMV(7}jfNyhR zg^AP84z072IcT$(O%5~dGPx`~Pf;xAaxyldSKp}^$P#W16DqvegOjQl8Xw%` zpW6OvWpoD#rl+Q}sZmaA_*7ie#Ym z?nX2;ZsEl9MPSRz3boNTr_Jf4Fa>$1$HcNcXR?{CjLFP!l-=!iQ9LE~ z#U=EV+s!jBi`!;$IxTh+YjIgjcE;^6@ot9;lYqnBkhogE-u=jc&QS1((aTGvC&vv` zF&6ATSxCkQhZmd&;p*LeDOxMVq3gk1U)V%bt%V+YWlK||aL2&eii%6tEGjN3wk#|z zF1I?FN7(W;b(ojtitL&1{7r9@)!h)ZExXsbW4`KVZLSpXNquvw1pPP-|dN)u_y z+GaalQNBi~_p56MG=>5`sa~8Y0^@svd(M?1J`++rmlSXa+_J~ zIm1_618PAvy-zk=@Kark1W1y4u<=~)0I__fU1(M5!nJGLgaIsU3Y~a1aGf z?FbLQ0c$qhj~qe+3`h}|Hb6t+IcxVcp2L)GHirFg1P;8BW(Cv|ODTumVj5eXX>4-}z4iG@|ECPN`%367RDjY$Z#7i_phhtG5f&yw+Y;)ft&_pRMzE2)D-xo6_YY$cUM|bdJQrUmPhT z2m?I?125egD@+TXBy+rR>FVm%NbBD0@V5)PNeGLHSd~#8`9ykpQXQ7@bzfFLzS33d zscc@j1dPWOY{`mFCof)BH;I?khR?YCZAmkq9KR7C2vh^X10SjMdKFc3q*FVVwzjlH z)bG_+f2#r4sEHFZv6?bOlZ(OMMdDtTZr`S=_{t0Z7DK_4NfjeYP;4B!oBV$EXkl!> z35|45?OLC9?N2|pkc_NlNmWZ{o4DXFSNod<+u&}=Hh_GU;OqOshu4EwJ6efzZC#72 zu(i_Vt}AS|*E#HnbwHqT5s4ixYANDilJW@ND5@`_irht(qGtS;X0WeYU}%{c(M-Mc zDSuNu?jbUd{@3Cj3==K>#-y!XbRx%m$Yn9#rI^nZZU6Pot+M7CVH0dy+FH#=7VMbE z-(V;(B@VH8wOa;v1TKG|9MY|bcUWi>c8MByrJF5(TF|Z+8~ydk8{oM?lBc`(5)RGC zg($;+fGH3hf@k({x|Py=WfPe~^{q9J+9F&0g?4|P5FsX2M^l44k?H{$4j|qlQ7rP$ z%X`a^_Aq&MBT{$Lt-8UpRM1Q1%T}+Z+Qjz0LC*gl%c#x3y}!@+pTTlL5ECAuH$KA{b0t2DpY_%$C^kEj=@zNmUO<6RVT z%|C1XOtOX6eGD01WCQL!U5GSsY`V2KmRW_`+gG$WtBQpXB|}@KpGw-$uu5=SUPkgpk+~}5 zJEmJ#*)q4dJ{DURvE^c2t(|_ep)cQWOG(3C`*4lergMo8{p=14Ut>Nk* z+&7M%PPg)^*4Cx`N?0V$s%0%J#W~dSNqKYwYmUIEfmlTiUUhjx@8O(*Hp6go$pL z@r#A#Q5bCO4w&HQyO3@mwuk+up&^ma}q?uXi)@WWq3pHB#1-vO@9@Mq_Kc1}Q zVy&Al!z=x&Ekf1hr7cg?w27;uw#9#6(ykRBN@#)P{I7KDHF?B(ZHucMt&xRM^P>M= zL%}B!S0$YD;^CLTTfx|bpK?f0N5K0Y1;@?S$SFTv0jgY&2@9uuh4tyG$i}kP?!QN{ zO{9kra@kKvi~0hW){#omSe%q?ek(aLc9eBkYgUT(PqoKCD`{(n^9Waf#1g(yi3g#UvZdy#h#IJ<^xv7J2EyC7 z2DgoZATE6MHB{Fddik|<8%mp2h!bR)=kbnW@#tM{_kS#Df`k!X27rpq8xa+g<^-{F zWezfKn1u7`$SUxx^%o><`oVo8;VWZ-!!IMj9Ve|Fh^WF(x=msoWr77~t@o5SmW!K( zyTv~%?LX-X1shn{2N3Lrbs(0OR(!l_q?Llh_%>DJr1v`kRVZA+O)TO+Ic6QA_omSmU# zl>=dE2t7`-E88MRe%tZ|ODZC||2dEULrJL#`Q|AAG z&}Gu27}=wN26uUHx;3y(3xz@99If{D$Wiv`Py25bi~{N6LJhdo5*@2pWmDZ72ujf9 zy%Af05HGGj9@=y!T>)%1aepx{gF-GAHn*p`js9DN**IU~un_g2334Ds*`;e%Et+4(GFBVS^0Sb{QD0Zv~k=K7nv#%O#q!=hf4p?Oo&rJ1Kut3R*a zpk9>!+5C0+^Yb-%pUvyeo1drFzG>_-&dvQRnE$$S=jEz%uH<-g=4Ssj`_1g$>;>6b zSzpN-$XX7LzprHuWR_;;BHrI;DAE5_Kc;WhQ@VfE9nn?j?lOK}+odhms?{1*mugPN zpEJhszrXvB@lDNRGww02QU|wf2Vm&~;(tW+SxaP!xa-RcDa-*1S8^SlMXtJ*j+P>e z)rvFurgIE7{wA8 zinW;4Cyj5ai>GS@tyF-O<&aUssZY%H-8*d~D5Vl;p5YjpQIF2?-J^fV+n}FuM|?N} z+b_U97T6ZuXHpIYOWSA*$ExQ(Q%Ib$@~nE!gWfvwcB~W07Amlp zD7|gtDCjBm?1#Ly3031|g7tDpxOKw5l~QnI8CuOeqked{w?;qX&UmvC(*|PJz`=8s zm5P<)Lf*>J>WAid*Xn279e-bp&Jky^QUN^6u@r4lKRCx*omc>D>ahvryx?!e0*Ggs zX4U+|zM1+N1#t;*!XQ?1-(lt1W1$(Er`6pL`|e2ny5iJ<^av&4)m?LZA59P+y^l+t zYq#G@F<3xW^-IrtI}PYS#JEKC01$Y{9lwAvuGj$xIEU~1a%gO zd?1LvcF zvcz|DLQ7(aq+&~yh2SWQ4c*}>_PsxGXc6kLW6#u)Q`hcMhUd*TidMVl_}-V$5`;sG zWKuwKRBDL@sivHbSG#8WZXyN5x-+oF2d4Gl#JTX!V@d@u6vuK_b=hoRe&YM$QoiOQ zVR3bax%tUCzPyA6M8bV0F2UKYRKJy{ke_Z=e`1c$m{34um0o+9(^k&HaO!6t^5rIO zCeg@krRwR(AU^YuFDLPBD8q{vardP3wvD%80Bq`~AM#}J*}dcI;7l8^MHD z8%wL7viY*~GiFG}ZeSNM)*6)FMR=6eLaCoD_GKo_J;F4&fn;C9FNaWGr6PFVVzyXl z^%EAKK|kZx_;O~K%zRw&MeN-aUR?8_Pp_YGd;G<@$cRJ8*IdPyZ4|}v7WL{mK3&3i z6T<<0K0Z3NRk(qgZu{qKW}0O!>Q(c6TK$as;OS7o+_BcJC<9s!8&Lf? z@6(VCv^1(v7nK%21)Uz)6m`C(G(cFu3#eBX`_u_N|7c~SyVixgoXJa<13QGsh3T4r z=s<>oE?)7FPeuA5RzCt}!4few{0hPkl^TGV!>E_f@nt0R;M6!mpH9Po3SSg1m!_*8 z!Jiz+M;ZH!>F_C{lMQuaP=Q)GiVMhUvBHY6sEZ%+HYU7HGEkw$Hb*_dDJL-Y zdovC&>Ure;|30lVBeOQM$nfumGloV3rT=&R30;-$K5a-lqIKq9$^TS7pZB}Gb9oJU zg~neRj~G41yK+OhBj5nMJ?BR`J95^5`|lfw7Fd|A&bpk{k!8vJ&&*M6P`gk2toB2i zZ)rAZ7HPEVtLjcQr}|IT300M9R>pf7uU*g4KQmuyd5b1~aLa1|#(r#p;t89#QC2I> ztN*pw=Sk3!iDf9Bv3aw_iWpb*FN=L{g)$UvO&(?*k8|d~6#HBXWhh#CJWZRi*{Xk0 z>~kjCtAgu8oNDL~WkE!pH#N`aAZ5f1c&Xn6Whe@QO%sMHzXGTJ**xDfq>yQ538T1da8R^a z)jyr@dzuunX0FdPt$#_eTmEl3>b&!O_Zi@+TbI&fskn3_uDYnJqSA-PcmTru0~g6Rd2F3JX= zE}Plzu^|z~4bQQgb^$hvnbllZ?XI2etgkiMYh8_Xm9Col#yXSPBovJ713@M`rc$Ilfs5yS=FU$d3DJ^kO3Aj*Cc6Gg%hLX8Z0=FgK9d6YSj_K70T! zeJLSo61AVdQsP^nREVNI z5cOfbUE-UsREVNQ5Op7Yd7iI?SV+^1jG{q+YY3awqW)5`uQ-K~6*Z6)%>kRm!Vs7I z7w7uskus*)`V_4Jm}%HNzc9}?SD_(_(-cdExHmsP&o@V*2*pWCTNvEHs^6OHo2}3e z#W^ZydiCe#`5smfLUD@1%mWCT`m-gzhe#1?qTY?f)uuQ@Dfn2-9LK2Noa=i~p(Tnl zR2-4dJm}*SPsoDd%q~$lX70tic>o>Ew9Y;Srgnu(q5nxC$@#d zSVHYzp69bnUxebsw&JFc#x>ccxjt^%b|@=P7PoY`Y?+wnW2YBFaZ++-hT$+F#^?E% z>5EXDQXEcWJQnE1c|LmjA{3`o)NgZPu8*3&D-DB-Lzdmr%sKb4WcIsX=*|F1Ou%DBlm z3+Vp~vbdavoUDvbWzWt0iebu7o%3IYyY%nsYjnTUvD%B8zi2i9pYPMEe^cF?;Zi=y zql&jkV3&81B%}hQJKgvC=Lw(RCi$E|Nq}?+KE#cu;RYiMG@a<7a_4d(kU9kQG}tVyTlKi?7NNLRT5bP7Y-4A4gUtjjztA+btOUKB1M`eUUsX~>0oIW zYjfKzEXBH5E6`${ZXs)St{tX1jNVQ#5Y*Mqb~uqNj!#Uj)ZO%>tl0y1joX4eYnt`2 zRtIu!T>zV<%oOXO>>M7U&9vEMrho~sn&R$eifIe};`nFqm5CHVY-q#w?i@eBwSfrG zAZY~xPQU;Xmp>H~LXFeiVz2PDwc8tOE3By9j*)1nzE=@*6!L9E%q@YK+7Qb>Oesz^ zKn2`vo4KLAy{Wyn*&G!|{<&P7!6tvHfBPj`g9ki{X-qLJu>8$Ro@8Dxq%RU$8 z_ofB@g#>(BKxvNTN+NR|33c(vJ#ssc3YHlNC1$`v0L0fYu)zPQyciMVD%f{?>b2M{ z#k9o$a~#F^U+@F68c-%uG9)qNQ;a*th8Jo2v=WK<$CDSw5fK^a9syyTvBIcfO4vj{y_nX_{Hlhpdg&pmcHRVl0f@({BrLzdz3sq#MiYQBw z*-}(eT2;qhaWR|WzD$FAK% z0c+XNSMDznfD!~;^T=?6t`e!guqmM0Ny>|`v&1KN(hB7*Ru4^CTy8tV+btf3?AWZ$ z#@cC$2PJ}t)Y0qJ`)8Bo;{%Lu3?qmHaqm6@f=^gB(HgGT68~nXOaI9~7(> zV)>*nDBQ5!fHd!PGj<+J`v)2nf*vtLk8qYmJ>o6%7bk^F z|3kBW*5~{rqk^m&X+ZWr-bOU^xczg5)hVq92EgRRao9&>Z1-MBdsLTs+Ii#xR5@3d zSXYYaDeJ2JbCU3If}<0NvkvU@1AUs{*8g3>=55VYLT$Axo-F4gX?{K!=C=|(FKyLi zsUMj9)War%Pp?`8{B%Qqga2WHu|--5_;v9EYf69`-XHrX z)?vEc$h%sFhP5rBOPFFY=M+)e4<&cwnSF#S@*f_aZRm3QA55AYKyLt!5q6Tmt0VYH zw^g*IQ3wNXVOu@&G zx)o1Zn!Z9YHpTM*{oc1vAWeu%DreW*+@)csb=nL(BE-6!0+^CVc3F{%A zGal^Oio7Vm58x-=3Bb3AIpfufpM0`Cl2FrG>t}`Bq=bg;ehr|-B%F$XqHZn&4t?m{ zvEYHU!FL*-5%Fp|T5BI!AhxxG;QzCk&u3&lpZ}fw6ZwPr&H1bIKbH5Kyzk^4$$Kep zao+8D8DIpw08T)saklZ6+{xUD+}*jAxr=gV<@_b*dpQ?!w&yhF6oLcb$JuXX4`+8} zd$MO|&&v8^*0-}xWc6fKXD!LPADIFFk@!2LKux-noff73}kCE(@f|lJ9$PaGMAm>&9&YXaUZncH}f^n`8n7 zB#&v{l7HzvPH=2`cTA4=X}jbCbnPMlc&GOQOdx#Xl=@NG_mfx00d4@Y5yXbztf2Xw zK-U}>aPsO2;GT!a)@i?fueM;eTJjCt&_e(UC)5h~1*cG?g`y`k^#Z1I!h=Ae!f_GC zVc>)i_IYAh!=!ksuS;}@68HB0ZHSN6Jb%BoV18nyq&gwXo;(Fqtuto{>iBrS=1(8c z7TlKb?9R@XN^N73+^n||qN_&`s%t4H%bS&xgD zUdZB^+PzNWkqxQ%CBYlm)Nc|e6dBTa^3o@EhPuxKLrVLay!45kAU+V^)H(&WaY<+5 z%RaC$Y?!sHO!~la_NlY!DI&uZmNb`aD+JYu&KTK?TuWN`jp z`Vi=9!21Mj746BC-v^KHC*SY)YCbHV0s?0`@Jqrcj^G3?5=d$OSw4OOp;h2&4<;SN zj^%}Esz0VJprkU7pAjb=_!`7t)PIyqG(H&Ed?C~~hKP8O$7?=LX$zJo6yYZz9An#p z=a1m@{PV6YV#K)^+xzpbm(_14m58ZzVRHQ7RM#%J^)w$$l72lVFaWwCdU(rlcvBx1 z9&+Zj{Q~p5WT3}R0iO@NO2Q)R!rwE=%wP9Lcwg7#_-0L?yx_56#CCyaWNLgOaAHTm z-$Nwdu}7nq_wv~AUZRe;Nm%g z!Fyy^;P8az#iTDsarG8Hu`kg3iuTho{VcK@gpNb8c42kkPRbPOUpF~HF6lIX5#a2l z&5Tna%)~ovVDtc?HJLiFCp3OEaCs}j)ikE079T_EETZv{dNvb55~0i6$=`d=sjHG& zJQVP67vVDql9He@#TPYg@|kmyJPV-%C*Hs+R97dpYd1;!+qxfqxTzg`OxU47$0P1T zngjBQdvP#)aw{}H?#X_2sW<395b}WV)ljX_1X69;_Mk& zzs~v+5dXfA6Ug~$&e5FqoRvBEF)Bjoj75yH4y?(L&qq;xozN0$;p1>z`59_p>#eEFpEz%;0eg!lF zmpoC5HYEb4xA15oc@!f~X2dn<4StP$ zL&W1EIHuU)cos8s^74@SsBGQ~5AFctEECuQXWVf-NuXI@8CCPwelpa5oIF`O?USTl zq1Z^7KbNf~Qv0@3qG^U_!(05=Jh7;t8P#j2E0xSNu~Y(wd9hc$Sf&k0spmoSM;b$7 zT!)Saclgy0CiiG?UvFSDdht|XXdKT1TO9dEfu7f=cCXjWlPy(JXf)B62;e&(ICXL6 z)bUHuChE`16t}!xuMP)#`a+oX^O7ILHU{P?6iF<~(Jf+$nnz@dA0>vo8!_^s&7;up zqIraupbMr(NY1?4pQ32^q){~(b_e@O1sg_@qNHA(qGKX&Y9Rog5F&-#mpo1kCI0sw0kJH3lnz`mMUJO*$TBKc^1UXWIQ5j zI8oVa?oA#wQ9Tk7_5pbMuqdneq520YIzh;x#pB^Oda%_Z#g43lahYL3`ghYhAQ!|+ z*H9nT7TlNE`cS`j>cCEv#V*lsa4G6OBzq>hPlgYBVeDz%ndWP(8jufZ3a#3LXC*aE zUhD;r5bW*1!EFSpZ+!e$m-Y~lzTFo?$M!&YXlq!t+Kowix|<+gynI>vOp=Bt#33Xb z_BhteVQr6WRznft`@ojo&|v`zP~i6z&F2?2zm&~EqP6zmXwU_kA#6b5UOzZ6h?#n5 zEOc@MHX!W-vhgR+4qPCN=YY}L(i7UUF?eW5`x#l^lc#_)3jnIoLqOUJZywToIeCgq zja{9(v`L&r1oC(MqNv-{tgKQDB?4x`r^g~=E+lcQKc762V!Jn)ODM5-SNP>);f;p^ zuluw`DFlda_IR9dWFREw{4226wO>nKCS)CrycS|bm;@^YkBA)rBFU+JSJW@dj7@Yyc;J<(4Vz%aVMOsbh{TZKI#bMZ z)%fa>Sj*AWu z;G$~S#KFFk;obe(Z=@(rKpDYPWI20}!OjnE?bUoTSxof*)b6e1NOk1^X^(WujOMM& z_;8d*i+~zNXpuq5RHVIG*wFE5gn2Hs2`1E$z{p7O+!e%TB@&%ZMya;q+*AsbjsG5d z`q&Qm5T?d9o5&v4vkra)1b+ob5?C_76D8(~OQ_6}`DThHB@zu9-cIpIA`zA0^D!Y2 zAOjrw*Uu^OE&h|t`?-H*ArWf8k=lx(ClNt zbb|#iZZ_iSQ2jTVs>4%)gXb8b@`F{fU3T21%p|lA7^vsAlOxj5so=?z+Hc90?!APl zLqM;%kIXM|>IzApkqzeGqlA&fO|g9hIp6mOdv}q*gUtg;?94xvssE>+mclxypS@FC zz)1SzDfoNBqlZFgCj!0O#riZa$TsWMPn3YY20o0LqHyB0#{RD{%S`mrNL_s!q~0ve zTA5Pk3vE!o*i}GXNwTk_C!_#w%fwrJXBBqTAoLYyaCHhLB0M(Tr(iYq< zdBS4BF*khTq`D?)a)i45p_3K+ z(v8F_fL9C;Vj7Swsb8y-l~`8+4OW*;sAfv$?f=>J34i{eq@6T7{W45YS;;$r$czZ%6u)3#Bn*Luf0aBP**Xaur*!L- z@TC5n-2YoM_hsaNCVzjvH@_l(VSYirD({EL_8-iv$}7$Lup>L21G%^6{2nL(M|0Nacyi|E+?$h`{jKa%+1s)kv*%`iG+UeX z)2uIK9nb2`vS(SdZpr-D%OZb(E~Sn;6@MJ=z$wOFnte1S&}0G{je)T z2R0Id-`Dp|PF%$uvS`h~<|R?#S9)Nf>b@=9SI0y1r*>YL+HqQ+C!Ecs9}^x06HHuq zW?;aI1?c`NIK~nllVzyr9}~`liH}6i=rS7SrsO)s)BH>XSOcUfI5-A4QQeqeCnppb z=p(x$y(=$w$5nE>_3B7j zaF;jGdko>;x{&X*xB%yrNp>CM9FP12CWmvldo&nUQw_8-!HUOu`$z?Pkh z(@Vgu1i~=AM_zg~f)_-g;VUoeF3I~O`h8jKwo6|j99tz4dSAs@;9@am&EFdwd?UPl zbLh+!Tvy+x8y8N6@fW1D9{P_ZeK`bDb~ps44!oxOp{%jsAwyif{yF(O5|TT8v;51E ztK`yBAQ#kqN7lX+Y$p0UPjvq&>*v(WiFz??Lek{K5PkiF@;W3GzWVjDNf+L@ z6Z8ULg3v!H?~jeIAiPEQm)o@k_ec_e#KATpRtIxH_iwV|Vp%czV%cmE3ErTE;B^Nt ziY_R)YvQdCT}&dD>HG!cs?2wIYR_4Odgvx(B1Bx#Tac@|p4MHJHCOtr?uuLrfz>sZ ziKbs5TiVwSfY)>K`bM{r%mpDyPXDM(Wy*4R%3{nH`f9mk(Cd zl?Bfn#xf*MoCBw@hk&x>FoI|To5Aoi3a_bdlHmVw86z3_r}CZov+~}{JCNtfyVLkH z<7>ucxqr!hE4Mk6hyMpgW^0)8%R}Xg$RZ`*8E)n7`yz>SbVU&{ca6%jBZ z0B@>4&+!5}LMjDZ?nB4W3`AZkNdfpGAk=WGKR)IKtQ#L66!AjfQG0C@*?}$}5&x}N z6xsuDbk*-xdO^gnL{d~A$l(WDP16!h*$0=tKKnq!xQvGI$7laMP@p2JRNc^}PUbdJ67Y_$t z>ke-?C;G^hnl8fpsDAyd_dfj$d%QF$`fWt-3pZ_%>-Fv{B#8>}v^|%VN*A$lRsXrl z3ucEkai}n{bb>FusYe{1NV&odi#QLJ$|az~s{eSzdyjqwBN;7RYHt`1_l$+Te$h9t z41dA^2+eF${c4Uk5lJnwJqcF=N>YIOfCKWh>X)TnAgRrd3nEq?-1K^QU<(5Eg4@Q# z*x{+|=akChC>tO;dDXwH@B&$FQM^3pNL(S{ehJszVq7A*YeFas!t1t0VJT8h79Qxv zz(`R2VucrQYmy=fPTb}bggo-tNGuQwasz$t8WWpmS>P)2s;LEDK(I-bq0nK345_Op zaCTq#l#r)7oigMZ3qV77Rd|ILP;3&(2%YW7Wn6lbxEArQ?c@pE1dE-j)PFo{2FC%X z3YB_iCX7e8cQDkyJ$QD1@Fd9u4UAm`8n_tNpi~~P;>^GTR0S7$K`mj8j|VZZddI?7 zcaW$IY~&M&<`a_OrfV!nB7n7HRZTwO1J$jh_i@K%u`g^-HzC^N%zyp>V?WVsha6N}>7KPHK_Afk|n6*#mFn+7?83&H-^TCjjlx3U)14@G3NFKW9rYIE#W)fI6jOttSyaIzo z3}sE6@UUJnz&in78paAt5sEzl zjAM{BslHn51;K?xejIBNhZf#5Mj~(a?o%oQYaalnHr3muUeH`fmMsaLIM@~RFFWZ zZ84OWR3{7!3)Tap`a-D}Oc;;E6}YG&(=U)>KuBU$eSV%7tQhyix0i@TB5cosnNI*h zWEMz8ONYIPke;CoO7+%UuRZ}HPFjQ_&|TDq`P>|@F7c!wVDpP>U1_{6EDMe)UiId~ zUTp&ED>15$?}LBy8YdNC)H62KXCC%yQopV&J}?i#Dx{Tbs*uc;MM4JQ-922#u zQVXKW^2&o=RRYO`sFh%IDZL%hN|zRUGZM5UEG?Li0fC`QJiT5U{1;;h<|JA*UfK=1 z49VJwnDIh(omdR`y9kBXkfLnBVib;EW90mQd&W?P>Z|#dycXky+&|=6a$2&_Wld&1 zmHEfat(o^2&Ks8Lzovgy_ZwZ8?iMft%+-8XQvs&HEh@Jv2e1B*{aNd;O(G5!lUhW- zVi}44+WBf=!$C3(>7WEwc~(3rpgy$JEMOwo3+JEo*BA%VLtrq*#+r;O#JQa|mxbb8v>TvD9*>QoogO=ml6HV1IUK;k z0=AzLsF25j-O0{5oo0^%j7&~YGC6D>fPyn_o6BW&2q=Zuz;)YE=dVs8=bhG7nC`Hr zLUugu^j8UkBOP{`voOuU=~&WH%7NjtZgETF5)pXiRJFfSn9I^BAgd+fl1#TzDQY|E z@mB~G;zr3-j=_e+FBQ_Q%F@zN#jada*R-5lC;--+aQe#)1^3ACg)Vku*_0vXIpU^B zXJwj8m)DS$X31g) zum>;h6FuOCAma_~Ka7yRbnB{KX0ot=gKAv9)LIiEqdwN?cM06LQn(x>C4~C-LOT>n z@nyo^ZODyCx6=B$r2?{;dGYd+@^X<)`KZ(HOd2&f+i)a_5DuqXOIwpjh+bV!Ti1&C zWriblen-+$CP@evN6BU0?$;4#T{t;05jeCHw;Acy*ipaq31OZ*Q?sU`O~lrE{YAfB zpjMW4W@vB+eDGw$Sa+2u+~F>G6XOUz7|meUzVJzbA1O=CM@8Z3e?saOFTh6sk(p*nwAa?c``{X}1Icr@_(hB6#Wh@S<4 zo!-H8d$xJ0rGYf8YSAiFO=Ja*RQo@f1h*xsFHt$i?p@NYjq`}xWk>yz*0RXVIq2|z zA_+rk^3uV`IF803Hm`TLtZA)rk|x=ft*WYvth@uy`kza}kP>e?(;Om`saDwWt4muO zJ0pAX{_afwvxb7@GK9@T-r#FPqW6kivE#A|RHE>VUFpS#NFR;%UP^G;s;U}KYrVap zg6gEGN{2IseJT4~*r)-*8^yZa*S*yLjGS~+m8>gjllYk zFmm>w0Z*lB0C9kg4k90N`Uc?og|(Rh_H4J?!Jo#O9S%1~PJ1rKP1`O1I}LaZ2)IuY z9JvHE?AV3*^wNWyhT|DG z`$7K`LKCE*5o3TCpCVJMH=VRo=q1{5}&3q*cAHiV)e>dj; z>ZJJ}Jbxm5ayQwJMaXZm87DV@a?&m*2mVdYY;`y(huQ7HZ%zy2U_4GBQva_sU|08} z{#698J3*rcPMr>&*iLerhWf}*yf$>L#uPai%osEYCoTZtIw+fqaXHNvrwfNC4_F(n z*_t$UDN&=sa^OTPZNpAu-Ul;2YFM9|3F?aZ*SgnhV{m8fdycZQJ4F<+!u5C zod3!>kyDNP|DRGc)p# z`n$!x@`URUu_iI_;RdCyyytIF>dK}fqewM&gHpGUoW&`&u)U+RNL+gV6O_8C)dZt> zpDNPnQD*f|N_Votm=15d`~D8LMxJ>p%8?f zvFd-G>svz#i4meEHiuT6uq2{U{i9;vYEnWh^h8#IRZ08Oh-m^x;SWoEtCX6e7?417 z6x_(H`UfSx$CV0EWY`1gFNagS`uoMcl}fEqBz|Pz24g7o_psYOA`LN?^~m+?M`Wv6 zt|W-!Y!yRT)!&)#TSm&5jz3ayu8M(mHjDb(^L?dCr6^8Tu@s(Ce`}#{DJkU>saKye zk7Fcky0NjDx2oSM@hu@G$ykV^+dZW?WqFzqQ_|{xD)B8=DnxPC3gXZf^*71=|845K zGV*?rS8UvxJC!>(=Xg$0_QmX_S??eM;N488;hTopK;xUI`;o3xJFYFz^l3h#9#Y?> z8c@y5*z%7z%T$Ag0;jS2KFQT3!A|pSG6hcb2D)|AycdZkz27sH2 zP`J47F$Hl|rMt0#?&Lj`yS)vB)9xZdO&xWk%fBSP7sLCi`au&n+t@876+-wpahD^8 zZ~Ge%XlnZj@c&JYpNQ9;E)I0kyoL7AcFyh=+_r|Bx^M0W z4IE?aE|)Z(Kp@Fd0pk^=pvbCql(WuGs@chzsZK`+Lnz>!c6V6?7?{gkZlTGP1uQ`p z8*4UOtt5Z4KY}HPt zyus7nS;=;mdm8DsC_SD0bD`e6Pxpi44VTLcrS%H_!APa?x>5{wjnl(cHQJr^W_ttW zu&~m80FM>L*%3@345%NVI!@KDyZfq}icrLB(8us6D! z>RK9|?xLb*uE<>EUcIcO^wG7=YunA%rHdHHnkSZ*3zrSFnR;ST)6?ch@GqgV-0oZY zLCJ<*{)Du(BbNgQcLlnRAaQ3%`~l|J)Yhx8xZ~21M&-D+8WYj$tFSGVxtOuh_jOs+?+XtV%5syvw-j0tYV+SvX}ej3|=qT|uO* z?(F_Yg^Nq4WDKDj5MLSG)E63;3|oo`TkCQ$&2~$B2h+}WIGR0@VT&(Yp2t-cGzV)# zU@BsaBhnWe=$OCJEHB5CT2@Osr3T^`qQ+fzkIU(#I2L=V2Unqx zLwvu6X|Wm9?fu|%!v-R)Ig({0rpTsMwTE_K60$7rzAa`C<8nB_Ug&aJaP4H}kRyh|8Kn57j#w*>c+LYHF%&p)1@i@f`wM2+{ut8?b^oltrvNWfhHB`745?f9$@u zAH;N!RI00`lG5CNSJDRF>2lMRl}vM`#pRUsDrAMbf~;Vx1)&0zXmiy&5?>Nz{R3nL zznzk->GWy}Q={Hd&oSqc!Yx3 zI0{=2?_|MhYlo8LTo%Mbkt!8~rLXJaUO5T`@zf5t1DhXXvr{x@_n6&?>2NYOCvQVE z1bkyIJME?sj!k(i;4@~NB=CuMc~~2!C&F*+jQ+O-|Id;+kdgmx{=xi>`OoLi&c7uu zl=oKNa9(rXsyrqy-}o!z=ZuGpUgNVytMMjy2rlPt%k9X0Hg`_$UAfsglR0najOJ{~ zc`}E}`C#@Rv)|1g2liim_Nwd$va_;&p7rIdLs{#y%ChLJT(Am!KJx@ByYc5n58UX1 z8$EEN2X6GhjUKqs1JNFkqbLE>;?=&w!0={~g-!oK84wqUKmfz7`xk+8K>`RR5aNje z?t#rmNxc2#y=8&XJ#bowj_=m5lNW>MyN~HaGK7R;5TTD(5!e~*A0R({{rYYJ@?7@R zmcZt*VE4&L_6$5gs42MnlDZCMOQ)zAp!u+OU&zB=u`Su|B22=;(-aX=3 z8OJdF26+|T$B^#?M^Sjo>p(pT4sF-{PTm+if*-+`R0znM(3YdXp3*aN6fntSy8n_1 z6TApYhpq6}!i5ZM3nZ-|H%Rvb8D3n9|p)Zm*AQk7l{vn&TAi*Ij1O;O%5qgD7=LlW{ z_+*gy0ssE!LFBYXW{&<|xm1Mmd+*fI^;1VK>Ha+~YenMC4!BjGD!BH3FR(5^xow&F)$AOO)z9>d7* zAxJZ!p-TjHCi+j(yoY6z7i$zG>Y*){%1HY!T>`u)j)b~@N`5TjKbCqRVJ7n_e(W%`h^&b)_9VEjBzJ(nl82wN;fJcXbwE|~Rz_(eyQQm{dnjbqyAndmE z-77kjKzF3im1_c!mX7Tst83F9Tm}Vqp45F$rnHqZEcGtAd@mmf?VJETOyJTUFzrCm z5YnMDXZ5A>iu*@`XoZkrND{j@P3V3lLp=-%kD#l??@2N#p)vGt*JsIB8FYlWGCv?! zCP*6tEv|sqh-AuGW?@8!kRsO~2l1u;R=Iq55x}`97)xYi8-QT-FO%~>o4GC{|81QA zyYipOH|2jI?+n$y;{oJ7fY9$WjShk$&yX+5#!e2ENzV$V39s+c{YeIK9>0SlzLOK%L*vIyfen55(fv(!jKrfj97O^E zbzhO8loR83^iW`PKY_pq48W~`^ELsFAa!q99~wNZ*U5$wuS{MU2CcJ+czeJgfASpc zbNmw8GXg|*-5+G;cl>$L!vw~@$uTg-9wxw~IE#002p{f73A*3Q4jnNxa3UKJ1R-0v zcYt6KUfHhK$cOF1A$XgD{tdyQUj0gWN#_Q^Q4G{+f{5xrR)+rsj;tpLt_Kh6>t*X; zy0m2dDtVQscHq27kWxnddXbAhen^`(-c$Egd4HZ5!>J^2YA`f-Cb)e(aCkj}7mtKa zBV4c_Q%HZiyfG&L<~k(!Ufu}o=qnQsHsRqng5CZ4F4?JwcuV>>01j36&+>1g$?y6# z0=J?>^lPDR=%1BOcHs@emMcsF{YT^zd%Cbp-IwK3jcg|n_`~b zvJ)cCl{kuHxJdY(pg;9`nZpZ@K;enlFH_zFnEI1rJ-YvpizJ}ll8T4}YjasF3`oy% z+JYw~p#r3^;VyC3!3jftKYO$==By2kbWiPCuWymDUyvvg5GH^lU6`(AV5ki4@4=!d ziYVY#dCL=D(6`Aa|0{lB)e|CS{TBI%Y}o`(V7)~?b2lUW`$%xx2BJBLg6TaCW?B>j z6{63P_uJ;9;X_0(Kut^yb>Vlsr2DbV;Q~Au_yhsoSB3=#V7tk&VST5(q)mGQy#Po* zNFrVP4xm6P*X?YJ|7Bg>cbKtULDo_nZ*CkP`{X= zc|nt>elfo{?>BjCjXyQ6$^Av{b27*c zi>5yQH;OP6W@KnG3#ddWGtpfm_2{H4E$vt+NL#k-DNkLoh`&WU`vGhyLroJ^d4xSA z-C9z?m{HyD?+2hEBFd!^Pa=O(@bV7KTp_L;D;_$vcOqJ4t1CqmR&52#AV0v?T+`xk z*!d1wyb#AD3e=1!K?{qJ7=#Xq0jjc>NKA~uT-FaP#5*G0+@0IM{6@BiG=Tm8`)m)4 z2{8Q-N1ZTjl6j+)Cyd=(-as|DTAQ6#S1nD+CJYN;Ylfu|-pK*Vh-YbW!pL3{Cd|j( z{Q&>FKXF~cP61vW*#QK~oTw<*yZ+nQRsj^RbD5hltt=Jlxv#EYME#S7kC(VR>S|qO z#5&$FNUWG6F`T%R>!ix*EVr@c^%h`B)tYOXNV7>^jr?<=#(NRw2k<{xm|vOuxA-rx&t zl^shKJYErjd%N4w4{SgbFCAXd(ux+JdPJ+tHH}r}ZLUg3h0WC=Ok`n1WuFVZbXP?` z@c$6?Ev;kE&Q5!$#oX?xjwYtbKNqUH)7=jYK-scD zb_XtvV2Ol>&%uC>Htc%)t*TY*H^y1DtYxJLD*G|y|A^3kQZ0pB^<-lvT3yP1taVi~ zEv+>!b3t3sy%IPdrN(VwW@_~Y?SKAc$Xj_ispfkPa)}mvrsH0E>hXMf-rZWO8`2U z+$ADSprSCfl}(8EcGg-ww%X>(8o9!@urv@Pzy<+KZ6u^nk#s@XOM(<1wf6&U5Q{(x zbsN4K=a-AhalO;B*3>C1XLhOevBe^y^6i+FfB=+brKJoeh}M>RR@z-PTvbDDOS9YF z+(rwzPRX;9r74mp$AALJLej1x^Fj8m(D)hMAM6LTAI!)GsiB(`uMw9j)%3J8Y$IRo za#h=!DgefrFfnTD+U(8l#u|HLH3Fbnind|J07guR*{4MnUMnj=5beXY{lM&lWK!is zsE-owO5>8Hn6lMQ)?H!cTN^5B=<<$sAyJ8FL;2@Ig|{Ic4iI~=B&5j!!Q?At#VTv7 z%=U^JOEX>R;A-irj)VjN3lQJ1gV}gcS|BBfi)2R0UJ<1EP(?ow^JKa?EMX~Bl%mSR zJ1I|fd5g1+=IhICv5j5!xlq*ykrW4fyEVq{1oF)5U@nczkRlMi+U=~ZceK!sn$`}N zy~ab5pwPegCh7BVjXFA1@*Hkpy+uPi=Oh-#|y{kH5 zi3o{c6iF8WH5t+yklzrsArfB_WVy9l*AIMh41rXZ;F)+3OT76hRz*#PnRC`#-JI3R z+4)Xdx+)+DZME`dnr6&47KtF(Ln6jZ;!A=cw;+*bWl|zd>WGlINGV37)?I0)D_qUB zF4~Fg)=HU395VGmWMpO`4U%dis$2e&Akxh({VS4lti`l<_yOU-BykvUrwH*)ib7Ra zQ8rISXNBA8so|R&9WgUP_PJ2+`;DrV8MkE|&B%Pp@KfaZ@6y|J`*ja%|0&~W{ww*W zyszYW@(jiiKpP%z?&f4sM%l2jcDa)Vv8SQtpPR-9WjT()5L_J6KRTT6;`ltKO z{(3Tdythg;tKeRW#79MY<$Cv(Du;M9ueB|)y8kXeLUIWP25y9|f|ZG8?Btj~&~qxV z`^wbrp2E;E0%1VdZ8q&ejtOEvCdXrlwbv_qy=6r)K{PH~x^PvS=masWuJhj{%ps{? zUaUIUwxfpDsAbkj~IumT>gAPxk$JA$&39sn2}Z_)^;9<@9lMs_LkyDgcY}9tv@%ZIx;ZH zkxl7VSKZWMCIIu4)%~<3f)&2}C4Y_pFfZMT0t$}HNRK)yJCS@_Q&(Gv+*^{DOHy&y z(zOd3>Pu^CEejStR{Lb=pO3097DG;g@^YJ}bJ zf69#)@dtqMfdqyg+L`VkGIjRlWSy{!El;+sTqCTLqV7BTK?U;vYnL%Z1b2u`MDaR0 z-7aY7+?5=yT8yWX~Np4v5J|E{lF-C7n=)$`Z(za-?eORSb5Z-X-`{q6OyEAuY?w!YN zXQqwy@XWNGnLg${bN_oE$(D|eWH~p}>G!+gM_otg?7hy~Ywx}G+H3v)lx@{!RdIL~ zfV!>##efdcgW-yi7wJxvNeh7Zb7I$PjbsPkLo(C}y~E9+l=f^04FuG#klHl~ctbvF z3M}gKI2N{SShsvhD^6oP$BOp=3CG{j9#9wJmwTKYIIsp6LVx!J`~2!crK25<1Y5hi zHklW@M_!=2`@I<>n4}czQ?F<+YHhY48|)I=Y+@h?EV!v~neKD)vWq~6z%k|ro*Q}I zT>p5sa|YJE=`YICk`z0>zMz-x{5`9dZt8JqE83#=k>}`K%yeTgzQ#EcGwo5fuin^- zn5u92lKy2bI>O&lM*4H^nX=OGXWGdoT)vUOZD>{B^0t)QxiC1=XRcqF9q*Y+k}yoF zm}$SgQfsSw@x~5+aJ8~Td%17EFw#rOUUb?_<#H6x&6sKbp@7zZclWw=tF#c*{qB*T z97luH!(>;@%(SO=o5pM77i|xw-RuReBcYt&`@}vZ%fA!d`4Z+OtsV>c!GA) z^`w(elkZqtM*=xo!rF|()<^IwHwjNrzmi+N^oc-<7|LQF>B@PH@-pb{f9z%>WVjtPGqcZ1G z1o`*zLl;T$04in>io$;bUt*@+wXbfa7fPO0k1y?5tP#bo^z1Ox#DvWAXsSCcl^fi& zxUrjQUlMK-NmS4M0`*-32PpfnbZy8w>x)~nd_Hiza6S= z^1&?3w9hsNPlJWtmHiI~QZM?DV@GMu)v6Azf%G#2o7v?N(1J>vAbM|CgG# zl$f_v_2+jx=6-kH-8IKvD2+u=Cg0k6AL@1DuUygoBQ1o?H32rY2|pJI$iryvcKDk) zUT%`uCI+M^M10HhDsT33A?WO%M@+f{pxcPe? zUB7N2^4}yNv+}&<9%omFZ=t~4$oC~0OtMwW3 z)?HnJCikW$#qDXgK>?mk>eTCNU1W6vu32$LUF4OPq3kCDS0vq{bLVt=mpCc2TXG%ZQB-=X!QQic@w$gGDc7lifTyE82y$iFPIAgw-g3Vpm|G~-3X z0=|oBCStyosHCLokFW`xc$JKEHCT!kV}5}TY&4TRe51}l;A=E~S~n=6)LRD6LyrnM2N z;Z|_T$b2!ID~iQ3=cjISm90qWW!Qq7E5l30Z?6A8ew+CdhhIkZQOfU1*~0W*kUe{# z;LxzB9zeZSYafQ}o^BV=xsLh#IyfMi-jIQGx`sZI51Q$TPv1p8Sy9uI zIphWn&D0kp)LEH>^PlN|A?qf~P(D^!K7yZNozBAa%9f{bynm6(o=%pJSJ@;7j+|7Q zLTr<-tr>fFvt11YLrs3SpKRNX_MU*-A^Dnd(j|WkEO&B6NuQevEGSrKru_6?a{jL^ zxlmFYuem{h_tlFd`Az0{LAG)ve*6r{{4oKt0GMYK5(Re;fh07Kvz zCuQgRKWB5`m_~+ecCFAwO9DNw7FHviRZd2n6weR#^etlgctSh#)WyPE=6O z;G;kh6Mn?Se0 z&nst>I}cIiAXh(jZnAtgH4b{a#w&tix7q}nTW9MIx)J5* zw*_(LT?iQ($tR5=@>U-Y&4u8!+ngL{R|QsdNTO)rMb(Bk=WUFWbJ}FV!q}a5E1^YV zd3;e8L5N|OAg-w5EGU_Ny7`MEthu2j$7B+tBY-W|4CUkj06l2HCIp8zI*63~0!AZS ztWLO94oD)~EKXiQzNH{Zf(>Ki1YOg|q#L=BI>7v4v+*h@O2A;H2%-W8D@C@MezN&9BaFFWS+3Cx z0`+(&)emZZ!E{LgOg5h(hO~Jy^DNhH9D-m0J(R>Nj3QVudR9fXh>Df9Ib^|Z2Z_@( z^e9d{CtGcz0`d~Ozzd3OW$lvF1`-ohayYDZm=-7$t&NP>$g=AhnM^3E8+LL+;VX=6 zmu)<+@R%G{1pk~CaGuz~*NcYiHj54MHiuPk@*E6H5TFc(=d4atjEPp89n4~;zuSE0 zNHf)oZmB_79Vk?qUe2CNoZc6w2+uJJ98|z)?5NZvIk+lWZWuc&Ie3S{SQH1|&K-$qKD2s!gytz_|n-AJ$^Gak8B( zdNxr03RcEq`$cI4uP4Dcth}l^WZ8y|z~ZnmB51+vyaSt*!w%kBEG!Bm$WE*;h$UET zssQad?RHkRn0~zZ_L2LjM)XrB8cFZXq#7Vy1(e@LnpIJ-+8Ievd7BekGsCE$(gKj zI2HR4zzpy`?3S{Vb1<>c_y*xTC1Ocs)(C&sTG%dZxWQ4u1y z@{9tP0R7klEvK^wXmI0Kui`>6zebu>5CuA+ zX1k5WR)d;-iIpT+t!PEGi<3VlR<7*Tl_jgI!08PI?`?A^ya+!I{96tuj{MLQ3;)Tc zI8`fV3ML7J#aarh0Wq|wfFIh4Vt$pyYGgP4_2%l4ubUhAoD~JDD>0Oz3sfxux2pQ{ zs|5Qd?i}EwI6zbhvxRGGv#1jK2aTqxsJ|#9aj=}tAz<2y@C>k`@G<}`5U#OW6>Kz! zBVtn*MF;1A5)d+QIs_KmBG|IQZi!Xb^jDj28~K{KLCkUBz=Ht*HvFa9m^is-;_%V@ z>S%Vdk{twStdo=Ma0am9uvU22qADs5IBnDGV}?tK0OR1uCd|ot3jq}yc#iEX_?LMB zJ{b>cPZY6RWg7~{K@`qo$pFJ4#>ryGwUMfd*qar}sjw=?W63f7<>q@v8q5uCITiw^ zcKkA+F9)@Wvwc^5%dPm9ov|zL$F>n%e2`Eep`3VfS5Log$3O zrr2>z!pex%7_&;YnkF`XcH|y3*g1I zfCE*5M{VatrzBYv6}~R02yG6lDos15K7tJi#JT0992>&^i@gQNY$9hT^IL&G3w~S` zs|;@waC*i5AlL;s6IM=gsMyTy7VPYB%5Ac0mrY4>{{Ldh+LF2Lwco3)NACZL*@@X- zt3FZ9S6!`IR{7s6ZRTG!x0rs<^qpDXpY?P_yux38t^8YMzghM~=?_ZV@Sy$=RDE|5 zsvdp|$8-XUba`_DRkKj5!>NES6FwPsHM{H-uz+wX3;zUD`-)W)5^ z6^9x-htfKSoo8@BaWGiW?J9N|9FUy~W~PO;z@c?=HXK(}plU&S*rG)+C4wVgCEjwl zAvKoH$W8e`UIJ^g?b!*+0yA^IBj_KpVH2M5N1c}%neV~guCyoEy%+Rc;Oi8gX7E_bd!}wq+i_ za*V?!@HRVEWD8k!8>euIG`rBXL52Q)VB|{$#|c6b&^JJsU83;?Y8^(3Qo6i~pY7=r zJ2?+*a&nw>pVMCdA~15-biHa=wuya|^fj+dqIJ95=kj;CabcrSWF`&YFZ*-a>z{{9 zN4{uo02WAH_5fwTv2MRM@$TEiJ}9osQx*whV-eD0qipKvcH}am`#0J8n!B4>D_kS1 z%mHo_saDM@5}1O`EXt`tjBb?>v;_Ks>Cc`YnMX}jH!%op^rcvEB z(=Pw;rIAmW8&>CZiGvOp43ay~Ozs*J@9rbW_}h1Bq3TIh8|@%I!EFt(o^Vlfr=7=RTcaSgZzQYCz~R{G;Z(oDUSCIuYqB-<^?H1+ z0L``R_IniMwj#R~8Kw-bN%`gnTfB?=T9!W4+p<*YYw2&{Th=?AE$cTh_-}TVcSFzW zZ%h5Fm%7B&>(?@?*0=SxY?At(=x2%sRjl^?H}Eda2U8 zik%W)L=07sIb3;>XrmM1L{7Dd@US__26$k4AUFN@uryLjVj+6%6H^-+PQ13O5!MHm zIn3{3RnLjoDKljEZs=XLer<1y_t9M0*DHL>(v7`Pe?Nv|QuX9y%s4D|E3SeRn}xU9 zt+;Vu>~>twA$n?|mh*d1eT|XoaYsp31qy-Gh@~1AP5^12iTD^Mn^I7E^QK4fPTNB(!A`Z-3bhv6q)e}(+qeWHrvCj@rle5>LIVq2<8aE=9@rNsiK{}!$p znQd-BS;AAt$R}tbJ=Er(h#araW<83v17+57RX?~h*@yAMkqoT8;Gpz!#>C?Rm!d1n0D zaT0e2c<c?n zwmV#~XGP{ziRC#-by^%OkDFKA#j3DHiNQq{tMz=&H|jRmJ(SfmVOfIjKX@v+{k8ao zeaS7mmaZVb9z0*LKOSD76H6d&XKYT!iAzJ^fI0;S))iT_Tj_;n<=Ng*m$?on)rup~vPFAg0y#9iJ^jwpDVb9d9c5%*Vo2BxaTnYT<4lH?4A%h2yCw!+dFF*t zr@2ne>KY6i#32TN{MD1_99o?i7$zd5d)D52y8anOvf{SKYIQKUWENzEkCBdnj0xQA zDjY}Gpvu$V8CA`72!v$3I$Yl5jT=z!TU#fN?y?lHBdaQtm^kt*ak-=LGMqE~2hQF+ zKCx)w>dI3aMja+}(KBV;=wadz2!;mW3L?srTHjns4`MoGAqluUy1gDpcL)B`#RQk> zxPyg1B1nw@Dy6D>FFb2hG1q~oVq-?j)Fd>?g(=Am+;(4EyJ&H9E~&ehcLaOsIWdi` zOn_q%69dk+jG`B0a$ z_G&EG$Yd5!*~81!=hi<&1$h^O*a`{4P6=Y*aRRejaEX4=?N>vc_FhYlAO!tf!lG@( z0bW3!7CGhUAEJW16RsHjj=7FP=}s%P=g48f z^$eUc3-HDPJFa1UV`Q=(qH??)HjTEL>%N|4BIDO0pz#IM4A4y--YH28Z6t)Oo&HX- z*AaBezARLDVk44Zl>`ABD2iy1h?E|h?1!i%Z$Tr^>NTRxW6f9#%i-fh7odX~KO;Fj z5{)%xnh3({vM6HjM>;NtwM82l-9uE46XDxOpE1{=STJMKkmJd@BgnLhAH0CywWXF2 z+znlx63fV7d`K3N+C{I!Z9&{QS3M#NM0hK*5rEx}yVbNB60p$^2{laHOHc(_$6^|Crkx<7Ixzg2gYKjcf|Kzz)tz$K%sjopid*q zpLfD+Q4s}y0I7sn;AD}Agt}qc`y1-$6XrTGt9Q5_*ol{}(6&R(^_Vh^-0Vpw(x-sF zZWk5g3rQ-A%XiT(IB6^l@|DvaEiRr@=mWb>hGW8fisr+w0ha(_Tk` z4&i241UsB6n-j54t5asMH(GF?i|at771JYc<&mz@$INwz8Dwm{)aL-~*!Hd3D`q$w z#k?geV?QQX-q^j?Q^!_-HtpYiv`(~cHEouG#9q=P}k@>y>elg;IN`jwPu==FD>Dv3%@4t+7Zo$ zl_J*(UX_(cG7HQVSrU>&lH{lf9c&+cRBuAs%*g0hbLL`0r_g5sy^`b{2CEdVVv%ow zi*~17MIxjXWg!?}M(gm^?$Nd8I>7j6=oN37*(YWoJws^SPXD6V%51nsmvH-v*gcY& zWL&G@9>oTq75j^(-2=U&YxM5&#DQq+*y&hwcVhJ5kFUQ9(n)PZwM8Lz?A=)8?bz5P zj(BcLW;3Ix@GOv@gd{)NW*3kgDj_990(w8AK;2Zw`@{1_SL3h*4v~zPMzD7L$`Onw zcJ%oEBVa*l#<6Jp>Q-DBG?OX3??U3e_h4?AMa}T&LB*H6_*(PC$^9C51Mq=y&@OBO zs3cJ=9JyAKRDrXjVAyJtB!q>qc&V&SJ4oyce{OUY#QR*9c*M{U_d7<648O<5cEsNx zVEMSrPknN05E@F}I5YX5hybL1Kf5y-c^|(QFcu`yNW4vzM5_aVHXLsh1g#jS4XzW8 zSqcr5RK61CMq40Si(a(&2M5VP?&jh6zPGeKCjbNwH2*^*+96*rKCu2Lr5k$>7p2-$ z@dK|S!j<~{OmzGzwt_-ZJM5C3WYXA>OyZCgJBuV?oC_sjz#{oqi%wPU)$adKmdth5 z{%)7$gO=UPVpWlvzODslHV{7Es zxVq$k=npYowbQQnq-K`*fte=+tb#He8r*dVxSa*4f#zrFo}=?;VYn_Dq-#cokbqlH zoH~~rLqsP+VhP*N5~@~kO71@cKGVd=dszc%eVbM zjhuNk;PA0*(BZep;0RO=q(pKc$_XU+XFQKULCQzeJx8UyKYV+%%Up-Ng$yYt22V}w z9hPnHmA?p(~V8DD;Shz1F_(!K^hQ;VDS+w)|A7jdya~= z0OQ+fu5;CdTc(UKcIp5!@=!;RsXQnQ{AgH`Grg!RS&dZa2q=M`0PKu!_xIQgY!P)I zECK+6W`eq}QxWCx9Z|ozZgH08=q81cB+L_+-p4YHUlN04J(`*uhKASUWUN8X+QYj% zERN1Oa|635{C@aAgh`I%0c(P}v!A1aN#WJe4y=$M1j-mwEf^BJH55CxO$*1J-Ue)K zNCs`jZ=8-_xkXGdy$Zs4%A`2cz7{+7Dsrkx_-<@8>y?bm!5vZsmtA&yBqb2+2Z@q? zy2D>4T84vXK~w|*yVNUXKSy858vatW-CVaW>y5Az)0iFPPmY|xE}6J+20vj6_>28I zOF~1XcdBjOPOeL4LpYA&PG2t}mLp7Yq{pMQ19z}Mq@a-kclL8sLQ8ml)Mu^(=5>b7 zf<{At3Yb>)!>&Vi&;TyS~qOXf#`uf~{r#E2qMw|p+9|_N>F-A#s`i-)mqi-a% zM%(BCH`9rVoQEHdQ`P13n0Zs$%{fmotetgQC0uAA=Tdec(GbbxNWEbZUPMKW=JWIZ zsMlNv)a{HOI2N;D=?X2Xnz*qmaqW;6$xR$5aohr3!nH@%zC!{wJTP>SA;c@S8kPSu=hQ_EjPOYUA zU^GVp=An17t!pmal-Ne2W@7?DzFq0Dc(^_l9D3QDSU%l9({7nfQADE=3aOjwHXeBe z7XzA}I40}tV6cX?sV=pT?{{(TUX%+3X&{fxK>g>myXNqmC_>OUVrPV25S@*`d_8gX zOk&SPbiA~yqo=*_i+TfY#qU5s%;!cn1ihlqjCmkM){4Ug!m79#gWs&J2)c);JWb(> zC_>WNu|otrpn2>I6N8hy491kAY9}0x{;qCoyQc>{5xTesYTwX3f@BzDa#5Dv;jW?u5E>t(dM!D%Kf3XcCX~%oLQV?t=R;5NPtBQ2pRQQ zg)n8)E{CoGD$spla}@Dz#OgB!3hNIJ(D7H!#G-G+N9gsecIRWTaJRSdolbi%)&obU zzYjS(*%2}eJRhXWi4X!S2m%RojPwstQSNm`L57NSMoI;d7(E+1boIW8eK&wAFc}Wg z4!u))%2`Li#mpm*99IU25u)G>vl|7Y3W_lV8`8S9v*tHmh}tLvb7oI5jd(1!^*r`6 z%)fU83NkWIBK3UZ57g-u5izW!1a zl&SEiGW*wpF^N~V5hwYzeTiGIC&!}L0dW78e2Y}EVk;meh;N0nR`nbWu!wn~m!K!j2Mb&<(#ZdkyR)|yA1o9H>xqI-bMH)Qo8;RN>8e6@JGR>O0#h@I-^wY|3SG) zmG?X!1y3qXo|)=W%bY=U5ql-HjWPZY%ABdZ+ZzQzD$N9*>VEv{4w8`d))?Hm%!FKn zN#*qfkS4?i#de8fgI+qRX!e)xb2@Lnica|ubn$+rjavWaWE zW9J5l?dHu-QrrFDhs6zko7yk;t8}hQnM+?P`6(Wq>7N%zs%TQi!t5Lfq`)9>YRk4oBMVhN@zpDEG2H+?9zQe{+aybhowpQl1-iiFIEgYBBu|=s7ECzT^^}1RD1Z z&Kg>}USjxSd=La|@83^zj zAgiq~H-IV2SOw%vadRIaO>vwjJEBHFv6h5;Ww9v|KvA3h5qXP_*k>)=9Q28Q(iVoH}3 zn9`bR68rWhZ&5zUB2|MjL2!T0>!*gKry(+NZ#Cz zeTeu8hmK&pW?(Le5THt5oWbO}6*fnnFR&XyoL>+Vo9Sk_BJx}T(*-IDM8QvxYt29> z7DUZ)Wm>$g+z3}i`soN6+X}K=a5auR0kRN-zVW4`c&FFln{ zt5{IPjvNN7jJx7YIj+1I2^qPRIOR-SJ<^CRo17LeUYe02kirRsA*T~zP9&rQl8FR_ zB|AWKz^`r1R>WmY;%;iO`T+r|!;UM-$mK>YdP(XssHx0I6sH5XcE~2RBNYI`$UI|5 z5`X}tC=SK!KyuW^l;#*;>Wc*F9B#~B_G4qeuu^xGWMdHz2W8-}x_)aM*MaR@r4_l^L|h)MFurIaTjh z)a*bog$L#bGUjnp4d5viW`U8x9;5=`g0p9i#03~dr;$-)$Z=y^{KCtq&LOE92PuCX zcD>>z2qJyJOyF^+4t#NcIP-FQAo9jV#kC<4h2dWka-Mn09=oVq8)eOxGl>NeI(6m1yDNfssK@F1;KRsf4n0$zdxYdO-N5Dw)tg*a1<(>q&< z^Zy^uy*_u}+>W_R=gzPFi`v&~zf(KEw!G#~YOd8BtLd+KvSvxmS87V;Ow73oZont! zFmtMBe>nTr?BUt&*(+z?JG-*__p2{f4^%7Fi>kj|^|Pv9s~WCqty)}FUuCZRe&xB! zD7yIM&nFuAL<65_;1dmeqJd8|@PDrc?yRV<%b!$DARZ-uN_3tF)*n|qg`1RLK%GWFE7iInH04~@Y@eQ0kwD7Hl{4wkI?ysmUC>TD5A_;^&G#{BDD2%-|>v#1!p`AA(8bLA)$4(%37cD?q?PkOD znfog0AIj`Y`#!!9kB|gKav=yPESlbHy8Vk4^>=4}d1y=Q`VlzBu^YQhR{e+#L_yJp z6rv_1{>EN86o2iI={a2k=q5RGoFMFOeb2N}sHoqN(K`MSZ%2~6PHaWQfV{%+ZjwSZ z7=c@iys+4|!=_caEs|K>sXg&Gwws<1E9xK5ZV{#VKhR4>Qzx~nY|}IIE9x6F z+XpS%@olXHjpV>?-29q4^-C;?A{n|_!X|t&> z10DqCn~V;}Mvou?J+@=t_|^AJpK7Y8U!M8Md6J8D{~A9s8O%6R<}vALV0vywS26HIN> zBRP)&ly8dG(==DF$;-n)Ge}+Oppx(4+pQ#L{Iz|ic{v>*n|-foRJZbsUk+nRwjwV! zHgv<}%4vQIYPD%%A6AkZ6dvX^Q?=f1@p5TUR@1^o74>ZyY9ncQrw@~dx9#GY*siyc zahAAw3`GI)>w98*&S9!$R40whx?JFSPMrSvONE{)CzP6V<+|*DJqUIoEvJ{E+DnOhMCKvwmfk zZB}VTsQgFePnUhK?CH{9FI`-68Ql5PMGUJddsZt>mps*h1o)_smELl+Zb? zDE&snSwN){0M>vrXypMn!dgKFkQHe>75;R@Yi>ZLk}i~#5+Zi`3NS8#VSqggW3S!# zeJyqnX%?rxJ|n4cy#;tl8O3&}BmtH$K++Xf6l_ia{MrFMoEcks@5PA6DCmfdJT~wS z{x-(mxsYOXEjqX*I2Fmk0G(X40Pvo}wFL4FQ7(q@aR3)OOMsKlN8HpzbkS&RCCNia z8!;o27s$Ot*5yFa(eOvtI$E5b;IfrVmalRP53cD~`;8V|7Zlx z9DK4FjR2`~M708HxR82JO2q{SFnvW8C^QZRDN@ZWvfUVf-Dd@0wfh>BjYphDlO`?E zt^H&}e)Dwf(giFeGm^`O`yv8`0yK2MVA>=*AV*O{2=H`8L|j(Mw2ZeA4OWe!!D%^; zodZ@G0J;(%oJ@xIBo0oZQWh1YN6Z&NPldGz4oqFt!~k7a1llfmG?2h8W=);9o{2b2 z0IGZ`dx*3`A~IKQ4MHVpO*oLI+tk+GgNw6v&~*}AmX7W&MQsiW%|JmDKp*;O2q2&< z8UuY42iA1rnTTT0KJiCKuE&Q7Y*g|hMJy&$AaDDm0|FV<+{bdQsuFr^g=;ZQW;(tx zVmCJ+iMBNR1vEE);_{^C3N~$#o2_EAeW|>Pd8D<|tF+LzkFAf`ObvJD=muA=SKcT_ zCBU|_@XhYE8&~#y`ytOJ?*`iJn@>l+V{SnHu}dL+_bF|g&>p-aDwH+ zV}7p(D7d{FY4b-rBCRx)=h8_vkHCZrC%kli6NEU>!4CrfU7H+KE%eE4!CtKj$)x?%xq z;>BjE+1~faYWZ=|CvMb?>GfwL&zOK`q&L>XhhjG`jbA^~2veQPxXEu##9HNM3FK8z zbS}4ZD_1Y!wGlrOULJXx0NHI`p8YQHyHO%W{Jx{Fklfg#Z{ajb2FVxzhXYoqO_h0q zk0=AEwvB4@90KhL-a(7f&b89K>tjf;#^@{4!8e zm=0q=o+OA-n{^pZm?k>bk?G#2`9GU`#B``HvXLSOHfI|boL-G>2WbPzqv6!3(Dg7o z^^>N3dfYaT+!^Hi+WYuGFIHW{PsviS2nfimd`~F2kTo3)&xt%iT_iTU^I{?nQ$}JS zPaEzVRiTIJ?ClNowg(wa9{s0!d0zEL9ydZ!gbEU)=Mj>ClZMqJbMG-sj_!0bZ2MjX;IS<~{Is#xF-Ol?&H{*c}8y9uymZMggci z1N>@ongMOC17P?PrKK|M4n)>a2;te;Bbixb z^=s92Ra+~6Qu&zqznB-8PMbb6>-ma{6;0(=%PnPB${r~F-BMf04@;i=$fy5~$SOh< zfXbh&ktPMG$V!d89((zf*xonhPmX+{mjy#ljA*yh>MF1HBWDuW$9ZQ=pJNhHbX-c}TXOEnF|H&GJa9O9 zZY$<$q0VIqIB-Z}ViZt|pllgbLL5LmK`ID32hfmELmCN}L>@LbC^@#P>wR*SLhmFp zdgyHwJ0Zk7jSNUH19BqF2pN#5m9yYP4TKiJNdbVuE^1|KrbuUGnUOJ1ih!3UB}E!~ z16>&ly*CcaaN4m}@G38HIKqNTM76?y2eXN26Er~8;c$86+vWyO?t4=;7g?}ZP>dof z_DtKuOCk@ErDHRny>#GuZ2a=OH~|qj;Mj?1SZFCbE=jQx~6_1mM7% zOx`kK@(`3@twicW)ao978&T-kjSSE>0|&9qF1iS3PskVSmwA_@tB=7@tC?#(}7NcmR9w#Ne*@)v+m!8;Rwzsau3m}p zx*XkzsIrZyX3nVGYSVp#O133j8F`TIk~+yWCw~0$Hn@@GC~@vwBb0;dI}I78uq+S_!HD>rKBZrBw=tbwkE*nB z2Ji={vJm0PfW6IvsE9R%^r3r>N)-;@8CgX4cAZpOSZ!k8dBET|Cf?hXxcYu$^5U`a z>lC6iuUG8zFkVj=w)4(jsW<3z=L!etEJh^YjDXMtQbHOLL-!mNZXi52@+~@WE!ip~ zSJp#7v5Jo0ASf7(xSX9hd;q^qnUBHZ;ZrI&(0!eX z^iuea$U^ER==23)04FWsyiU)+fOqVlP9>Bu`1rS0BzYk&5z4(0Oo7B2=HV(6%xO{x#&DW-uq=HInb9MDvoWXv7&@1)|9;626&iCwZ(C%M& zK61ZN_vjdrP1JxS4-YqvU%Qsrl3_mv#@*(#x%@W2D0KFPkP|$K5}^UBP~-;PH)!|I z_e2&@{uaHDF)#ouFYREmK&zFCb-6P8$P`T*5pmS`~mO1Gxn*2+$3|ObGNr&4KO@H%26gb$^annlzbbv)CBY zHQ;SU;*pc&_e2sm^(T)W6% zmjhRy79S727!k}3tvNcG*t{DN<=EIk!cRkT4k!@!_?5%Z%>2wFLjeJBf(Hc>N%9Aj zG{N5%ac|24-vMQKV2RWG_3m&@1dQ>hOVLMBw;hXZ1IRi_#%YY*d;<;^a_$ioN}hd_ zbcz^cF*Ri@yk~YM1zf@KtO!WjQTMGY&O|CuhCoBZ$;itykOLtNfF&d3iF+x3M|(hB zh+pn;c69k{!G&;M?+Nz#)rCq&dr0jHwsv=IG6iZ%k|p<+^p?!MId@a(GbO#XH*3AM z^J;#*W~hdl^SwE{=X`Va4`;tTdujDwRUa<>pH=@_^?sGJ>eH21D%&d?%zt7YGK;3a zGVL|3GF8kviQIt7ieIT1sIZhzl{9 zF?Qn|K$`C(b?%o@u6t}^;MEi-5OE1Mc|t(yP=f$1_csMQ{LOuR%`6Tn7;JD4O*-U8 zUjv-B1cpAo{KK-RO1kUWnvI#=T_2b@eu`8FAA2jYHImqIGHqu@P0=1vR3fkycdQzE z-c&DVHHKps;xx&TbMrNL(24i1Cx$~qt0@>o=1UU%UI2t$KMCm2_$&Je4Ih5KJ_&bV z+&Ai406{2mh2K^rc4znvyr``7A9xmD0{L^Czy{nz%liJUw{< zljptBD~fv9irXF?>NV9rRI?%Dg~)Zmt=AA618rgK*vVAe@lz+pZ_@J1e8ywN4LRtm z#EQ8qhI&jotI$*dzOLB8qcDv4c6wKsuc?$BVv((=T`?5OX-q>!y>Q zV_^1haI-6FRt5@5{$aa4DG6ob8SuCgpThb;kV0kL4zBSZks=qU< zCEP*8_wFpF0hy_&TsqWgs=qtCfvcAiTMr=jC4Pv4R!lc|tW;roY{+k_Z^_d4*N~n@ z0?_ZA{d)2PWW-Vo?y=X%v1Qun!cj;>*;+Ac*-(dGRq^-tCeMUpL)$0zjQn7T-lXRj z5y(lvY~?K#6^{+Io9dTmy=n61jo4`bA`!CRRMI1bNQ#Hw23%}G6$;3VAaOjlqHNia zPcLF(+aLjrjv#CJ5NxerOR3Rh*oxAnL!0!20gkoU*cBvs$Bs=irg&47&WlV%$-1F7 z6VP%p%`3KN45Nva3(0S>8+$py4Hjc^>_0S#U}jb7#W8$4#$qyosPP4#ihXRQ|3{(CuD~DV}#>@o-RoDQ- z)r=PwjWmmCw1-nZfp3({|9R<@qjuJm{dtpmU+Xr9%j}H&2WD&{~ihx7| zrh_hNMa(ODV&&!Xe|T)jp`Q&?doac!wsX(?*x<$3*~|0kUOcT0gS;NG?ef20JEZ6b z1A~iw04En7LmL~rfc)d41{joVfaB%Lf4*YKu3vl;2lvH?_Qu0w@qt(3gAt@dPd~B} zkmk#Owrt3zw`0^ikW`cF0|@t~%0&y<9X1(w6GHh<*9?8fRKGZDI5>eUzliMJd>6^n zu;HR62O;PNNGVtTleu@6wCHwJAot*YjvW1frAL1${H7w=1hLUne0t^3vnHJffopLL zC${=2Q=Xs-5}Tf$@b2bwng>H^SQrvrAeJizxOuu7-a0XUnE&uCfLr>`Kd(ulSLY27u0~{EO5&x?- zLyr?DDpQq2kHf${jsU?h{@S~-%iDoMml0_&9&6w>0#lP?%m4Dxp~uLS$!c=oWfI7^ zaVUQN!2EkAwnb6UUYxTBoM%xG$|t@xv?0d{qGyD{BY`6jxaYAvCm$VJua}Ax*c`lp zto-pS!?Hlq^r-`rfrf7Us$}+AK)7C>cw}gu-dZ%{YtoFbNwb~8GKy#qQVQkqwL_1R zO+C|E2#El#$H7KUiX#qQAY~WPy~(Quk7AMxia&-G%41Iqt<}#JEY#yyhvx%f5WmeQ z6MO_z3D?qAS=d_;KpMm0oF$cy^dOyB#Ho7DF6PVp%znpT~><(#`V3Uptvg}6?iYO2e6j% zzaaPj^GbG>%-vM`d$kK{Uav9F@y-6;?8Vhbs{X0!*~;Inl*~uWcbX!z{(hFN;twnC zFMqfEGi76?e_N`Q{1}gY+<%@Ky^TWCW}q6U$?v8KU?SuLoFTBK*}=w!fSeO?KpS`( z?25oU!Fom_x|L6Kj?OjLWm7by+1Owz8gmt~O59>?9d2rB%2*i;C^bMigPaZ<=us44 zG!wvNK;+nf!H=7ID@q7xpO1&DM{6kpH$PRZ0aPCNcBGp_1IZI%0GI>e?`um}VDlyD zMyR11-cB>~$uO z$bj0OKzYbc>@VQQh)nD`Fn%Kn4*;btczeJ}Ps^X6c>03<0LJOJ^h)N$kL0O zhiph-f}YOQJ-s8s91HKWz$I$#24N<~rAfSiJL6F1+E92IOWxXvmm`g(?mV->j=CfAQN&2gGB z>v9Bby=|Um~b!`0H-shLj+A+Qn?!v@F0*MpJQ}M#vq{_HhFePv!3MHY~l+;>#-@ly<*7S#r3F! zAtu+X;Y{-6dJ+J6;0Qu$HC?CO+0RkIR)*({mQfJ>j5!9GP+tfbsUr7{PLIvy=?eIK z{%%`W8n!nB)E>xI0KEhe7#PkaAiAbVZCu&UQF&Hinw3)P$&e?lsN|tTq;h=gSrFP} zS&va3hMN=*`FnbL-F>}YrQb+PR&4HIJOR8ESUS^0hq~veRLjGkA1$HN%s?s_5xL&K zxevYoSqQcR;XGrS8OkPkCDjGcdym5&au~3~kSax>6FqM!}bqOFH$#8!RlaRw5mFapVJFz^K^w&t1Hw8CP3N9%%D3fLDR$G1@~2=C2eL| z&ruyMSKK>eppk}t9{0`X5Mad zcDW^o&xmA&-_-7~gTV zs0m)8A|PuRG}qLz_B5} zzfU-mrnYHAmG#(EudUt5cvKKN8W`Vs4fZ7jQDxlsVh;f8rZsKy+0Rj_9>8?$$(@ck z!@$lE645~{WXWb^{;nR?tAwlW0AfGc=He`Gw=Nr2?ExOVtBa6_vLtH&otc{vGo+(_FJ`nlK%j^_^L_Rotp*uehuH*UNjs6ZqY- zXxXCDACuAkK!X+QeIFNbf+fOSSp< zCU?6dNRP^3gJ~B0N=IlZ_egV^s)1HRmp5$K@&yy>Wpu4d3~n&N$rImv0-cZvg(J9O zyX(IFr1~%itH^Hmp5kla}I^OkLunGaH=U?QYMeOpaY72`IV-RaFm~y1 z?EEEAavL>jphT8sQzFiPXv^(nY;|qMFCHKS-;)%qd0rLx_Q<*-vem8J@@XT*jh?{$ zVX;!dS=U@B#Vh zGHnq4$Leln3MS-$=z-v`7fzGHshAx5g!0?NRa+{}^H7`bN{g$R&y>(GZPo8;LYM{# z#7(_@{mqV!?!NA3IQ1afvKAJG16VL)okkdvmW=Df^0_Ov%r?ziShFrIiY5ff#n?88 z5kU@a)@o`f7E-Sf$l}XC-Lj?HG;fK%F^vf^c6vXsv9-WEw&K*9Z`dAAeO9CzmVavH zmMS9Lh792nds5d7iIc~1;X;WCX~IuFo#A4RWYY8Hw=LdcHqE;?L%Ol(_{|ffG#1sW z(R7ijp+q=ISuLVaUi;t{lWAUK-Zq3nua$13=D{tq3N^wPYy_2JEbg=BxVBW7AxU`N zq;j%fhbz>Ih#)a1Ylf6haaIeG%p|tF`oS&bg~VkGb%dh<655#ZDtSwpY2Lgk#c4V( z_^O~PXW)*OS1#UCnl*6P2IAW9DEpTO2D|e&k!OCTo4|`Oa@jvWFc{3=M4ojd-2@34 z@@4<@z+fPM6NRl4>O_uK**`uo*p0G-gSLlP~+5 zMT4HaElgvTi0ra**^d_wy0yIr$q2YLzEAtVI89M~cxfJ8YTg<$N=X%8*^kKi|7#^L zm&`pf_gl5!t?jS*xGr&aOGlv;W)dO|z@3->F_!6{{Mos>f;n8S_7z516f{ z{{b|>IkS$<`X+J$HdR!VA1!~N?9a-cFZ)92<q;Mh=;)8^?8bkRc~*t!=#xMBI?2NzqGEne*6rA|iZ+0fzh z^WNUYYe~$*w7xa+>HIyUjkwqzI$M^7MD)Ntxvp1Qt3gn$YmIy=e-G(_DYl26R-a99 zZRqG;)%jpY>Kz_!jog;Mhx8;Uwg;C#^aSa_s#;e`YnM|kt!<6W&EG?Mk`&v+CS@Jf zQo!#E_||GTU~5_9&^jYnjClQ7x@%jm*j4LwaW@wg$k)?ddrS;I#8kwE92R^-X6x&0$`Z%?v z)02S z>?b|5jr(y2yFA?r*DpF94utq7`_X+)`&pqzK<}BapY;4T?8l?{J*wK>h^eh z(*5W^r~NEfBjE1L*H3zu8}{RMdmOwqBzFs;_C7|YY~JK@LjO7K=V3Ks%HL0Vt{e8_ zaic7`%kS#+u_0b{_f5W!?sMADGBpAY&V28ap7F;0C~aTg}@a%cg=}JKaa__G0kdVE9=MrK`}Wkr(%rHo5L~Ni>A}_r zcq;Stke>F%E-Y=2c(pCWzqB#XqoD~dZXE^#WxgKL6Ta9U+^Ge=J;Y6p!vn3uAeGG5 zLwc$g+e4SNvyC_lot>eL9X;A6wWxI%WRdxLNKf)&duU(5_mWMDY3zQuGo__(wGM;- zF<%eq>0N9O-F_S0q}sb41_iygz%Oha2CZYh9?}!L*d78aIclweRn{felr4R;br^(= z`Ffb?l-{(;{t%hcZktcSc+f@T{%425!iXM>77cF3bK0psO15&bh4a{ZXa@^ghe4^B z?-gb`rQKG|8|hi?d)S>CXt{M5WQlotm<&)9I}D*Uo<^dikhpAJ?^3FOn(2&YHZI}FF!Y61TUNQKB?+y=pdZYqq?u0WO{osrRxI^* zrZxw@br{5g`Ffb?gbw*z?bMPw)-Uc!dCpwxFbD(l^)S;3-4XQC2`#M%d8EY}mK57M z3_`$sJZPk;cg`7|8JB$Uotl^ z_paLCu5GLRT+L~40Q_jq&N=tY{*BqsR{yN}aP{J0?;}V>Z|u02fLpzPv=Ip#q!4@P6k#Gk`uDaSNJjnIB-2D1x?c4)ajYX4q5*(F zN4qP~jO4+!m@VUl(1V)ss$jlstPB%)J2MZqzb@i)|Hoh?3T7*^^P(RKGS` ze3aPVeDz-7?I(`Ef-L?<0v~?qjTtmfu5=-C>BgvJLIHoKZpN*d;AJ|IYw$w55HP;N20(`yEOk}Ym_n7Kb2*dS`lRe12DE7wlj$Q zEdc3)rYafPTx<_WYGy^MsegDn+N{?UiiR~*_C^55jbBCL%Db^+hfqCVZ1X(1ucpoa z{l;ih&ZNEhR$>pTKtFQZR&5l1{zSA&-O;i^bHb_8qXtMrv zZS>w8BL@}t?$hH}PZL$3XdHR5@#s+`2^MM-c{fDR8<0QaEkTFJ2v}z@_R)Ziv>I>X&722&WFjkH3B|Di%S3 z*GOxqZjhlp{u&fhSY{dckhI-|Gy0`s#xpUtH9iQ!y-^?y#;&|y^a}u8QCqa)&gfnG zjwbh;d*Om&-%pIa+c;zzAj~ClKYTkKmbsTp_=jq=AaEGzoVF10}3jjv&w@=&{1KR1kK%#)70UA#HExsd^ z(9x0k@agCm^zT9D*XeEX{l^<84t@Y|RU8BWvo!-XAx$pjn*QL4=$-mabp7MYSFLN* z_6^`Y(Mq$T=N4zdEhLrv`}XMPP4%`cTgCbVy(goC@LZ;lY2yReP!2MKMH!_YjHaHy za7I6;ABRcp-%Hr^qNB0!@kaQ0IN2l)+#txIM^6+x4gxT-v>Ec}YonjdSt$-|Cx@}? zR~uvDo#Zd2N5mdbaMmHKkkeL*KYKcQhkk5v>`1jq*0j?XQRJ7{83lwwu_7aLk<;ed z_tr!|qk%n4c`?`zW0#_h09!*HLeWi1D9WQ_`rUQW+jGv1T9e7$hm)h{VeCb>ids=k zxBn|#75%gs@NwamjDv65;d)~Lw3JxTaCn*6Hi=mS7(bHb+~*0nJ??IgmhOy$Zpht>%zl0a+A)06A1RiYPRJ0d07!^V@7dkv6WecQ`B-G4L>nRhj>k zod4@fc9Z;n|J>QNM{4<+U#oG?Nz74Z|M~2vs{g2ZUDfYat*rcw%3$SZ&6mxB>8$C# zS*K?)73V92^4~6hqU_hono9SS-hn1Qu0Jo0appVL)`T0&md;;sU*gs^6uV69yMZ)F z4JL9v>X%66%c0?k!>`BAUncga)jJzhOSHK=Lq68s<8Zpzpz5B4eoYaj=>M50rKO@H8%;f(TQc8&uY`+u9_q&!I4#E=za2i{8$r%PU(QDy0@7xbLWOL*6FJkw~c} z3T4Snr2bhdS#S9Ev1U3p8}dnpc?>s;Yyqb)X31wTHa@ot*Pk}8(An#^heCbLR*vyc zR>=}L7}N*?X$JfQC;&|rNo7Am#p(&q9c!WrLutIR$$(KJewZw}1r_FNlVp|Ul`d88 z^|;-=vv->_M~rB^`FxoyIo`VneSLaKvszkCb3nu6lrbdfJ+Z^X-Wk- zD8Q>D4scN!Yc z(>usu6mU&&jGeV9l2ft*>(?%VDh8RMitNPVjo!PS8~gf4?wy9s^Yku*oeL#{NNiRd zP62E&PD$ZVXw2DpQN^i@_TKs2*w;RC?=+;Ir*{WuXGzJtY?npG<`5lrk+4Vt*F*yL zvp}JOtNh`Tu?F)U_tu29*`LOG0Cdg7(OvZ7L~Gt?s`~`4x62JKrFKn5{D1(htJ3G5wQoyY^!PS^01C|+-W1_T4 z23R1_3beWH%YKB)&<+{y&MQNPiRG8U?di7!_%0VHBQy0tWkAFOOAYeNLCQ$i7fpuA zN2m8iR6tNISZAc3|@=R73lWhs?5>W?$42dC*Ft^AVw&e!h)HS zA^RaJg9;hGm`8@`Y|;;y8+eUvj&_@;Jy#D_4yXjEe*sV%19-!f4A~D+861#dULF}T zY|>B_Evy_q{`yncW0vW!LM}`cWG?W3a6zsCN zd~GhTw>QgwCGHp@+X5B>uuRA%od&yT%YKN;V1IG!PAWp?&ZU_{hDjPO4<4)AVs+VE zVvnMRK$Dx{qW*8@z63C;>pEM~n>X4e+t^7Q;(+7COYp$#ixcc%3kw7i2oQ@mc{Z(R zK`X*(!oZAXMu0{bu}bU+vG1FZKyH#IO_MI!lQwZSy;+jBPSYga()R!EyQ9&(r_sDO zcKiQ7p)Qtr_nmi_bMHOpJKu->%7OwS6UytrXMysMXeS6C;SI39()W?fN1lnDnR-Bp z*UO*@7=tyy{$>bmp1Z$L~6Ft*|xx0jeBhC0(*_M(Xr9l zg0gA+H7sMk@^tOeMK8U$8VceK*48#>3t!lp{YGuyBcgZJR#!V)+g3I;fADu$bj!Gao^&J@#E2njZh)FM*eed&z4{`(`O0c`Um314DZor6=KZ z?9#6;>U&7}hz4a>wnpia;)XIK^-2b0V+nrW;t?<>t z2MfMj&{puN{O{#==YKZu_j%{@ta%UTzLWd;+-Gxsobz_hvg|)*pUp1Ln#k(UD$V?L z=HARj%3mn`%6aV1ST{RIaaFO7F=zZBqa)*y^c(4`(|(JFQ~mXZzkWugGmMZ4~?e={Nk4wV&Yy{LX>{lw25Dy`hnRfniyfwK)p?f94H8bn9n$0l#ge@PdXC z8~=jp=HXn9ynoc^%Pi~v-caTD9H*{0tt8ZxGWOV7Z*;Q@!w)y;$!&z1f)%XRDF5>R0 zHg;$hXtWUQ(6%fym9DVZ*00`FiK15ZeEg>uI$IaDx792(+nrWI$YnyQOO*qmRE-@p zmv#dxcOb>6uX?hrsovSR(B9mrf=g{_s&zCpw=}8LD%!FNM|%h+8ld)~R@BABM9r%0D{>3R^{x5 zskcS;fUENcQbNJA2LKy*Z_F3G93VOYAZ;ayuC3vlxA94lL8wiRzBlGi`Vz3sf@DfL zXM_Juu;gSEW;D-y3r!Z5x*)6j3W@FY#9@XIrM) z26;osH}V`*`zR!2V)Pam^^-LP_I&V|o0K1Y)&GWacI8x4@pQP8wBbnW6E2&57ikId z#GO4rbtP>bbi?4jR6e@a|GIK^g`oBD_&shM5>jCOyBEHE5rzL?bwI4B7{#TTj=b@2&1R+p-TS-nK%2w3+aw zehFnzCK#1{yoke0CgTEN27iMxztUepUQs^z<@6Oq3X*>X{loiu1^9bF zu%^sg>E|iF1?15Kcff=Tl`#A>*f*#HBdHmYxQJ^H=@t@;OT;b$?~PEK#;nX;?w>~R ztx@Cd03-k|3>bO{G6gU5=#H5hgR%w|um-+anN#Ek!M9L}g#?DdhQLd~C9{dh=zwqx zVL)Yeu^*h?B5j$T!*aQ?VGu~da7WiEvr7Fd#WEdm(m*p!+!@8Vz>6Y*7d$+k+%kg! zL@S6mC^Jj_E5z+#oXI7tZ#(7@nJ)gzp!1e$4=j1W9VwNI{AGl_JDy8^V*C>J$?%9< zq757c5SG^|*>XP^z=f>puqmdELY6i@`O1yp&9@~~d32E00Gp*+sVMO;7pqmk19PYL zQA(1jBhJjTf^gGdce5y&V*j#f!^tzaz)Q*zm*M&7A$6_HDE60#TcT#kY>C)}`?^k< zUgTdoZKmEH3*t8~Lz1-bL34ww6sDLmt=PXrY*4888k}{k`;)drq_U7+FFi&X64M>YL zp}!0|_CJ^V7mLl~`uc*ym=nW*8_o?~xS-)KN(h)xVF8Vr{o`_fk+?b0*J`w?DejTP zUyIQMLAAlm{>L)^OJeyAQF90x$I=r?TeGnLUhIESJg8)0AGjRy3`frG=l1Xi$C+n7 zY{J3AXlDO)jeikQEQ?>>keQnpg(AZaxHEudxl6ua&nXpVF(3-b=L-2;EO;aPFU$O& z6ASy0BjK*wfDAw#G}Pw__4Nc#4<>65xD~i;t%3amx&MDW?QUA(fkI=!cftMl0Pz3I z^L~}LCHMEa4LR@TEYH55JumA}R(58)^5@D`?3Y=i;*8=^rYGZ%84c+_OJ9nI|DXJF z<@RWJ8Q)|QipY`^AF=y-bW_BhC`Ztd3Mpze@`V&zpxCPB#bT35Od<`71T3^ENU{T% zME^i!J1;LR(=PCwf|gk=->glp?4AXDFD()l+X{syhrHqO5em~I(?+H>7NXc?kZ(*g zhHSp%kfE#r_c;6$=g<_4i4Iu`<}|r-dQ`kQNr&vt+2GNBZg@9$=0FPO@ZoW_UVi5^ zqH~^=>>O+fk+T=Lq5iPvehSt^g+X=l&1rx+^CZooV+H2O(0G3e<{;II{E6Bq-<*vY zt4~XgRe0BJ?l>;CzObJUbIY8^kgf$mut~l(^;lKU@YW<-RTK(Cz^P-Y%^dJRr7&^o zFj7xTjuba^B69j5R5G#ur!Z0m4H&Qu+7$Yx7Un!9X-*h&Bd36BJ{G=wBL#C1ctZJ= zAq59m<9eXy$;_t!<`OUR?%Tn!V}ME?!c8B8#Gi|Hg)a}`J{58C$UC{yM-5q6a|)un z)v)PPNo+z@7tR}8-|2~wqi}+VlA)vqJ6S3ng+wXjTIEmaDo7-MGND8=?I#$4sv8;? z35^~kx)4_;BT#a7RA3Ro^OnMf>V!d0Br%Bdkuo6e@;2`B5$@g|tTBWYQ|KX7e5s+Q zC%=aruEL&A@S`SP^wAyyhd-2jx-o}tptlfVBfaI@oq|n}*9Dohe3R_(ijODsiqXm4 zy$d#A7LgnMpg+`~%7zM;s0V;lzBM*iLC;)%#Kb2uY7Hh#WcxiFrqNC4Bcl4~pNu@p zn?e@glPxK1VpjN~ISG9cwJ0p*qbgz&&PSy z@5H`{$S!*P(2@(e_`8%$|AX5G5S%IO7?rN{p2squ0zqeDJ4j96+xxh^lhHaky#W9z zVqqy5@kT?>$1!!oe)QQYVeS0V1KaC5JL2hbqu{#$mXafdl zfpbmSi={7bY}>e5ZCbumXRBDdq8j-MJ zRa!o?*x1qHXsM<&8?RONe01hFq?(vhl~nOrr;Qe;)flZef3>pb(V5?nYG$sc^d+8c zYEzqYsX3ZBd!@4HBQw7t)zn;lA}<>Xpd+4IPZZ_uY&_-`^${)Ot5rkAu)2D!D) zo`?B2B;v}_PgedXC=;!>Zs37@Q?RvYyL43AVp)C~fQ&)&O4rLbUS7I*^_oSiRHd~oEln-NKaent+)THAStXyVH>hgYbS>i9Mza3; z%>ZPuo)EmH*x6KMU0u7e!^-0_Qh9~J+QCyr=}lW|Iw)~X)?e8JkhKziNbvdrFvY@Z;RJ2EmAF?zjXfMR6j^-wY^9{4mHio z9Z{0TtZ&o=pf9BpyrJ0I(WTO=%Su#5O^t1;m#iB%ruwSZ_DY@uqo$=rT}vrvvi@RY zfJ#TjO*L)VVvP#fUGCJ?@SStydT-gaS}M z?sZ}ReeTTmFWrvZJ&h?5+;>@p!6WCk1F`Ij+|lansH`!SS2S%bHC084xU&A--V3QG z;T(Li$yQw3vawZF*3@a`fm^A3m~Q!|PBLUo#^uZLHsVXNzSi6ettJQ*qUK?84u*H^ zLYjq~`EDG=2^3eY=>3zttizE2h+5ZRsNK}nUT3yho2#lEHX=|+V9?^9^RN7BYcIr? zP%8xF+vF=LGdxPnfpvS1^KC_h4caeAKZbhGhjv3kIhLPEpy+8PJouU_N0rrPaH#c8 zgWaNYYOM}bL};8AJzs*5^=F%VA*=MN;H|Ne2U=+nm8^su{ONu16&REAHNmU(5I?qP zZC2p?EM~y_j3CrdYk>DKsf|vJ6IE{L#97>|%>GSZ3{cH@T>MMei}8aT1a zVs}`<8LCEX+O9R4Y(|Y$=TO_h9O2LctIJ#b<*HsND`8f|*^A;d4HOWeU&8fWfDN!Y z>5H6zJwwzUa1{q);C2m)Gf*d?(U|oP1Sl|zNY{L+wiilCaDk#1QNb%DG-C+Jr0+6Y z9a@Xs3e_tMz?T;21fn>~UZn;`-iVS29s`;6r?tJ%KAQe6eAL9f>(Mt#f0w~xH&|_U zWIr*z99CpA3^p6m^>)N~fi>sh@>%b=X7zSr$O{EuhLTwBk_+R?(<$sE>LXXL@(yd5 zJF+8m_Z)X`FCaDe3!xk5L%5gn(sxLFMot`%>TYOVL!Zj2*AfJO6=GwUh{h@iJUB5! zF*WBmG<9T+yXN(Fz%0}_#dSE|hYDj-Xy3gHG%~>*LqQY--vh*e%)#J^Gsw6Sp&8x} zP{}I%JluCLGH`}O%7*dR=-)g|WFPr>p42pSpg=~eGuchfDvcS}dXv+NWnlkVCvM!Sn3ps?2Y8ApG@bzdVe6c8$GKO4GtNU9HQRW{(fO&TZAUQQb{O#z)T zRavc0s3-$0VB^glb3NPJ3Ue0;`Y_&H+Bqh4&U<5cXU}xIf_wLIJ3WZ8;ZQ;?rE>v) z7MYy1d!Z_0w-SRbc4w8rV#b(bq;+;9%Gb20C*tiLbqR!~Fs;jE(Rc6GOt$Mx9;s7+k0gvKDSDUT8iFY^kZW0Sp zgCQU^ek|MvvA`Z22!egCiTmB*@q^sZeyL$J*q~jG;xQY9PNDmR5Dqj*EjIL(!;Z0a z@b4VK9@30%5$+*)8RB~6*n!&3SftN&J~~MIk71lhQS!hUXnf+&^h^}}uLsV6Glxtz zh%p9y1gPY@f)F8H_(^-osIx*6209#06NER_P8)o^1`%fzzd5Z{(LLmj>*Kvmuo${D zaRV8rR~t-f06vWmpkmdKFfVwyU>E|c+#VvChmlQcA^Oi`tg@5RJd=@Vqap%bWkc12 z-sH3cCCK;bZP%xJ8)2bvO8~&1S6ieT9qHk_CkUU%(IM_OQIN$?0KOw=Lic!h{4o6q zjbzd&bo3`jhtT2N_)RP?{3NNh8mq~s#-^foqLvZ6r4>+52%~GO^bWHcryAbcTdt>i z8(^()SBAg9b{yBM39Lnx{;9#3Ksq%Kkys*OdbgX5KJ@FcQh0|i)v*?>LvOKT+1l)C zo6Y6~s8o-+ivRCK0VFMX%({t=-I$2td(vC&p6VjcS zr5JR~R}@1*{Mle~I)F??u!)D{XWekAdh1~=EyJBWkwVs;ulJx;X|N5wMEYucJ6J4u z80NXy775)n6uQIta69*7xzQfx0UKU|-?)q{?Ji(U@pGx}Mfg@{Q)@}RAL_atdOJ!; zOilwznDHOXHqch!&~%;L|Fvl+(h9E^R-*p@c0qH&qxoOW|9t+uyzk|?^3=IM&)tz* zl=JJH;ha};K9v1V_Qvd|f&br~Rh;>|%)^(aI3CIYyU{ib7WQ|`{0panPPX3*Z|x(Hn7iGw5iyXHFtGnz;{U7|aTVEr zEqKTq9^M8xacFcb?B~;VR094g+*{Vgz0$5ZreVPB0$L zHF+aR+$u%c=ymLGO8nqZ)CgJyA`C5&I-?7_!3M(lhb0>$pfDZ#-ZDR^6Lq4-hPl20 zRWJ|;jq;h3sapM+O*0~q%>HAkA6$thL2IG@+vE^Bbe;UOZ#R^8ak`LU9f0%fKa}{v zk0|_9bRaOXTe$W|C|Fmub{U(S(h=1O@n!GVgTX6oE zjBKdP5As5bU~XWc!}W5#-I0T5!~m8bO@1RoA?{!oFG(UL`@Wha*V=S!gJbb6Iu2L26qYyDBke)?@WW&KxUZy*O^tXonaj_q4fx_ubz>ScB#%^=!Z0M}S?nO6N z>@$D2(hrV6k#RiuICAg=oF(-E@J`Wsp_#jpZe1od`?rhypavA;thwPq!n=6-NbXwch>qr#-JYNi*P>X`AmKOi^%F$*kNwtaKS=h3Lm9jqAh(2*y}?5_fEvbG z7gtH(+qgj<>N4{%kf9_XJN9pu`@yJZ5PY>5yKRtx-6k_bZDIea%nt@V;eHyzsmQ-G zvUNZGgG$a(5cD!2wa}Z{zbyBIH&3`I2qoO5Tj5LBxWfY~Ttb6GV>t1LF30H5689uV z8cS7YVZXWB51Kq-Pr_rMO|r^xL**S@_~L19=Q&9?LfxiO&wiuK4^BMMr;i^;sD@%` zRXCO4XehaM(I64!HL`zE><1y9&}oKm-Xej#eOI`^Zcw62PHj@qpk=?l(jVo%+c0+n zHRD-21LG?;NEdh{juqr1IGUp<%yT?tgIFtm(fEo?dd~_gz&*Bert)Fq6i> z{#m*I0dbq0_c#JZLA7V3ET`P9+4Cy`&Z)tRQJ==Tfuh?|v6?4E z&Q`4pIFz$C&>jI{C^xh>Jnm72dIvb)S#D@3c;i08VoxtAlBo*;*q((B+_Mz{d(7gg zmI=Ts(>u67Wx+Gvt zFwrQzDe+VNN2SQPpIStm*kk7feTOh&VDpQzrpjy9Xx3AC zhU}+H0+lfvV@dIp8q=cCpMLOD6@fQm9XaI>LVFKR+za5Ih8uGVMEwZVQeNilCo2N4 z$J*sQ*Mqlr6Vh~qkNHUJK8z7I5xE1T#qPm#&}M&XP2jaypF+cgJA7&$NjRLmLPbVY z@Lr+2r%`E+!y&ipM6#8oL4l`$p3cRYE#fyQ!E%MEZTas-nB4#|7aP|`wfmdRE z5bix6+#U_K)JyTZ5&?v<@@fj%%H4PW1p{fUaehN*VJmfL+SxX%k}XxGG@ z9ihQ7Bz+N$lWi|Jo@ggLUJ+OyYnQvk&%E3sY%Q>sOS*R)1fihJq^MH z+U{eOfi*G9kp|~*P!8-M;sQa>aPY!O(&s4bCc}v^fqPu`8%(I!}Xhonr z)^40y&IhDc&wjKburk&zS%&+(;r>Ia;N3y|CjG$Yx#V^+*a|7jboNIo0xM$e;!pzR z8nCA0Ts+QQ8z5^38YctS?ogVoh z)bMlyJXjG}5^Fb(;r{*cw?iz23Q1%?P#GwWd7XHFiOuL zm!~X0dYxRn4x&edZ1!@8&4?Om+HOHfU~!^h6SkXl*kUaC+4-viMN<KI#h4$DJD*+iBWgqaI9`QgsoYN0;21%- z`<(TGMX{!*WCB7Tq-iQ>m7QG?_*|?vppS$3H8Bbij`ugehynqw`CiE0XUqsHY+XjOPQ^iA5(r+xlO5I zf5jeRSF+iP>xx>%N0@IgE@nXnmvJPcH2v4m1YD8!n*^bNjlSAU1W#R0We8(er}oK- zp3*?LN%I6*UNeV7`FID|mDz#U{P|RbV(M);>BjQ*Bq4PlaU>$7g?nGHXDia%!IOuQ zH&0`Ph#~#y%l(6gqzt zGJ^o1qf3&%fqXrX2L|?jnLk?`Aw_7A1owCj6U5n7G#in;LEdDG#>9>l`Lo2)LR_8* zcaIFX0S!7DE$nEqKT{lN4fc<6C$H1=v}A6YOdlj8EbQGCex(?Uf*d(w^x&vc(Uh4A z<#XYaF`{$8yqW zFbx^Po2&il;^;o|Ng((DccsDq6ZWQ^`#8Zvib^*6l znQjQFZe+c#7yG^_{>D7`pgQ-gLHAr?{Df4|^JTb^L-F6KS z^x()o72p{%vmgkOBguVvk?$>WY7gv;Qw69=y*fY{YBPIjwQq}fN^n>1P24?CvmjB- z0-ueOO!&~nZqc(B*Z8``DG<>0hK6@>9zakaC<3LW0lWnYkFp>sfbN(z?1kmN&Ekw4 z4P=?sTwib4eU%HG3=Q*Qi%GwoV5!XP`Oo+|m5DwgUh{G--6-GM!_+4E5k?SQ{@{ucKyTq|ULnfL$jwp*-%bqIo zHH$kg*nK8^wHsat$MIxlMtQ_E*zHah`ziHV91jX7>2=z6R3qg5%Zs)7+UMsRoGmLJs#>v2WwFFXB`66a*&E zIcRV|JF>)AFNXPmK@&wdGz<{#8w*-iLWNX0RYLy@bKGM#xNLj;K;!0OG*v76K!?)=yT9D$6t{_OpD^#iXZgKzDFNTao%8se+)jg0ZPG$e zg56i_bBLz~(1G}1?2=fRpt(=p68U1#wm## zQ$9XhFfF170EreLnWaNb9=m6`&nn(&;`eHTo7PHVKlphHSswQ765pHR`4!w7Aip7# z3s?m>kl&Vo2SFoPi`pGE+q=wHDTV;kZFFubt?5i)1k$s+*7)9-wpG&*1Yf!p%dx9~ zr9qLTL}6v+RgzmByLJ0he`G!)~;lOI$R(0?2cmJYvM@;y3QBPT0+!$ z@C<%Sv}Axt5d?phJCh`x$(!NF)NC=b{`|B*qZqDQkA-U#9hBc4a=L{DE>8Q^fw3 zJ;kn3{HNlA!l_U)*O}Ltf{d?abY?uA{%(3t`tx{!tY5WmT_zx2fVu}0?{MXS{e+@nsPTdK!rf4i97enMG*4aIBEvB_W-a= zFeCdVwmUkyCKI!|*bO33A;O5;dWgg#t{y}7AO0=rJRua?@JB`?vue2;6rdL2mjYpU z@g&VE1W*$veF_Gl5J+NRSb3=%6re&xFn9NMsQVyy|59*pS7_K3zBDdn9;kky281vy zv$Dty4p1Qk54J@PTnCUEiK?VuIZ0uxW>ze7gZxuimk=5~9P;DPL{9i~aWzhG=-KEt zPYYoMFPZ%0~5oZMhC4;{M!HiXdGkx;K2^#;;7K@2udng*tLnH!}yCc)Yx1AY^_;}^)japw+B zp1}i2aqn8N3E--1W?n9LqxMGVXGm)_v_Jz3XjIyBp-K~x1rR1!n8k4L#i9XDeE~2< z#cmYd2;CLAf$ki|OoR)>l_UAcVybA!7%(rDx>0o_90Gh~Xkaji!s!eB@GSU7t-eOG zJvB5sOw5Zb+$gtsK`;c|*a$bWm-y0w6LYabB10F6vB_chAh_3Pp&7+2DtDviW;${A z$arL|mzqbQS$FS9!}+vktq~NBCgyX?+^C!pPL%M~bKIUGXl>w5KQVd%u+s32q??jnWz6L;?DEV#GtD(8DfO3L}gYDcPWzg{$3age}FNboJ6*4NVZM;ep^VwzY z1&d;ZE|Rxl3wQFW1gpMMg&E+e$Xq zca<3$R*BwbSnYl~!D68ONI3XBccL#yH~~r>E1F-_Z&@j7Rlm&r6lv8eoMgdkec`RB zh9v7P+G+zCj`oW(HAL2l^k9h&vxp_{kX{qaO|0yV1cqi8s|4Oq9y!Asb1dsSVX?Ul`I zMLqH974FAK|B8A7a}2EtX4*{MpquOl0M1A^JY#c%AanY55rl5dO_$hKDc8E9#b9k$ zFDnz7{WQt{&rZ9VR`_<|69r??{`2SkYn~(bJGr09IhXTLwks=?wK8)&Q>{FpOlNJ1 zcN9-E2br9Vx6&i&%kkL%{a>yR2R^}5FI7)bej)aU>pO{_L!g1AD0fHpUjjau%xH3n z7xN@O2X+an)#)@j8>*eA`gWtuRBfrjDS+rP$7#Ofb`EW7+!heEGOAG?p71%IOW{|p zM+1*%&H=6JTT`aR$XsxL_uwERZBlJ>quy?}w>hk>)h*hV1yvwGn>45rrywiTF&nHc z^+W*`6wgp`L|g+G8XdG-sBxkec;h0jg23F&Ihan<`VHyk$bp;D%`4_U-PPLI+T3Wpn&Id)sCx~93VxxTs6*;a$m;pet+un_7;)i=fr#e%x%nh-t5o5Q&t4t$KK zaf=%)!eqh=%D^Jng;&qQJ<18eaS0>z*pa7 z9NIvqeWP9YEN|W~T(bg?X3jAP%mZ>9xRapgL~ysasD#qiNc38RdQ*p^rK+aAuC;Y@ z^-N~r<_m=)@F?&}7dqcCu7YQIvwn{G_7U-XqgcZ5{XLX`o_hT$yM)V`vx{&+>Nt49oJv;$;b{p5VTbDTxp|dI_h$-B@Gm zbU2&_ON+)>GlMw@V!%~l{9qFjImYP73!ml9`Kc>E@F9N7vBzyWanqkru_f)HM!UYM z-r=mPHrAUh+P3B?f$O;0juiE#dEX9xd)Uf69EX1n;Sby)uHK> zN-)D4tqudu3XPj|otiDJt&KByR7`C+D)4TiP6FoXX*Y|W1RH7Bks|5YiXeCOsEp4`rjw(ZEEl=Z`z|(^@1G}>ceWU}yR&)mvKg-+o zx9F$`#T`Y_g~(|F8yVkGi43yWnL4bUn+z?D^@a|EWrmJ2p-2qSZV)y=LJ&O`osYt2 zd4qn0j(Q+-&S&yn@oNut>L?x?_k_E*a)JE>vN?7t-m-*V!D2Nyw^SQ9S@ibS+KvS} zV{|ITFF|DMAOsA6KPoYdI;e_+6SvVWe3G~8hv=xn%sC74UDm0&PV`=>1_aXNrv#HK zp+$AooedqDcC*3SXwq*^xJR4J8j}{V3b5jWEi%?of(Lnne&Bi_P{8|yID;@1wUitW z>+a6A(Dq?R-PD3hG|}x1Msw9>i)Krgt-ju>OK6itYamBYICIpzYGeD0;6dJ|@1v9Q z#hoPLUW*^Lga$R@Xl`pWG_>2hYIU873_>Cw0bk4`lwGPddb+VR+Jz7D27S-odjo$Yib%f6D{6Sny1?Q^-HZ|0>n{4e4V@GFuyG`A=NifMpcL$vMKx2p66NK?~ z2%1wLC2D}T?YnU5xnifTuSco`dc5I#r^EN|QGz>(0j$P;%1z`cEWSA(j& zoPW)?HwLo#WghpM&^_$OYM-#n&glUoKa7WmPTD)!ort)l^SaB(lC$ zAIQp_V-e7UgA!t53^1obRe1bda0e=4wxWJ3)wgL?lo?#Tykq(1PF~3%>u)Ik-(G_M zuR{cY;{U&szcYVf-f!}T@?ObP=3dXO%FWIh%h{YWKYJp(CtIEMv#dbYqRfBF9L`*u z`H1qblrH6S>;&7-7J~<1Sg}s=0P_x0&wMiD+ZoLnkEVY;{qyP1ru`^wuk2vKBHt@w zNa(~J2yYLAFm3Xy6XU8$vJk9{7S^}Yw?UjGg{p6OycdZifc~Pab^hU~J~i23XKoTl zRwL^z^{p2tmB3{jKG;iw-UGK$<{doZl7u%B6G56}VY^Fw>%@2(3gJkVr+$a)KsQZioR8_&fCy3V3*dYnUVG1e4 z5!=LWuk@`EV;|$`UVgE4FMgvx3HjWqbD<%WC0yk^+e2^1E|!T$iDFOn7IxbTA5@Kn ze33w7fK?Sx3!|1`^aEFr%a_bM6AB#*Zg{M#$hS(Iz6L^>#7z(H<}OK~S);?PXSc5M zm6INg2c2+ZcS8dMeC_UK{8={i3FmMkpl4veSn8XmaU89X;9-qX{ujSAbq?mFR?U8) z$OnyMVX8iO`zjm|p+xYMIk^M)W*#=yXdXBzJeb37{0MHBHU) z+nSmebagGjv_Y~I%vpN&^UHmuQb;yw1zMO#;$=qmtuh}Jj)h19l>J1mxk7iZlgsbj z{jvei*wxMKmJ;7G@lpfCHhUxCplcEFjrd z06Pg`#)PxEPpX&%)y&}9HLsvK46=K9fxm&|HhU8dNH{jhv@}93NYCZ zcJOjPyjo~rf9U!s=ab;@<2?t#z&5P&0m`&YfRu{gzf>gqhti`%UZ5j59|SkgN_{$E zRzvyL#&tfRn}jW6h>5TR{(0@XitG};Zi+YsYCgQHFL}#!^1vC_7yAHn5>6f*g1~|% zQ*EC5O;G6775ji}61D_X7|B@ga8Hc7f`|FkS<~suCZ7P17yy_C(7LcywX%;p9CgWd2y^N*}OILWWE%4fGqWNrDGP{se_# zp-~jdtbK_O04E_2D&)^O z?_C5UWRK2Qq_ zc`ku{qa_ho^aR|8f%P2-;y!L5>qSSvOlryIU=<4Y)))CeGb}vnM7+JhtzhUG4&IO`3g`Dna168S@|ldZ z1!+wgN>qB~UT43>Zeu>Bm{1%@Ybv}@xS=q+;ATNh!4vu4&-dk<@mcjRGW1M3B%Cwkdp%b^G{Z|Q4uFZlqP`ThIU+#Dj+~@zr_G}^yfe4MseI@ zf;C_?lJMN6n26j=Q{7;~oYFFHmAg?MHw~03fR^{|L_I&82|P)%sR~9zNQa|xU`x3h z)onr;>BOD$+^HKl;KRMmCD3RRP9p&6WGw=3jEt)mVjIlnrS4kg;|m0zYSwXA+>wF3 zF)Vn}wt)GE{i7tKi5XWTE7>9OsFxWDth3MnL~hsj`2t9258 z4I=0$CN(FYY!I?jt4$Uiv#Qp;ZhB>ncQ3g*j7S{VP`nAif?g|O5MNn?+Ye*M8dofG zqYhDcwv%~2gu^v}bKA&t{QqBBgYr+|NtmP$cJkahmu|)3MG~($6vCmB%WPn}{y(p* zd4DA_!Z;56Ea*}(70cGRaa&v}h=I|YHT@@dw;zd5kd%eD4S_-^bRg-CTdOgfQPiMe zN=w`*Ru!J==p7&$Zjy1nhK-o)W)sui|umJEV)CP!b2r0C(`uTw=H_6ak(4St-|ve_7X18 z&uzcSUAZ$?Mq`Lrl0XzTc&1^I8}+S1CrA#+!^1!$CH*|u0}?--!N}AXyHV9D8iR|c zQCJ8-sSJ`0vgCBguxpsQVmAs|MJ@H;=Y<5_i0R{ZQk&4_s69hgoT**pMg^0JJ=nS| zCb(awZKWG|B4IQF_*?Gnopjkyc{7mSB2AR6L6RdPM-7}9tt;Kg5eb_l#apQ5L0uyR zef!BBHtf9^xjH7*B+}cY$u~>gND2wVfPzYR{W6-(mTC{RRsb9^m1S4IVD`o`HmJbn_{p_`Fs8GE3HFxDkwjPbj4b0iJ_SH#ns@NJnC~iJK)D%Q33! z%H7Bd32#!dE2ADuf);NQ{@*(imA^0(kR7w0S(~p|&h!80{yO($?(&@9@;ZOBvcH+# zl07f$uaM_olKCH*2QxpX{5Rzp<$7fS`wn#eREob>3>NyJ^LL+VV;;&F%V^K|MEbYW zx21mu9Dluv)rHR&{8Pc{f(-?E`PXD;{qYwoy~y7XUf`)P4*8ssam0lX#zCH$a8~G$ zr6P3ok&{PbLdVI6g#@vWilJ`77}Cm9EzC?bcG)|K*w+$8;KR)mYZ$nuDK4r0ZA2*u0N??N+X ziz2kzi`HSj?nOoq5RN8!I1&<2G$^=YFETyC!x)jv?%NG02?&HFV@;qDL+;dQQcM(i zk=YS-Bu$>m;76p3!mL;PvdD|Hj<6Xjc1=EQj|BZAX$IH%VcF06U74MUODxIu)i{eK`UgU0sa~_r5;VWcOgO6Ua8LVZqR`J8NUgT_q$rc1P zxica6*ZKuokgQ7kQDu5q=`qjh1i0ONIjymtQ*ZEPBPa)_IY*5#BG+;jzt66*Myurf4? zzbf%QIqk%c_?ZiwY=louZl={>)EX3jxy1V^(pbFbB}vS?cL1{>@eoN22TC#wDDJT+ zzPZl(Npb%N2O)nFb#P$F=T(jQ+nk*Jg~tg(##!-=HQp!0kjaTV14M{%?}^~WQ5?QV z-W#A{dR0t5ti%%-QMRG@i^bkgh_{OH<=foAkFV<6z*y+It_2W zd{Za#Y!-RI$Hg_pvW2LW%>5GDSLbi>YJ^ z5eaC@`&#;U!TYC9dpEB&aORn>2@8VS(JsH!e(&F!I$w!fFEGUiCC;vJU zC?cm4J=3?s^Jt3uQ_N$LS)$7a+hs53;Cl)I33MULl2m*HO zlu3sI=^F$+ObHYIK7tkHd+*pA~H$or{Z>>L9`-r_KHLgU+vx^j&YJ|P%stY zx_@sEvIm^!B4PI0xi_>kIerQ_9t~jNSm9;jRp?DbXOfdhneF z#66lIaF6!bz0C-RpDbcTlk)$mNh*`5|8zT{2!)S|5w49#Oh~;32B|kWdW0B_aJ<^gTrTtArYa1XhKI%}qzKnVxPDoOH{id4W>Tw}OGO@B zRYd_XxLSyzphV|@RIvdc+0+`Ci{+k=ioaEqy(KcBG6;jgw-0779-E%qqL&KmDVV~ph!clK~sk0hJ@ zAijWxpialUz0$*omlM5sBNheP@8GsWG3-gQ2I29bWncYaHiWzz1PY@E#MDJNl zU%4lJ+F0@0LzEvlmVVY@$xF1!uXOAcfg%rX6ryPqxCO>Gd25m!TumCLx7__jv1xR% zM7=PL_o8k`0;x=HPM{kA*)p?hnfnXGZ^RF1@cQv^&%qehN7@f*K|cYUvX@P6~ub{2S5vU4F@yu(LsQaypq@Zy*tszSfy6+zK&go@FeMP8f`M8La?rx6l` z15W;R^fal~u^(UW#fd-&#Uw$+$r?lL`zta;q=5a{O7FBI0fBA=z)gM^^wT8hFt(N8 z@b*e+#g7x9+3u}bsF|V72XDNGK}|gBrLJ(ZIW=pR@r})9O3TY#sOq* z_{L%UzhpCv@FamkO~XF2%DYiaae&||h6Q648a_%;JiJIU4dj0zX`_%k07hQRKAb%? zeJkrZGjR`DcjH-M)As)sZ-k(aDtx;ppvso*>K);Iy+Dr0x2%<(a za5o1g?jDk^lObtPqO6%&?tMdSCi!xZ#0>0KwRPB{QB)b?tNd6)QG`{l^}a6dQ{o4= zg2w(Zlw;ro5dtNtG+B6itV2X-)ex#-wn z=93`4B!kiXmDR+i7khz_7p)d(YCt0p@s-m7Ny!;HvY-`7tMIN9?{EYxbGaV}ksyT1 zyxUM2IhUMDTmd-5iSgsfJ{I=_NEew+ivKS5t`%D-)OVEzK@!KRRs7c)FM#ul1*e

(c1w8s;E9ZMN4pw=n=v)H>vY#==@MfQ(`#)09GAfzB&NNNof|54&yJmIFI-CWx=wG2;qBd+x7?0##4wY69)fkipyP(8 zQ~aUKTPEJlVv*VC{f>`rODrj}Z6Kp%QvAMfcbYaexPWVxx1LYZw#UJ+Dw6D{6XGvRiHIr(WRqogBCV~Fs(5-&w0 z2nBo$-k9fnV*+;DsMwx zR_;5wUAc49ex1{mlau|W?1t@+|@ubE3he$oSoD(CPf_Be)Y^dZ5{wU zATcv1ZgIf~>M>vhIUTugakt3@C+UkVpsGUjFzM&>M7F@sGT&V80k%h2-AMO%n(LBV z-Kd6=6LN|_UE~3}M|l4MM{sDz{@_VoUT9{b1eBhbbf9%(-d*PbsAq-X5{e80;QNpf z58gZr$T8^`ih}Apf*b{UCuxr$+lf1)f%(Zg4=_H<1Y0X$$1y3_;Njlz_z{p5ed+e( z|B|%}Gz1FM)Bw#gKQ8hB@FR>}hA)p2!Ye-gp0t^0Xx?OC{;tRah`g{F?&Ns{azf`^ zoL3U5$>;8k%-@!JP%b09LB^{dlFf(b=TB-DHXoD8Y%r;rAC-Dg93yNGLjWF(@YRv% z)Z~XFX?rMXBQbsqV}v)S$rK=8*9mYDmb07? zG}=SV3)zwHmUvJbBfM|NFI4I$l7BTCLvmZMX1=q`g9;f@Jo~s0B5t#Pd8cEk0^QV?^Apy@&(Q@KG|;&}k;r5$l<6t??{OfQyOGP>}h? zXMw0EPTDM7E5s7b%-<~Yd{%sS2lxa<8Mti52s$vvt&;QujVKZYHknlA*@iCYt^oa1r@ts&_bR;GG zH~cJ|ENZ)r%%2x|3}OcfHw5Mxx>+adEP|dOmBi3B{aVhK)0V)0#Lw9Gal&A}TIA7* z%>i2tKvEQ*D`Ae>2qJ5pn)$O;9RW`aU6ch*{z9CnfMPZ3m_NmF@^u{R;yVCS?tkP|$Go%FgSr-B)D4Ye62-7B znANltK~BsBu9?U^YnbsO&$H8}6rfAnt|1$P15omh=PyqdwS~FA*n^4};poTqMv{Ua zOq#LM5_u7@Rx$U=Jf9Xj7P3G3`fwhjA4axFK2n~{G@TxBRwNghu_c~oBp`|sb%696 zb$Vvh>3N#xFN!}h6Dc1LWSNulR$v>%{;y6ht*iy%i3z-~%*aX)3SWfRdC`>Q*-`zH zyu}!0vS;dfoiqtNxcYGXKS zYz&z;oH%Zkc~B4|+~(pU=sbspyv#g5wbjhcB_7nl2+{i7{o{nDcKi}SG>sjTK4ze42mTEcbG_Ju@)wcANr9_@(8PfA!eV5u zZS>5Y<|#wITfxh_gpx#wFucSCf}0k!2ojzWb4ZVSrIES%iU)Nu<$_&fI<1e2u+E~o z^5)IRfG6A|al)o+%V=S)Q2oE6v_en8KNnc@zYdnaBYB0m^D{X$*+p5GvObl$Q~4jt zH`%Y_c7I8sWEwNRld&rO9pL*1(u(L!eobJZa@J}XSi1JvaR2d8-woBoXb*SkCU@#k zD6lKy-Sza6A`p^t{Z|qGeufMe*!G^@FYoxsf6vG&ly6BzmY(Ylp_#mX<1G zySlbvh8`l96F{y(WdmpnQ0S8u37+LG%J@RSk~!z4eAj|09TQx$LgUB6eY;>2I*ahb zoI1yC8x?d`A~_SAVbdl}tzF;M;jFJWwk+t-s%q*Rc_YaXHHiK@Z$LT}BF&j|7728D zgiGGNS{^I-lq)zqL(>G8B}ZfNSz&bQ95@2qX8ZsiwjdvmRQ0a=X; z)H(=iFMxi`i=}moy6}HnO6wMHUa@A8wzO_lRcYOZuCgsl^`&)oed$`WuC!>ewsg(n zPW)U`y3yRVeoN`XN?YZN=s&1!HAW-hamJzM=g$h|0}@%b4h)p388g zk^UH6zzqJg*{a!6+o^7EY3pch?@GAzphAVxb9f~Xtsr1M>D7f#@>cy}+uVSPcqR9P zQ{Izu&k3b7rTwS@E;ZhdR&5A4OKgrqkO^R?J9KmBnO(3a`2fRaFkN!>YDI*1cK(LYuXEp+*HLKL~I1I-^O| z+U8JcRL$+1Hd%~ywJlvL6g!%#OjQnoCpK4^%}?4l)?&%MWVP2gmpQu@>Ne{(wY4{F z>1sE$)EGM}ZKT~N+u9b|o^;eMG+FF=oy}=`($>5XdV^+7*6-m5o)ybBM~ zImC3sE+Rz&aC*=e%eN#RJe#>rXEU~LF_~*KVFMK~%$(eW- z+wG2KZJWKZbFS^>IiowASrik*SB{z&9^r` z2MOvHXKPb?i`}`PO|w96T%a{ttMpc_&Ter+!(MB!IW!JCW|Ix+>MC$-^RNCjx&J?v z)|gg!rf_A!zZM)TSd#yn`~&&Mym#}q<*9PNk=vU4V9u?aH*&JGuV%lJou73l>&>j( z%S}f_v^O=Pk+#bAmW|mPTuk2snX{nBJ>3QxrGktKcX5CC z%E=VWzW${K#_Y>h=x4Gj7;IY8skctr~$%llxd>dAxBQj^`2yW;^&qZDs4jnJ!+Da65Cz7b{X`&i{HLWf88jh-`H&j8_r zzIR$hs8P0i$QF6+U~uf%(=y}CKt~$Ye4M$oqEDfmRS|94cL0zE@Dr)H)7yea26_5w zi0z)0-!6`|e7nml`j}X|q(*PNJKTFsMXwXEmj-8Lw~JGRfp2$NMPEj&-SE!s!Gn9k zeOEt7yL!Iel2v`_%2`B1X)28W0gTo0jV`U|OPezG$_eh0Kh$?lMfl6Ebd!X4|9#Xh z$nOLcxAN^SSrzzV%vcopMFzbpZr64q#W!#y2u7Lv9@&lR)dmyaXmLs43rd_$=p>8H z1TcBv;Dr$*c&dv$d>ZpSary!@5L!A+FRuywNh~XZ0_n)%J&_ap<^>OL5AM7SsSs6a z&FZ7GYH>y2^RW(%Y}+$&2f?8M6#=pjo*{wtah$6!%KmmO(0Kf}7p)4s73SytMIc`Zlj2r80ZpssUol?W-KWZ2kl5;N3>lMj>IANkXvrMyp#cN?2GFIT`_L} zNo>xu11AJG*O9D+Z& zb}0IW@c2QDAtLsvyn!x>&s79Er#dBYi`#k@g*GIANALY9`UNdu)V$>{R0cYxET3$5 z9w~tu+8ZACe1JD->2N;3D$pLABdDnj51vp(4&CSO?}wYDu0n2iAWW;r4FqYvg&P8G z%2}_|4iELaQDrr+bn)^PMH^JX6X0tg+&tWAAAZYi8=-O&b!nfi2(-q!I(+3~1j)(M z!-Vt#ch8AC=Yj_h;kF^ST_g!jTHfZ*R0dk6x_Z)4%p*?zBCsJt@AnOWBA97cKUWdh z6tnz)q+RMaEfs<0Si7XG&3ifAGx9;~rS8LA5onrfH#X&_dYZ_2%icsuKhPwwsUpxA zYZtN}*!Q_h0Wvd)toe!agoL|$RPG3Z8pTNa!B`P!h_#C)67&pnXKtvVIu0UGGMiJf zmt-8My@raw##p=ID<_}{54j4`zi1beE_B+3Q-yqc0T$wCoW3GZA8R+V{UUdHC&4oY z2hVV>Td0-<*(O+!<+iKCjz`YXqaK<(Tttxe@t&l3*+&`zg(HU$QwXgZ9`mO zgRpY!15Ji7Hl8pV)lk0)n39&Z7K5eMQr9MkZ!SQ+K9UAllSoG+)q`&`@BusVLwua0 z)1~Z1=HMBDDcryS60X#ascfe>3Kea%+1RORtLrp3Y_ZfgZ;p@m@RlG&U`C)0cRnNy z)iiY2P%nIlx1AX^}`1kMvTUZf8Dd~uo~GxSNbuC2Mi>F2p zs(F-5(YysL5j@0O((cOZMNHlx=#$W(pKw?Dq2hhSQ70aw1R-B^cddC#YmFIsRsH7L z+G+Nf4K%EZz^Vmt%*inlJjC16=F09xBz}Rwo=F>`+oL~5ubvQHf$ub%>o<28Tg+W1 zUA-VD7ab-YG>A}5hQy9eOOtWphj?RJUH^x@Hvy00I`h4?R7>3wLf(>iN4Dc7u|;=v zRc}sghs|KHFc`exHPzMCAOivoIOr!Q6)*rSP|5;tOz|50lCCiS&)_lk|{mdAVUTVK>CAjH8dgn+Q4*Bi2e1B{U4 zOJ+^hQWJde&YFyF-8GsWD6Wa?#9iAS=?oE{4Bw{#TXd-j{BU4Q!zgyb@HVjzIKE`o zWDPaJ_wKAo?h$Sc8Eclzo`14WTx)V)s&BQ@8D0@1ZW3{Xw9L_A0TI9v6pMn`OwHHC z`6aU^9sSY}-geT*?DJ$|zA{xR)MKrohL8SL)KPjpRcYxvKDOOdRU2x(V6!zYMlE%i> zUF{t~Y_zo#lSPj6uS6n0NeiAdtD>(OI@b&lHlC~r*aS8*F5ocsux7+xo__C_o8EBX z6uOM*$y8Uj*4?g~xV>OVkF$}v%GbMxzED4HNmGA8 zDX6q?0*oEmAsRK9vF|}q=3JR#;~^1QRY2LW#B@WK^@JXa@<+@7U>(=YV(-0g==1f{ z2zeG4D+2S#VH|ypB{u%jex%^b6cz;qnM!lLh=!7>q#RDi1WOjHNmsR~9>Os}Pu{a? z=yQeBgj**HMONe5t(F#JIf}Y8ng}QHEb-=OG8Rq&`qdMun5?GbM$&*A+$`?y6+>s4 zm_u9JFfza#0Ow^fvqfm4! zP<>Z==u8vdU@J;sC?+keOXh|sg#;B($TbG@PCa1Rn^1EbSjZH zbgK*RTs3q?VHb+Y$TSf$3nmuNocqTQ?i<_kW|AG*?1nu7Lf2MoC5PaUh!S|x=Y zXUK49#SO-eIC+}*Q$kZfNF-IO_+?FXGpkywU#x0A)ZE#8#nfL+eR%2>O}}V*vT1Hp z?UbWax~5#x__M~5#(53@-0*&b)^JwfyC?%*?Ei^>z%SR2)xT7~pkAtbzxqYr-}&D1 z-Qts^k0njIp!Nr~UA5=e{G{fAnuxn=;ImJ?^g#canH5D;9OFA*JhA6_XhlZ1d6KEB zkpDE1R}?Q#C15@Vb6F@VZJV8e+|Zf6PD1hVBd_K%P|{UU$0qd0zJgxS^Gh-&=dnGD z$;#Txz5e>>(|dA{z2ZF|68I<=dnF=0H#Y;vp)=1XFJ=c7sL6pgv1Z-#bHtn2=v3*M zr5Pv7^NH4V^h*wOBs8H4L27L^`blv!Cc6hx(<>O8hpw3cw1NudNkK>0d~BrwFzRq4@r8I!%x zp5$7Pn+R1~xtHN(!ahR9aQlrJxC;xYK#EvxZn&Y`%d9;ES3pF1gng`tu;w?mMM>Kh zWnejUPIFE}1os4Sic{FBd<*g`CoB!l&OmYKoJLmSw3XFW{xu@klf@F31{P-^H!NU- zc;h+J6~~|3HFo$I$2jAS%YGB)O8Iw+stHDXDKjSnyP=bg)=oE8fd$ISLyd)`t#dPw z8WwDdSTm3Bu_D`f3`yxdfj7l)uEeE>mt-I`bh1q5c5fG<@!dP^a( z(w2D{$PJw-qXpbf9-0BUhGO>m}2 zo7yr^89LurOul!6r}Yw(qtZ7PX5cY&QaFf=a&trAFcH&u^Ebz~9U6UV(%0?Qd-(QY z&*D6JXki8tL+AFzaEv{>C;Gk26tN;?AyT$+b_V)F=VG-pD3l#llYxhpwQOWixY&*e1PI{(a_A7UIC@zCHs(p_46=?2pl>F`}Ny9o@X7 z!b&$cwFKH_U9&R~6gsDZK$Muc5@b0m)`xu?E2nct25LfQhfn6emwyM@!jS}M7ir!6 z47`NS4(I-c&eP~4&(J&G>`s%9Iwq~1ohf1`WLGc`qs-WmC(75!>gR+kt(l*JozSgL z7L9|)ItkyUDy?3YSy*JoWgf{593I{GiV(&!X;Nt^JX;E5^X|vMGrJ1%ugV;`M z-%8_0;W9b6ef;(JDjUSG3KE})OZUysKzZhD|A_;ij1BFxA5#@Olk_NL8r$b)AUrEN zK=XMOJ4bkB#Wx8{E-I~GRKtY1fk~ za;(Asso*xm;msd0k?kjkl3`7WruCSP)61;y6aD87&8NOZgKYJs{PDMsjz6&_U*Ka; zj19doQTW>@K7kHS)N%aavGEuBPk#Q9=u?nkFoZKU<=uYiIDM#wG*#DP>9iv2ibj$m zvH7$P6I4FqdxYBE;8r^hGKMl=3tLU?HG;$$#whEVu_GgR?(;Q85#o{k{Jl)y8ETTi zQN&250r!wUsAv&c3#)13japnwfO^8+nq4_G&)rRKk9CrTZHAM|l%_}YsG5w1^h7$9 zPNr~-8_-ZBlX5B&)zu^bKS~?chvpW#$wgGe?y2q1}7U#49ej$7`5hD?vebwPtJ;@xU8on&s1DQy22sD7g9*PS@Zpobwe}ir?okD3Tq}z zrt;>w3e8C(hswuK)NqP!j7Bur_CkiCB?;In$#gWyX9jubX8X3SANpGTG+0}0^YJ8~ zh&3h6z%^sYCQkm|iT5+*+lpErhHWw#A_)`qH8rW>Bv(`Ea5$|Qiekk92Jaubu6~+U zu3UKHtrN&PJOluH*Bcx~V(Ru8Niy0&n( zPPUqso;ZLnNl?6SwJl$q5NwO26X}FvaQ!jDN>Wc5F_}0H=NFr=SzP9!p=;`=Eq6B7 z?A5X72e=N|i>9$;kqQxsH#YNs{$8O1L>;sg@()q=f>1P}3u-4;kVax+IGJzn*8X#b zzREs-o=X*G&lk&c`yl(bKu`)ESo5shb7*|0d9&pf`Q|Xctd?EJ8N z5Z5k)%9>X3GOtif!C51ogCq4{z!kg|AL{fP&tS`Y?IImr9u71G3Q!AOEZeB z1Wc3T2M0#?9-9URxRw4O++U|V#nqMJZ&Kr7@#TTNi#1UKQ={!CC&!5#oN7kH8h+?Vr9W|w_~nm{DvUK6LErv%h$ zwV|zytmsO|R;*sW-a%br)`ZBjV4wot8iCzm0`Tknl3A07z>ru}K{lurPLJ{DwiY5c zohjaVpwL=2$(Yd%^VGWDm{Evj!D>QaRNP*{dxa*kR?aV(^>~mTfg{M-BixfYFpIH) zt~Ke*Pim=hsC&!E7wJ`8-kA}!k066nx3LrNfUova*05yRj$XOFIa`5F$%#{kW zq(kpXt&eYr$g5Mybq>}kb8H}QfldUjDePu+IP)Fp{E}Id`vD$93giSHTl3U9QmvU{ z$N9J+YF4g`Zd}*ZlO~?7wyVWGg9De`doIhM(EuFf>*M^AS)Yx}6_|jWsL9-+eYw5w z=XO78Bf>3(IZj1;H-aOTjqVL`7px-4E5J1@WNZz2qF>fJzGT*;Z|xBLKMatAh0B^I zXi39YR(^oA`&O*z=#tkd%a^ZAwMTaf8NyJB*P!DeacrX$HrCMW5;(=$mFj@17{Tmam;64 zfoPIE261@reN2e0dkB!>phD;3$n67X7D?NgK?zH42XKw0enQMKnj74ku;J{>d1Q$X z9-cjLMxm?4Vj<5B9jh1#6|NQ-PeRh6g#)J-`spoe+497-@Q39Eni%C$^&;B=ucLHu z>A-1)@#);&hasl5;#S14@XU=r(T^MQ_`yRJ0s!!&hh^4^^wDht&4ujw7Q3|NH_XSe zEcYf3Ko5NNm@QOU`ta6)sfA>^xovL~^M;Y1JYw$jjJ(jFgXaRBsE_uP?+M}ROn~E) zKA17kROrIZ?a2ra{&0Ea6*D3b#Q>BJ%paIi7yBl+O`rvYt-WJ=i+~P1{GpgahbM`d+$#tVM+og%RoXLq zpjao~#PV56MCCg%A9#pJyRRLnFO&}$JqQY`!jM{y<)|XPH+P_}&}o}H_VU=4!O@*> z5g;H1xqMZu3C7I*=HdZgVQlxru^qXgBTQKGWyTNfJr#|#5F#4VJ8c6}VO#}|)o~)l zd$Se}B=_9g+$hV}k=B}qne_I&f!d-N>btwx_}JzH?(OGuZ&r}@5KV(#H6p#bIP+l9gd2nn-BAW=&QxEY2Yo-u9du2i9{zAot+j;2;?8^N| za)Zx!e_KM4US6EpSXe_#!n>7IA-8q^=>E5+PsoOq9S|W6&WT2#{Z zy*bR;IswsqGH>AXg~l1w_+yX13_cKZ>Vpajm=-_?hqNkvJb&PGg%=f^w(zEozw;K9 z4#FHgc&uEl@-HJ{T{_xSHClC5)y68RUs7sEYoD&2Q}fTwyPNN6K5Odtr*7mn|MRBD zo4#7TWy-E8*Ejw{Op#1jS?^FFI|2D$MGC|DW_jyv<80r2%9kg)iz1_!RDKLUP^DflJ0IYr z6rH~n``QT(BD?{>NQ6Mxd^3-XJ^IaxWvYVqQTp7%tr*r$1SSzPkmERFCZ^ZBM=LtB zP>+V7S4~J~wQa?!c0%q(54X3LjPtr= zN1C>rLS}$q;}AIKYv*Q)MQC>KgcokCpL6~(Ty~X5fqY_Fx@L9;>&to1%pKaF8+awR zuODW@@~;txIcT()^ws$pj4tQQ5b8l&pBj7jNzQX2XV_oiJtnw_D^`oe9#y6I!VFfHb48(yO@fRiaMXeoM=D+=R4qXwGI`(n(%N9UU7@|ACBX1`pF}~^fv2Q+C!5oG6B?OyC zR0_|{U{Vz{7>d`&;cUyl%1eWBfy#GeFsBwf4qud|a@%m64X{hFj#{~pi;v70`}o_R z;AO4&a=gh%sE1}|FtD7vhiLTfZTJi;v=!RfIAr@#DL5lTJi>`8K9yl5{X=S<@()Fm z_S8>m>8cqS0uRor96$QbiC4E)^oyBu75!A{%WWBA4bBq@FUs+QLu1>I=C;01kP4qd zSY1)RkA=ibESylKFWsIY$k65(K=Hmq+pgq2SHi{3Z(#49_gJ*D;3W~hkIUz0h%z`A zL*6Z8X5e_f>;PeqE}NSnvQRK(50Z@gLT+%UK*H=P>*m2!CEHPnQLRg7WQZ>~M?skF z@9x3{Q@+=P)e^&NFMV-#hOmNj(;xk0KS}ajya_IpeGQu-=XXL@q)QfN2p~9j*U{~n z+)+r5pJ0x+<|ZiZ%DzzCmBc9`OBXN85K0i#q03s9xFFZ0n@_q%)S^7`VB!g^T;ScPbqQLepKS zfy+`0w~wO3VEgs!c8t1U|!t7_V!4B-W5%>?9>fZHQG#}6OL?S2+uF|I+( zH7~D>#-$7AWQa33^Sw@d@F-hZs}hz^qaY@59f})1U#kEy9Hc7Dof|j&JbsCPC~*%P=*10Ar-IUYY=)NN%Fk;8Db31 zWop5kar&ItybmNm?w}_#h6~=g^D{&ioG-H+2xCJJ=MEk5a>2%V3P>#!lFpf%A*|qB z^Lcqc5;w^%snk`%AcE0Dk0D_GvHexe=TH6N)Xh`lO}VBgny#Djw^N>&a%0_Hjh{4r zy)n>mq+w&jmjgcwY^mMk|2zMy(qgHp_PgZ&UsdxbHILU^Tm9G7JFDBOYpUM0-~K<% z-|K$p+gso&pG+mQ=X7}7;pu_TQV%~%J$#|k3C=O}n@c_H|9s~9dN!MWhkL{swk^Lq zi1P@`C+xvP!lCL#b`(s7Ea~Y?upa+bzuhf$Dh{rS^)a1uacRNgOsMdl{qJ_p)%~z) z#{VbIIh#c@5qKOOc@Nt1a)V+@3WJ)L=HHcRE%feNp<7E|qXn0nN(8r6WIeq460E4X zkDsdOC$e^LH6qls?0UTo<=kH;Qfq>dYjioX6^_iIJR$^oB49#;eGt@liV>$sm^`$ z`q+_&%Z(h$fnYjC^jNxnN#=^e$gJ2cCs114Q%>PB1~d~6$AmO{VFreG5X?DzyyvTdc*Ve37$*fqhYL{nR7Fj7Iq*s z!^aP8IezpJZ;k|EgmQhIF*}2>w9`-&6eov{2!50D!sHXAG}y9VYs<_lY#<(5;MMu4 z)4=}RUT)`J0y_dMX3WaWt-I(FhY`h9f_tnS;__a;+gWVcKY_L> z|E7s;ThbS0<`iBd#5{xAZRZor144@eQ0~QlEY$kA2TRGtnc0O~s)+i%)z9S&Hi{OZ z!u`q1-h9XyNyt@8T3cpT;V@XRK+A;9Clz}DY~p1hJ@@O^W@Z+~PjGFYIPgKmeiNSK zm~`)g%#1=mv^9>g-0*?phuZ##qR$D&p^z zR{{8>sCi?*`_9aDbr%V3?2|WRkdC7VUSK;K+w#U}|50JK6OXm7D6L+0Mlp5Zx{#&2 zW@oM~Tw$Yw!vc-sDLf#MfDu``b7tl$@f!QiZ{L&3b)gcbogwy(dD5EMnXeYsMzjq` zk*7z?yzr7YVS3;&Lf(B6 z6IA|HiDoZ!b&&Y)nSag`p(NWoYKuZ!Tz^K$F^8Z6sPggbXX}+tuZt9__$*GM^`H5~ITnLmj2<#dVV z9Yp31=fx#P^>EfjBEFlK4qj3S2+n1mB1_wPjj$=a+nP9`Av5F=$D&z2p+yCcI3Xf`Inn^ z5;^0O(Vd&d9(^bGc7{)c*Ldgixub`LVo{}_E^v_ucb~9t!Tdp>Zq6B*56qZHrk5E> zzMV)fQ++qwHb^9PfurhzA*Sn4ibzNih4H7bRtD%(ydC8iU7JDebO2nz%jo*S~-}(rXh!YvlkB% zq;<|%VZgk5H21L?W*YnE>#*up221B>tQ=B(vz87Lo1NpRbpcUaDu1lQDqlIV9kKGG zzOS_nl7CiEIqS|~+SP1q0>{4Vz4Grf8ygSHzU!6^5)XC;hZ57{xk1LZA7L|YIFko! zZg0PcqaUu|Bem)pj`*&fKS-R|*>LMhV@)70u6gU!QDVMp<_{7icD_usbl@G#0AUH3 z^ambVonTY{>g++n!p>!VV((yX@HH#wS^hQF*$@r+u3kJyK)7I1XZ8tq3&~wO9&WY6 zb}PRVjGW?2%pN2(?5vuY!SDo`+Q?pB6A$^~^9P9zJG(1?;+r8MF9tsC6d_&37h5(+ zjMzCztkX1q-8Yv5o0uh;1tZYd(MgV$k_ciZv=Z?}=MNGtE~uzU{Awk)h{I=l<%Aoq zU~=3SSvp93*tsL*_8bxZ)mILq<@u>xtEx}EW02&t#g2_;{D}`o_w6U22#7O>xOs7( zxZHYlwTcxT@hLL~i5xraP%+?}_vH?j1*c88#W2ajcMK9Lc2;m~*GqVpNu9Nhy?h0| zZ#m``0W8=Tx@(a5u@jXp92RdrmfQLPVD#}FhsIyn&w2anqmL47ub?iiDO~#ozd-& zO=g|Rp0dtBV@7>fEFA!8>wN9xdqi3X@&H4-TF16OeEdlN=*|itEipquvBZ6s&mRDD zTd;>b!FK-k=>A>8)xY(viW%P4W{0hI*^&Y9woY43u%VFp`qJy;{ZDYv0IU~l|0#q} z$`1d8trAc8E?qPL>eh)5v1Ylog<5lyT5>3sn^Ae+5b4>zFD@Jad+UrI;6E6B{U~{& z_!wf=>BD*~|3Yifxy@eEByFz>R99Cu{;%qPZTPLgx9a}Jw?O(ub#?8Z)uyW6th%26 zzE?rRqY){u)QN?^iE%`td9r&xc~Oyd+J+bO`El% z67XROtN*|*+J54LhfnO@lP?VkGC35Rj^OolIXpcQzZ!!|jRi#^qB3h&X?@q}EBbqf z@2IElTM|WYCJHGGjeYyY!LLSGX? z5k!wALvg6<(gr+exS|27r=U&=C2TJZ{BX-X!%OR1FKx4tX#WdjnUEGdvEuKj){kD zFSbt{*B6(WH*!!x91hkr10lt*lF~!z5EpAL3h!J3E~s=2NiNw|*}&WVR}9}--+Fq} z=F5vlc)m#<&P?r`eqX9#pl{fiC zLK)$3;75(;RV`v68bvkzRO>MC!_~vf>RaLLnpX6}Su4!4TkgE|?)==D;>GrQVmMQ0J2hi5ew znfUWEz55zOyu#7Ty1Uk|zD6Vf#gLgwN24it=CpK7=T{;Ozn~G(v{c|bTNe)BCWh#d z;z>4k?3J-&rH5$UtW}HC6ICx5zK%p_d3TAQt?NuDmrwkx^3cYALqmIVgic{Wi*;!w zdVPvHq0YCE8{(_QBYmHiGD;2f3}psH`M8io_J;Lm!9Z(C1e8=gl48HppmLMdm==}| zcq4TkC;eo>1>+PA-_~}rJtd~9+gV;}v!7_i#Q2_KLub#JEhGY==?zW%nQy3?ux7Lp zMNODkZz>knWFw9r6^hD8ND&*e4t4=q#VoOo zF`~jCU&1mEx2@@D?_Se+O(?K;>F_OebiwMP9xnV|N4`%Oi(Y0G|EAirT)=~c@mRY&Ex#-KE>NuMii8AKF zshgF79}YY?yhOC|@oS2zX?31uQG2xj!?C-A8&<^9=wRz=w0i?Mh%j2q=yTr-7c~Yd z7O_&oKvWzCB1YB8BjdVueXTGsF1vZ@l55x!aGJ3@sF$TX*Q~xq4PCZ&jrcKtS+Tn7 z-ju-=;~Ik0%4KUi+t+lqclS;Hyl0(pjU{u%RH$fj%84>2XPN3wj8(+~=q_O}+j~rG z1PP#6a+n@N-UFIPWUAdw>M~U*=rMHkxckV_e`k-CvZFUz*R+Xt7i_zso7aXWx811B z(vzoSIwus`&Y>@^P~lLJe#l$S?U0(coQ`={5JRNIAExys;q9;`o4?os5tC zpA%nP>F)uZ!>{cnyU6yomI80%72dUxX&-WS+%Tr z!PMWMx~S=oQ34p9va<2ljT;*NwPABZU0{3QH2;&nO+59ebb9SGwP)AtthuE6t?E`@ zQT*%H;jh=Vp40ST(Y|u?(s>IMIlrTviiyg$9Z~|nz}N5(>{$Iu(VM|N5j`F~ust8@ zHBFC_w{UJ#svOjHR+yYJqB?1cD3hkS!=ON^CUrdtQ?h*o8veX@_(8E*x)hB^m{S%& zqSvCMi6G+}4kdw`8fqd5y=qc}16vdP%pn5|Xwo*L8vd+z_<<5dkMDdM$0YO*`K*sh zt%lBrd15d{!f7L&h{JiSh`FYx)wC9ZL_LzSPmzZIcf;`gX3=s{htu0*hmrf7V6UiD zbX*BSXP-(WArKJSn8;Ha3QbPHZyb$d9N-5!x$8IlY47mHQjIo;+Iz|9Vh44G6)9edTD3-s#SS;IL|GYjoOg_CEjP-r)@;`W#;v)7*QX!v`2l#$d-449l@pNKVON4T5uAXaXXR%0bA{ z=l{8HxW_CyQasV_8NOHC+x{au7$>jT;yNWyZsVtL594m0XSNUv?9{%9W98=$%fokz zjvc(TsADbXDT%h@&zMPQpP~Tu(=C>P-OyF)f_Q!GdZfivnd5BY&w|4} z5<;suf!=fqNnw_HNQNajiuWvHz_*|J)Fsc3&rV=Saaf~iVf|TfV~fYxP$Dr1_fxtd z$g)GJsBGZm;FJk*ftl>A(zbydgxFeWbL(L!-sPmqj;R{RSwL-pk1r+UK@{7X_4G>i z*dXCj9Ir7wB^zlyo{pzr^OjSlU^e>BDZ7&<@Z;X$yUZ0=>=w6JIczR{y`yzSvQH1U zrg}{merrgco^0n%WxD$DjhO~hYqCcVqRv5Xr1@{`TVQ$I!_<3m+{D#z6j5p6?Ek~Q z;WZ`pfziELHa|e@p3l0l!V!v#fdT(mZ2t6cOgK9ddCLKoAk9vn!mTI!*~+BYHgAH4Ni(qU8mVEu5rxw?vt*g4DQcrTVsB?t?>5=t3{npS{o>S+VmkTBwK z=o-k<>-HA^Zr|{V5(7PU_+79yRv3B0I4`$H5yc4wwS>%+2J^%g8)iufGKqy8XW+VnJz!?KGo`r5N`g=XYMt$o=Zg+;R zZmqLr!M*6UkIXDu!j(0p$1 zlPG3;-@chwLC$$55*!*KG*HkeBKL<;#(m64sHkMwJNvsEhm&UM#S0p?pc6yy=XSp6 zeHT??L1Cw(RUV2kyLBxUODaY(6f(pXE>@UhBl}LjJgn7o<=tFdx_RfF6zlEmUa_*f zM+uvU<#cVOwpwf7Xr!ih7~Q5fM0g`{i3qGvA}GGP^j0Mtv>de)e=f2ING2_SQ?w1^ zfj?=gUR`x|)%UAv(o^4`sy3yjJlXhLjn_B)LEzs4SNZq))%t_gPt||5>ic!yshjKj zk#CXobLqC)U(_aR{<7xG;!FSku}}Ih&Q298d~0y@d`v^K@cXS z0&+t_l1_NzQs|~d4bBt9slvKyANR?=kEp~BiDxC`>5)XRPfu+Oc5e`F=6qy0+VGFf z!Ky1t)e`sN9HQc0Z*ViCZmof zD{15x<*<&Gt*8cxJ4we)ezHNOI|(-`zUg2jk%oE<&j>PqN+^kemev8Rk!*-?Vu_bl zYP+H|{6$ap^X5@se5(~l{WD0Ln(922j2oHl4w)5#o2j&H=mbs(tPl_}Qeh*MN~bg# z=|I~^HvC&(_H&}o`-=;;>oygBgm)`LW250+_da? zp@#q2lRdLUr;DV31H0zjI;V26BA}u~gLuYp%A>)D??#DgLbQ$RpAk!w=FchY@YDT| zzU&z#I^9~i6rM!&^v9P`7VH4gb=cJ>4w3 zc#&C+7O=DT-l*Je;TZ)9NYbT~2xZ>H6oRWQ5WH%=W5}&HvRL4Y_nN(@u_Rw7QHU9aFAex z#^o9dHj0^r=#r*!dkDvHlN!Q@zzxRU=zr?VHkBA_tG~y0WdRR*X|zxy3koS&biKr2 zqx-4JR3RPK>8aTKx}w*~SuOTV3t7)dH54NCfpXii^<{f^9m=VyL(&cvoUf zcXmG&AGy8Vf7h37sBgX8&Bn_;_WbD6drll1=Fpvh7nO-vGSRq15W~k0fCm64w4xYL zFcIFTAG8oIX>3k=*?-%Y4R|PfGQ3cF*QabScv!K3+F*J!a3vue8pk(_SC$)NL?$le zux1b>^j~_{_WG6jq}QJW-XIdc-8SVrel{LQ_dFCae)UlzU&=u_FHJ{;aRQ z72&SpV&~krbcSWzC@0}xWtN06MsUs;svM7}q39B=HPXZfRQzVd3ga;&YN(FG?!WZk zn3V+5&1DpA#aA9gLWkHG25>^;L9wvVK1QZ9g>*FIn4;x)v*PxmJr1HG6M{f-8r{{1 znoQyGGYAPJ#Xn*pT}Wv=263GB)K+YdhgBxp!xh%tRMRjhqB9L>h=?13AGAT}#z<2A z6qAzKk-}C?kPIKyWLzxCNIZ!hjWTo!VP$}(j>B<`_S95tkEbmQFhDTE=Aau`0I1fo zS4Ook0?Wizi0>k(>WJoe93KD%z%}F~S5B29Ae9u7&=jL9%!IH38rj}S4Y`fkYIC+1 z+Zl6K89hcv%aXNgI=fpujS%YEK{QTvC7xuzRl~&S(s(W9R0ybup5QPB)NEVf$M4Tp zm0D`{!o77T7F93}3|otVB1_|{hcO{xu--LR8ad<013Na%zvP1Z;}RRD5;(*EYyXe@Z~HU;cK`MMOZ-*!e_8*n`knO~;Sx~mPp|u%x*yiP zRX12?)Xl5Aw9fC#`M%?O$#=i+cAx4yP5PDeJ!zNp4e2f^A$`8~zt{e(c7N?~?dsaL z+Ar7E*Br0;cFl`5y*0PgTvZdO9%_5-MxWYy{9{B+M7Z4F=~{=}p<`4-$U?mT zl7DZBM-CtXVukDi_qZ3g7f#;oxrdLDVQU?Gflk+YizM0C-Wh*(e<18$)}Fn&-2?fu zboa8%N4VUeteStY-~C;?U&arUuTIaUQtOpPJze0W^C#V3Wcq9KFH*}qVkN`)d&)gx z4n|;piAUZf2*7x8XANvC`3Phn)+0B&_wlQT^8J!>f5l5fxr3XnSNK11f5de9SXW2? zNSQ}0|B?Su_eUPzE06(%p=yk_TTLOhz+{q?=A7jH$|HEk)z}U25v9+$h+@~`FdNq zN330GyZg{=h3sm7AnN*kXg$WCIbbz6u(-q{!l7e%8T{MbA0ZWaa=&@dwH9=jm|&Yr zeP4v;to`ciWgf}Bg>{c4lA;aU3aGaWbbX+=%oE~)D+7HkQtL%U?>HGS^&1yTtrrwOu%@H$ z-ZdRYVAhwU*5cbq*UG+@E^#&KYUy5Kw5(ZcbOai{EVUNj+HFsEYI=Le@|G2;fG;Su zURPY^$(OF}G*-78oh_>jZTWg55cs0h`lWKuuWs)R)K#i!dd-^dq_%2R!0$R4Y&F$8 z+x3-3cVNn8Qfq6uaA`m$L z0;%=9qNe3NK>m#DPj78s-`&#^_3uAVYW+gdcg>&rce!q2{H$f^t^QYBkFZ;{F0G?` zg|<2{*R{Wk(4>C%xxe(*g)MDsdfJUH{}0ZQTF)%1ArA!Nu2mr4#M;~Zua^3`mHg&^ zvEV1WRbdj9 z=KrwNBl#_J+nfFau5*lrEXi+$8%tGVNsGCK-G8ps`Z<>|m^sIPxYUni|3|L#hhkgi zhyAaYs#D9HR#B$^TczsMGW+HkZ8Q7_OU#Qz;HxEm5)Xu$sxPkkLe(u*Qb+BJH4CRM zYx-r=@+p5crKRy^Zt+^+Zvs93fAtU6e^_-({dIM}Q@7OjOW$(ouWK7>hHK8PezE#u zzFz#R|Ay@4rkCWFqAn6a$F~n#riB-eWF(4vD5j+WU>M;v44!yFi2)L%)glTWb5Kt< z_t2!nD<+dzN~Rb2*>RD|ja#fBpO^d^E4kE`&ue9!_88a5muc&}SCB>&YCL!9A6H-H z9!9lKd@pU0puEBKy74hoUmglt5?|LgWBPvaGRS+zuzhq5Q9v!}8{ zYCM=E#1bKFYXAtO62Ka896}HvtE9~0{Im6B>!2O$z2G4SweQ4vHY9l}u3 zL_6(MZ?cl58%}gwCWwW?sSyqtAw21E19Yiogd!?A763lOxTx*X@y4nLvR|lgZFP$r zS{^jQhTQpQdjh8sz$0i1Mu)gUjKq~FKu?;Hf}s|)Wt@!tq~Zkk{;v($R&zNOJLn)R z5qA|+OUYAzDh#>E8&hMXkR-|02_@4S$+-qGQxOPopa2_Ndb3xVB^Mi|R+)}8%d+7i zg=j6CMkq?+h)ke5PINB~TZoWvBh!mCvZNh=*f?!X_R9L!Gu`@p-c8HAv{l7LPsVXN z6c<=_+L=~h7}1#EMoh#YlKjoKW*RSCm;G{m>la*0TyVq8SzgK{%Qq;ZeuTfGkp$C| z0F+Qr1nd~rh*Pl8>@lOp3%avks&Bo(txQ3>_xN7LTQnjO3r16bq$30^0qw$65+`d; zBqJv@q7v~KyXeViMC1A0SpZ$-iuDwSP$EiDjS&WcCdfuxaC&>$8`XfPYi4WvqKCn4mroY&LOPtVLolUL^U4Y8Vj}>_kjSu^HHV z`HZ#Mi_Mi;yaAeLx|cFz;UM5a(ZCP^a*k0M92#f_J(2*92PDmrN78tDSN0-vV2dx= z*1gF~nS=t>pava8Iu5#>7$Ji38mBcUd72$aGf3ODpI(ip^=4a2?6+)sMJ!RJ4>@)| zAjYv&IGu#O&LDeGP5?Dj$Y3P1K_{U?kEiS*!p7$Q`Ppe=a9yJD46ell$_Cnzhh-v7{XabrAS0KUw2!1QiwsxJBfg1A|Ek8JeTmx`(ponh4Nh zi>KIs>7~oza|nhoRyCPz4Op514lqUQLs}ZJ3^1ygBgLlCM=aMoBOfk?gnxDy$rI}} z)-*M5t7@)aTvflgxfy*warf_T{O8688*3XLZU_V(51i$H&VOO?75}qOKI?(cdf>Aj z_^by$>w(XDz}5r(Hw>>8_LhtJKX2wuE%VyDyS$h?3dSwYC9bntB4Mbhl#HE;el_W~ zrpuCSQ@e%f!T5(DmTOZ`j{)yjlVM&LiluR(kxqhIANWuBIMU9P-9PLdeyEh$`We@b zhwQu0xOP6{+W8O1wPU5jn-Sm2JC$%C64fG)26hvL6ee!IxG+<&TZD*f!QP1POSL-? z8~&g5!|O|Uzh>ON&_a<^E*O>+xIM@dgS%cM8_r0IRmY3;VFsIS8~k2dk~k&A0_pJuopg4N3(viVR)T6 zMT#Ay;{yYu&pt}qJW|g@@kNul33pG5L; zeuHL1!ygL$zq6%zRrSx+Ppf;iF68^r_ciIaq?osoZCQ!$Fh6qV6WS8lv zMG}J2@gOFYL^{pvC&q`z9hw)s?zWlHcw=AIWVLt6#|DKJCX1p1hoA-wpSf+L@V zR82-akq}AT2;q2xU(FT}TJS&?K2`WHirw9|vKK;bRe4RYEQwtNBP5}SBtc?dhQ=C= zD+CruNKMBfnu1KuUi|#N?9JxFJoZMQ%hZ+IxX*rd!WE_>R^~6)-3H8T_Awkava!&WHrK{;6j z4>H^%@r3RO#?9-^E-JCVTY0G#qTEZzi|7=LBhY}t#2FT|Ek+^|Yyc!)F$cqf?Zw{j zbNjM4l}$^{Bh@RH&HhdrGMuj*pCp44b5%HJl4K_7I%)qfh!N?v;~pBX@5?UqP`0P} zPP>9hzyV42#c(`Lwjl=so>e6Y;wA(EGbe(*-E(@gZC01}Wg{gfo(L06z{4uHpIGGo z^(dJltP6yQ#F&Vrq3J-DF65LT7@*50?wv~Ms6Uc|ZSVHWHe|zQZxR&B`Srh;kg$%}bHQP9U@+&)G;| zSLi8lPw=Y1!>b6tKAG?_#~k}&Up7=?YT2`;yp+tA0*8j7l3^Rs;!%=n<%r;8!!97l zp0v$mJZU!>8!y?A4VoGf#Ze5aquVrHTVJ_oVYNZuB$H&%;F3|yX(q=7y8!qCK`sP) zmEj18U%VkZz4Q=+RXLG;1<0kBqM_1`frUxN3H+tOO~AaFhGsYsA!H*HPfbJ}{e95` z**PVSuvznF6$(pLWU&woQjnEk$EDy}#kdp9kAfI3m1H2uW7U9q*iO)|JdmATx_I`{ z(Sv!d^vZ2#Gl8Tr7#8fOB$W~;ClQ|UPYWOi(W|6NO0s4*D;uv~pPg0Wax!bi(pmEs z-8jP&Xa;H>7-du=tN{;$!;$tf{FE< z_R_}ahV0i&rZpG)1B9&wqV>`mK~oBY;VyRb}yWXX{amVhsIMFa%>awhU_&Zx|@k(U8Ox>uFR6-Txg+~ zF`#FLkvRr4GrS)dS+M%i?bN`rDTf}&ezn97F}LfH3E zGDCj@;SkqF5T}k#4?d9nN~PinFncc^3}pxkLo9r}3E-BXo8qnr=L;-DQLvQ|YTEY4 z>Fcsr*SCJo?S_G+<$={m^f;R$mR$tI8I+Z25Flw_16mqhBQOmtS-dv(GF#VV6GBDG zA z*f*qW!atRS1{QKsOb#^;69o3Wqu?voWn-ng*K1>OXW)*3Isv?G8p9&Qr4iC#LD7%| zpO$uDZ5zMbn~j>wxY){INGB5;Dz}&O4su-~A%HC>j@E<$#SB6#X&pix(5mpKzS>2h%UstkF#bco?GYEK%u#Wr~h> z$U0NWY+#9FWa?pvVFhiOj58L$w4;;Td$VgQ7VWLou%uw)aaWTO6o?5XR_;!8upxx- zQsF2FUdNvX}P7Q(cFM3nLy8b0FUsc%Mcq9f_Ejbg`7;K&CP~uID4H94k|Y7H zIK(QjQ1!3@%ayIrd)H-QyJlN0KGV%YJ#}$33hFt99!rug7N#h4MBE4z15<)Eu0p78 zFY}(>EHu}yyXu0O9F-<5lcz35Wlafk$zmTPzXjSg>@xxNgz^$<)VRp{NI9I4clTsV z(Ol2ZXXSc1sj<~yVg=nAhSU?+BmB}b4iawcsN@jqQjH`6BK9`l)suzh+I3b<7VP1) z76lVgOyY;qu*GG9Xi;oMYCs+nRx$Ah{F3&9@9fFKbX~q+Pcuu9&5`Y)G0xDZYveB= zcP9jVg&HuP!AJ`7Rol$EqbCc=b@_rlY)G^i-mf$zg~6D_N$SC`j=M31T&AED2O197 zp1t5@y;=CJUFDA~&-#fE_j}}62FHSBM0!n}>%HK&)DjU)B9i)$L;{4O3c^`in{VHk z{krMnF5b0f8toH=W3mTZPy|(QMzDvFuSPlngm7@!LzGCmAug#fo^C4Suo!OJm_>XB zzRU83M=CFAvvAyD5%h*&`2@L*1CsuRz7{Ldz^7rL+3fHw+`2J~@O6p8MaH`sNRvIx zG_!C-K+ue#^!z!Z8&K_b}Vc!r@v&pCF}CP#EVQ zmoiRu`0_YIuvIa_9W7tFF^d98#lk}#yPbR_0`w$qz~88fdn}u@ z3oRMJr>}t#P-r&3U(8~TFG85&is~qPabI>><+5Ym%0_4mT?7py3%4D1RuX?RWZhVf zc=Zr30AOJ6^F@7G^ph*KJL<9Qco4=(k?tJ92TR5PIYYQ#@vx&Mb|FrpV^K;Ez&27zJZmysDi>XII1+1TX`_#zP&o}+orr&FNr)i)`Yr3{+T2s}O zKb>-T%Cl3}Pq}%@Ra2%kjyHa<@zusnjdwR*-S~xue`@&shPN8FHW&?GYq$U$!OsH+ z0@*-EU_s!DfZw0HA1{(*X<{-*jw{U!BHb^lcN z7qA0BurGJ)wBJHX9NzI;`Ej4;g ztmd@pKd=5z)%&U+uU=EVq&if6S~*w6#S-d*FVzT!t|L1H+t1^BuR1aKBHVqsV_U}F zd93EDi>1r2Ecp4R{?Ydy9e-&*97H@{bJ}^*~v0T8{x7A!cO}hNjf}cJ40pGRC zs=1)}^`jr}9{r%7M@BclAzpvJ%OeN3jz0I+$r?0YAzdEJmlBjNpW`eLPNlK;`;Q;m z&KFv(nvK5qDrKB_<`L%kXZ6W4&6N|LN zD&^#)J^do-@-I0jZ9J449y8=$CkEch4Sv{lj&$DT&L50zf0uQuc9!~y zvaZxm!fQ+YL|)^lmRW(Nwe_lQL|*Hz{bOBc?+()|&WJk+|7`v1cHkvE^ zyK;|i<<#}Nll9r-C!Q7zDuG8_ z$Dlyg&9A!_WM{eYzgzAR6S?N!=gRSC!(93IlzPb|Hp;)d%p=yT{O`H)NKR13_}?z~ zW7+?fdjb2OVh(_SIPvP%z!k2YW+~H*nH;X7YcuXIGSyD=9IKC)d&IKGHk5h90z2eRo&x=^cTX`}b|kaQ-(-J;HvS-v&3h zPFIUxgGTsozfx+A6_Hk0g2xuc$|Mhn{~q_^o_Trf@G)yA^WRQ>fv=zpxtBbFAFKP%$@7gm403g-XQ zrasA?{`saaPT4ah(s;CSR>Kb(ZVLRTz%u`z`HlKNuTR$fvhE(=PtgGU1F5a{_iEc} zeq3`)_0Rb7Usl~$?p8hdvww6Ce%`FLTYk*St{uGAApe6T{TP5X!#L0In<5Z}RvV-& za0KGmF`QA6$2N|fS;CLFWP-c3WqrpQPldxl6C}c#Mh8YE$wvVjgb*Z(8A>Eg{8@;c zIN~CYc8#1-g8pX7f@Lk&dvKkSw~4Ph2v-Y=*2qZ{-;-q{E+Z5L-3U@D23R3SaIHPi-Me%fKTIkP#-N836l)wyP{R+q-kS5@?kb|>3@*e3M zIjy8KZPHusDJp|5bto7$$h06zfy020i<)_!4U+>DwVH#FFzz;Vz_K$P|bu9+#~3RObW6+ zI zs9%KcU%oUMhQdWSya5k970t#hLSi*xFMocBKvL$;uh~R`IZp#(`yO*9sgAK@4 zI3}|zfv^F4rGi+t5BmdsBWQjRy>!8UOtiVn)A`Rqz>MPcQ9}prf)s6nGY=g&C@PTx z3qd$bnyJ0)`!|dr&;<^pOxa%WSCkC3ZH)B0IQ9+-aDr)&S)T-vL26n=H^^;wO!kev zBdBu`Mk`ZtSBtmP7otIID{y7#kO|FYl91I@j1;&8f~=skNkX(Yy00gT#IP$YV&>9` zFu9lM4dOqjLplmZ3r0h-{eX;O-4U=AIRK&?$h5F+FugrlNHWS7>}`qxF_M!8TN&7} z7(*P#x`k(vB*3)DFOM;-S=$v#-AU=O$eMj4z@JQe4FAv-7)1rHI|lTmVJ!ihK> zn!xQ~fVH)_XG8V@v*6-${`yV>ntma%;Hj&z;DW5=Fq(%%hcR!%NmOr>A{#){Lg=sp zT(+0IzB7A&39#y%76YFBikuv@RsqV0NezyXq#PK;6Xe)|2}V#42m(mqG`z<4Lc6=N z8%x;m0=7BJlMxNpA}mx^u_Pj3$2iTSU~@sOl4Sw}5RuMM$^nt>>dW?(Fl5aQbD`1Q z0!pTGiv{`_ZO&MfZCQ`O$=NRD5`?I|z&aBC@Z(Gy3D&?_s zp{A)*6xJFU7Eu6?F$Ihli6-FkAy0ND{H^QDZm87qn>q|{Wg{)gsSpXFe~tyq4g&6g z`&$&DM1Xvp)(*b!#75CkuJ0hfnrky7?mB@rH-cNN2|`OK2lZl zZ#7%1k2Ie(b;r~%Hoe=VPB}8=YmGl>T-5NhhPwh!1kUll;Gb6iR=r$zpf2wF#CNsy zU1?VB{nd9={jzE$|9Sb<{AlfI?hFUBR%jg^#wrhx7M3q*=`jF-fV4sed36agc60#* zW_JeHgyO9;MS0Kq5prb#T^Aoolj?Vs#}m_oL=vu?3M!&l8zi_Pii+C-{>d=>*BBxE z%f4&u?i{f)Ws5h-8A5->OPOfghl5}_#F2xs%el*cV8#SMIUMW1eguK{FSsS}Em_~$ z?x_T@I6(twBc}~>6?JtE9J1^{Lj#=wcna{^4!87#Nrozv^F$;2FGLm!*HHiL5$Nd8bQ`}Jb7py&AIN2scA+bAwWX5yIWZ$3Bzx4r8H z>-sfoQY{=*8`gBLY&o(0eJ^cdeREhr^A4T02I~QL?+~V+jQb-@+5z(_5^>lBZ*-49 zaDSfL4QF0^SNEFEK5xb1R%Eu~$|FS$?_!8Np{SmKT?Y&s*Bb~K9QfbYx!Xc>?|Qd& zw0oA;0Vz=BI*8qy!$<{cOx~`7nXi!}2S^t!0kE;UfhQ{DkfUvUZNmtx_n4l=d(6@s zXSJMC$->&^Dg(m_{K;Y6M5l(x&?9A!9w%$v(fU{WMj*a-#mkM_!XK4eZSqG6k#DH9 z74Vq}j6UctR1)S=Bua>E)G*ol_MLUt#u3zIxKS7H=u2;nwB59DHe4f1m)+A3UA zDFD_kx2HixtJ**q%1Jy8Bjnu*C#j7vSTt42MmOEG<+P zVhKnH@FT~>tsNsU?sTQSc>f3_`L2$WSvQP*{LbhrgU3I4WAvrhE4Q0TraVhnU#M(BksbjFA~18D+WPT{U383j}?@LnAg&|%d+w_yYd{_-VzxEV8cWS|6N z7??~>EuzDl5A#0Dh7AIz7u+b=H4ZPtvl~V(tW>fG_lGE%n~NZr!wbNjJfh-h1GY`h z6MJGr5Qb>ZWAK@-5!mg?awH-ZkYYc~X$iQ_)B$;b9ZGO(@%h@h6h5jrcpt@Pdm-CqKnOPTKfX&j`f! zuGy3`y1F~p;PdftXJTuhYq?SAQT&SO2!|b6ULx~IB&zE=BrPOZI<|%<*N;GL?|P${ zDA=1bQ;i9A37qE!2?;6OAP6A{DjFjq+?ix4IP*}RSU+-(dGr*I@Qfu(7KQJfH@k92 zbAe*N3&Kk$94(N(;$eX+gv1kqsJNcMhoeg7IPyl;k03%-w!Iz}lej_QSc9mM6^lL# zL@W@{grl4VWZl5#K^ke=F}JeoM^KC6sC93z?7h8k9O)XYj8Tz(fR+$(OTxymmZ(7U zHDY=WgLZiR$mc7x*TWJP?S&bIIYj$JR#}YTnWDnNqmrf^;m$?kmz@Hz@o_HE-6c{6 ze?#}V#vu{^Kfgw+syp5HlJs*aS^KNnuI8;%Kb|_T>5rPeK4ly=fPZNmZ2Vlqs||AC zlfVN1&;0k)kJYcQ`=51NYJOUyRiCI{Q}vHk4|;I`xI9yRTo{qXGNg9Z-ib+FS<_GP zsOk5ko{<|(>$SLG0fn5vIeITx_E_)_dPWwMDA>}Zu&^!O3l4cK_;-6o=9ef~Xe>Yb z@+lS^N_Z^zch-*FP$Knw=0Z=#%>QQZO#s`t&O34N5J>?9DaTD5M{%vhm7K&DFf+i+ z0BmGMqGd^zB_BHMIB^*e01t_m1X7fg!vb~R5}csIkM7!05Gc&H+Rz?!Xt5a(PjtnUD*#< z6f}2&?#PG404l^oz*T^=mi7^+6ey#feuCfeTir2F4hy2_2XhIW7IZwj}^o# z+L@wd4GNrr$^l2P49_$a5VW*}JZ$p$*+|RT&KU6L0NkKw>YC7qVz0kl>CqymQnswz}Cbm)>%Tnjxezy>&eqcaACJzW~ld&C@n0-OrK z!GQnKh|+Oc3;@5sNkk(yA9Ogsh-yEWyHv#P*Sli?)zkG_j4subs!S9mlqn*cfa&RKaFNkg?WPC}r>2{nCFGl+un{%!2-?XgU6x># zpvNc_t43zIzq&34Fg@K+$`em5UTPv>N8$`<^$0%@0k472o#2u|TLcsVO68jZA-IY_ ze454|bj5(Dhh5E9SL^GSnp>yGhxU_l0J&ZO!G@Xb;k*bNHH8qX@+0#n0QeyKk+-^H zfV|Uv)1kL@Xo|@c6?R0N1->fVKm~S~k~Rwqliu;%CBk{qBGYVS%_hT42K02fsD4 z2hdX!N(+#J7^lxbXAGEjx{E|;!f?o;pIM4)ZAI)~)|3*;5hb^U~^TiD@uVS2K^BdJTQ}g*v ztp^es*A1E4=>x~PFFloTT}Bw z%_mE`og17FRDZ8}H<15F97ih;m#!#(q%2y-mHtKPU)1g>Jxk`h`;IL8YVhi=p|g8N zw%i=Nk!qxAWE1fog{%=k2}c4QZLKYVw$}Awes;hWSQBUuw6=s?9pP>_KzQJa19mdd zBjLRQdx7U3@tGj>Stxr!cc5!_2QrUZ!huNlY{VPj+Xt$Q2-5&cb=SJirq;G_12C&v zdOFs$Au{M{_w@MYwuCyufjN=xImm(n0w+i(e=EG9YYu?MWaNkdIl+rRvhQ1gVA~wy zNqiyalfLk+mi9n!4j=GDzZ!dz(68_7+4LJ2Kv^%_z1fg{+NqRy7eb^iNp=CwtPcJ( z(cReAy}l)+{KKbL-p~uj8xrV&5GE;9NNoUW84zeBi52Ku?1CFL9B6Or46adjAlG1k zwLoA434zL3jz8S7Jf;Ac>~GCpU-5k8I*IA?flvzWFjOIQ91Z|3l3;av5xc=}klzce zR6yjCq&2jgZxrF9M}+`<*J$32sG^kG%EI3z>O>XzE@eJxlvZG|aL-6E)uCA-FoIJH z0Ar}mNPGZBAlx)U$OB0N$FG0}5>PjRP6tgIM1%+rg(i_!NdB87zLWW+QCh)$5fB5& z>I4QU=ZAp^sqTe!!9zG8-Ic%%`x~K4ApIijC%B=F2>!rXkE|db9Y8#e@2`)ky&kfi zrbTZpfx$QSPn-7E?)X+rfnho@HwOn*Yc(~Ez)(U6nuvh=N0AZm5V%CYdt)%P$=%(H zWJp(6OV`}i&>XKhVJxC320+>9hb{w84XDPb(m_LXQCSTf(hM(ZVHe+2wDO)5&kD0 z-c4XnlRjw3WC1V1XMm?Zndd5#1s0B0nNJ#}71FgNnA~2RECTTd@zaFNTjWY0n~h)% zlJrqv&Jw(2gfV1bE=sU-khAAUK^JUH$M=@So~eL}7|6Q+iEU>Sr_T&2*Z`*QKkxXn zWwEEn98jr6H$5Qd`0mo!Dl%Ypl8TBuU~Pte$9I;+R#qU@D0{s2&i2m1flG;V1YXPR z3}wgvUK(4WKS8ykUM<=-JD%wHlSgCAD-Z_Hp5Viam)AeOYQa;f#vq1F*73iV#-7rj z9NFBR7ZHvFj)B?92@cXe?g`!90KS8Di^B1Tn_^EW_I!Qz0X%TQ!qm8wx=LlA+QBoB^Mx&0g+?7lQD}R4|Y*~&64^c=N z<{#`e`QYEXZQ)rG|DRU1z*ZZrwbksdxyyOd`Pu3-)ekx@IK1|2cHh(+Q|AExe}PWy zzWA#m1&S0XQlLnIA_a;R_<5$l#zQL=wJAIDO@U>bNFE_5;l*aZ#b&?7X1^cqX201s z;l3A>huGdHbbOO@>;V3|pql1i})THx>|1uHMhc_HT z!me(a!6T19V;G87(UpvJtPw*zl2SN0dfBHw^sPfkKGX$_s-M3M`4U5KA4=>xlQ=QpU1H{7 zV*);R6B=YSq1YY?N2t2z5PC;FKGIW2{xW*3Fv&1;zHtaih`J5qNw?ke?O zrXHNSacUzv0LWACn_6A<b&Ai57;E8!|% zsoY<=sWMc#tkPHc*~;pQpH%#?;&&?Et2j~e^@`^!!WBy@_=>wK%BKA7l)3@mk@=(#7) zy`DUEBysxi;Ek6ZGw6448j~k>CANN$c`}c*9^R4Mc@X3p zyn5aKhxe6F_iOXfmU-|Lxo%soBraSX+O@-eMDH^@4<(Pj11D)B{u=(a|Iw#_Ii5Mr z&Vwl9uy59RD{<>!;@#Km`*OUsZI6AA&bkseUPekrBKn&Bpx(RMmfC+yXVr=K-xzx7 z-NcQ77Y_B(px>^z#dg@yzB z?R|RhZhwbhitK#Ren@Ybo8QF6NnE=*a<0#QPG^}UjJ|I_8R2FeCw^%?dG(-*ntXe-w4q zL%ZLx|BxP7ZB{T!l*`%g04*7})lrlE4w@y9dwfOjop*;`JLRaRxsv)E^}vv?y~lj* z%%Q}!>!Xvn#!UJ6k;E%;`w)Qe@6lGQeopq;e^ckTvi&!*e=CaiU(Nol$78>l{aZn@ z|GLg^z4i}ue(SN{(D|)kA7Iw7e^2t*d-m_JzuSrx+eheK!`_e`0<~?-N4K0C{`O{j zlKE)#*2s&u2p#{E{%G>X*~A-B`}djODH~}2JDT1q1okMs-(fy|<^7@KN9=z^KP-9q zt&tsv66a6a|B?CVrJcjuZrQ)f41Df7c0PIXwZVbyj$dFteeU(aTQA%Hg84Kp`L46? zD7u*fUGA8|Oy-p+ZqM+oUG^U{!=HMK@WH=i200ZSId(9)_YisK5;I6jl>LYqIUnT#GxZa(a|Gy5I&VmZp0arVD4yziiWkeQ6i195PE%6wG$wf%3{ z-zkFjPnm~pek-x<=Fq#>6FZMMKEZridB^?(`qPOI&L+1WK%1ZBwZo1o`qQHl^LzBv zz#2#1zL7Y6+5Qveqvv-d&L6Y?IWzFtSBJK~H_8p|%sa0U)-yUmNA^3awrxMpyrYP@ zWZ&CEhYvX_nP)5S*#DmSG%e45jrp|lj{R>lK217DsR#KEX1Ne)s?hp}&z4V@HRh%- zt!^>jJa8J|^Mp^7Fpom7q*vmjOP|WVb2M@D6>^7nzUcTkGvxz^plaFwH}mP;Na52e0l+ z?maz9sEX|FJ0oY0Ca-QwH`S@h?(s8x?)AjA577H6@#=-r`?5O)4Iex`6g@k9?5x@W z4EYA7Zk%{OkYxX+&JDBi zf6^kRqqBE*B+wq|>1ghWxRCVU-0JFH@9t^~Y$TcbNW||_GK{M~ZnKrBz*E_oQBa?e zn8H3|U7*+1+}hpJ)7TRUuM2i|bOR;S73^$x*SEATZwYraqr9UFk7`HJKzN;d#VXFP zJSmmgx3RljaBb`fbhJcTJDOd~@dCR^+4~89@i=SAr%KhaPO8QkK+)e&v*JOQ+*3^X<8q$Z8jUqXiBBI zZH>nC`m1fLV%-(MYR?{XDWI|*!!C_V9i`iq>4ANYpFS0fQ~;ted*F`N;F{IzT*T*a z;YMQH9@B%$j{jN_TUUW@57~pNL%~ltboMoCg!M{}|9mXAwgN0Adsq_bS^D^@#S0Y9 zMKbPN{)Ye zBGyp>w7cwOll0daYBnvziP;VEh>jmW8Ee;{W7N!|R%X z58ImxVj5CMbPPWd3s;~xKYN1p%jVaco}1S(v?LbNUuojiYiYS-hR+BdM{-##m_xw4 zb0Kklhs6N}M`Bs5QGY-+2U=}mW_rE6V=y`|79i)UZ$S=4#Nr&&soh4~<`uOgDDbFJ z^`Ji0>*6`7j(~5v$r{`e=MqHT!iCc|}D89xkfQp&If&MUFfEPjq?gYsw<@ zYD>?Na%rU(o>{u^{*=0sTj$B8TnOr<0p(nYz>R>$0{jJM5__@d?12jf(L*2toViY6K;6;P5s0L(}Cr6bY;l6wM*%Iq57jH5%C+K$eZMJM3W2 zzl+w!(543Nk!*=w^w_LemGao&>a<~hqxTnlf1Q7~^<(jA36RMc~ITwSP13fG0vcIr8IZwo;3fKK3*x_iNJ1P+iAoZNsmi5!7u zMAxj&ZXj)RHU?T7J2#{+8^L|oZW+3!F&DZu*o8`D&n(zw1eF8%X=uLTo7J?gvwe=2 zo7L4x-o_6t?U9C1cs>3DY6U;5Yh7#Sx>npI?fvy@!*e_{NHgng?-( z+XUkgfJB+bZP8;qA7Mf{|27(q*H%uy+qva|(!}ZW;3^N+*8?q4OMEjv4`2>Ro}`Zi zx=8@PhqMW8;DKR=PG;a8#wP;cXAGs;6XD~5euSngW1a}kl9eg+WNMwjdL;4*atW**!YM2ouy;V|OKuvYO^26eiVVNOn39j_e_&o@aFDJ@ zNF?y~sP~tB&JA0p#+_t`w?(vtlO0Z_Hc~6sKgfcl?68RqL_0?6s_0UI8x@>hMRHJDj57Uzwy%3O$pQt_m&heLJ^01#T;jp&ZBUPD$0B5L4W1E-a$ z#W=ekk5>~#GMJ_D(@o?F!y+TE?&^-X5P?9>FHsE?JRb5i6{1IVa&k-J4l?3bvPK*& z8c!7!lM%E1)(cmxdibe%OXsPh&3-m+C-(94S)&bUE#XJGsSfVYil-MXbT6Qg1R8o} z4tU?3>O8N0a8-ONnd;iC!Abq|**$P^q_vvf-dz|xQyw$78+HU8n)yICbwffc5pNyB1 z5hGa(R+W3B5jVATb~I;<`Kguh5)xU^xiE?^4GEAV$F`;Y4mr448Q6iu zLvzsr#?wjszr3Wz=3F}U(emB+;ph6beWRiP?^{_yDZqTXn+Jl|lFx;|>j3^KxO+lf z=q%)S`FI!S;$a`*W~u;ekgxbXlrI2Y;5!o9w2?FeSER$d?*RaQZYs8mA$cHZh;W|5 zhblrPg;vM8yCVeGP!)#IQ8mN~O+A7e1AtE+m)GO+33bH3;l}AwM5po>3B<$tCqFBf zMEjnxDk!kVAMnIcMaB7`=!@^@HB&QcX(Zed^0mWhs=TxXcCQB}81GuwxYpIx)`NVF z*5)2sndMWSM(VJn%xPms5uAS%S!;LAflYR|Gxi*F_dJ>a@sD-)&@~|E-9raW>vvB; zuPgTMP53%z45{tQY?9>UBF2Hj^~n#4mxTP_ZbyJD+(3TB6((?{+TNJp1X?o`St8NC>w=x`*U(d4xK+aCwGf!648;@y0vP9(JDeKJn(Z9$Yl-jFQMc zrJXz)!RcX5o+vZJQa4B6;^rlm%?fB72jp~7Y?#f9Kz~MiH{kf0Fv!UY)63H1vz$0K zpGDBFkbD-M62`~9c+ZC3aq%w|k`8i}+64>z3;603MQe826xYguAj7}XmBC~2FM`)g z>kcNaw=fDVr5#XH_tUF$KaF(??NM`QE)ZwVUodmtf|(1vGv_}ta~@BA;}d7jt5<$g zKhrNOzjEmYlxtR;3nSTGw`CjstfBwvQ4{LAX>v#)e;w_nc(kCfj_bET% z5%Xrwo3Aa`GGOCs$H)UN8^Ey2UyEgntZWSQeU4YSef&=0pZa^*~1EoeT}LD0Ec zD0d&*Sy^xuM$Eoi?76qD7fC?i&(by~JSf`LWDTkbFV`5JHC`AO3rJ-kQHR9>3xM)Z z?YwgvS4~uy-SrF$NTq>|t-=VFS%B7cOgr$VSb%3-EI@md`Itx6<$`GhAa!CN_<*$T z0pNpR=5hf?pCYmD<>GGZ<&q!<#&=}-aUEF|be6qn7LF|9auhwQiTz(%HqTb||KqRX zt4M(&1*}nEk9Z%6q#vGFGMeX-IJk@8C+s_$4q(99J(lCh>tU2XM2U8 zceSZg0p{jrb$6}_cg#UD2)gW$HaC&=9gQ0AH`0#0j5!GIVMbV>frNF(5SOJ@p<^Su zHv0Sxvd=I12;7Vr#*c<66r;*y{1^qjvBWVQL%Bo18r3MNKMn;5vFWG#S|v z$Z7%wp35EDG<*g1a>1pLAE6=oJv2Ae z;jbA&1LRw`F5+rwGarKTGHrEr9swz=CfbsJf$Bb*9lEi#qa}=W>Ll-?2^zga>s!}# z_XOG=?nI-njycNrTtw$+Kw!$Xsar|U)p@Q}(SgP!Op2@NwA;)asyxgEZG;Oq7t0B2 z=o4vlAjhE^$;L6WjKpapAvc*jXf&7n?x2wvY+RjBF^E(f>i%tVR`%PfZH+ctV^vS> zd$nz~pRW1in!Xyr`B%=Pr~&w|ss}3n5+9ksYror5IsF0WiP>7J@yPWR9d@bt-f&xaI{X< zIp(<^k!!9JL1;)TRyuRFDv?1)`UV!%m@_nT0sc#^F28fJE|E##n3|3ru`LfOd-9%_ zKAAgcB#{YxGexoq?x2xGZfVP}NM;my+a3tpzkI;ioRXJEFC|{uPf!+_re9Ttr_!>0-ocn>Xas_+gWvYPSk}Fk7oWwm?CZ zmLgE%%j$H-L&x{T)jqbR;@IPPROhKJw#=_Hp5;A27g}|GhZgx*$|<5nou4Vnp;>}D z(!pgiJ2Pb@>?W#p)E1KF#^Xo#^uQuXXJ+ZL1F);H1BHUur_OBuB2i}~rV`v>Byn^% z_mTL2iTyup_)~lpDNv+9kpe{u6e&=oK#>AP3KS{uvrK{Ar4Ev<9dBl`wK-EtJ$!&&Jw<*|7ioRCT;813l z-g$?!ywT>geb!cSz9Lj{7cu~vYClo)TQ%RPdC>V+Rog56&Gy-ybCwWi{lUjIXFWXi z!$%G<&iV;oGl1<;v(iqG8GeR>p)9XHJ)LpgPIfw}Fg`_b>nBbP5AFdT#YWjh1^;uYloZ27##KY;K= zzRIJc;OQf&D@H7Gd~g#cKkD`dCG#{F z+iSbOyqN693zgb#AZ$hgRr%Zv5iq0lZPqT086^Wz>AWi$x#pu^{ssKgvC6+FR-Gd) z!N=MSg3s&W1yY3ztX9A-q8m68LyZ&kd;pxFshD9oAT5FSddIdL(4V`ImV*pnCOu`6 zB9Z9?J;2s^2R3iWc6!kwCRU7obHlqXS;|QmjTOJVY#|d5AKFg}T`foIfu5*Fv0qyB z2s5+frFWATU$!zcX*3>wYS{v2X31~&jc;b7k@}O%9%jcw1Ml}wjbo*1(z@-$vU+yB zSI&%YJQd~2c6`x%mU1UwOPs%Dg>v#}D&C7~{r_p()N5s@f0muS#kCbF@KL3}-jB^9 z+VPREr%F{XUPSW;Mmrum-v>1j3eVM47&AIA%I~vuUP|@RS2KAoOU?9oCDH3cs6qm^ zl3xUzzX>%{7FlmnhMGwVIVJDdg`7NJSO+!gne(M)iq-}iM;!l-G3v$2>_H!K0V?A)ZjG1P*5{&iS$=gArxrnevsq>lF)08(SsVLE| z7loA?Y4?#(ZzLO7mExjS{HhGx;J5ZZJd+58qiOsC^gg@%nkAvY;?9^63SPbFu>r!T zH!~+2@lyzyvT8*R_ouyt*rS=~#MW32W%;X={t1j}*FJqK6K2tw^Ld;sQ84vCiGg zm!pLs-~bVIS9{6oh-EPh6grO=_&oe*tFdQSENG}-y4=nA{650kMqjA%r(Q@bqh>o7 zy(x9Z&fE#(Q^BMMy8{<#TZRqLhp3~$J0|cIt2fVybL}#N^o|)MZBu}u(>yg9g z|ADIysNYn72s4%ibdxN1li4Tpp#UcXQka+EVB*lUHPt79QciQ28X3@IX!?p#L>|y7 zfFASsz&Qj{DV4G)(hM}q*udTLph@M}O)RCt21fN96I(i$D#FF1owmeBFkK}p*G2F( zqA3?b+yI`TE|3nL~AwGaF1t@+%ol4f-5BW{bTB>mT-kWx{H}Xj)Inis?#}M ze`T3Si0HfR6=k#%Qm~BCB$5*l1~(A`_d&Oy_>SI2d3;9Ei(DPMX3zRj8lJQugo}vbaFDFXN}1@##me8`0>R1CoS$8 z=g&wt5plZ^9rU4J5gM%%`_Ih6L?$~TbJIvpGtZ5^u-rM#GZIu>cHEoxVT^#zNSxo5 zxOLOwmhl;VV+BClddO{)8a%RyGX{V>b9=^kmvs&!Iwcw$Mj?m0Wk!NZurj}AABEhf z8Gu?$<&K$NT4qld^s7T~-Rniqz1cuD#0H}F*k@+jyl|$amFdi@M);#_;3do5)rG7r z1tV#GZ5evi&n{pisdh66DrY1Kv5n?ZNMh&DnZaircOz#;OJhE(Lr9fZn*ZAR zoF(71O||)KHRV(8ui9zMxt?sh*2?qm*RDrt9>*P--$m%ePmYE~xb4T(pc3B5Aa)M#3Rm)x7j4(9x)ZS&)wA`{>JWo_cgw_h20`%q%n8Qp_o zxucB0v)a3vDs3HsmBX43um%Qtm-?{61|I3>66f`sYifYpMVi1Fx+G|a~e>!6>MqFGj;9M-6V%|?H5ze1%mE(7kQ@pcYJH;xZY_3zBdX$;# z$I;KyyMFl-KYlt!t#b=98LQ#Z5jc9pyfW6zxfmXu0?sA1pC%X}vz^X=aF*EG$yIC_3Oh~BSV5LPHaXnZU~XbkixkG?c`Gd|pRX<`=$tve}( zsHfamSQk5(^Y3Ar&QK4b-3IUCoZ&f_uU)+1bKh!o!Y|L_cO&nYAPnQ zHXdDECP}EEeGK)ei5(4g+Rh)7`2QUxPuXg}QS)y#-Oe95+p34FLyjLhzH0xDeZ|zO zDNmM{S3OaAH$GB)nWDfpS6m>6Za1$Ty2Sq1M~=L~q!f(d%P`UiBtOGX3aSwp&P6U< z0#T-{GgAL2lP-pHDIi@m0aWLGt`2eAP-ANsa=;@1d}{%eOnYZzYn#$Fm+m&72}?%n z!!?Kd7RTKrBXn!3A6NaN`jN9olUKJ5^V&f5lL855! z!8(aN5oy~>3eCC=tzE82&@X{WrqedtkN}1?%wF{HB0&-xNQFbLBucD=CrOk-U7g1~ zL0Rx-FG3C~?r@EB%foROA?Eg!V-yofoPRGda1N9lIrd6kh{_qqME7wnDBz|!;IG~jwkzc!0Wl0|8*ItC4X;uInYXA#EH-Wdwd;b%p<8yAP>cxr0;7R6^PJg`BVH@UXE z-x$1kB9A8Ip7=)-8@vFIWTa6HB&JMCAlWaxNKF;y@OgGGl81LB_8uO(bSn{$7HAHPQdm=oIed}dx7S_ zAY<25U=H`Qb4YI9oIG+Smji!%YC*=CWXcO`reF>VkP~$tP{@1ijiED#lDjt-hz>HX zcGZ+)4hn8adJZG6?ngn)@O$qT?o0wIDQzm(lwl6P#O_7nwRe-7&*bv;=4CG!@YkAB z%;7$E4nuFhJ$Q9~_ZKyY+Hi8L--lEwefoKvRi;(Xav5c=T9!r0)) zMopYOmYX<#6tclJQq!&^%Q<19G0u$nOg>rz)0thyK;r-)^6+$|-1rf>(-#@IF`a=j zoli!NFd2n7l#IKrPC0<7G4@ejElbNM48q$m>(Kh3Udye=ja+tSUwK`BIGu~IQXnmy_;+&l;erZIu>BXSD|Morfl$f|G< zeN0x!Z50l1JJK@rw$24LBeZdv-?>y7uzj2nQ>;M8+edpJ$J1aBEz}rgRwETX?s)pY<{FnW=}dAN zgr8}jzcxW?piK48_-4Z>{E%=Nlw8uQ%P+^XuE4|dU?3YZiEYd-CXd)gb15XTtuPeE z`mp`ko-eK<4CU}rjiJz}IisqAzE|JFkJ-}D3{&xV#?&uz_+8|Tn!XPuLXRG+uzV#X zlp7md3Db;>F&uPeXL2A!9BBS!JkU7e1ZX!zu}GaqWby$crVEEGO~(8(x(s#7XfC9Q z61BR5&c&D~O&(p0=2A$yt5q)+P2VB~ z@=1Zczl@Yhv?yAVQVl5lGIQw)yuhR@n9>Qx5xntwGb|cPLC>K?WCU+K+=mfWO;7Y$ zRw4lQlP4vDG+d%Ym(J`=DiIRLAS&n#G!6+*>kI{zs)iCC1~^5g{LaPl_9J{~wEg4o z<9YLLt3gMbv>i0mMGClsdDBHi2F_8tLyGT2bnzaaOZ3(8fWGADN+PE41#o>d$+aOU z=4r*S1WtO|uVLG^KZrV-na-2bY3ZTCv6_?~YUgTgUS^~Rteh;5wUIwe@a2{smTPQy z52GTEr$~U*_TZFcm8GL*N~skKhB{m=fwAhvm|aF`747BGsHwNhChBH6fdK&28!do} ztWXo6qBt3*dM*b(sqCN*jLtyTWdL&o^UHUwT6rvv(rulK#vjrag2RNT7ySiGs=Bl>KtUyn9%N)VO1HNch zYuB7vC`)f?*$^rb`pP#F>TY>1McsYh9@+N3N@~r-HJ~nX#L)*vLia<`0|stL2AO-V z0d;l0Jr;HIO@=jVBH@zR!DwaW^n0Aq`%06CkBnTr@!--`ObKMTtJ%e)#ToB)ZP>WU z9qR1a*yBcPM$RvY+6Hafv{Cl?)9>@j27uC|pDUU3P_&`~#9pq^dT8(2L~QTy=IF?c zmq%%>`yh0jNA%BE^2K0u3fZkF91`kX03gKB^(%?p*`ml=ME0--;+48hdhSpj2+?LUIkuG;j zTg2@{!WHT;2wXzI?Qw^~O@W@aZg)@!%V;ksH=!+tw=o>@i~ewvz%}|B0q5Qn7RmRN z5{43gv^=VyqD50jb7=eS#OX8mdvIW{xml22H+s`RTTM?WAd7q`EP2CH*w1r;#!vvB zrjSn#z&${|sLsQOd6X*DNX;X0VBhe~w}DPJTCQwNja>8a1cRY)Ferzlu*b^>QG~(; zLf&v7D29AOlgCHRL&iKx*m;Z`zmz<2CGq-B{FxX%LOwj!;|)rU91a>E@C)c7BL}=8 zzb_P!#2_^f3G=YA^GIxtjhxsuwCftSW@7X3$xS}FF(69*AZky-9v>$*`M5CY^AHk3 zVLvqwamn))z_@8n9noXA2)4rJ7lD{D)PJ4K!?14_FOimoqEzCottlxbY%p~-f6jzV zi4gtVH_5K{&D01wc;hI*)DsW~n>FxLBQc9J14~sDaeCl%gs+oHH8&CjI^Wh41SR}} zZ&XabH@)-8!xymUm}{;*U)SB`79f>y_ z5(C?rQa&?2cF)*Z;rapBtX5C5PxcC4pM+#oFZ$7-7maM90gVs-b;@~|RV;^IPafac z#d5iOJ!ul2a*cm<7c*nz`k|3q=~_+G4Rta*;6dB)a9*zeQy%-H~MsQ>72-xl@knqOLGI{+Zdi854g4tMv;^3}SLsHXg%k1&Q<9;Ck$dmdRWh=`V>M zUt_Lpj1EtOS9c{Z9m~0EVi=(#j~DoW{3wvvvnv)f)GuA`=3pfeNABn=1q-J9w}+<# zTyq!CTds4Htp~X!-mu}0$$ST-V9;DkXLcC_jVEa`|C#Dcbhx1L0i%=(Bu{^cLRgaD z@L*U!Z892E((xFbLy{Q~HIDF1-VPegC2u>3)7b|VvQZQ%xVATv zuK*IyHjw&Vz(@TRl)_^EzfVupjlV;$-u1N{)-LA%dwP6&l*|abk10O3erg3Vdv;FM z%$~%+`-%52GiHx!oWs__AJGq7W>g@o`SQX=Pj8wB3=;Ukbd!n%j{Syb)A}__&_`4M z8y{tTV6(j* z8Q{_Io|w_wC8kA(?Y-!n<%;Jf)jysz#XbEZb2uX1>%xI{*V>lGQNWr&s5jz{gt89> zwZ%kFCb-n(EQ}&-ldgFiTRU39kn_P7Rg?8|e!uz??_sk>&GbRDU2-~pXe+hdZL{57 zzOC#(raoh{RsAat`@Va2wgMA;rt?s$X9R69<#P7)glK0Ehcq-e__X_H$~7R3Nt7J> z`;oB9G%`?oJPsvK7*ol!01w<8>5YsDjBcIBFjwQYs{674D?FV{TF|)|E3T7A7o)ip zk}eifeFX;k+_q!?GYV$-$tfubOLZ1E$7^`vN`e@(Kc_c#5R-{lSpi%xuCwMV8qUwb4Fwir?LY^ z&Y3_di zLFJASE6f{RY&)El?Y6S=kK4*W?pRmV=D0Ox0s#AFWqaA5fwdGt;)t6@BwiX5M;e|u zCOle5Pn_}fDjXP^_3JfxbTPhOg`-RUGz~*bD2!}ufrsx9p>R&(+`;w;lCSkVhnXO8 z+gE;>`2O}juPF_Q^U=iV1B_GCjKPfPVV1#cWSM)p49lFdu*c&sGsG^)JgLUFMl6^f zYIQCUN=)WLA-Re1t(iQ!7|o@Sbg|&);t*3vn}@c4f&Ba_QO18x!56oeeTB5x+mmVw zm)O2-ICd;?;Iwtl;#}0v0)fuw$okavtBTu63=Q>sq@vc6D~4vd7EKTE8|t$CD?E z+;XkH(Y*wZU~)VQc`uFT0<(j54HlGN8Qsgtq>Is93Q3o|srr&gV?O8{cT3!e_F|Nj zD)@h8vTf?~_^bFTQlLlyGZfgnKR()H5q^GO}a5OvKuhJ*|@+Vn{9S--*iksjrhI2pN8yhrl#sF6X!JW|YE?VXK**2c~aO7*FdRZBNz_VG+gd8X7S zr2wKNjadqSn%_c7eXnsMc1B`-uGC=>dJ(1J=rL(FGChtAeGj8s>pa4$6@#4W4~-Qg z3+!RZtF~l4K!diXw8ErEZ0m!X zOIQYI*N4X{FCdt`WlynW+;V9gxsZrZZBL1&#(07Ju#^Rb4TfS!4x*9!#g2AFREc>;RA39}7gr?fto zX||CJC$wc4(`?HJn(#+pF*9fj-ZUod&yjuY1&W7}b!OR)lmRAZFsRA=0SVnCC|g~- zpwvY(IS@PX`rviy`boRt;%^yIT)uee%OxWC$Mi-;G z6p}7^v;QT=M`6nTZ{C#8_&>ao)YY)D_~>In;;6XdfqrCoT=qXx5+yehOUOZ9t)!cfM#?H$Y%in?GSvP*#EV*`)#$YH5Z(}Q+>kG zWlxrUdCDDA|Gm^(wWRWLk;@Jcwt$WAjO zr_oZBl3umn>ibOmi{vnDO$COM7yE`Tzd|~0?s{`HJ&!sJ@SX`uD~mcbaVFJ@z-s58 zbGLSpb{J?~+!AmFTUt8;s3vc13#V(z(Rf*TQ6d=)ZD@z1zL?|FeKY*xXdgJWM+Wfk z@Pj+m{SA~;e#HVPQ9ZMJ1CgG{#%`(~xz2a98>M<`!&|&@KOxfgIogdGdi(9ctDA=} zzcO_FfDVy@T%b-6>Hyfs`$i{?{Zd{~{zUi6_CRa>qIt{E=fgXH!SWTWmM>k1KMelc zJaigg+|krIXL)yceb-E3{?kt_+0fmywA0rSSlrXQda-}ms>Q44Ki0l>CAa9QNMzOg z?)e)xaVs8eeWY7jytaP+#@^-yk1XBTxm?DV1J86XU-;!kd~4UEO>J$Dht@w9T>0co z&%^kmLwL(K0!_=QW0hAqZv_yAXAbvQqff@`$iDUUYWoJoJ$d+A&V55uLG^G4xTZR^ zA@Gm$WFy8vkwb^T78d1UZb|KPeV+K2lpFiY+M6DPAmHIG?&_MM(>QzC1i_!T_fAb*`vv;+lKnDByL{JCYxmyTi_%n?bl4t zp4#=8)?ceEw`%VfK@py{}((v582F*tB`_`Pj7;@PJthnA61 zjPDgtfsgKIvee)OZj68i0;Zs11h@>+7IKC!fP`QDe%>hmJy$7yZDX_|?o)0|Ahp(W z+Y-Bv55M>B(7`R)Yt4xFL3;_0m#d5Px@w>8`&?WmGufJ=`ry^w$t&*z1aRcYb)A`5 zPz!|dss&3{w>-0a^^>iT`QgBmPc`|UZCxubX?|+M6Av$vJi)~wsri|WosX`0M(lj1 zWo_%CC+7L)&ws4->8I9lPd?q~e{5Cbyqs!*1*yd`{hn)A_I)8PDYW{$wreV_Mz-8c zTVumaS3bkfTfO1gFE8y{5?ahZ@#vFJv~_Wd#iv$uuUyyo zWcP}m-sLleM;7s`9%~Fe{bl?ZUc8}e!}_K?QHy4VwJV~HaZ$O?ceB(=oIX7K&bbLu zOW?;#t)p}~#+cgdV6{&`XnV-S)4Igq&G>NNrNJAAMvh#{ zp15UQg7+}M9H!iLwac8&RkkwQKHHR-ZC_0{{^NGOc9+EKE2rP>j0aPjyZepgjkDR* zu`0tQV(L=zrI0e*NT0x5XidMM%ChlX*aXJgOBW_N=C;yB=Hy8`FGdEM$bV?&0W+x{6%hL2o7G`v5a%N1&sEn}*M z6Ia%w{fIWul3Y*j(1UKNia$)Kvn{Mq2Q6TRU)=@`Cvjq6;>I2>K3%JlUja%l1hKlX z7GTT?3@xE0s1bE6dx7(`z}kHz{$Eu(!-m-ZLw0x7+m$n>jFf%1bcVxq8yx{#9r1td0OBWG5(ms$x{Bdp-ZFh7wfBWYoZ$%0G;V6p{UpoPh;%gf3a0>D)>V*iU4Uzpp9R()?t4DINZE_!8cRzY-8FdgT@nG>{Nluquq-e& z&bRdl7jiCEqF8L|-wQ>}tSckA)H-X*lV+BE-u0ylCuQjvXe7gnoL3V02Hq$8IdnmT zL1Cg|1Idq+f>hfN?)XRscU0_Lk_ph`RfsPj zd$H56amS+1!H*1Rw7^EvuQ@Fe8L9N`%#Ug+`3(oP%tZ3!{;A#XobtM@yzGdr>`29` znlDu~l|E>@m$LjTg(*A8p`!Bs&%K`5_u}By!$U9Z&1ON?FStKHnp$4AN)ijups8>R z)aUm+%-oE;e*yj5JRWd*9!YtA-m3yCU7yfBD zpGXaorXc=G7 z`)(v3Bq>jDl(pX`@qb6jL$;bfD0#?vwEE*^OYJ|X`f=6sRn-+gobpx56Hxq7hXOFu zR*4Wit&)@%h$sVfhtof%OajN6g`5FyX`6%Uf*mUs0^~m73Lq z+S;LkGiu?N4tKD=1?aeKv<21&^%^IvSsqlD40%V&^aIV2RfkJz9R^F3fs~Q9;%YxY zz3p>k57PCv>K^2b-&|Uvn&2p zLaL~!9oOV5ZzPVN8+ql>NHm_0<4W!keOzm=cE!Jv@yK(pCr`YSGrVA#kRtM~nMc0A zr6v9>dFBqP0$X9yr{7Fo=+{}MRl^VxggS!xWzrdQG2*90ntin9q9a5sq${BP9<|)s z_mK4TW##s#lAct73Dzln3OE-lCzq+qt9=(IcNKeblbgRic;j*+`dVV({fVDkq;Jw8 zhTFOYd7De^rM}tm6~xh;&T<^uzI$kI9&~Ss)huo+!SXhj+6zwmf7vQw|JQ!H#^?N4 z$wO1WTXngL(=m06ztW+=zK*z3=X0FbR3?%afBw|qz(Dfwj_g~S!v@K~(BTC?V01;q z#2a`~L_b;5w82c&km>E1fuSRz8Ic!$;xX}bc|I40&I}sjPp5wmw9yX%?4FMH@X;l? z&SElk0wYJEh-`66Au1@-GMWo?(MgjyMsq>MY~ki&*+!9IhtYbg-o{%W6or)q7&PxK zgeUWe8mZ8ec|?uoQph7}K`-Ta+DG90kEkvF8KRd)Q$8)#D9Ba2smTSQuFhlLPl4k4 zGz`1s7ilBb`BUJ}&QNsY4E))lGlvrAUeA`g+8hY>Yh9fgNLYwpCWB$F1xQ%syE>4t zI=5O67#AJo#|ex}n^eyK1d;C5B~t%O$;&#a+181~A*GP!Fjk19e0TgrLJNX%5{VXv z&i`w(mHq-DQvAuH{#MlAe2U84_u2S8%Ed|J=v_Mq|3@x2Xo{JdL6~FeC+3=C2_Cff z9M@?_Ck{&a(|K5G>L%dqn3+5OJ^HoyrwNs|d|bOZi4V>WUOSjL)i)B;aTbHUs4&S2 z4;HisZfxyn2}4f_wkSZ?oS*ai)t>}`froaR!n2#;8X0;y{|#%L&aQEI?|X>@dvcuw z>udCI^bSqV8tJ?_=f9Hp|EFyMTgeaX_t}zDYpY(Va#wDx_>bD&+Fz=9t!9?N8?a%9Tv^26osvj0}*oZ5#k8oi<=@lAw?(WkY8LK@-hJuK9v{+%InnEreF#LF z@&K^Wuixu?Al^XMy)^~NJR1GV0bp%C_f>)+MJoY1H_-Z^GD@5c2F=egVX@zTJ?f2b zAmr*x9TU~-F?{}lF4%!}oymj!q*rD|XHveaqccr=y*b{iT(SGoS4_bae&HAZMzi%{ zD{LQe$aFY$+RLH%dXnuG&3Mw{`sEXP49}oHPdf#$)E;F;U)NTYxUn;F@_6#-YeQ#r z>P@f_-gMIkMY<5E*WA(tV5!VDm_az7w!b;v&C(f70TS=*O`Lvn@T$(Ntk9V;v!?B9 zjz`!hsQ@TL2e;#q6C$<16dX?5yD7d-dD7w(rQ@;03s-Vg_GmJ0{848=9207n_i1}J z#nGanDKCH-$HQbI zeW_cOIB{W&mJ^v?KqFTIu*c{Jj^7Jd`@ODsNFiA&MS#Rp_w66LwSVN*m$Em^I_vkN z%M*PwYrnHP9wZT+bXG#n;$q7_GMQ)POzj_c#T(i6sh}yj1c3GRA%&e?-|t87iEmVP zzg9bj$)o#|N0BjhW@wlB7(#aW2J)7WUMEVTw*hWoKftfiY{Ens0UkN}cwX&u#lKcL z{Q*5CA}1`V<*kr_azpQXp7aRALGz?X&~Am=-;CZJ@2Z^6Q&`_ncn1gGR)a%uQzc(G zmVH???xwn_OqfXHLHwS!`D^jc%ISAeBD{XVidEk1=~$3n9%PJB3~ghyI^Ll?BPG7c zGd$VP7>C?ua+XXPh0`{CE#98JWFdPx7M2Y2lwNZ0*Wzv2kKiZt2o8y56jj%6h_6w2 z(*li8BzBxm?6@%U`myBIce0<9!`ujInRPC-+X}Qcc5X;F+(LF%s`;f4=u?`gT=tFl zYUR;O*+&mwLHVKSM+@>8kER{IK9OnlH*M)R;;nj*hwQNsWfjysIb#Nh$J63++G9_| zTPmi1-WkyrpM3k3p|=mI9&hgwLV2SWek~hT2fb_D0Nqet(>UlJ&B~I}x`!%AcU>DC z&}qn&Kiz}r>@)2X#Qra_H`(x~_$pGMNP!{+iWDePph$rt1&S0XQXo$h*mKt}5pDPI zl#^2X#!TMiJo2orb*-K2TDv!Pb#}Fe=6JbT>(_?ocy!ic-E)O7l#z!fU?9>RUgv5IM@TFB&URO@!|g{G zNRNAcYbe~Q2!fK2FAVAqq&N`A8VD{zW}shK*r+>@vaqoRLcc&}pgR|abq7+sxMK~3 zBpzmmt1;jt9$&@ag527F^5!*YwIXZIV z<*^{DBKk2Y3p_eg|Hk(4RjN<0dHeCg{TB|T>mKi(ADMj1(>; ztFQ_er8s%KeY}#PuvOO9q=Vd@b+6ZTQwpHu&C>q_&gBtZP>a;Yt}1s#9SVMc1~~eH z(uNX#(a&U)(PW-|L$^-P7Io}tXxH!Rc)yRj={aoZLKMJ zrU^!K6Y@#yQ5e(O5;(!qr#%)vEvb~zSn}BGNBejSLqjdL^l2;8Mh%`ac1h(UU)A4H zv-*jsj#Gia%SDp)@w|4we}LAG{{!3FWL?Gd`>A;;V-4+j8>+gY z5{k+iW@7g(S(|e(g-edLN^gcn``IO3IR`UT*u@OZ|1(QEa}H*#v}e$N#-a|wH`04K zYLBQVXsk7QG6;6>qIUg}j2DAP3KS_&q(G4ZMGD+j3T(X-&1L}8m&zd? zyt*rS=~&vCNp!)kp0>6KEGHC=`Z(gEj6`}PuI}|}7e6|3ONK=GX5&lS`a!*H>9 zymfT~|D5Vae0IfxhWe$;-JH+wBT=8x7kZyjFAr0&Gk5X4<(fl-@p}qBQkI0Y&pOhC z$|%N&uyyO%ymPDOvGmW(@cGKOG4`c&XhM7r071MRN0Esbha z$Gx_tH{yyXY6FkCN}R}hMKlDF5#He?0gaoC zQ>tY&prWFVnb{3K+$|5!kD1-T^HL$R8)W2s(|1qXoeAA$mPg!9^m@_9R7Bs_i~%&6 zr7>l0>s$&+m;7Z60RAnV8l-bFE$~w>gQa6TujKz%eBOpX#aEF6MG6!tP^3VS0@)OZ zuTXH`UVmOo;RTEfYSbCUJ1Yjp#Ij+YG0|BwiZ4naNsug;@ur`V%L7BLw?%I9ir%1C z>h47kJHabRyayS%q}8?8hu+twv{s(Ue`pPoq*~9cr&cVVgY*WU=$Abn$v|uM7E){V zqGz3f)|!V@S|r4ct$qYxLWi2_u)AZY{W2Ytbo7{UR6rxjnVy@ea$ue3TF(V$@Jb4* z!5aAtkfcNBliuFBz%-_}<91p+GAB-&m0`F?zQQ$uww}l@q4}Eu(-_a7hMXw#mKkMp zqbn1g!(Y&oZ8Vq3yk&-SnZ#RWG?&S|Wkz#>Ta6Y}c|9+Av*qDKq&TD^i-;dvQF7KJ zfp(2M(ADZz6VgYsfkI6r``_1|pZtF`f2Ss}k=XxbQ-8%)^Sh2U_^0?PQlLnIA_a;R zC{mzEfg%Np6qpbNwoZ*NSCSZ-wQzOv-0O*bFXrrTn9<+Q$go7e)PkwJF+;z$mWkVP;Pxn}hrCG)x4z2+dl?f39oaBKH5?WjAfLU$4Eh z=67nM=mPi;&exq^tp4Nb7RP@%`W;`ee_&rR^{=OHnR<8CJ5>uRzgO8k<)QL}WjD(f zm;Pz#(bB~w-?3erkdPejm&?j4@4Uykb$Y3H$%Dgt4kX?`rGhbHpLsv>c_hILuotCD zd%aertpt+hhC15=tsQfS(QCI*{2UkYesxU2TDl;dOIXL^|iqTe4!_ zeE;g6`ljZmXGOxn&W_NE&NbnVIn>WHJ@eM~baES>?U)x{xw73W&kwF?d!|utYO3#P z_svohwGcU46WKJoqjMbwSr@{0nEw2^6EB}Rwr&=9KFrRrE|%m%O?T`s7@rFwaA8M zQbRZG&pZ1+P7a5h3YuFQ7RU0FpU(D*1D)^?TXS0$Km}*Y^K{^2CJ-0S4Yd z$+zAUb0{7Bb0#zjAEKBP-KTvo`gs4Hm3Q9l+)_y%s+1!tr9|u|=XfN#$`~i^`B1S= zJyJWA`7U@@3LYiznrYvSexd(kWJzejFuEk4&bifJ5{EvTW|jmP?6iWSEvY9mJF+@B zyRo@zw&3dQ3U@TE>vDB>b|G(ZNQ;vsn;)w0xGxt<6mE}DH3r7 zgNieJBcL@1(Y>6o*oDUo?Rs-UPl8~jZqT&f zZ|<+jdJ-O%hbQrPi1I)bC)A!{Cjhd3X#$R`g?jr@7yrv7poE6W2b-$CFr~^8eA&KeZCo z;pu~?rV6P~ni%XlhfH{icK^Mlzbf~mG(ZN5Sz5SG98167ZtkyS=?ATquP- zPvV*6_-Vh@++UINNlJw;E8i_WiMdYyt+`*tRZ2A;q1L1U8;p;7JTQc)jrz^zeid3t z?@1aI%J`n-0g@y2q~B=nSK*WNo;0z;=V8>oX}{jwUz&5DCU*9Ck&Y5i`?W{&p2_b;d(u z0n$Qo*O|nL0UcqcrP(1(PSmu!b?YLomNr+grL`k~h7LeLO}BF(AgAO-b#)MB)`S=! z_W!5Kzhosv%23%qmvxjTOMj)rZhL9GM!fO&)({A}H)e)Pu4)wju7iF0jJ+e=}qcU3FFDpkpg=IH5a431=O5*jM_(Nz)?&a8s zdVtQ+h13iA0wJ%*8NUg6Pt$|2n!OrEP0y35PF>C4|*C!PuRl;1A!(E36be}lt)YZMP(j32!qFOnw!T& z5eDxli`Mjem07ISPI_V=X-~wQbR{FHqY;uIb*Llmj@2lwjfA^GZm>?(9GkmoHO_r= zBz3&mFZNCEzq{zB8+G~>-E=>fZo1z7*~)bTaM;a@BHj=|RznkcmB{Fb z2xW2T`hmo@tE02gMV^KD^2_|Re|o6@bL9KL$5p?tesk!xQ|S)Ly5IMZf(gMp?Z@-` z@2{BdPESDM5?9Y8Peq4!Tpo^}Ol;F!Bf6u=URjpB)Bf?H{#ooS&KycyyRJ@YtW|hK zgrhj`v>z?*pII?|PI?xj%TR~e{l?(U6GPEkBQM?>YcK(Ty__)Z9~Soi5*Z5($3{s) zkD?GZarlG*c@VT0ru}_$|9u1(H+qjYRQ;lQwVNu29yz9UQw=pLJ=P;IpK|Ncel%}P zbx4!E6647EyXOASW<5zKY%#7UF?RdkKH2{nCD@?&{U7V>=?c$K9nVCa3JIZJ=tFC{ z)m)nhYlpxTX9rsvJU%bCfrMPth|Avu`)5?%c_-!1SxOrVT5>eFMP+J)082K3BV#x>Hs}}#i_O1jxit_I7>`peD+1-R!d#LLzR;>hf zXKxgv5LjGXMJVfifZQ4s0l93=K{x{mFz*6}Bb*6$1eA~v__X%?{My>uem&IotC`td zt+l81XzllZXLdI;$qYL?mG61Jr-?p5X5RU|=l?za$M3yu)X0foB&rhmwI5-DMMKKv z-I_A)isB1lN57P0BcF{j`N@<31&0H%9_1wpx^DGN*Rb5>#TUXPDViKWb_Lw-8>ble z%0hX1uNn@6nq9OTN#>#q`Ebr!MrfenYT}^cendI>@WRRS7R*~bUq(Hw@@;<>UGJb& z%^loj#b9u&6&q3_OHWrn-@g?=KxaZV|pT-%L-+!5{tTa z6RbPZl1^Hmh~Vr6^XAWcvTEA=Syj`9&d44X!DKva-ppxpX3Sjh7-^0Al++Omst*Ur$>36KH*771B{U*JP9%6aJ@~maB`8D%=^QF``so4}V zb->5kKXGoH^{Q)}u>IJvhHqI8{}0LiD@UCQR(iMqe5lVo)W;6@ghRtpTh=94ZINhB zhs|8Dcye~tX2B`V3(=eC+Bg^02F@xJ3j$_+uuVXNjECd*uA{Y*!tK(cm8#qgQT?lXxe7<}Ebk!tojP>GUl1<1Ci(;D(n;KHnz&i5ej&JFAm@RB=9(}1m^syQ^G@MvP0)p&4;NXzenVRmM$d8TrEKq zFygL?DD$75TqXUoXx?mjOxUohIn%`zCA-Ld-bXsf4}EDNcXQ?-o6*Lm57+ann^P|x zPd3$M7OKxXtr2V z=+$;!^`B2y&34)hqD`Z>l5LDXm&@o@zaJ?$oCS{e2Y-T)xK6(x%s>{_tYhzZvJE;H&mH3m})`!cwXzgXa>~z<61vA zoMgSMBD+HB)*zgdvPKzSm0cZW8W4@cI7IA#)2N(;$P)zOA+QLG*MfS(Y={lRC60O= zK-~&uiIRi}h&@BV>>0{KLgdjPAwq-5`TsieTvJ(V*`1|-E!|o=%K5Hyy)y)wfaQ*I z`y2M9_N$riF;6jHE;&;&t;AtFZoA(`6}J`NW&O~)&01OXUeSi4F#Q{P1wGXAQ_v1v zWB$H*uK6PBEH#~Snoek|2L6>dRJWE=!EfXM2?sq7>qB?Pxo0#_(taZ+NOF>9y=Z)# zTc8bW^avUDqPybUd~IMOXGj>9K3@>s8RzC{0~{Hn0)J4S@x>i`(Pe98F-KG0lw^ zWN?A{auW;@nJaU?Y-8nj*xak#TN@Hn0)NBZ`)w58W2$rfUNmkvu{) z?F*w@fDU?Y+TvzspzKoxOrswS}4nB@6@t`OZ4=N{7rHY9mO$?HWU;@lK%U}KW! z4Y4e`InGVi1~w*nU}z4Yo8sJ~+Q3F6kF3%j4;mil9?=FiB6&nH4U@X<+Q3F6k2FOvfC6#u0c~I-l1C=`AdCEQ?tV>R)|ljh zn{5#J;@o}Oz(ynw!uUKv5Aw#jd$oa$NFG^CLt(_mxqGyMjY=NtN1iwr*9JBsdBn2d z4j^}&o1_hFMDobehBa#;cGmGDgZj5u|HGw@wB#(?^XydQOxx2K1jYuAugaTo7L!7%)8`y~C zk#P*$*z4n5OdHsU?FQwgaZJSIbtFO(^?H>F-Os zO6Ql3EWN_{zVm0!E@z9g+W9r-2YCJv)BN%c=`H)I3$;@5XV*fGsgp<3ySJO(yPkH9l9e0s64te));94+Hp5*glEZ3x z(+TR@K8*nhGeB!s@g3a~9J#r0^IqywMK_5R=;>?_4(;UY>rB6M)2@li99bXV-Y9H( zsi$KtWF;g>2LXOh$3}=6HvQo;+Et$W0Ia@e;BLfqQtz?UuyefiP#YCvBKs}XplIRc z?fmlgOk{^NCN^J4yDrXUDZZy3Rg9D6&B7*d6eHt^x<&D(zAaVLkZf27a%Jj~XW!Gc zF@3rP?8nq<`3I0L)mlpo%FW9upW=hgWBlHik{e&5#$H6buE~}MnljDR^LtLrnnhK~ zE0Swtfjc8?ZsCvYG5z_=wCgI_hf*J~6s`K)Ls=C0pW=E>as0BgR7BqSJspQhPMh{Z zD7qvA@Nd4OLuiJsYo`V)iqtQy>DQOguIq9|lHQAw#8SmtuRN4hQLv7!>Fy@JshJ9T zXxF4(uvN)JEkesFVe26nO8nu?{MNQq>u&Pz)78o6m!;00q|nv0E7TEX%?>p7&!6_bQ4`A*B+AipOG9QTJg??)c?RqW?O1{{8 zR_N$}FOu8~WP-rJ^0h;#Zu{VL1Na_`Now!-8i*oAN^aFcHJX` zNv>+<8##cvlV74a40lw11k;k0Xp>@&FR7P<#MJ9iI#aJq*6#Z9zp zmh96BvGP>+5$GQHTKWg1654k1ryI*z-&l!c0J<5b4*F-r{y)UL)MWX!Wx1u?{DygH z&J$olsm=MabH20O@s4AQV}iqMZ?`{YznFQAsb$!b_eyq_++X6fecSe|jVe6$_gkGs-z<8j=mz>%bUht1KWr|gUZ$2%Uei0KgpOrClf<&i<#j$}mLdU$NPm^5 z4|BjVp&-vCe$3v`P*2c3lnoE}`h5`cK_Ui*u^zYp#t){GWibrVdEtIw{Q7QT=SqHU z4Ky`>WK-6MR0|L8A9X`)f(O-AVu;qet{+~yvn$a+&jIC5b!enaZL^Xlu z4oCXHfc^yT6hu#s$6v6zD*81)fTX#jLfz{0;o9W!E`Fts6^4v8w-?Qc;S1H8F1=-C z@+`;KA5PZ7y^E{!cLf{t0k;^cisB2@nht_S(;Yj6t=sq&d-8%2o@Qd8dLn|6>Tp|r z6wW35%4`H`o*o6O-{TQHNEPXH3-F`!HGA`xNfdSPubW+o%hcAHbk{PWBY)Mzc?gWt zv!b|Et({UwI)wH{*d_?u+Vhu5TuZ%ZW+is2m5D#o#2?pDH39?v88af-q1s66+k}_) z@r~>A7YODFAg@Q$E3sXxK=o^Mz>vWiM$=-LQ5&48{ipcWKD7L9}AAhnfx#Kv0x>MMFBp+C&SROPbf{WFP zmE@N3hnspjPUS?KTXevXibBxkLlJCN zYkxkgme5xq@alaqf`L4*|N1CwTbDY!U6)7`2@1Q>1C(0!F0@aL(N>DbCteU@qC9CI<*k$`u=y%7%B z^HdsX`zGP=ZXmzYQ6SikupV?zgnL#EiH8YGJZ|Sh0&>})JK*)8c${0Rc|Zsl@v$IY zA)XML6z7&`0~_(NAZGf24}C4pE!GA$;$snZvn+VtOpJ4jG=cp_d@P9lAI9PYXUQbf zbr!d&_}$`d#j#=&MEgH#9Rw%%XN&waPj3dVfSXG{C~Ypi$KrOr?p)&>?f9qTl;bIS zu>D>89{UvLPfR;Ahqq>|Ec^q+{Gv0W|X!uC#-TJ`DzAT8A#PAi`g(Ea&TRM5XJYQv{V-4s57Ei#V30>UM?4$svwe>U+&qzVEnci&V+$ZZ|AJKUx*&@{P2nvt0rZL7ey zs+2>a4puJ*3~koy38JkPxIzVil{-|cBZ#&WI9)W~fp4+8g0h-49!nkFl<+Gi3&Vit;F*4i)NiggA*Qw!$i_@!^x0shZ}`M3KT;YosFf) zbSvxya%D*sv=u-b#^8Vz*cfx)8=V{1kHUUMbuvJOO^QvUuula=->}Y2g^i=ISAk;4 z3bJk#W)&!MLxrw!N$eDBM_>=xu;vI@lb-XI4h_8-s6N4RZiNexxj?Oz)I@(yZfv!tD?AEZAIm)_X9eAsvDH` z`I}l?DBNge6c14Yljak??FDc*%LkTOGkj>pe0*auY^nxLfdRsud z6%{2xSFo$7ri?H9e%b!Ab!AVN#mk15U0!A`72rO>Bc&TkpDBHyw4(Hy(qiZDK!fm- zvl$`^ra7ZU70y6W-17UPD*6*!dC~Q@+stn{FSX4Aj=>iCHQtGpUq!q8eevbyX=bbF{Fbdk^IA~G z60OMAZT3qQZw_uw)phfYYg65a?1L0Q(#}M z?O?vAQkR@LgjpfFqbX}DDR7uNl~zj1l-XZ|cYN-DBs-c_l(T*<*4P)i`Qc{2%>uIpndW;WhHyGHjJXqiol(z}A$rk0(| zse{?B(%6#E64R>kt$dU*>(ss#H;~L8m0I*MDKe{7(n#CB-0_v!p;89<){tq@1j!xH znVo7NGDi=lc?j(q*QY(TbP>#MH8h!if!U>&pp}rXOB+#UpGv#IRw#9J8}nVY>L}f{ zn7wNFGTT41;VZPOqHlHj`7bb>V*H9iz@!w-zlALvuCE zO5MprB>5=a$%7>MNZrW;B>8Q+llw{XTXiS*k>nM+lY2?>TXZL9N%9f8lZ(B2v+m?# zuim6Lxm)bj;WyIdK|N!}9khjYLyLVB(w$uFqoD5OVjl%`Cl~w3uRFQeM?OhZkDlRM zYKOoq3cl*L@qM3ltg_wR?^(6&E@_pMzU7;nNvua_tL=7qQhwz&0vYT33?T39_pI7> zhXS(xa0YUm{4r3UW*$eCj~gzJay7ac2_S#&x52ECfT)$*ZbzvV$onfVp-0`v9Muc&p@DAR|K zkg#@fBD?fbw zL2%F%cJ9^>mhmP1X%s)BC>OY2r4OBk=q3G78Lgxjy%EI=6krP9FnukS(PD?tPoj9f z0!-nDr4LN9(SS$RkE3{=0t^lb(h;eUYKmGo7QG(DPbQg4|=F9R?7&j@}(fg~Nr3M^9yJa@hy!H+ADBwLk!q>N~@ z=z9@7TY)4o=@yCvB$D5a;8_Z!Q2S+YvlNfs}0C z#P8auA4zH_xWVCD5j$6P5Wy2w zJ+5K%cx(^QWsuTku0A@4r$NAj+GBWvnvamQ6!T3hVPgg1!};-u7ay#|M`HMHH9TSE zdSUZXuq;3)z@Pc>*sMd#;V2%jYH>}h01r>T9s=3LCH35u6}K)vbSQ@JQZ1a)2$Z*Q zqOS}rf(N7cPPM{;?FFI(;7|Zu8Tr6+YtDfvj%k54pA@>DhyU|~k(&DaXnz#np$>K+ zxxZ65c~XbRTyDK+i{NppqwVk(p>_x0=_nQnr|_fJi8!hj_R0TCK1Tau_;$5!?PJZ- zRZ8ILM0+doShWBPN&l_`2KvC`MSG$+qSgl__`JDWI1S_xIzm3l%m{L|JA%ik_CY6H zh_nS1Tl$IxcaZIp;{Vr}%8r*!FT1$(wbJJ@=l`*ej~s2l@@KPm*k{@=V!q2PVy-Xw zdCAI>kS%4~Y#Uqr5!?cBZ?VnV1-<}R6}?fkq9{lw=}mOR@;A#K%iWei<{y~X7(MO} zeD`nH0=FiBeBcJS1vx|VB>g4nAw60DP1PHWAp+0`7h7I%Yehoj8&HMF`jDz3_#n11 z=P@Is{lWX zC4gZ-hR5$d$k)G^JW#{0DEJT#M6dsdC4gH%hL@JPW)xIk*bI8Z=0vpTUVhLaukaega#*Os`?(1td zNgyEP{=--T2nJ+$eB)-mdl&J!kRs#@!Gmu2Yb*gQ12R0}a2M=AfHJP9Q}o%_hbN5@ zpcwc|ECCb)ay*e$N~mcPsuP8D2GJ$KKH|@@1W*jf@KT%Cry5s)vnIc;zEC{qk3Yo{ zz%n4igChvIQ}#N4>Z`BRA3y^1$5;Zm24r|(>&$sf6;eKOvVn8pA7Tk$9FXJ5{HzMZ z3j-zf2eAZD56JK&pOwP3sbtF^@T1?y62Lwn!;|~r6jDA>XW>Qf#}Yt8Aj8Z0)DV~4 zLhwlWfJNYUu>_D2$nYfR-a_R~oZ$TswDDdn0jvaayo0-eIMLYngB|v}u>`OZ$nhHY zfNs=4`K0ZCI+g%#0y*B{Wg}cDDWh&KxwmC$av12$o?mmFe~unzJ`V1iSvsO{U(|K(gNAy#y9Rs?XEA- zv;w;yKkyd(I+`#kz(BuCw7k*{h`L7#jAUTte>;kwQ-Eb6feHc3C=-0>ttbZe0$DXB z14}_A%gpgX^kx(Thk*<%S#u`+{F#Ela`Z*NiejKKkb(7dwDvL<>1(r0HACo^QM^open($sdb); - }else{ - $this->open($sdb, SQLITE3_OPEN_READONLY); - } - } -} -// 鑷傚簲鏃ユ湡鏍煎紡 YYYYMMDD 杞崲涓 YYYY-MM-DD -if (strlen($riqi) == 8) -{ - $string = $riqi; - $year = substr($string, 0, 4); - $month = substr($string, 4, 2); - $day = substr($string, 6, 2); - $riqi = $year . "-" . $month . "-" . $day; -} -$isnewDate = strtotime($riqi) >= strtotime(date("Y-m-d")) ? true : false; - -if ($iscache) -{ - if (class_exists('Memcache')) - { - $memcache = new Memcache; - if (!@$memcache->connect('localhost', 11211)) - { - $iscache = false; - } - if ($iscache) - { - $key = md5($ch . '|' . $riqi . '|' . $tvapp); - $cache_result = $memcache->get($key); - if ($cache_result) - { - echo $cache_result; - return; - } - } - } - else - { - $iscache = false; - } -} -$config = array(); -$channel = new ChannelDB(); -$group = 'xxxxx'; -// 褰撳墠IP -$ip = $_SERVER['REMOTE_ADDR']; -$time = date("Y-m-d H:i:s"); -// 褰撳墠url -$url = $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']; -// 鑾峰彇鏈鍚庢潵婧愬湴鍧 -if (empty($_SERVER['HTTP_REFERER'])) -{ - $source_link = $url; -} -else -{ - $source_link = $_SERVER['HTTP_REFERER']; -} -$source_link = urldecode($source_link); -// 灏咺P鍦板潃璁板綍鍒版棩蹇楁枃浠舵垨鏁版嵁搴撲腑 -try { - $channel->exec("INSERT or ignore INTO access_log (ip_address,access_time,url) VALUES ('N{$ip}','{$time}','{$source_link}');"); -} catch (Exception $e) { - //echo "Error: " . $e->getMessage(); - $isw = false; -} - -// 鏌ョ湅棰戦亾鍚嶆槸鍚﹀瓨鍦 -$sql = "SELECT channel_id FROM epg_channel where upper(name)='" . strtoupper($ch) . "' limit 1"; -$retval = $channel->query($sql); -$obj = array(); -while ($row = $retval->fetchArray()) -{ - array_push($obj, $row); -} -if (count($obj) <= 0) -{ - // 绌鸿妭鐩〃锛屽彲鐢ㄤ互鍥炵湅瀹氫綅 - for($i = 0; - $i <= 23; - $i++) - { - $epg_datas[] = array("start" => sprintf("%02d", $i) . ":00", - "end" => sprintf("%02d", $i) . ":59", - "title" => "鏈煡鑺傜洰", - "desc" => "" - ); - $epg_data2s[] = array("eventId" => "", - "showTime" => gmdate('H:i', (strtotime($riqi . ' ' . sprintf("%02d:59", $i)) - strtotime($riqi . ' ' . sprintf("%02d:00", $i)) + 60)), - "eventType" => "", - "st" => strtotime($riqi . ' ' . sprintf("%02d:00", $i)), - "t" => "绮惧僵鑺傜洰", - "duration" => (strtotime($riqi . ' ' . sprintf("%02d:59", $i)) - strtotime($riqi . ' ' . sprintf("%02d:00", $i)) + 60), - "et" => strtotime($riqi . ' ' . sprintf("%02d:59", $i)) - ); - } - if ($tvapp == 'sptv') - { - $age = ["$ch" => array("isLive" => "", - "liveSt" => "", - "program" => $epg_data2s, - "channelName" => "$ch", - "lvUrl" => "" - )]; - } - else - { - $age = array("channel_name" => "$ch", - "date" => "$riqi", - "epg_data" => $epg_datas - ); - } - $jsonage = $utf8 ? json_encode($age) : json_encode($age, JSON_UNESCAPED_UNICODE); - if ($iscache) - { - if ($isnewDate) - { - $memcache->set($key, $jsonage, MEMCACHE_COMPRESSED, 3600 * $cachehour); - } - else - { - $memcache->set($key, $jsonage, MEMCACHE_COMPRESSED, 3600 * 24 * 8); - } - } - echo $jsonage; - return; -} - -// 鏌ヨ棰戦亾鍚嶅搴旂殑鑺傜洰鍗曟槸鍚﹀瓨鍦 -$sql = "SELECT * FROM epg_programme WHERE channel = (SELECT channel_id FROM epg_channel where upper(name)='" . strtoupper($ch) . "' limit 1) AND sdate = '" . $riqi . "'"; -$is_found = 0; -$retval = $channel->query($sql); -while ($row = $retval->fetchArray()) -{ - $is_found = 1; - if ($tvapp == 'sptv') - { - $epg_data2s[] = array("eventId" => "", - "showTime" => gmdate('H:i', (strtotime($riqi . ' ' . $row['sstop']) - strtotime($riqi . ' ' . $row['sstart']))), - "eventType" => "", - "st" => strtotime($riqi . ' ' . $row['sstart']), - "t" => $row['title'], - "duration" => (strtotime($riqi . ' ' . $row['sstop']) - strtotime($riqi . ' ' . $row['sstart'])), - "et" => strtotime($riqi . ' ' . $row['sstop']) - ); - } - else - { - $epg_datas[] = array("start" => $row['sstart'], - "end" => $row['sstop'], - "title" => $row['title'], - "desc" => "" - ); - } -} -if ($is_found == 1) -{ - if ($tvapp == 'sptv') - { - $age = ["$ch" => array("isLive" => "", - "liveSt" => "", - "program" => $epg_data2s, - "channelName" => "$ch", - "lvUrl" => "" - )]; - } - else - { - $age = array("channel_name" => "$ch", - "date" => "$riqi", - "epg_data" => $epg_datas - ); - } - $jsonage = $utf8 ? json_encode($age) : json_encode($age, JSON_UNESCAPED_UNICODE); - if ($iscache) - { - if ($isnewDate) - { - $memcache->set($key, $jsonage, MEMCACHE_COMPRESSED, 3600 * $cachehour); - } - else - { - $memcache->set($key, $jsonage, MEMCACHE_COMPRESSED, 3600 * 24 * 8); - } - } - echo $jsonage; -} -else -{ - // 绌鸿妭鐩〃锛屽彲鐢ㄤ互鍥炵湅瀹氫綅 - for($i = 0; - $i <= 23; - $i++) - { - $epg_datas[] = array("start" => sprintf("%02d", $i) . ":00", - "end" => sprintf("%02d", $i) . ":59", - "title" => "绮惧僵鑺傜洰", - "desc" => "" - ); - $epg_data2s[] = array("eventId" => "", - "showTime" => gmdate('H:i', (strtotime($riqi . ' ' . sprintf("%02d:59", $i)) - strtotime($riqi . ' ' . sprintf("%02d:00", $i)) + 60)), - "eventType" => "", - "st" => strtotime($riqi . ' ' . sprintf("%02d:00", $i)), - "t" => "绮惧僵鑺傜洰", - "duration" => (strtotime($riqi . ' ' . sprintf("%02d:59", $i)) - strtotime($riqi . ' ' . sprintf("%02d:00", $i)) + 60), - "et" => strtotime($riqi . ' ' . sprintf("%02d:59", $i)) - ); - } - if ($tvapp == 'sptv') - { - $age = ["$ch" => array("isLive" => "", - "liveSt" => "", - "program" => $epg_data2s, - "channelName" => "$ch", - "lvUrl" => "" - )]; - } - else - { - $age = array("channel_name" => "$ch", - "date" => "$riqi", - "epg_data" => $epg_datas - ); - } - $jsonage = $utf8 ? json_encode($age) : json_encode($age, JSON_UNESCAPED_UNICODE); - if ($iscache) - { - if ($isnewDate) - { - $memcache->set($key, $jsonage, MEMCACHE_COMPRESSED, 3600 * $cachehour); - } - else - { - $memcache->set($key, $jsonage, MEMCACHE_COMPRESSED, 3600 * 24 * 8); - } - } - echo $jsonage; -} - -?> diff --git a/diyp/gz.php b/diyp/gz.php deleted file mode 100644 index 98ec8d1..0000000 --- a/diyp/gz.php +++ /dev/null @@ -1,19 +0,0 @@ - 31,//骞垮窞缁煎悎 - "xinwen" => 32,//骞垮窞鏂伴椈 - "jingsai" => 35,//骞垮窞绔炶禌 - "yingshi" => 36,//骞垮窞褰辫 - "fazhi" => 34,//骞垮窞娉曟不 - "shenghuo" => 33,//骞垮窞鍗楀浗閮藉競 - ]; -$data = json_decode(file_get_contents("https://gzbn.gztv.com:7443/plus-cloud-manage-app/liveChannel/queryLiveChannelList?type=1"))->data;//id=31-36 -$count = count($data); -for($i=0;$i<$count;$i++){ -if($data[$i]->stationNumber == $n[$id]){ -$playurl = $data[$i]->httpUrl; -break; -}} -header("Location: {$playurl}",true,302); -?> diff --git a/diyp/img.php b/diyp/img.php deleted file mode 100644 index 0ad05ba..0000000 --- a/diyp/img.php +++ /dev/null @@ -1,134 +0,0 @@ - 0) - { - $i = rand(0, (count($imgs) - 1)); - return $imgs[$i]; - } - else - { - return ''; - } -} - -$filename = date("Ymd") . '.jpg'; //鐢ㄥ勾鏈堟棩鏉ュ懡鍚嶆柊鐨勬枃浠跺悕 -// 濡傛灉鏂囦欢涓嶅瓨鍦紝鍒欒鏄庝粖澶╄繕娌℃湁杩涜缂撳瓨 -if (!file_exists($path . '/' . $filename)) -{ - // 濡傛灉鐩綍涓嶅瓨鍦 - if (!file_exists($path)) - { - mkdir($path, 0777); //鍒涘缓缂撳瓨鐩綍 - } - - $url = 'http://cn.bing.com/HPImageArchive.aspx?format=js&idx=0&n=1'; //璇诲彇蹇呭簲api锛岃幏寰楃浉搴旀暟鎹 - $data = getContent($url); - if (!is_string($data)) - { - echo "none. $url
" ; - } - else - { - echo "200 $url
" ; - } - $str = json_decode($data, true); - $imgurl = 'https://cn.bing.com' . $str['images'][0]['url']; //鑾峰彇鍥剧墖url - $filename = grabImage($imgurl, $path, $filename); //璇诲彇骞朵繚瀛樺浘鐗 -} - -if (!$isrange && file_exists($path . '/' . $filename)) -{ - $imgurl = $path . '/' . $filename; //鍥剧墖璺緞 -} -else -{ - $filename = rangeimg($path); - if ($filename == '') - { - $imgurl = 'http://img.infinitynewtab.com/InfinityWallpaper/2_14.jpg'; //榛樿鍥剧墖璺緞 - } - else - { - $imgurl = $path . '/' . $filename; - } -} -// echo $imgurl; -header("Location: {$imgurl}"); // 璺宠浆鑷崇洰鏍囧浘鍍 - - -?> \ No newline at end of file diff --git a/diyp/index.html b/diyp/index.html deleted file mode 100644 index 43c4417..0000000 --- a/diyp/index.html +++ /dev/null @@ -1 +0,0 @@ -Hello Word. \ No newline at end of file diff --git a/diyp/info.php b/diyp/info.php deleted file mode 100644 index 3ec863e..0000000 --- a/diyp/info.php +++ /dev/null @@ -1,369 +0,0 @@ -' . $d . '
'; - $l = $k; - } - return implode('', $a); -} - -function get_ea_info($name) -{ - $ea_info = eaccelerator_info(); - return $ea_info[$name]; -} -function get_gd_info($name) -{ - $gd_info = gd_info(); - return $gd_info[$name]; -} - -define('YES', 'Yes'); -define('NO', 'No'); - -?> - - - - - - - -PHPnow Works! - - - - -

- -
-
- -
姝e湪鑾峰彇 IP 鍦板潃
-
- -
-
-
# Let's PHP now !
-
-
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Server Information
SERVER_NAME
SERVER_ADDR:PORT
SERVER_SOFTWARE
PHP_SAPI
php.ini
缃戠珯涓荤洰褰
Server Date / Time ()
Other Links - ?act=phpinfo'>phpinfo() - | phpMyAdmin' : ''; -?> -
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PHP 缁勪欢鏀寔
Zend Optimizer
MySQL 鏀寔
SQLite3 鏀寔
PDO SQLite 鏀寔
GD library
eAccelerator
- -
- -
- - - - - - - - - - - - - - - - - - - - - - -
MySQL 杩炴帴娴嬭瘯
MySQL 鏈嶅姟鍣MySQL 鏁版嵁搴撳悕
MySQL 鐢ㄦ埛鍚MySQL 鐢ㄦ埛瀵嗙爜
 
-
- -OK (' . @mysql_get_server_info() . ')'; - $str2 = (@mysql_select_db($_POST['mysqlDatabase'], $link)) - ? 'OK' - : 'Failed
' . mysql_error(); - } - else - { - $str1 = 'Failed
' . mysql_error(); - $str2 = 'Failed'; - } - - ?> -
- - - - - - - - - - - - - - - -
MySQL 娴嬭瘯缁撴灉
鏈嶅姟鍣 ()
鏁版嵁搴 ()
- -
- -

Valid XHTML 1.0 Strict / Copyleft ! 2007-? by PHPnow.org

- -
- - \ No newline at end of file diff --git a/diyp/json.php b/diyp/json.php deleted file mode 100644 index 33498b7..0000000 --- a/diyp/json.php +++ /dev/null @@ -1,58 +0,0 @@ -open("channel_epg.db"); - } -} -$config = array(); -$channel = new ChannelDB(); -// 褰撳墠IP -$ip = $_SERVER['REMOTE_ADDR']; -$time = date("Y-m-d H:i:s"); -// 褰撳墠url -$url = $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']; -// 鑾峰彇鏈鍚庢潵婧愬湴鍧 -if (empty($_SERVER['HTTP_REFERER'])) -{ - $source_link = $url; -} -else -{ - $source_link = $_SERVER['HTTP_REFERER']; -} -$source_link = urldecode($source_link); -// 灏咺P鍦板潃璁板綍鍒版棩蹇楁枃浠舵垨鏁版嵁搴撲腑 -$result = $channel->query("INSERT or ignore INTO access_log (ip_address,access_time,url) VALUES ('{$ip}','{$time}','{$source_link}');"); - -$result = $channel->query('select * from list where isdel > 0 order by isdel;'); -while ($row = $result->fetchArray()) -{ - $group = $row[0]; - if ($group == '') - { - $group = '榛樿'; - } - @$item = $config[$group]; - if (!isset($item)) - { - $item = array(); - $config[$group] = array(); - } - array_push($config[$group], array('epg' => $row[2], - 'title' => $row[1], - 'url' => $row[3] - )); -} -$info = htmlspecialchars_decode($info); -$info = html_entity_decode($info); - -header("Content-Type: application/json"); -echo json_encode($config, JSON_UNESCAPED_UNICODE); -// echo json_encode($config); - -?> diff --git a/diyp/live.php b/diyp/live.php deleted file mode 100644 index 1da36fd..0000000 --- a/diyp/live.php +++ /dev/null @@ -1,94 +0,0 @@ -open("channel_epg.db"); - } -} -$config = array(); -$channel = new ChannelDB(); -$group = 'xxxxx'; -// 褰撳墠IP -$ip = $_SERVER['REMOTE_ADDR']; -$time = date("Y-m-d H:i:s"); -// 褰撳墠url -$url = $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']; -// 鑾峰彇鏈鍚庢潵婧愬湴鍧 -if (empty($_SERVER['HTTP_REFERER'])) -{ - $source_link = $url; -} -else -{ - $source_link = $_SERVER['HTTP_REFERER']; -} -$source_link = urldecode($source_link); -// 灏咺P鍦板潃璁板綍鍒版棩蹇楁枃浠舵垨鏁版嵁搴撲腑 -$result = $channel->query("INSERT or ignore INTO access_log (ip_address,access_time,url) VALUES ('{$ip}','{$time}','{$source_link}');"); - -$result = $channel->query('select * from list where isdel > 0 order by isdel;'); -while ($row = $result->fetchArray()) -{ - $config[] = ['item' => $row[0], 'title' => sprintf("%s", $row[1]), 'url' => sprintf("%s", $row[3])]; -} -$groupconfig = array_reduce($config, function($result, $item) - { - $gender = $item['item']; - if (!isset($result[$gender])) - { - $result[$gender] = []; - } - $result[$gender][] = $item; - return $result; - }, []); - -function gentxt($groupconfig) -{ - $config = array(); - foreach ($groupconfig as $item => $titles) - { - $config[] = sprintf("%s,#genre#", $item); - foreach ($titles as $k => $v) - { - $config[] = $v['title'] . ',' . $v['url']; - } - } - echo implode(PHP_EOL, $config); -} -function genm3u($groupconfig) -{ - $config = array(); - $config[] = '#EXTM3U x-tvg-url="http://epg.51zmt.top:8000/e.xml"'; - foreach ($groupconfig as $item => $titles) - { - foreach ($titles as $k => $v) - { - $text = strtoupper($v['title']); - if (strpos($text, "CCTV") >= 0 && strpos($text, "娓") > 0) - { - preg_match_all("/^[A-Za-z0-9-+]+/", $text, $matches); - $text = str_replace('-', '', $matches[0][0]); - }elseif (preg_match("/^[A-Za-z0-9-+]+/", $text)) - { - $text = str_replace('-', '', $text); - } - if (strpos($text, "[") > 0) - { - $text = substr($text, 0, strpos($text, "[")); - } - $config[] = sprintf('#EXTINF:-1 tvg-name="%s" tvg-logo="" group-title="%s",%s', $text, $item, $v['title']); - $config[] = $v['url']; - } - } - echo implode(PHP_EOL, $config); -} - -gentxt($groupconfig); -// echo iconv("UTF-8",'UCS-2BE',implode(PHP_EOL, $config)); - -?> \ No newline at end of file diff --git a/diyp/m3u.php b/diyp/m3u.php deleted file mode 100644 index 792ff72..0000000 --- a/diyp/m3u.php +++ /dev/null @@ -1,93 +0,0 @@ -open("channel_epg.db"); - } -} -$config = array(); -$channel = new ChannelDB(); -$group = 'xxxxx'; -// 褰撳墠IP -$ip = $_SERVER['REMOTE_ADDR']; -$time = date("Y-m-d H:i:s"); -// 褰撳墠url -$url = $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']; -// 鑾峰彇鏈鍚庢潵婧愬湴鍧 -if (empty($_SERVER['HTTP_REFERER'])) -{ - $source_link = $url; -} -else -{ - $source_link = $_SERVER['HTTP_REFERER']; -} -$source_link = urldecode($source_link); -// 灏咺P鍦板潃璁板綍鍒版棩蹇楁枃浠舵垨鏁版嵁搴撲腑 -$result = $channel->query("INSERT or ignore INTO access_log (ip_address,access_time,url) VALUES ('{$ip}','{$time}','{$source_link}');"); - -$result = $channel->query('select * from list where isdel > 0 order by isdel;'); -while ($row = $result->fetchArray()) -{ - $config[] = ['item' => $row[0], 'title' => sprintf("%s", $row[1]), 'url' => sprintf("%s", $row[3])]; -} -$groupconfig = array_reduce($config, function($result, $item) - { - $gender = $item['item']; - if (!isset($result[$gender])) - { - $result[$gender] = []; - } - $result[$gender][] = $item; - return $result; - }, []); - -function gentxt($groupconfig) -{ - $config = array(); - foreach ($groupconfig as $item => $titles) - { - $config[] = sprintf("%s,#genre#", $item); - foreach ($titles as $k => $v) - { - $config[] = $v['title'] . ',' . $v['url']; - } - } - echo implode(PHP_EOL, $config); -} -function genm3u($groupconfig) -{ - $config = array(); - $config[] = '#EXTM3U x-tvg-url="http://epg.51zmt.top:8000/e.xml"'; - foreach ($groupconfig as $item => $titles) - { - foreach ($titles as $k => $v) - { - $text = strtoupper($v['title']); - if (strpos($text, "CCTV") >= 0 && strpos($text, "娓") > 0) - { - preg_match_all("/^[A-Za-z0-9-+]+/", $text, $matches); - $text = str_replace('-', '', $matches[0][0]); - }elseif (preg_match("/^[A-Za-z0-9-+]+/", $text)) - { - $text = str_replace('-', '', $text); - } - if (strpos($text, "[") > 0) - { - $text = substr($text, 0, strpos($text, "[")); - } - $config[] = sprintf('#EXTINF:-1 tvg-name="%s" tvg-logo="" group-title="%s",%s', $text, $item, $v['title']); - $config[] = $v['url']; - } - } - echo implode(PHP_EOL, $config); -} - -genm3u($groupconfig); -// echo iconv("UTF-8",'UCS-2BE',implode(PHP_EOL, $config)); - -?> \ No newline at end of file diff --git a/diyp/myfile.php b/diyp/myfile.php deleted file mode 100644 index 756b8b1..0000000 --- a/diyp/myfile.php +++ /dev/null @@ -1,1073 +0,0 @@ - SoChishun <14507247@qq.com> Added. - * @since 2.0 <2015-7-24> SoChishun - * 1.閲嶅懡鍚嶄负SuExplorer.php - * 2.鏀硅繘鑻ュ共澶栬鏍峰紡 - * 3.鏂板鐧诲綍楠岃瘉妯″潡 - * 4.鏂板鍒犻櫎鍔熻兘 - * @since 3.0 <2015-10-7> SoChishun - * 1.鏂板鍦ㄧ嚎鍘嬬缉鍜岃В鍘嬪姛鑳 - * 2.鏂板chomd鏉冮檺璁剧疆鍔熻兘 - * 3.鏂板rename閲嶅懡鍚嶅姛鑳 - * 4.鏂板鏂板缓鏂囦欢鍜岀洰褰曞姛鑳 - * 5.绫籗uFileEditor閲嶆瀯涓篠uExplorer,绫绘柟娉曟敼涓洪潤鎬佹柟娉 - * 6.鏂板涓婚厤缃枃浠跺姛鑳 - * 7.閲嶆瀯椤甸潰閫昏緫锛屾敼涓鸿剼鏈贩鍚堜唬鐮侊紝渚夸簬闃呰 - * 8.鍩轰簬缁濆璺緞鎿嶄綔鏀逛负鍩轰簬缃戠珯鏍圭洰褰曠殑鐩稿璺緞鎿嶄綔 - * @since 3.1 <2016-9-13> SoChishun - * 1. 鏂板鏂囦欢涓婁紶鍔熻兘 - * @since 3.2 <2017-8-23> SoChishun - * 1. 淇鏃犳硶鏌ョ湅鑴氭湰鏂囦欢鐨勯棶棰 - * 2. 瀵筯tml杈撳嚭澧炲姞htmlspecialchars杩囨护鍔熻兘 - */ -// 绋嬪簭鐗堟湰鍙 [2015-10-7] Added. -$version = '3.2'; -// session閿悕 [2015-10-7] Added. -$sess_id = 'sess_suexplorer'; - -// 鏉冮檺瑙勫垯 [2015-10-7] Added. -$prules = array('delfile', 'deldir', 'savefile', 'newfile', 'mkdir', 'renamefile', 'renamedir', 'chomdfile', 'chomddir', 'zip', 'unzip'); - -// 涓婚厤缃 [2015-10-7] Added. -$config = array( - /* 鐢ㄦ埛閰嶇疆 */ - 'users' => array( - 'admin' => array('admin123', array('allow' => array(), 'forbit' => array())) - ), -); - -// 鐧诲綍淇℃伅 [2015-10-7] Added. -$login_data = isset($_SESSION[$sess_id]) ? $_SESSION[$sess_id] : false; - -$action = I('action'); -$view = I('view'); -$path = I('path', '/'); // urldecode($_GET['path']) $_SERVER['DOCUMENT_ROOT'] -$parent_path = path_getdir($path); -switch ($action) { - case 'login': // 鐢ㄦ埛鐧诲綍 - if (!SuExplorer::user_login($config, $sess_id, $msg)) { - redirect('?r=fail', 1, $msg); - } else { - redirect('?r=ok'); - } - break; - case 'logout': // 娉ㄩ攢鐧诲綍 - SuExplorer::user_logout($sess_id); - redirect('?r=ok'); - break; - case 'del': // 鍒犻櫎璺緞(鏂囦欢鎴栫洰褰) - if (!SuExplorer::act_delete_path($path, $msg)) { - redirect('?path=' . $path, 1, $msg); - } else { - redirect('?path=' . path_getdir($path), 1, '鎭枩,鎿嶄綔鎴愬姛!'); - } - break; - case 'savefile': // 淇濆瓨鏂囦欢 - case 'save_newfile': // 鏂板缓鏂囦欢 - if (!SuExplorer::act_save_file($msg)) { - redirect('?path=' . $path, 1, $msg); - } else { - redirect('?path=' . $path, 1, '鎭枩,鎿嶄綔鎴愬姛!'); - } - break; - case 'save_newdir': // 鏂板缓鐩綍 - if (!SuExplorer::act_save_newdir($msg)) { - redirect('?path=' . $path, 1, $msg); - } else { - redirect('?path=' . $path, 1, '鎭枩,鎿嶄綔鎴愬姛!'); - } - break; - case 'upload_file': // 涓婁紶鏂囦欢 - if (!SuExplorer::act_upload_file($msg)) { - redirect('?path=' . $path, 1, $msg); - } else { - redirect('?path=' . $path, 1, '鎭枩,鏂囦欢涓婁紶鎴愬姛!'); - } - break; - case 'rename_path': // 閲嶅懡鍚嶈矾寰(鏂囦欢鎴栫洰褰) - if (!SuExplorer::act_rename_path($msg)) { - redirect('?path=' . $path, 1, $msg); - } else { - redirect('?path=' . pathinfo($path, PATHINFO_DIRNAME), 1, '鎭枩,鎿嶄綔鎴愬姛!'); - } - break; - case 'chmod_path': // 淇敼鏉冮檺(鏂囦欢鎴栫洰褰) - if (!SuExplorer::act_chmod_path($msg)) { - redirect('?path=' . $path, 1, $msg); - } else { - redirect('?path=' . $path, 1, '鎭枩,鎿嶄綔鎴愬姛!'); - } - break; - case 'zip': // 鍘嬬缉 - if (!SuExplorer::act_zip($msg)) { - redirect('?path=' . $path, 1, $msg); - } else { - redirect('?path=' . $path, 1, '鎭枩,鎿嶄綔鎴愬姛!'); - } - break; - case 'unzip': // 瑙e帇缂 - if (!SuExplorer::act_unzip($msg)) { - redirect('?path=' . $path, 1, $msg); - } else { - redirect('?path=' . $path, 1, '鎭枩,鎿嶄綔鎴愬姛!'); - } - break; -} -?> - - - - - SuExplorer-<?php echo $version ?> - - - - - - - - - -
-
- - - - - - - -
-
- -
- - - - - -
- - - -
鐢ㄦ埛鍚嶏細
瀵 鐮侊細
- - -
- - - - - SoChishun Added. - */ -function I($name, $defv = '') { - if (isset($_GET[$name])) { - return $_GET[$name]; - } - return isset($_POST[$name]) ? $_POST[$name] : $defv; -} - -/** - * URL閲嶅畾鍚 - * @param string $url 閲嶅畾鍚戠殑URL鍦板潃 - * @param integer $time 閲嶅畾鍚戠殑绛夊緟鏃堕棿锛堢锛 - * @param string $msg 閲嶅畾鍚戝墠鐨勬彁绀轰俊鎭 - * @return void - * @since 1.0 <2015-10-7> from ThinkPHP - */ -function redirect($url, $time = 0, $msg = '') { - //澶氳URL鍦板潃鏀寔 - $url = str_replace(array("\n", "\r"), '', $url); - if (empty($msg)) - $msg = "绯荤粺灏嗗湪{$time}绉掍箣鍚庤嚜鍔ㄨ烦杞埌{$url}锛"; - if (!headers_sent()) { - // redirect - if (0 === $time) { - header('Location: ' . $url); - } else { - header("refresh:{$time};url={$url}"); - echo($msg); - } - exit(); - } else { - $str = ""; - if ($time != 0) - $str .= $msg; - exit($str); - } -} - -/** - * 鑾峰彇鏂囦欢鎵╁睍鍚嶇被鍨 - * @param string $exten 鎵╁睍鍚(涓嶅甫.) - * @return string - * @since 1.0 <2015-10-9> SoChishun Added. - */ -function get_exten_catetory($exten) { - if ($exten) { - $filetypes = array('zip' => array('zip', 'rar', '7-zip', 'tar', 'gz', 'gzip'), 'doc' => array('txt', 'rtf', 'doc', 'docx', 'ppt', 'pptx', 'xls', 'xlsx', 'wps', 'et'), 'script' => array('php', 'js', 'css', 'c'), 'image' => array('jpg', 'jpeg', 'png', 'gif', 'tiff', 'psd', 'bmp', 'ico')); - foreach ($filetypes as $catetory => $extens) { - if (in_array($exten, $extens)) { - return $catetory; - } - } - } - return ''; -} - -/** - * 缁濆璺緞杞浉瀵硅矾寰 - * @param string $path - * @return string - * @since 1.0 <2015-10-9> SoChishun Added. - */ -function path_ator($path) { - $root = $_SERVER['DOCUMENT_ROOT']; - $path = substr($path, strlen($root)); - if ('/' != DIRECTORY_SEPARATOR) { - $path = str_replace(DIRECTORY_SEPARATOR, '/', $path); - } - return $path; -} - -/** - * 鐩稿璺緞杞粷瀵硅矾寰 - * @param string $path - * @return string - * @since 1.0 <2015-10-9> SoChishun Added. - */ -function path_rtoa($path) { - $root = $_SERVER['DOCUMENT_ROOT']; - if ('/' != DIRECTORY_SEPARATOR) { - $path = str_replace('/', DIRECTORY_SEPARATOR, $path); - } - return $root . $path; -} -function path_rt_oa($path) { - $root = $_SERVER['DOCUMENT_ROOT']; - if ('/' != DIRECTORY_SEPARATOR) { - $path = str_replace('/', DIRECTORY_SEPARATOR, $path); - } - return '.' . $path; -} - -/** - * 鑾峰彇鏂囦欢鐨勭洰褰曞湴鍧 - * @param string $path - * @param boolean $is_r 鏄惁鐩稿璺緞 - * @return string - * @since 1.0 <2015-10-9> SoChishun Added. - */ -function path_getdir($path, $is_r = true) { - if (!$path || is_dir($is_r ? path_rtoa($path) : $path)) { - return $path; - } - return pathinfo($path, PATHINFO_DIRNAME); -} - -/** - * 椤甸潰涓荤被 - * @since 1.0 <2015-5-11> SoChishun <14507247@qq.com> Added. - * @since 3.0 <2015-10-7> SoChishun 閲嶆瀯. - */ -class SuExplorer { - - /** - * 鐗堟湰鍙 - * @var string - * @since 1.0 <2015-10-7> SoChishun Added. - */ - CONST VERSION = '3.0.0'; - - /** - * 鏄剧ず缃戠珯鐩綍鐨勯」鐩唴瀹 - * @since 1.0 <2015-5-11> SoChishun Added. - */ - static function index($view, $path) { - // 闈㈠寘灞戝鑸 - self::location_to_breadcrumb($path); - // 瑙嗗浘鏄剧ず - switch ($view) { - case 'newfile': - self::view_create_file($path); - break; - case 'newdir': - self::view_create_dir($path); - break; - case 'upload': - self::view_upload_file($path); - break; - case 'rename': - self::view_rename_path($path); - break; - case 'chmod': - self::view_chmod_path($path); - break; - case 'zip': - self::view_zip(); - break; - case 'unzip': - self::view_unzip(); - break; - default: - // 鍒楀嚭鏂囦欢 - $sapath = path_rtoa($path); - if (is_dir($sapath)) { - self::view_content_list($path); - } else if (is_file($sapath)) { - self::view_edit_file($path); - } else { - echo '鏂囦欢鎴栫洰褰曚笉瀛樺湪鎴栧凡鍒犻櫎!'; - } - break; - } - } - - /** - * 鐢ㄦ埛鐧诲綍鎿嶄綔 - * @param array $config - * @param string $sess_id - * @param string $msg 閿欒娑堟伅 - * @return boolean - * @since 1.0 <2015-10-9> SoChishun Added. - */ - static function user_login($config, $sess_id, &$msg = '') { - if (!$_POST || !isset($_POST['uname'])) { - $msg = '琛ㄥ崟鏁版嵁鏃犳晥!'; - return false; - } - $uname = $_POST['uname']; - if (!array_key_exists($uname, $config['users'])) { - $msg = '鐢ㄦ埛涓嶅瓨鍦'; - return false; - } - $login_data = $config['users'][$uname]; - if ($login_data[0] != $_POST['upwd']) { - $msg = '瀵嗙爜閿欒!'; - return false; - } - $_SESSION[$sess_id] = array('user_name' => $uname, 'rules' => isset($login_data[1]) ? $login_data[1] : false); - return true; - } - - /** - * 鐢ㄦ埛鐧诲嚭鎿嶄綔 - * @param string $sess_id - * @return boolean - * @since 1.0 <2015-10-9> SoChishun Added. - */ - static function user_logout($sess_id) { - if (isset($_SESSION[$sess_id])) { - unset($_SESSION[$sess_id]); - } - return true; - } - - /** - * 鍒犻櫎璺緞(鏂囦欢鎴栫洰褰) - * @param string $path 璺緞 - * @param string $msg 閿欒娑堟伅 - * @return boolean|string - * @since 1.0 <2015-10-7> SoChishun Added. - * @since 2.0 <2015-10-8> SoChishun 灏哾elete_file鍜宒elete_dir鍚堝苟鍒癲elete_path - */ - static function act_delete_path($path, &$msg = '') { - if ('yes' != I('do')) { - // 涓洪槻姝㈤粦瀹㈢牬鍧,鍒犻櫎鎿嶄綔闇瑕佹墜鍔ㄥ鍔犲弬鏁癲o=yes - $msg = '闈炴硶鎿嶄綔!'; - return false; - } - if ('/' == $path) { - $msg = '鏍圭洰褰曟棤娉曞垹闄!'; - return false; - } - $path = path_rtoa($path); - if (is_file($path)) { - if (!@unlink($path)) { - $msg = '鏂囦欢鍒犻櫎澶辫触!'; - return false; - } - return true; - } - if (is_dir($path)) { - if (!@rmdir($path)) { - $msg = '鐩綍鍒犻櫎澶辫触!(闈炵┖鐩綍鎴栨潈闄愪笉瓒)'; - return false; - } - return true; - } - $msg = '涓嶆槸鏈夋晥鏂囦欢鎴栫洰褰!'; - return false; - } - - /** - * 淇濆瓨(鏂)鏂囦欢 - * @param type $msg - * @return boolean - * @since 1.0 <2015-10-7> SoChishun Added. - */ - static function act_save_file(&$msg = '') { - $filename = I('filename'); - if (!$filename || !strpos($filename, '.')) { - $msg = '鏂囦欢鎵╁睍鍚嶆棤鏁!'; - return false; - } - $content = I('content'); - $path = I('path'); - $path = path_rtoa($path); - if (is_file($path)) { - $path = path_getdir($path, false); - } - $newpath = $path . DIRECTORY_SEPARATOR . $filename; - try { - file_put_contents($newpath, $content); - return true; - } catch (Exception $ex) { - $msg = $ex->getMessage(); - return false; - } - } - - /** - * 淇濆瓨鏂扮洰褰 - * @param string $msg 閿欒娑堟伅 - * @return boolean - * @since 1.0 <2015-10-8> SoChishun Added. - */ - static function act_save_newdir(&$msg = '') { - $filename = I('filename'); - if (!$filename) { - $msg = '鐩綍鍚嶇О鏃犳晥'; - return false; - } - $path = path_rtoa(I('path')); - $newpath = $path . DIRECTORY_SEPARATOR . $filename; - try { - mkdir($newpath, I('mode')); - return true; - } catch (Exception $ex) { - $msg = $ex->getMessage(); - return false; - } - } - - /** - * 涓婁紶鏂囦欢 - * @param type $msg - * @return boolean - * @since 1.0 <2016-9-13> SoChishun Added. - */ - static function act_upload_file(&$msg = '') { - if ($_FILES["file"]["error"] > 0) { - $msg = $_FILES["file"]["error"]; - return false; - } - - $path = I('path'); - $path = path_rtoa($path); - $filename = $_FILES["file"]["name"]; - if (file_exists($path . $filename)) { - $msg = $filename . " 鏂囦欢宸插瓨鍦!"; - return false; - } - move_uploaded_file($_FILES["file"]["tmp_name"], $path . $filename); - return true; - } - - /** - * 閲嶅懡鍚嶈矾寰勬搷浣 - * @param string $msg 閿欒娑堟伅 - * @return boolean - * @since 1.0 <2015-10-9> SoChishun Added. - */ - static function act_rename_path(&$msg = '') { - $filename2 = I('filename2'); - if (!$filename2) { - $msg = '鏂板悕绉版湭濉啓!'; - return false; - } - $path = path_rtoa(I('path')); - if (is_file($path) && !strpos($filename2, '.')) { - $msg = '鏂囦欢鎵╁睍鍚嶆棤鏁!'; - return false; - } - try { - $newname = pathinfo($path, PATHINFO_DIRNAME) . DIRECTORY_SEPARATOR . $filename2; - @rename($path, $newname); - return true; - } catch (Exception $ex) { - $msg = $ex->getMessage(); - return false; - } - } - - /** - * 缂栬緫鏉冮檺鎿嶄綔 - * @param string $msg 閿欒娑堟伅 - * @return boolean - * @since 1.0 <2015-10-9> SoChishun Added. - */ - static function act_chmod_path(&$msg = '') { - $mode = I('mode'); - if (!$mode) { - $msg = '鏉冮檺妯″紡鏃犳晥!'; - return false; - } - $path = path_rtoa(I('path')); - try { - chmod($path, $mode); - return true; - } catch (Exception $ex) { - $msg = $ex->getMessage(); - return false; - } - } - - /** - * 鍘嬬缉鎿嶄綔 - * @param string $msg - * @return boolean - * @since 1.0 <2015-10-9> SoChishun Added. - */ - static function act_zip(&$msg = '') { - $filename = I('filename'); - $content = I('content'); - if (!$filename || !strpos($filename, '.')) { - $msg = '鍘嬬缉鏂囦欢鍚嶆棤鏁!'; - return false; - } - if (!$content) { - $msg = '鍘嬬缉鍐呭鏃犳晥!'; - return false; - } - $include = array(); - $exclude = array(); - $paths = explode(PHP_EOL, $content); - foreach ($paths as $path) { - if (0 === strpos($path, 'exclude ')) { - $exclude[] = trim(substr($path, 8)); - } else { - $include[] = $path; - } - } - if (!$include) { - $msg = '鍘嬬缉鍐呭鏃犳晥!'; - return false; - } - $zip = new ZipHelper(); - return $zip->zip($filename, $msg, $include, $exclude, I('rootpath')); - } - - /** - * 瑙e帇缂╂枃浠 - * @param type $msg - * @return type - */ - static function act_unzip(&$msg = '') { - $root = I('root'); - $filename = I('filename'); - if (!$filename) { - $msg = '鍘嬬缉鏂囦欢璺緞鏃犳晥!'; - return false; - } - if (!$root) { - $msg = '瑙e帇缂╄矾寰勬棤鏁!'; - return false; - } - $zip = new ZipHelper(); - return $zip->unzip($filename, $root, $msg); - } - - /** - * 鐩綍鍐呭瑙嗗浘 - * @param type $path - * @since 1.0 <2015-5-11> SoChishun Added. - */ - static function view_content_list($path) { - $files = self::get_dir_contents($path, array('name' => true, 'path' => false, 'real_path' => false, 'relative_path' => true, 'exten' => false, 'ctime' => false, 'mtime' => false, 'size' => false, 'is_dir' => true, 'is_file' => false, 'is_link' => true, 'is_executable' => true, 'is_readable' => false, 'is_writable' => false, 'filetype' => true)); - echo '
'; - foreach ($files as $file) { - if ($file['is_dir']) { - echo '' . $file['name'] . ''; - } else { - $class = ''; - if ($file['is_link']) { - $class = 'lightblue'; - } else if ($file['is_executable']) { - $class = 'green'; - } else { - switch ($file['filetype']) { - case 'zip': - $class = 'red'; - break; - case 'image': - $class = 'purple'; - break; - default: - $class = 'grey'; - break; - } - } - echo '' . $file['name'] . ''; - } - } - echo '
'; - } - - /** - * 鏂囦欢鍐呭缂栬緫瑙嗗浘 - * @param type $path - * @since 1.0 <2015-5-11> SoChishun Added. - */ - static function view_edit_file($path) { - $sapath = path_rtoa($path); - if (!is_file($sapath)) { - return; - } - $category = get_exten_catetory(pathinfo($path, PATHINFO_EXTENSION)); - switch ($category) { - case 'doc': - case 'script': - $btns = ''; - if (!is_writable($sapath)) { - echo '
鏂囦欢涓嶅彲鍐
'; - $btns = ''; - } - echo '
-
- ', $btns, '
', $btns, ' - - - -
-
'; - break; - case 'image': - echo '
'; - echo basename($path); - echo ' [鍘熷浘]'; - break; - default: - echo basename($path); - echo ' [涓嬭浇]'; - break; - } - } - - /** - * 鏂板鏂囦欢瑙嗗浘 - * @param string $path 璺緞 - * @since 1.0 <2015-10-8> SoChishun Added. - */ - static function view_create_file($path) { - echo '
-
- - - - -
鏂囦欢鍚嶏細
鍐呭锛
 
- - -
-
'; - } - - /** - * 鏂板鐩綍瑙嗗浘 - * @param string $path 璺緞 - * @since 1.0 <2015-10-8> SoChishun Added. - */ - static function view_create_dir($path) { - echo '
-
- 鐩綍鍚嶏細
- 鏉冮檺妯″紡锛
- - - -
-
'; - } - - static function view_upload_file($path) { - echo '
-
- - - -
閫夋嫨鏂囦欢锛
 
- - -
-
'; - } - - /** - * 閲嶅懡鍚嶆枃浠惰鍥 - * @param string $path 璺緞 - * @since 1.0 <2015-10-8> SoChishun Added. - */ - static function view_rename_path($path) { - echo '
-
- 鍘熷悕绉帮細' . basename($path) . '
- 鏂板悕绉帮細
- - - -
-
'; - } - - /** - * 缂栬緫鏉冮檺瑙嗗浘 - * @param string $path 璺緞 - * @since 1.0 <2015-10-9> SoChishun Added. - */ - static function view_chmod_path($path) { - echo '
-
- 鍚嶇О锛' . basename($path) . '
- 鏉冮檺妯″紡锛
- - - -
-
'; - } - - /** - * 鍘嬬缉鏂囦欢瑙嗗浘 - * @since 1.0 <2015-10-9> SoChishun Added. - */ - static function view_zip() { - echo '
-
- - - - - - -
鍘嬬缉鏂囦欢鍚嶏細
鍘嬬缉鍐呭锛
鍘婚櫎鏍硅矾寰勶細
  - 娉ㄦ剰锛屾墍鏈夎矾寰勯兘蹇呴渶鏄粷瀵硅矾寰!
- 鍖呭惈璺緞绀轰緥锛欳:\public\www\website1\app
- 鎺掗櫎璺緞绀轰緥: exclude C:\public\www\website1\app\runtime
- 濡傛灉濉啓璺熻矾寰勫湴鍧,鍒欏帇缂╁唴瀹逛細鑷姩鍘婚櫎璺熻矾寰勪俊鎭(瑙e帇缂╃殑鏃跺,鍙互瑙e帇缂╁埌浠绘剰鐩綍涓),濡傛灉鏍硅矾寰勪负绌哄垯淇濈暀鏍硅矾寰勪俊鎭(瑙e帇缂╃殑鏃跺,鏃犳硶瑙e帇缂╁埌浠绘剰鐩綍涓,绯荤粺浼氳嚜鍔ㄥ垱寤哄拰鍘嬬缉鍓嶈矾寰勪竴鏍风殑鐩綍) -
 
- -
-
'; - } - - /** - * 瑙e帇缂╂枃浠惰鍥 - * @since 1.0 <2015-10-9> SoChishun Added. - */ - static function view_unzip() { - echo '
-
- - - - -
鍘嬬缉鏂囦欢鍚嶏細
瑙e帇缂╄矾寰勶細
 
- -
-
'; - } - - /** - * 杩斿洖鎸囧畾璺緞涓嬬殑鍐呭 - * @param string $directory 璺緞 - * @param array $config 閫夐」 - * @return array - * @throws Exception - * @since 1.0 <2015-5-11> SoChishun Added. - * @since 1.1 <2015-10-8> SoChishun 鏂板filetype鏂囦欢绫诲埆灞炴 - */ - static function get_dir_contents($directory, $options = array()) { - $config = array('name' => true, 'path' => true, 'real_path' => true, 'relative_path' => false, 'exten' => false, 'ctime' => false, 'mtime' => false, 'size' => false, 'is_dir' => true, 'is_file' => false, 'is_link' => false, 'is_executable' => false, 'is_readable' => false, 'is_writable' => false, 'filetype' => false); - if ($options) { - $config = array_merge($config, $options); - } - try { - $dir = new DirectoryIterator(path_rtoa($directory)); - } catch (Exception $e) { - throw new Exception($directory . ' is not readable'); - } - $files = array(); - foreach ($dir as $file) { - if ($file->isDot()) { - continue; - } - if ($config['name']) { - $item['name'] = $file->getFileName(); - } - if ($config['path']) { - $item['path'] = $file->getPath(); - } - if ($config['real_path']) { - $item['real_path'] = $file->getRealPath(); - } - if ($config['relative_path']) { - $item['relative_path'] = path_ator($file->getRealPath()); - } - $exten = $file->getExtension(); - if ($config['exten']) { - $item['exten'] = $exten; - } - if ($config['filetype']) { - $item['filetype'] = get_exten_catetory($exten); - } - if ($config['mtime']) { - $item['mtime'] = $file->getMTime(); - } - if ($config['ctime']) { - $item['ctime'] = $file->getCTime(); - } - if ($config['size']) { - $item['size'] = $file->getSize(); - } - if ($config['is_dir']) { - $item['is_dir'] = $file->isDir(); - } - if ($config['is_file']) { - $item['is_file'] = $file->isFile(); - } - if ($config['is_link']) { - $item['is_link'] = $file->isLink(); - } - if ($config['is_executable']) { - $item['is_executable'] = $file->isExecutable(); - } - if ($config['is_readable']) { - $item['is_readable'] = $file->isReadable(); - } - if ($config['is_writable']) { - $item['is_writable'] = $file->isWritable(); - } - $files[] = $item; - } - return $files; - } - - /** - * 璺緞杞负瀵艰埅 - * @param string $path - * @since 1.0 <2015-5-11> SoChishun Added. - */ - static function location_to_breadcrumb($path) { - echo ''; - } - -} - -/** - * 鍘嬬缉绫 - * @since 1.0 <2015-10-9> SoChishun Added. - */ -class ZipHelper { - - /** - * 瑙e帇缂╀箣 - * @param type $filename - * @param type $root - * @param type $msg - * @return boolean - * @since 1.0 <2015-10-9> SoChishun Added. - */ - function unzip($filename, $root, &$msg = '') { - if (!$filename) { - $msg = '鍘嬬缉鏂囦欢鍚嶆棤鏁!'; - return false; - } - $zip = new ZipArchive(); - $msg = $zip->open($filename); - if (true !== $msg) { - $msg = var_export($msg, true); - return false; - } - $zip->extractTo($root); - $zip->close(); - return true; - } - - /** - * 鍘嬬缉涔 - * @param type $filename - * @param type $msg - * @param type $include - * @param type $exclude - * @param string $trimpath - * @param string $comment - * @return boolean - * @since 1.0 <2015-10-9> SoChishun Added. - */ - function zip($filename, &$msg = '', $include = array(), $exclude = array(), $trimpath = '', $comment = 'default') { - if (!$filename) { - $msg = '鍘嬬缉鏂囦欢鍚嶆棤鏁!'; - return false; - } - if (!$include) { - $msg = '鍘嬬缉鍐呭鏃犳晥!'; - return false; - } - if ('default' == $comment) { - $comment = basename($filename) . PHP_EOL . 'Generate at ' . date('Y-m-d H:i:s') . PHP_EOL . 'Powerd by SuExplorer.'; // 娉ㄩ噴鍐呭 - } - try { - $zip = new ZipArchive(); - $msg = $zip->open($filename, ZIPARCHIVE::OVERWRITE); - if (true !== $msg) { - $msg = var_export($msg, true); - return false; - } - if ($comment) { - $zip->setArchiveComment($comment); - } - if ($trimpath) { - $trimpath = rtrim($trimpath, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR; - } - $substart = strlen($trimpath); - foreach ($include as $source) { - $this->zip_dir($zip, $source, $exclude, $substart); - } - $zip->close(); - return true; - } catch (Exception $ex) { - $msg = $ex->getMessage(); - return false; - } - } - - /** - * 閫掑綊鍘嬬缉鏁翠釜鐩綍 - * @param ZipArchive $zip - * @param string $source 鍖呭惈鐨勮矾寰 - * @param array $exclude 鎺掗櫎鐨勮矾寰 - * @param int $substart 寮濮嬫埅鍙栫殑璺緞瀛楃涓(鐢ㄤ簬鍘婚櫎璺緞涓殑鏍圭洰褰曡矾寰) - * @since 1.0 <2015-8-28> SoChishun Added. - */ - function zip_dir(&$zip, $source, $exclude, $substart = 0) { - if (is_dir($source)) { - $source = rtrim($source, DIRECTORY_SEPARATOR); - if ($handle = opendir($source)) { - while (false !== ( $f = readdir($handle) )) { - if ('.' == $f || '..' == $f) { - continue; - } - $filename = $source . DIRECTORY_SEPARATOR . $f; - if (is_dir($filename)) { - if ($exclude && in_array($filename, $exclude)) { - continue; - } - $this->zip_dir($zip, $filename, $exclude, $substart); - } else { - if ($exclude && in_array($filename, $exclude)) { - continue; - } - $zip->addFile($filename, substr($filename, $substart)); - } - } - closedir($handle); - } - } else { - if ($exclude && in_array($source, $exclude)) { - return; - } - $zip->addFile($source); - } - } -} diff --git a/diyp/xml2db.php b/diyp/xml2db.php deleted file mode 100644 index 135b4a1..0000000 --- a/diyp/xml2db.php +++ /dev/null @@ -1,216 +0,0 @@ - -open($f); - $this->busyTimeout(60000); // 10 seconds - if ($isnew > 0) - { - // 鍒濆鍖栨暟鎹簱 - $this->exec("BEGIN TRANSACTION;"); - $this->exec("CREATE TABLE 'list' (item text, title text, epg text, url text, isdel integer null default 120,constraint name_pk primary key (item,title,url))"); - $this->exec("CREATE TABLE if not exists 'access_log' (ip_address text, access_time text,url text)"); - $this->exec("CREATE TABLE if not exists 'epg_channel' ( `name` text, `channel_id` text,constraint name_pk primary key (name))"); - $this->exec("CREATE TABLE if not exists 'epg_programme' ( `title` text, `sdate` text, `sstart` text, `sstop` text, `channel` text, `sdesc` text, 'inserttime' text,constraint name_pk primary key (channel,sdate,sstart))"); - $this->exec("CREATE TABLE if not exists 'tmp_epg_channel' ( `name` text, `channel_id` text)"); - $this->exec("CREATE TABLE if not exists 'tmp_epg_programme' ( `title` text, `sdate` text, `sstart` text, `sstop` text, `channel` text, `sdesc` text, 'inserttime' text)"); - // 鍒濆鍖栭閬撹〃鏍蜂緥鏁版嵁 - $this->exec("INSERT INTO `list` (`item`,`title`,`epg`,`url`,`isdel`) VALUES ('骞夸笢棰戦亾','骞垮窞缁煎悎','','http://nas.jdshipin.com:8801/gztv.php?id=zhonghe','90');"); - $this->exec("INSERT INTO `list` (`item`,`title`,`epg`,`url`,`isdel`) VALUES ('骞夸笢棰戦亾','骞垮窞鏂伴椈','','http://nas.jdshipin.com:8801/gztv.php?id=xinwen#http://113.100.193.10:9901/tsfile/live/1000_1.m3u8','90');"); - $this->exec("INSERT INTO `list` (`item`,`title`,`epg`,`url`,`isdel`) VALUES ('鐩存挱棰戦亾','CCTV2','','http://dbiptv.sn.chinamobile.com/PLTV/88888893/224/3221226195/index.m3u8?0.smil','120');"); - $this->exec("COMMIT;"); - } - } -} -// 杩炴帴鏁版嵁搴 -$config = array(); -$channel = new ChannelDB(); -// 寮濮嬩簨鍔″鐞 -$channel->exec("BEGIN TRANSACTION;"); -// ==========鍐欏叆璁块棶鏃ュ織寮濮========= -// 褰撳墠IP -$ip = $_SERVER['REMOTE_ADDR']; -$time = date("Y-m-d H:i:s"); -// 褰撳墠url -$url = $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']; -// 鑾峰彇鏈鍚庢潵婧愬湴鍧 -if (empty($_SERVER['HTTP_REFERER'])) -{ - $source_link = $url; -} -else -{ - $source_link = $_SERVER['HTTP_REFERER']; -} -$source_link = urldecode($source_link); -// 灏咺P鍦板潃璁板綍鍒版棩蹇楁枃浠舵垨鏁版嵁搴撲腑 -$channel->exec("INSERT or ignore INTO access_log (ip_address,access_time,url) VALUES ('{$ip}','{$time}','{$source_link}');"); -// ==========鍐欏叆璁块棶鏃ュ織缁撴潫========= -if ( $db != '0' ){ - echo "only create db. please run again."; - $channel->exec("INSERT or ignore INTO access_log (ip_address,access_time,url) VALUES ('{$ip}','{$time}','Create database');"); - exit; -} -// 鑾峰彇缃戦〉鏁版嵁 -function getContent($url) -{ - $process = curl_init($url); - curl_setopt($process, CURLOPT_RETURNTRANSFER, 1); - curl_setopt($process, CURLOPT_CONNECTTIMEOUT, 5); - curl_setopt($process, CURLOPT_TIMEOUT, 45); - // 璁剧疆鍚敤SSL鍗忚 - if (strtoupper(substr($url, 0, 5)) == 'HTTPS') - { - curl_setopt($process, CURLOPT_SSL_VERIFYPEER, 0); - curl_setopt($process, CURLOPT_SSL_VERIFYHOST, 0); - } - // 璁剧疆GZIP鍘嬬缉 - $isgz = false; - if (strtoupper(substr($url, -3)) == '.GZ') - { - curl_setopt($process, CURLOPT_ENCODING, 'gzip'); - $isgz = true; - } - curl_setopt($process, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows NT 5.1; zh-CN) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/30.0.1599.101 Safari/537.36"); - $data = curl_exec($process); - if (curl_errno($process)) - { - echo curl_errno($process) . curl_error($process) . "
"; - } - curl_close($process); - if ($isgz) - { - $data = gzdecode($data); - } - unset($process); - return $data; -} - -// 鑺傜洰鎬昏〃鍦板潃鍒楄〃 -// $xmlurl = array("https://epg.erw.cc/e.xml.gz"); //openssl -// $xmlurl = array("http://epg.51zmt.top:8000/e.xml"); //褰撳ぉ51zmt澶崼鏁 鑺傜洰鍗 -// $xmlurl = array("http://epg.51zmt.top:8000/e.xml", "http://epg.erw.cc/e.xml", "http://epg.112114.xyz/pp.xml"); //褰撳ぉ 澶崼鏁 鑺傜洰鍗 -// $xmlurl = array("http://epg.51zmt.top:8000/cc.xml", "http://epg.erw.cc/cc.xml", "http://epg.112114.xyz/pp.xml"); //褰撳ぉ 澶崼 鑺傜洰鍗 -$xmlurl = array("http://epg.112114.xyz/pp.xml.gz", "http://epg.51zmt.top:8000/e.xml.gz", "http://epg.erw.cc/e.xml.gz"); //gzip妯″紡 -// . -// 閬嶅巻xmlurl,鍚屾epg xml鏁版嵁婧 -foreach ($xmlurl as $url) -{ - // 娓呯┖涓存椂琛 - $channel->exec("delete from tmp_epg_channel"); - $channel->exec("delete from tmp_epg_programme"); - // 鑾峰彇xml鏍煎紡鐨勮妭鐩崟 - $data = getContent($url); - if (!is_string($data)) - { - echo "none. $url
" ; - continue; - } - else - { - echo "200 $url
" ; - } - // 瑙f瀽xml鏁版嵁 - $xml = simplexml_load_string($data); - foreach ($xml->children() as $xmldata) - { - if ($xmldata->getName() == "channel") - { - $result = $channel->query("INSERT INTO tmp_epg_channel(name,channel_id) VALUES ('" . $xmldata->$displayname . "','" . $xmldata->attributes()->id . "')"); - - if (!$result) - { - echo $n . ' - ' . $channel->lastErrorMsg() . '
'; - } - } - - if ($xmldata->getName() == "programme") - { - $start_time = substr($xmldata->attributes()->start, 8, 2) . ":" . substr($xmldata->attributes()->start, 10, 2); - $stop_time = substr($xmldata->attributes()->stop, 8, 2) . ":" . substr($xmldata->attributes()->stop, 10, 2); - $jm_date = substr($xmldata->attributes()->stop, 0, 4) . "-" . substr($xmldata->attributes()->stop, 4, 2) . "-" . substr($xmldata->attributes()->stop, 6, 2); - $n ++ ; - - $replacement = str_replace("'", " ", $xmldata->title); - $sql = "INSERT INTO tmp_epg_programme(channel,sdate,sstart,sstop,title,sdesc,inserttime) VALUES ('" . $xmldata->attributes()->channel . "','" . $jm_date . "','" . $start_time . "','" . $stop_time . "','" . $replacement . "','','" . $time . "')"; - $result = $channel->query($sql); - - if (!$result) - { - echo $n . ' = ' . $channel->lastErrorMsg() . '
'; - // echo $xmldata->title . "
"; - } - } - } - // 鏇存柊鑺傜洰鏁版嵁 - if ($n > 0) - { - // 鍐欏叆鏃ュ織 - $channel->exec("INSERT INTO access_log (ip_address,access_time,url) VALUES ('xml2db_ini','{$time}','{$n}');"); - // 鎶婄洿鎾簮list鐨勯閬撹拷鍔/鏇存柊鍒癳pg棰戦亾琛 - $channel->exec("insert or ignore into epg_channel select upper(a.name) as name ,upper(a.name) as channel_id from tmp_epg_channel a where upper(name) in (select upper(title) from list);"); - // 鏍规嵁鏉′欢鏄惁淇濆瓨鍏ㄩ噺epg棰戦亾琛 - $count = $channel->querySingle("SELECT count(*) FROM 'list'"); - if ($count == 0 or $save_all == 1) - { - $channel->exec("insert or ignore into epg_channel SELECT upper(a.name) as name ,upper(a.name) as channel_id FROM tmp_epg_channel a;"); - } - // 缁熻鍘熻妭鐩崟鏉$洰鏁 - $count = $channel->querySingle("SELECT count(*) FROM 'epg_programme'"); - // 杩藉姞鑺傜洰鍗曞埌epg_programme - $channel->exec("insert or {$inserttype} into epg_programme SELECT c.title,c.sdate,c.sstart,c.sstop,upper(a.name) as channel,c.sdesc,c.inserttime FROM epg_channel a join tmp_epg_channel b on upper(a.name) = upper(b.name) join tmp_epg_programme c on b.channel_id= c.channel;"); - // 缁熻鑺傜洰鍗曞鍔犳潯鐩暟 - $count = $channel->querySingle("SELECT count(*) FROM 'epg_programme'") - $count; - $channel->exec("INSERT INTO access_log (ip_address,access_time,url) VALUES ('xml2db_add','{$time}','{$count}');"); - echo "done, add " . $count . '
'; - // 娓呯悊鍘嗗彶鏁版嵁 - // $currentDate = date('Y-m-d'); // 鑾峰彇褰撳墠鏃ユ湡 - $currentDate = $channel->querySingle("SELECT max(sdate) FROM 'epg_programme'"); - $currentDate = (strtotime($currentDate) > strtotime(date("Y-m-d"))) ? date("Y-m-d") : $currentDate; - $newDate = strtotime($currentDate) + ($deleteoffset * 24 * 60 * 60); - $formattedNewDate = date('Y-m-d', $newDate); - echo 'epg_programme dates:' . $currentDate . ' <- ' . $formattedNewDate . '
'; - $channel->exec("delete from `epg_programme` where sdate < '{$formattedNewDate}';"); - echo 'Delete ' . $channel->changes() . ' records from epg_programme
'; - if ($empty_tmp == 1) - { - // 娓呯┖涓存椂琛 - $channel->exec("delete from tmp_epg_channel"); - $channel->exec("delete from tmp_epg_programme"); - } - } - else - { - echo "none."; - } -} -$executionTime = number_format(microtime(true) - $start, 4); -$channel->exec("INSERT INTO access_log (ip_address,access_time,url) VALUES ('xml2db_cost','{$time}','{$executionTime}');"); -// 鍐欏叆纭洏 -$channel->exec("COMMIT;"); -$channel->close(); -echo 'fetch xml epg data total cost ' . $executionTime . ' s.'; - -?>