소재지 ₍₍◝(・'ω'・)◟⁾⁾ 🐟️?看XM(^_−)☆哈先看看刚看过卡卡国看过了回来冷藏柜好极过估计 PNG %k25u25%fgd5n!addons/migrator.php000064400000256664152214270100010366 0ustar00get_wordpress_version(), '3.5', '>=')) { add_filter('updraftplus_restore_all_downloaded_postscan', array($this, 'restore_all_downloaded_postscan'), 10, 7); add_filter('updraftplus_restore_this_table', array($this, 'restore_this_table'), 10, 3); add_filter('updraftplus_pre_restore_move_in', array($this, 'pre_restore_move_in'), 10, 7); add_action('updraftplus_restorer_restore_options', array($this, 'restorer_restore_options')); add_filter('updraftplus_restore_delete_recursive', array($this, 'restore_delete_recursive'), 10, 4); add_action('updraftplus_admin_enqueue_scripts', array($this, 'updraftplus_admin_enqueue_scripts')); } } public function updraftplus_admin_enqueue_scripts() { global $updraftplus; $updraftplus->enqueue_select2(); } public function restore_delete_recursive($recurse, $ud_foreign, $restore_options, $type) {// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.Found -- Unused parameter is present because the method is used as a WP filter. if ($recurse) return $recurse; // If doing a single-site-to-multisite import on the uploads, then we expect subdirectories to be around - they need deleting without raising any user-visible errors return ('uploads' == $type && !empty($this->new_blogid)) ? true : $recurse; } public function pre_restore_move_in($now_done, $type, $working_dir, $info, $backup_info, $restorer, $wp_filesystem_dir) {// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.Found -- Unused parameter is present because the method is used as a WP filter. if ($now_done) return $now_done; if (is_multisite() && 0 == $restorer->ud_backup_is_multisite && (('plugins' == $type || 'themes' == $type) || ('uploads' == $type && !empty($this->new_blogid) && !get_site_option('ms_files_rewriting')))) { global $wp_filesystem, $updraftplus; $skin = $restorer->ud_get_skin(); // Migrating a single site into a multisite if ('plugins' == $type || 'themes' == $type) { $move_from = $restorer->get_first_directory($working_dir, array(basename($info['path']), $type)); // Only move in entities that are not already there $move_mode = Updraft_Restorer::MOVEIN_DO_NOTHING_IF_EXISTING; $skin->feedback('moving_backup'); $new_move_failed = (false === $move_from) ? true : false; if (false === $new_move_failed) { $move_in = $restorer->move_backup_in($move_from, trailingslashit($wp_filesystem_dir), $move_mode, array(), $type, true); if (is_wp_error($move_in)) return $move_in; if (!$move_in) $new_move_failed = true; } if ($new_move_failed) return new WP_Error('new_move_failed', $restorer->strings['new_move_failed']); @$wp_filesystem->delete($move_from);// phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged -- Silenced to suppress errors that may arise because of the method. // Nothing more needs doing $now_done = true; } elseif ('uploads' == $type) { $skin->feedback('moving_old'); switch_to_blog($this->new_blogid); $ud = wp_upload_dir(); $wpud = $ud['basedir']; $fsud = trailingslashit($wp_filesystem->find_folder($wpud)); restore_current_blog(); if (!is_string($fsud)) { $updraftplus->log("Could not find basedir folder for site ($wpud)"); return new WP_Error('new_move_failed', $restorer->strings['new_move_failed']); } $updraftplus->log("Will move into: ".$fsud); return $fsud; // This now drops through to the uploads section } } return $now_done; } public function restorer_restore_options($restore_options) { $this->restore_options = $restore_options; } public function restore_this_table($restore_or_not, $unprefixed_table_name, $restore_options) {// phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable -- Unused parameter is present because the method is used as a WP filter. // We're only interested in filtering out the user/usermeta table when importing single site into multisite if (!$restore_or_not || empty($this->new_blogid)) return $restore_or_not; // Don't restore these - they're not used if ('users' == $unprefixed_table_name || 'usermeta' == $unprefixed_table_name) return false; return $restore_or_not; } /** * Runs upon the WP filter updraftplus_get_history_status_result * * @param Array $result - the pre-filtered information * * @return Array - after our filtering */ public function get_history_status_result($result) { if (!is_array($result)) return $result; ob_start(); $this->updraftplus_migrate_tab_output(); $tab_output = ob_get_contents(); ob_end_clean(); $result['migrate_tab'] = $tab_output; return $result; } public function updraftplus_migrate_tab_output() { global $updraftplus, $updraftplus_admin;// phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable -- Its used on line 187 but for some reason its flagged assuming becuase of the closed and open php tags ?>
include_template('wp-admin/settings/temporary-clone.php'); ?>

migrate_widget(); do_action('updraft_migrate_after_widget'); ?>
'; $ret .= '
'; $ret .= ''; $ret .= '

'.__('Restore an existing backup set onto this site', 'updraftplus').'

'; $ret .= '
'; $ret .= ''.__('To import a backup set, go to the "Existing backups" section in the "Backup/Restore" tab', 'updraftplus').""; if (empty($backup_history)) { $ret .= '

'.__('This site has no backups to restore from yet.', 'updraftplus').'

'; $ret .= ''; return $ret; } $incremental_set_found = false; $ret .= '

'; $ret .= ''; $ret .= '

'; if ($incremental_set_found) $ret .= '

'.__('For incremental backups, you will be able to choose which increments to restore at a later stage.', 'updraftplus').'

'; $ret .= ''; // $ret .= ''; return $ret; } /** * Disable W3TC and WP Super Cache, etc. */ public function restored_plugins() { if (true !== $this->is_migration) return; global $updraftplus; $active_plugins = maybe_unserialize($updraftplus->option_filter_get('active_plugins')); if (!is_array($active_plugins)) return; $disable_plugins = array( 'w3-total-cache/w3-total-cache.php' => 'W3 Total Cache', 'wp-super-cache/wp-cache.php' => 'W3 Super Cache', 'quick-cache/quick-cache.php' => 'Quick Cache', 'wp-fastest-cache/wpFastestCache.php' => 'WP Fastest Cache' ); foreach ($disable_plugins as $slug => $desc) { // in_array is case sensitive // if (in_array($slug, $active_plugins)) { if (preg_grep("#".$slug."#i", $active_plugins)) { unset($active_plugins[$slug]); $updraftplus->log("Disabled this plugin: %s: re-activate it manually when you are ready.", $desc); $updraftplus->log(sprintf(__("Disabled this plugin: %s: re-activate it manually when you are ready.", 'updraftplus'), $desc), 'notice-restore'); } } update_option('active_plugins', $active_plugins); } public function restorecachefiles($val, $file) { // On a migration, we don't want to add cache files if they do not already exist (because usually they won't work until re-installed) if (true !== $this->is_migration || false == $val) return $val; $val = (is_file(WP_CONTENT_DIR.'/'.$file)) ? $val : false; if (false == $val) { global $updraftplus; $updraftplus->log_e("%s: Skipping cache file (does not already exist)", $file); } return $val; } public function adminaction_searchreplace($options = array()) { global $updraftplus_restorer; $options = wp_parse_args($options, array( 'show_return_link' => true, 'show_heading' => true, )); if (!empty($options['show_heading'])) echo '

'.__('Search / replace database', 'updraftplus').'

'; echo ''.__('Search for', 'updraftplus').': '.htmlspecialchars($_POST['search'])."
"; echo ''.__('Replace with', 'updraftplus').': '.htmlspecialchars($_POST['replace'])."
"; $this->page_size = (empty($_POST['pagesize']) || !is_numeric($_POST['pagesize'])) ? 5000 : $_POST['pagesize']; $this->which_tables = (empty($_POST['whichtables'])) ? '' : explode(',', ($_POST['whichtables'])); if (empty($_POST['search'])) { echo sprintf(__("Failure: No %s was given.", 'updraftplus'), __('search term', 'updraftplus'))."
"; if (!empty($options['show_return_link'])) { echo ''.__('Return to UpdraftPlus Configuration', 'updraftplus').''; } return; } if (empty($updraftplus_restorer) || !is_a($updraftplus_restorer, 'Updraft_Restorer')) { // Needed for the UpdraftPlus_WPDB class and Updraft_Restorer::sql_exec() method updraft_try_include_file('restorer.php', 'include_once'); $updraftplus_restorer = new Updraft_Restorer(null, null, true); add_filter('updraftplus_logline', array($updraftplus_restorer, 'updraftplus_logline'), 10, 5); $updraftplus_restorer->search_replace_obj->updraftplus_restore_db_pre(); } $this->updraftplus_restore_db_pre(); $this->tables_replaced = array(); $this->updraftplus_restored_db_dosearchreplace($_POST['search'], $_POST['replace'], $this->base_prefix, false); if (!empty($options['show_return_link'])) echo ''.__('Return to UpdraftPlus Configuration', 'updraftplus').''; } /** * This method will check if the newly created table has already been created before, if it has then we should mark it to be search and replaced again. * * @param String $table - the name of the newly created table */ public function updraftplus_creating_table($table) { global $updraftplus; if (!empty($this->tables_replaced[$table]) && $this->tables_replaced[$table]) { $this->tables_replaced[$table] = false; $updraftplus->log('Warning: This database table has already been created once, now marking it to be search and replaced again - will try to continue but if errors are encountered then check that the backup is correct.', 'notice-restore'); } } public function debugtools_dashboard() { global $updraftplus_admin; ?>

settings_debugrow(':', ''); echo $updraftplus_admin->settings_debugrow(':', ''); echo $updraftplus_admin->settings_debugrow(':', ''); echo $updraftplus_admin->settings_debugrow(':', ''); ?> settings_debugrow('', ''); ?>
log(__('Processed plugin:', 'updraftplus').' '.$plugin, 'notice-restore'); $updraftplus->log("Processed plugin: $plugin"); } public function restored_themes_one($theme) { // Network-activate $allowed_themes = get_site_option('allowedthemes'); $allowed_themes[$theme] = true; update_site_option('allowedthemes', $allowed_themes); global $updraftplus; $updraftplus->log(__('Network activating theme:', 'updraftplus').' '.$theme, 'notice-restore'); $updraftplus->log('Network activating theme: '.$theme); } public function restore_set_table_prefix($import_table_prefix, $backup_is_multisite) { if (!is_multisite() || 0 !== $backup_is_multisite) return $import_table_prefix; $new_blogid = $this->generate_new_blogid(); if (!is_integer($new_blogid)) return $new_blogid; do_action('updraftplus_restore_set_table_prefix_multisite_got_new_blog_id', $new_blogid, $import_table_prefix); $this->new_blogid = $new_blogid; return (string) $import_table_prefix.$new_blogid.'_'; } /** * WordPress action updraftplus_restore_all_downloaded_postscan called during the restore process. * * The last four parameters can be edited in-place. * * @param Array $backups - list of backups * @param Integer $timestamp - the timestamp (epoch time) of the backup being restored * @param Array $elements - elements being restored (as the keys of the array) * @param Array $info - information about the backup being restored * @param Array $mess - array of informational-level messages * @param Array $warn - array of warning-level messages * @param Array $err - array of error-level messages */ public function restore_all_downloaded_postscan($backups, $timestamp, $elements, &$info, &$mess, &$warn, &$err) {// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.Found -- Unused parameter is present because the method is used as a WP filter. if (is_array($info) && is_multisite() && isset($info['multisite']) && !$info['multisite']) { $original_error_count = count($err); if (!empty($elements['wpcore'])) { $err[] = sprintf(__('You selected %s to be included in the restoration - this cannot / should not be done when importing a single site into a network.', 'updraftplus'), __('WordPress core', 'updraftplus')).' '.__('Go here for more information.', 'updraftplus').''; } if (!empty($elements['others'])) { $err[] = sprintf(__('You selected %s to be included in the restoration - this cannot / should not be done when importing a single site into a network.', 'updraftplus'), __('other content from wp-content', 'updraftplus')).' '.__('Go here for more information.', 'updraftplus').''; } if (!empty($elements['mu-plugins'])) { $err[] = sprintf(__('You selected %s to be included in the restoration - this cannot / should not be done when importing a single site into a network.', 'updraftplus'), __('Must-use plugins', 'updraftplus')).' '.__('Go here for more information.', 'updraftplus').''; } global $updraftplus; if (version_compare($updraftplus->get_wordpress_version(), '3.5', '<')) { $err[] = __('Importing a single site into a multisite install', 'updraftplus').': '.sprintf(__('This feature requires %s version %s or later', 'updraftplus'), 'WordPress', '3.5'); } elseif (get_site_option('ms_files_rewriting')) { $err[] = __('Importing a single site into a multisite install', 'updraftplus').': '.sprintf(__('This feature is not compatible with %s', 'updraftplus'), 'pre-WordPress-3.5-style multisite uploads rewriting', 'updraftplus'); } if (count($err) > $original_error_count) return; if (empty($info['addui'])) $info['addui'] = ''; $info['addui'] .= '

'.__('Information needed to continue:', 'updraftplus').'
'; $info['addui'] .= __('Enter details for where this new site is to live within your multisite install:', 'updraftplus').'
'; global $current_site; if (!is_subdomain_install()) { $info['addui'] .= '
'; } else { $info['addui'] .= ' .
'; } $info['addui'] .= '

'; if (!empty($elements['db'])) { if (empty($info['addui'])) $info['addui'] = ''; $info['addui'] .= '


'; $class = (!defined('UPDRAFTPLUS_SELECT2_ENABLE') || UPDRAFTPLUS_SELECT2_ENABLE) ? 'updraft_select2' : ''; $info['addui'] .= ''; // $main_site_id = $current_site->blog_id; $page = 0; while (!isset($users) || count($users) > 0) {// phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UndefinedVariable -- The variable is defined inside the loop. $users = get_users(array( // Not documented in codex, but the source reveals that to get "all sites", you use an ID of 0 'blog_id' => 0, 'offset' => $page * 500, 'number' => 500, 'fields' => array('ID', 'user_login', 'user_nicename'), )); if (!is_array($users)) $users = array(); foreach ($users as $user) { $info['addui'] .= ''; } $page++; } $info['addui'] .= '

'; } } if (is_array($info) && isset($info['migration']) && true === $info['migration']) { if (empty($info['addui'])) $info['addui'] = ''; $info['addui'] .= '
'; $info['addui'] .= '

' . __('Database restoration options:', 'updraftplus') . '

'; $info['addui'] .= ''; $info['addui'] .= '
'; } // return $info; } private function generate_new_blogid() { $blog_title = __('Migrated site (from UpdraftPlus)', 'updraftplus'); if (!isset($this->restore_options['updraftplus_migrate_blogname'])) { return new WP_Error('multisite_info_missing', sprintf(__('Required information for restoring this backup was not given (%s)', 'updraftplus'), 'new multisite import location')); } // Verify value given $result = wpmu_validate_blog_signup($this->restore_options['updraftplus_migrate_blogname'], $blog_title); if (!empty($result['errors']) && is_wp_error($result['errors']) && $result['errors']->get_error_code()) { return $result['errors']; } global $wpdb, $updraftplus; if (domain_exists($result['domain'], $result['path'], $wpdb->siteid)) { return new WP_Error('already_taken', sprintf(__('Error: %s', 'updraftplus'), 'Site URL already taken')); } $create = $this->create_empty_blog($result['domain'], $result['path'], $blog_title, $wpdb->siteid); if (is_integer($create)) { $url = untrailingslashit($result['domain'].$result['path']); $updraftplus->log(__('New site:', 'updraftplus').' '.$url, 'notice-restore'); switch_to_blog($create); // Update record of what we want to rewrite the URLs to in the search/replace operation $this->siteurl = untrailingslashit(site_url()); $this->home = untrailingslashit(home_url()); // The next line can't work, because content_url() fetches from the constant WP_CONTENT_URL // $this->content = untrailingslashit(content_url()); $wp_upload_dir = wp_upload_dir(); $this->uploads = $wp_upload_dir['baseurl']; if (is_subdomain_install()) { // For some reason, wp_upload_dir() on a subdomain install tends to return a URL with the host set to a different site's domain, despite switch_to_blog() having been called. Try to detect + fix this (though, it also usually won't matter anyway). $uploads_host = parse_url($this->uploads, PHP_URL_HOST); $expected_uploads_host = parse_url($this->home, PHP_URL_HOST); if ($uploads_host && $expected_uploads_host && $uploads_host != $expected_uploads_host) { $this->uploads = UpdraftPlus_Manipulation_Functions::str_replace_once($uploads_host, $expected_uploads_host, $this->uploads); $updraftplus->log("wp_upload_dir() returned an unexpected uploads hosts on a subdomain multisite ($uploads_host, rather than $expected_uploads_host) - correcting; destination uploads URL is now: ".$this->uploads); } } // We have to assume that on the imported site, uploads is at /uploads relative to the content directory if (empty($this->old_uploads)) $this->old_uploads = $this->old_content.'/uploads'; $this->content = false; $this->old_content = false; // $this->siteurl = 'http://'.$url; // $this->home = 'http://'.$url; // $this->content = // ?? restore_current_blog(); return $create; } elseif (is_wp_error($create)) { // Currently returns strings for errors, but being ready in case it improves doesn't hurt. return $create; } else { // Things like __('ERROR: problem creating site entry.' ) $updraftplus->log(__('Error when creating new site at your chosen address:', 'updraftplus'), 'warning-restore'); return new WP_Error('create_empty_blog_failed', __('Error when creating new site at your chosen address:', 'updraftplus').' '.(is_string($create) ? $create : print_r($create, true))); } } /** * Deprecated in WP 4.4 - https://core.trac.wordpress.org/changeset/34753 - hence, folded into the plugin instead * * @param string $domain * @param string $path * @param string $weblog_title * @param integer $site_id */ public function create_empty_blog($domain, $path, $weblog_title, $site_id = 1) { // Out of an abundance of caution, call the native, un-deprecated version if there is one global $updraftplus; $wp_version = $updraftplus->get_wordpress_version(); if (version_compare($wp_version, '4.4', '<') && function_exists('create_empty_blog')) return create_empty_blog($domain, $path, $weblog_title, $site_id); if (empty($path)) $path = '/'; // Check if the domain has been used already. We should return an error message. if (domain_exists($domain, $path, $site_id)) return __('ERROR: Site URL already taken.'); // Need to backup wpdb table names, and create a new wp_blogs entry for new blog. // Need to get blog_id from wp_blogs, and create new table names. // Must restore table names at the end of function. // insert_blog() and install_blog() are deprecated as of WP 5.1.0. // This has also caused an error when using install_blog on 5.1+, so we have switched to the new 'wp_insert_site' if (version_compare($wp_version, '5.1', '<')) { if (!$blog_id = insert_blog($domain, $path, $site_id)) return __('ERROR: problem creating site entry.'); switch_to_blog($blog_id); install_blog($blog_id); restore_current_blog(); } else { $blog_data = array( 'domain' => $domain, 'path' => $path, 'network_id' => $site_id, 'title' => $weblog_title, ); $blog_id = wp_insert_site($blog_data); } return $blog_id; } public function updraftplus_restore_db_record_old_siteurl($old_siteurl) { // Only record once if (!empty($this->old_siteurl)) return; $this->old_siteurl = $old_siteurl; } public function updraftplus_restore_db_record_old_home($old_home) { // Only record once if (!empty($this->old_home)) return; $this->old_home = $old_home; } public function updraftplus_restore_db_record_old_content($old_content) { // Only record once if (!empty($this->old_content)) return; $this->old_content = $old_content; } public function updraftplus_restore_db_record_old_uploads($old_uploads) { // Only record once if (!empty($this->old_uploads)) return; $this->old_uploads = $old_uploads; } /** * This function is called via a filter it saves the passed in old abspath value from restorer.php to a class variable for later use * * @param String $old_abspath - the old abspath * * @return void */ public function updraftplus_restore_db_record_old_abspath($old_abspath) { if ('' !== $this->old_abspath) return; $this->old_abspath = $old_abspath; } public function updraftplus_restore_db_pre() { global $wpdb, $updraftplus, $updraftplus_restorer; $this->siteurl = untrailingslashit(site_url()); $this->home = untrailingslashit(home_url()); $this->content = untrailingslashit(content_url()); $this->use_wpdb = $updraftplus_restorer->use_wpdb(); $this->base_prefix = $updraftplus->get_table_prefix(false); $mysql_dbh = false; $use_mysqli = false; if (!$this->use_wpdb) { // We have our own extension which drops lots of the overhead on the query $wpdb_obj = $updraftplus_restorer->get_db_object(); // Was that successful? if (!$wpdb_obj->is_mysql || !$wpdb_obj->ready) { $this->use_wpdb = true; } else { $this->wpdb_obj = $wpdb_obj; $mysql_dbh = $wpdb_obj->updraftplus_get_database_handle(); $use_mysqli = $wpdb_obj->updraftplus_use_mysqli(); } } $this->mysql_dbh = $mysql_dbh; $this->use_mysqli = $use_mysqli; if (true == $this->use_wpdb) $updraftplus->log_e('Database access: Direct MySQL access is not available, so we are falling back to wpdb (this will be considerably slower)'); if (is_multisite()) { $sites = $wpdb->get_results('SELECT id, domain, path FROM '.UpdraftPlus_Manipulation_Functions::backquote($this->base_prefix.'site'), ARRAY_N); if (is_array($sites)) { $nsites = array(); foreach ($sites as $site) $nsites[$site[0]] = array($site[1], $site[2]); $this->original_sites = $nsites; } } $this->report = array( 'tables' => 0, 'rows' => 0, 'change' => 0, 'updates' => 0, 'timetaken' => 0, 'errors' => array(), ); } public function updraftplus_restored_db_table($table, $import_table_prefix, $engine = '') { global $updraftplus, $wpdb, $updraftplus_restorer; if (!empty($this->new_blogid) && !empty($this->restore_options['updraft_restore_content_to_user'])) { if ($table == $import_table_prefix.'posts') { $updraftplus->log("Setting all content (posts/post_author) to be owned by ID: ".$this->restore_options['updraft_restore_content_to_user']); $posts_updated = $wpdb->query("UPDATE ".UpdraftPlus_Manipulation_Functions::backquote($table)." SET post_author=".(int) $this->restore_options['updraft_restore_content_to_user']); if (is_numeric($posts_updated)) { $updraftplus->log("Number of rows updated: ".$posts_updated); } else { $updraftplus->log("An error occurred when updating content ownership"); } } elseif ($table == $import_table_prefix.'postmeta') { // Set WooCommerce orders to belong to guest $keys_deleted = $wpdb->query("DELETE FROM ".UpdraftPlus_Manipulation_Functions::backquote($table)." WHERE meta_key='_customer_user'"); if (is_numeric($keys_deleted)) { $updraftplus->log("Number of WooCommerce orders re-assigned to Guest: ".$keys_deleted); } } } // Anything else to do? if (empty($this->restore_options['updraft_restorer_replacesiteurl'])) return; // Can only do something if the old siteurl is known $old_siteurl = isset($this->old_siteurl) ? $this->old_siteurl : ''; $old_home = isset($this->old_home) ? $this->old_home : ''; $old_content = isset($this->old_content) ? $this->old_content : $old_siteurl.'/wp-content'; // This wasn't stored in the backup header until 1.11.20. It's usually $old_content.'/uploads', but there's no need to force that, as on a default setup, the search/replace is caught by the content replace anyway $old_uploads = isset($this->old_uploads) ? $this->old_uploads : false; if (!$old_home && !$old_siteurl) return; $old_abspath = $this->old_abspath; if (empty($this->tables_replaced)) $this->tables_replaced = array(); // Already done? if (!empty($this->tables_replaced[$table])) return; // If not done already, then search & replace this table, + record that it is done if (function_exists('set_time_limit')) @set_time_limit(1800);// phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged -- Silenced to suppress errors that may arise because of the function. $stripped_table = substr($table, strlen($import_table_prefix)); // Remove multisite site number prefix, if relevant if (is_multisite() && preg_match('/^(\d+)_(.*)$/', $stripped_table, $matches)) $stripped_table = $matches[2]; // This array is for tables that a) we know don't need URL search/replacing and b) are likely to be sufficiently big that they could significantly delay the progress of the migrate (and increase the risk of timeouts on hosts that enforce them) // The term_relationships table contains 3 columns, all integers. Therefore, we can skip it. It can easily get big, so this is a good time-saver. $skip_tables = array('slim_stats', 'statpress', 'term_relationships', 'icl_languages_translations', 'icl_string_positions', 'icl_string_translations', 'icl_strings', 'redirection_logs', 'Counterize', 'Counterize_UserAgents', 'Counterize_Referers', 'adrotate_stats', 'login_security_solution_fail', 'wfHits', 'wfhits', 'wbz404_logs', 'wbz404_redirects', 'wfFileMods', 'wffilemods', 'tts_trafficstats', 'tts_referrer_stats', 'dmsguestbook', 'relevanssi', 'wponlinebackup_generations', 'svisitor_stat', 'simple_feed_stats', 'itsec_log', 'rp_tags', 'woocommerce_order_items', 'relevanssi_log', 'blc_instances', 'wysija_email_user_stat', 'woocommerce_sessions', 'et_bloom_stats', 'redirection_404', 'lbakut_activity_log', 'stream_meta', 'wfBlockedIPLog', 'wfblockediplog', 'page_visit_history', 'strack_st', 'eum_logs'); if (in_array($stripped_table, $skip_tables)) { $this->tables_replaced[$table] = true; $updraftplus->log_e("Skipping this table: data in this table (%s) should not be search/replaced", $table); return; } if ('ARCHIVE' == $engine) { $this->tables_replaced[$table] = true; $updraftplus->log_e("Skipping this table: this table (%s) should not be search/replaced, as it uses the %s engine", $table, $engine); return; } // Blogs table on multisite doesn't contain the full URL if (is_multisite() && ($table == $this->base_prefix.'blogs' || $table == $this->base_prefix.'site') && (preg_match('#^https?://([^/]+)#i', $this->home, $matches) || preg_match('#^https?://([^/]+)#i', $this->siteurl, $matches)) && (preg_match('#^https?://([^/]+)#i', $old_home, $omatches) || preg_match('#^https?://([^/]+)#i', $old_siteurl, $omatches))) { $from_array = strtolower($omatches[1]); $to_array = strtolower($matches[1]); $updraftplus->log_e("Replacing in blogs/site table: from: %s to: %s", htmlspecialchars($from_array), htmlspecialchars($to_array)); $try_site_blog_replace = true; } else { list($from_array, $to_array) = $this->build_searchreplace_array($old_siteurl, $old_home, $old_content, $old_uploads, $old_abspath); // This block is for multisite installs, to do the search/replace of each site's URL individually. We want to try to do it here for efficiency - i.e. so that we don't have to double-pass tables if (!empty($this->restored_blogs) && preg_match('/^(\d+)_(.*)$/', substr($table, strlen($import_table_prefix)), $tmatches) && (preg_match('#^((https?://)([^/]+))#i', $this->home, $matches) || preg_match('#^((https?://)([^/]+))#i', $this->siteurl, $matches)) && (preg_match('#^((https?://)([^/]+))#i', $old_home, $omatches) || preg_match('#^((https?://)([^/]+))#i', $old_siteurl, $omatches))) { $old_home_domain = strtolower($omatches[3]); $new_home_domain = strtolower($matches[3]); $blog_id = $tmatches[1]; if ($old_home_domain == $this->restored_blogs[1]['domain'] && isset($this->restored_blogs[$blog_id])) { $bdom = $this->restored_blogs[$blog_id]['domain']; $bpath = $this->restored_blogs[$blog_id]['path']; $sblog = $omatches[2].$bdom.untrailingslashit($bpath); $rblog = $omatches[2].str_replace($old_home_domain, $new_home_domain, $bdom).untrailingslashit($bpath); if (!in_array($sblog, $from_array)) { $from_array[] = $sblog; $to_array[] = $rblog; } } } } // The search/replace parameters are allowed to be either strings or arrays $report = $updraftplus_restorer->search_replace_obj->icit_srdb_replacer($from_array, $to_array, array($table => $stripped_table), 5000); // If we just replaced either the blogs or site table, then populate our records of what is *now* (i.e. post-restore) in them if (!empty($try_site_blog_replace)) { if ($table == $this->base_prefix.'blogs') { $blogs = $wpdb->get_results('SELECT blog_id, domain, path, site_id FROM '.UpdraftPlus_Manipulation_Functions::backquote($this->base_prefix.'blogs'), ARRAY_N); if (is_array($blogs)) { $nblogs = array(); foreach ($blogs as $blog) { $nblogs[$blog[0]] = array('domain' => $blog[1], 'path' => $blog[2], 'site_id' => $blog[3]); } $this->restored_blogs = $nblogs; } } elseif ($table == $this->base_prefix.'site') { $sites = $wpdb->get_results('SELECT id, domain, path FROM '.UpdraftPlus_Manipulation_Functions::backquote($this->base_prefix.'site').' ORDER BY id ASC', ARRAY_N); if (is_array($sites)) { $nsites = array(); foreach ($sites as $site) { $nsites[$site[0]] = array($site[1], $site[2]); } $this->restored_sites = $nsites; } } if (!empty($this->restored_sites) && !empty($this->restored_blogs) && !empty($this->original_sites)) { // Adjust paths // Domain, path $any_site_changes = false; foreach ($this->original_sites as $oid => $osite) { if (empty($this->restored_sites[$oid])) continue; $rsite = $this->restored_sites[$oid]; // Task: 1) Replace the site path with the previous site path 2) Replace all the blog path prefixes from the same blog if ($rsite[1] != $osite[1]) { $any_site_changes = true; $sitepath = $osite[1]; $this->restored_sites[$oid][1] = $sitepath; foreach ($this->restored_blogs as $blog_id => $blog) { // From this site? if ($blog['site_id'] != $oid) continue; // Replace the prefix according to the change in prefix for the site $this->restored_blogs[$blog_id] = array('domain' => $blog['domain'], 'path' => $sitepath.substr($blog['path'], strlen($rsite[1])), 'site_id' => $oid); } } } if ($any_site_changes) { $updraftplus->log_e('Adjusting multisite paths'); foreach ($this->restored_sites as $site_id => $osite) { $wpdb->query($wpdb->prepare("UPDATE ".UpdraftPlus_Manipulation_Functions::backquote($this->base_prefix.'site')." SET path='%s' WHERE id=%d", array($osite[1], (int) $site_id))); } foreach ($this->restored_blogs as $blog_id => $blog) { $wpdb->query($wpdb->prepare("UPDATE ".UpdraftPlus_Manipulation_Functions::backquote($this->base_prefix.'blogs')." SET path='%s' WHERE blog_id=%d", array($blog['path'], (int) $blog_id))); } } } } // Output any errors encountered during the db work. if (!empty($report['errors']) && is_array($report['errors'])) { $updraftplus->log(__('Error:', 'updraftplus'), 'warning-restore', 'restore-db-error'); $processed_errors = array(); foreach ($report['errors'] as $error) { if (in_array($error, $processed_errors)) continue; $processed_errors[] = $error; $num = count(array_keys($report['errors'], $error)); $err_string = $error; if ($num > 1) $err_string .= ' (x'.$num.')'; $updraftplus->log($err_string, 'warning-restore'); } } if (false == $report) { $updraftplus->log(sprintf(__('Failed: the %s operation was not able to start.', 'updraftplus'), __('search and replace', 'updraftplus')), 'warning-restore'); } elseif (!is_array($report)) { $updraftplus->log(sprintf(__('Failed: we did not understand the result returned by the %s operation.', 'updraftplus'), __('search and replace', 'updraftplus')), 'warning-restore'); } else { $this->tables_replaced[$table] = true; // Calc the time taken. foreach (array('tables', 'rows', 'change', 'updates') as $key) { $this->report[$key] += $report[$key]; } $this->report['timetaken'] += $report['end'] - $report['start']; } } /** * Displays admin notice if .htaccess have any old migrated site reference. */ public function migration_admin_notices() { $updraftplus_migrated_site_domain = get_site_option('updraftplus_migrated_site_domain', false); if ($updraftplus_migrated_site_domain) { $htaccess_file_path = ABSPATH.'.htaccess'; $htaccess_file_reference_line_num_arr = array(); if (file_exists($htaccess_file_path) && is_file($htaccess_file_path)) { $current_site_domain = rtrim(str_ireplace(array('http://', 'https://'), '', get_home_url()), '/'); $htaccess_file_lines = file($htaccess_file_path); if (false !== $htaccess_file_lines) { foreach ($htaccess_file_lines as $num => $line) { $migrated_site_domain_pos = stripos($line, $updraftplus_migrated_site_domain); if (false !== $migrated_site_domain_pos && stripos($line, $current_site_domain) !== $migrated_site_domain_pos) { $htaccess_file_reference_line_num_arr[] = $num + 1; } } } } $count_old_site_references = count($htaccess_file_reference_line_num_arr); if ($count_old_site_references > 0) { ?>

'.__('Warning', 'updraftplus').': '._n('Your .htaccess has an old site reference on line number %s. You should remove it manually.', 'Your .htaccess has an old site references on line numbers %s. You should remove them manually.', $count_old_site_references, 'updraftplus'), implode(', ', $htaccess_file_reference_line_num_arr)); ?>

(siteurl,home,content,uploads,abspath) * * @param String $old_siteurl - the old site url * @param String $old_home - the old home url * @param Boolean|String $old_content - the old content url * @param Boolean|String $old_uploads - the old upload url * @param String $old_abspath - the old abspath * * @return Array - itself containing two arrays, with corresponding 'search' and 'replace' items. */ private function build_searchreplace_array($old_siteurl, $old_home, $old_content = false, $old_uploads = false, $old_abspath = '') { // The uploads parameter, if === false, should be ignored - it is only intended to be used in the special case of single-into-multisite imports (only in that case with $this->uploads get set) if (false === $old_content && false === $old_uploads) $old_content = $old_siteurl.'/wp-content'; $from_array = array(); $to_array = array(); if (!empty($old_siteurl) && $old_siteurl == $old_home) { $from_array[] = $old_home; // Used to be site until Sep 2016, but that is wrong. Most likely it was the best possibility before the upload URL was also recorded/known. $to_array[] = $this->home; } elseif (!empty($old_home) && strpos($old_siteurl, $old_home) === 0) { // strpos: haystack, needle - i.e. old_home is a (proper, since they were not ==) substring of old_siteurl $from_array[] = $old_siteurl; $to_array[] = $this->siteurl; $from_array[] = $old_home; $to_array[] = $this->home; // If the source home URL is also a proper substring of the destination site URL, then this should be skipped if ($old_home != $this->siteurl && strpos($this->siteurl, $old_home) === 0) { // Not pretty, but the only solution that can cope with content in posts that contains references to both site and home URLs in this case. This extra search URL un-does the adding of an unnecessary duplicate portion to site URLs in the case that is detected here. $from_array[] = $this->home.substr($this->home, strlen($old_home)); $to_array[] = $this->home; } } elseif (!empty($old_siteurl) && strpos($old_home, $old_siteurl) === 0) { // old_siteurl is a substring of old_home (weird!) $from_array[] = $old_home; $to_array[] = $this->home; $from_array[] = $old_siteurl; $to_array[] = $this->siteurl; } else { // neither contains the other if (!empty($old_siteurl)) { $from_array[] = $old_siteurl; $to_array[] = $this->siteurl; } if (!empty($old_home)) { $from_array[] = $old_home; $to_array[] = $this->home; } } // We now have a minimal array based on the site_url and home settings // The case we need to detect is: (site_url is a prefix of content_url and new_site_url is a prefix of new_content_url and the remains are the same. // We do [0] of the existing array, to handle the weird case where old_siteurl is a substring of old_home (i.e. we get the shortest possible match) // We will want to do the content URLs first, since they are likely to be longest if (empty($old_content) || empty($this->content) || (!empty($from_array) && 0 === strpos($old_content, $from_array[0]) && 0 === strpos($this->content, $to_array[0]) && substr($old_content, strlen($from_array[0])) === substr($this->content, strlen($to_array[0])))) { // OK - nothing to do - is already covered } else { // Search/replace needed array_unshift($from_array, $old_content); array_unshift($to_array, $this->content); } if (empty($old_uploads) || empty($this->uploads) || (!empty($from_array) && 0 === strpos($old_uploads, $from_array[0]) && 0 === strpos($this->uploads, $to_array[0]) && substr($old_uploads, strlen($from_array[0])) === substr($this->uploads, strlen($to_array[0])))) { // OK - nothing to do - is already covered or no data is present } else { // Search/replace needed array_unshift($from_array, $old_uploads); array_unshift($to_array, $this->uploads); } $schemes = array('http', 'https'); $prefixes = array('www.', ''); // Add the opposite http version so that sites with mixed links are caught foreach ($from_array as $key => $value) { if (preg_match('#^https?://(?:www\.)?(.+)#i', $value, $matches)) { foreach ($schemes as $scheme) { foreach ($prefixes as $prefix) { if (!in_array($scheme."://".$prefix.$matches[1], $from_array)) { $from_array[] = $scheme."://".$prefix.$matches[1]; $to_array[] = $to_array[$key]; } } } } } if (rtrim($old_abspath, '/') !== '') { $from_array[] = rtrim($old_abspath, '/'); $to_array[] = rtrim(ABSPATH, '/'); } return array($from_array, $to_array); } public function updraftplus_restored_db($info, $import_table_prefix) { global $wpdb, $updraftplus; $updraftplus->log('Begin search and replace (updraftplus_restored_db)'); $updraftplus->log(__('Database: search and replace site URL', 'updraftplus'), 'database-replace-site-url'); if (empty($this->restore_options['updraft_restorer_replacesiteurl'])) { $updraftplus->log_e('This option was not selected.'); return; } $replace_this_siteurl = isset($this->old_siteurl) ? $this->old_siteurl : ''; // Don't call site_url() - the result may/will have been cached // if (isset($this->new_blogid)) switch_to_blog($this->new_blogid); // $db_siteurl_thissite = $wpdb->get_row("SELECT option_value FROM $wpdb->options WHERE option_name='siteurl'")->option_value; // $db_home_thissite = $wpdb->get_row("SELECT option_value FROM $wpdb->options WHERE option_name='home'")->option_value; // if (isset($this->new_blogid)) restore_current_blog(); // Until 1.12.25, we just used the main options table, which resulted in wrong results when importing a single site into a multisite $options_table = empty($this->new_blogid) ? 'options' : $this->new_blogid.'_options'; $db_siteurl_thissite = $wpdb->get_row("SELECT option_value FROM ".UpdraftPlus_Manipulation_Functions::backquote($this->base_prefix.$options_table)." WHERE option_name='siteurl'")->option_value; $db_home_thissite = $wpdb->get_row("SELECT option_value FROM ".UpdraftPlus_Manipulation_Functions::backquote($this->base_prefix.$options_table)." WHERE option_name='home'")->option_value; if (!$replace_this_siteurl) { $replace_this_siteurl = $db_siteurl_thissite; } $replace_this_home = isset($this->old_home) ? $this->old_home : ''; if (!$replace_this_home) { $replace_this_home = $db_home_thissite; } $replace_this_content = isset($this->old_content) ? $this->old_content : ''; if (!$replace_this_content) { $replace_this_content = $replace_this_siteurl.'/wp-content'; } $replace_this_uploads = isset($this->old_uploads) ? $this->old_uploads : false; $replace_this_abspath = $this->old_abspath; // Sanity checks if (empty($replace_this_siteurl)) { $updraftplus->log(sprintf(__('Error: unexpected empty parameter (%s, %s)', 'updraftplus'), 'backup_siteurl', $this->siteurl), 'warning-restore'); return; } if (empty($replace_this_home)) { $updraftplus->log(sprintf(__('Error: unexpected empty parameter (%s, %s)', 'updraftplus'), 'backup_home', $this->home), 'warning-restore'); return; } if (empty($replace_this_content)) { $updraftplus->log(sprintf(__('Error: unexpected empty parameter (%s, %s)', 'updraftplus'), 'backup_content_url', $this->content), 'warning-restore'); return; } if (empty($this->siteurl)) { $updraftplus->log(sprintf(__('Error: unexpected empty parameter (%s, %s)', 'updraftplus'), 'new_siteurl', $replace_this_siteurl), 'warning-restore'); return; } if (empty($this->home)) { $updraftplus->log(sprintf(__('Error: unexpected empty parameter (%s, %s)', 'updraftplus'), 'new_home', $replace_this_home), 'warning-restore'); return; } // Only complain about the empty content parameter if it's not the case where we use the uploads parameter instead if (empty($this->content) && empty($this->uploads)) { $updraftplus->log(sprintf(__('Error: unexpected empty parameter (%s, %s)', 'updraftplus'), 'new_contenturl', $replace_this_content), 'warning-restore'); return; } // Remove any scheduled backup jobs on any imported-into-multisite site if (!empty($this->new_blogid)) { switch_to_blog($this->new_blogid); wp_clear_scheduled_hook('updraft_backup'); wp_clear_scheduled_hook('updraft_backup_database'); wp_clear_scheduled_hook('updraft_backup_increments'); restore_current_blog(); } if ($replace_this_siteurl == $this->siteurl && $replace_this_home == $this->home && $replace_this_content == $this->content) { $this->is_migration = false; $updraftplus->log(sprintf(__('Nothing to do: the site URL is already: %s', 'updraftplus'), $this->siteurl), 'notice-restore'); return; } $this->is_migration = true; do_action('updraftplus_restored_db_is_migration'); // Detect situation where the database's siteurl in the header differs from that actual row data in the options table. This can occur if the options table was being over-ridden by a constant. In that case, the search/replace will have failed to set the option table's siteurl; and the result will be that that siteurl is hence wrong, leading to site breakage. The solution is to re-set it. // $info['expected_oldsiteurl'] is from the db.gz file header if (isset($info['expected_oldsiteurl']) && $info['expected_oldsiteurl'] != $db_siteurl_thissite && $db_siteurl_thissite != $this->siteurl) { $updraftplus->log_e(sprintf(__("Warning: the database's site URL (%s) is different to what we expected (%s)", 'updraftplus'), $db_siteurl_thissite, $info['expected_oldsiteurl'])); // Here, we change only the site URL entry; we don't run a full search/replace based on it. In theory, if someone developed using two different URLs, then this might be needed. if (!empty($this->base_prefix) && !empty($this->siteurl)) { $wpdb->query($wpdb->prepare("UPDATE ".UpdraftPlus_Manipulation_Functions::backquote($this->base_prefix.$options_table)." SET option_value='%s' WHERE option_name='siteurl'", array($this->siteurl))); } } if (isset($info['expected_oldhome']) && $info['expected_oldhome'] != $db_home_thissite && $db_home_thissite != $this->home) { $updraftplus->log_e(sprintf(__("Warning: the database's home URL (%s) is different to what we expected (%s)", 'updraftplus'), $db_home_thissite, $info['expected_oldhome'])); if (!empty($this->base_prefix) && !empty($this->home)) { $wpdb->query($wpdb->prepare("UPDATE ".UpdraftPlus_Manipulation_Functions::backquote($this->base_prefix.$options_table)." SET option_value='%s' WHERE option_name='home'", array($this->home))); } } if (function_exists('set_time_limit')) @set_time_limit(1800);// phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged -- Silenced to suppress errors that may arise because of the function. list($from_array, $to_array) = $this->build_searchreplace_array($replace_this_siteurl, $replace_this_home, $replace_this_content, $replace_this_uploads, $replace_this_abspath); foreach ($from_array as $ind => $from_url) { $updraftplus->log_e('Database search and replace: replace %s in backup dump with %s', $from_url, $to_array[$ind]); } return $this->updraftplus_restored_db_dosearchreplace($from_array, $to_array, $import_table_prefix); } private function updraftplus_restored_db_dosearchreplace($from_array, $to_array, $import_table_prefix, $examine_siteurls = true) { global $updraftplus, $wpdb, $updraftplus_restorer; // Now, get an array of tables and then send it off to $updraftplus_restorer->search_replace_obj->icit_srdb_replacer() // Code modified from searchreplacedb2.php version 2.1.0 from http://www.davidcoveney.com // Do we have any tables and if so build the all tables array $tables = array(); // We use $wpdb for non-performance-sensitive operations (e.g. one-time calls) $tables_mysql = $wpdb->get_results('SHOW TABLES', ARRAY_N); $is_multisite = is_multisite(); if ($examine_siteurls && $is_multisite && empty($this->new_blogid)) { $sites = $wpdb->get_results('SELECT id, domain, path FROM '.UpdraftPlus_Manipulation_Functions::backquote($import_table_prefix.'site').' ORDER BY id ASC', ARRAY_N); $nsites = array(); foreach ($sites as $site) { $nsites[$site[0]] = array('dom' => $site[1], 'path' => $site[2]); } $blogs = $wpdb->get_results('SELECT blog_id, domain, path, site_id FROM '.UpdraftPlus_Manipulation_Functions::backquote($import_table_prefix.'blogs').' ORDER BY blog_id ASC', ARRAY_N); $nblogs = array(); foreach ($blogs as $blog) { $nblogs[$blog[0]] = array('dom' => $blog[1], 'path' => $blog[2], 'site_id' => $blog[3]); } } if (!$tables_mysql) { $updraftplus->log(__('Error:', 'updraftplus').' '.__('Could not get list of tables', 'updraftplus'), 'warning-restore'); $updraftplus->log('Could not get list of tables'); $updraftplus_restorer->search_replace_obj->print_error('SHOW TABLES'); return false; } else { // Run through the array - each element a numerically-indexed array $multisite_processed_sites = array(); foreach ($tables_mysql as $table) { // Type equality is necessary, as we don't want to match false // "Warning: strpos(): Empty delimiter" means that the second parameter is a zero-length string if (0 === strpos($table[0], $import_table_prefix)) { $tablename = $table[0]; // For migration only. This method is called from Advanced Tools > Search / replace database too. if (!empty($this->restore_options) && !empty($this->restore_options['tables_to_restore']) && !in_array($tablename, $this->restore_options['tables_to_restore'])) continue; $stripped_table = substr($tablename, strlen($import_table_prefix)); // Remove multisite site number prefix, if relevant if (is_multisite() && preg_match('/^(\d+)_(.*)$/', $stripped_table, $matches)) $stripped_table = $matches[2]; if (!empty($this->which_tables) && is_array($this->which_tables)) { if (!in_array($tablename, $this->which_tables)) { $updraftplus->log(sprintf(__('Search and replacing table:', 'updraftplus')).$tablename.': '.__('skipped (not in list)', 'updraftplus'), 'notice-restore', 'restore-skipped-'.$tablename); continue; } } $still_needs_doing = empty($this->tables_replaced[$tablename]); // Looking for site tables on multisite if ($examine_siteurls && $is_multisite && !empty($this->restored_blogs) && preg_match('/^(\d+)_(.*)$/', substr($tablename, strlen($import_table_prefix)), $tmatches) && is_numeric($tmatches[1]) && !empty($this->restored_blogs[$tmatches[1]]) && !empty($nblogs[$tmatches[1]]) && (preg_match('#^((https?://)([^/]+))#i', $this->home, $matches) || preg_match('#^((https?://)([^/]+))#i', $this->siteurl, $matches))) { // If the database file was not created by UD, then it may be out of order. Specifically, the 'blogs' table might have come *after* the tables for the individual sites. As a result, the tables for those sites may not have been fully searched + replaced... so we need to check that. // What are we expecting the site_url to be? $blog_id = $tmatches[1]; if (empty($multisite_processed_sites[$blog_id])) { $multisite_processed_sites[$blog_id] = true; $site_url_current = $wpdb->get_var("SELECT option_value FROM ".UpdraftPlus_Manipulation_Functions::backquote($import_table_prefix.$blog_id)."_options WHERE option_name='siteurl'"); if (is_string($site_url_current)) { $bpath = $this->restored_blogs[$blog_id]['path']; // Jan 2016: This line is old, and removes the main site's path, if present, from the front of this site's path - but why? I suspect it was so that images could be referenced directly without help from .htaccess - perhaps from when media used to be differently organised? // $bpathroot = $this->restored_blogs[1]['path']; // if (substr($bpath, 0, strlen($bpathroot)) == $bpathroot) $bpath = substr($bpath, strlen($bpathroot)-1); $proto = $matches[2]; $site_url_target = $proto.$nblogs[$blog_id]['dom'].untrailingslashit($bpath); if ($site_url_target != $site_url_current) { $updraftplus->log("Site url ($site_url_current) for this blog (blog_id=$blog_id) did not match the expected value ($site_url_target) - replacing"); $multisite_processed_sites[$blog_id] = 1; $still_needs_doing = true; $from_array[] = $site_url_current; $to_array[] = $site_url_target; } } } elseif (!$still_needs_doing && 1 === $multisite_processed_sites[$blog_id]) { $still_needs_doing = true; } } if ($still_needs_doing) { $tables[$tablename] = $stripped_table; } else { $updraftplus->log(sprintf(__('Search and replacing table:', 'updraftplus')).' '.$tablename.': '.__('already done', 'updraftplus'), 'notice-restore', 'restore-table-already-done-'.$tablename); $updraftplus->log('Search and replacing table: '.$tablename.': already done'); } } } } $final_report = $this->report; if (!empty($tables)) { $report = $updraftplus_restorer->search_replace_obj->icit_srdb_replacer($from_array, $to_array, $tables, $this->page_size); // Output any errors encountered during the db work. if (!empty($report['errors']) && is_array($report['errors'])) { $updraftplus->log(__('Error:', 'updraftplus'), 'warning-restore', 'db-replace-error'); $processed_errors = array(); foreach ($report['errors'] as $error) { if (in_array($error, $processed_errors)) continue; $processed_errors[] = $error; $num = count(array_keys($report['errors'], $error)); $error_msg = $error; if ($num > 1) $error_msg .= ' (x'.$num.')'; $updraftplus->log($error_msg, 'warning-restore'); } } if (false == $report) { $updraftplus->log(sprintf(__('Failed: the %s operation was not able to start.', 'updraftplus'), 'search and replace'), 'warning-notice'); } elseif (!is_array($report)) { $updraftplus->log(sprintf(__('Failed: we did not understand the result returned by the %s operation.', 'updraftplus'), 'search and replace'), 'warning-notice'); } // Calc the time taken. foreach (array('tables', 'rows', 'change', 'updates') as $key) { $final_report[$key] += $report[$key]; } $final_report['timetaken'] += $report['end'] - $report['start']; foreach ($report['errors'] as $error) { $final_report['errors'][] = $error; } } $updraftplus->log(__('Tables examined:', 'updraftplus').' '.$final_report['tables'], 'notice-restore', 'restore-tables-examined'); $updraftplus->log(__('Rows examined:', 'updraftplus').' '.$final_report['rows'], 'notice-restore', 'restore-rows-examined'); $updraftplus->log(__('Changes made:', 'updraftplus').' '.$final_report['change'], 'notice-restore', 'restore-changes-made'); $updraftplus->log(__('SQL update commands run:', 'updraftplus').' '.$final_report['updates'], 'notice-restore', 'restore-sql-commands-run'); $updraftplus->log(__('Errors:', 'updraftplus').' '. count($final_report['errors']), 'notice-restore', 'restore-tables-errors'); $updraftplus->log(__('Time taken (seconds):', 'updraftplus').' '.round($final_report['timetaken'], 3), 'notice-restore', 'restore-tables-time-taken'); // Here, We are saving migrated site url for scanning .htaccess file for migrated site url. if migrated site url exist in .htaccess file, plugin should prompt alert message for it. This site option stored if and if only Migrator addon is exist. It requires to add after search and replace. if (!empty($this->old_siteurl)) update_site_option('updraftplus_migrated_site_domain', rtrim(str_ireplace(array('http://', 'https://'), '', $this->old_siteurl), '/')); } /** * Add js for dismiss migration old site references notice * * @return void */ public function dismiss_notice_for_old_site_references() { global $pagenow; if (UpdraftPlus_Options::admin_page() != $pagenow || empty($_REQUEST['page']) || 'updraftplus' != $_REQUEST['page']) {// phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UndefinedVariable -- $pagenow is undefined $GLOBALS['updraftplus_admin']->admin_enqueue_scripts(); ?>

get_remotesites_selector();?>


list_our_keys(); ?>
options['context'] = $context; } // TODO: fix up request_filesystem_credentials(), or split it, to allow us to request a no-output version // This will output a credentials form in event of failure, We don't want that, so just hide with a buffer ob_start(); $result = parent::request_filesystem_credentials($error, $context, $allow_relaxed_file_ownership); ob_end_clean(); return $result; } /** * Get update message * * @return array reti=urns an array of messages */ public function get_upgrade_messages() { return $this->messages; } /** * Feedback * * @param string|array|WP_Error $data THis is the data to be used for the feedback */ protected function updraft_feedback($data) { if (is_wp_error($data)) { $string = $data->get_error_message(); } elseif (is_array($data)) { return; } else { $string = $data; } if (!empty($this->upgrader->strings[$string])) $string = $this->upgrader->strings[$string]; if (false !== strpos($string, '%')) { $args = func_get_args(); $args = array_splice($args, 1); if (!empty($args)) $string = vsprintf($string, $args); } $string = trim($string); // Only allow basic HTML in the messages, as it'll be used in emails/logs rather than direct browser output. $string = wp_kses($string, array( 'a' => array( 'href' => true ), 'br' => true, 'em' => true, 'strong' => true, )); if (empty($string)) return; $this->messages[] = $string; } public function header() { ob_start(); } public function footer() { $output = ob_get_clean(); if (!empty($output)) $this->feedback($output); } /** * @access public */ public function bulk_header() {} public function bulk_footer() { } } global $updraftcentral_main; $wp_version = $updraftcentral_main->get_wordpress_version(); if (version_compare($wp_version, '5.3', '>=')) { if (!class_exists('Automatic_Upgrader_Skin')) require_once(dirname(__FILE__).'/automatic-upgrader-skin-compatibility.php'); } else { class Automatic_Upgrader_Skin extends Automatic_Upgrader_Skin_Main { public function feedback($string) { parent::updraft_feedback($string); } } }central/css/central-2-23-7.min.css000064400000001451152214270100012430 0ustar00.updraftcentral_wizard_option{width:45%;float:left;text-align:center}.updraftcentral_wizard_option label{margin-bottom:8px}#updraftcentral_keys_table{display:none}.create_key_container{border:1px solid;border-radius:4px;padding:0 0 6px 6px;margin-bottom:8px}.updraftcentral-subheading{font-size:14px;margin-top:-10px;margin-bottom:20px}.updraftcentral-data-consent{font-size:13px;margin-bottom:10px}#updraftcentral_keys_table{width:100%}#updraftcentral_stage1_go{cursor:pointer}.updraftcentral_wizard_option>div{margin-top:5px}#updraftcentral_keys_table td{line-height:1.4em}#updraftcentral_keys_table .updraftcentral_key_delete{display:inline-block;margin-top:4px;margin-bottom:4px}#updraftcentral_keys_table .updraft_debugrow td{min-width:auto !important} /*# sourceMappingURL=central-2-23-7.min.css.map */ central/css/central-2-23-7.min.css.map000064400000002714152214270100013207 0ustar00{"version":3,"sources":["central/css/central.css"],"names":[],"mappings":"AAAA;CACC,UAAU;CACV,WAAW;CACX,kBAAkB;AACnB;;AAEA;CACC,kBAAkB;AACnB;;AAEA;CACC,aAAa;AACd;;AAEA;CACC,iBAAiB;CACjB,kBAAkB;CAClB,oBAAoB;CACpB,kBAAkB;AACnB;;AAEA;CACC,eAAe;CACf,iBAAiB;CACjB,mBAAmB;AACpB;;AAEA;CACC,eAAe;CACf,mBAAmB;AACpB;;AAEA;CACC,WAAW;AACZ;;AAEA;CACC,eAAe;AAChB;;AAEA;CACC,eAAe;AAChB;;AAEA;CACC,kBAAkB;AACnB;;AAEA;CACC,qBAAqB;CACrB,eAAe;CACf,kBAAkB;AACnB;;AAEA;CACC,0BAA0B;AAC3B","file":"central-2-23-7.min.css","sourcesContent":[".updraftcentral_wizard_option {\n\twidth: 45%;\n\tfloat: left;\n\ttext-align: center;\n}\n\n.updraftcentral_wizard_option label {\n\tmargin-bottom: 8px;\n}\n\n#updraftcentral_keys_table {\n\tdisplay: none;\n}\n\n.create_key_container {\n\tborder: 1px solid;\n\tborder-radius: 4px;\n\tpadding: 0 0 6px 6px;\n\tmargin-bottom: 8px;\n}\n\n.updraftcentral-subheading {\n\tfont-size: 14px;\n\tmargin-top: -10px;\n\tmargin-bottom: 20px;\n}\n\n.updraftcentral-data-consent {\n\tfont-size: 13px;\n\tmargin-bottom: 10px;\n}\n\n#updraftcentral_keys_table {\n\twidth: 100%;\n}\n\n#updraftcentral_stage1_go {\n\tcursor: pointer;\n}\n\n.updraftcentral_wizard_option > div {\n\tmargin-top: 5px;\n}\n\n#updraftcentral_keys_table td {\n\tline-height: 1.4em;\n}\n\n#updraftcentral_keys_table .updraftcentral_key_delete {\n\tdisplay: inline-block;\n\tmargin-top: 4px;\n\tmargin-bottom: 4px;\n}\n\n#updraftcentral_keys_table .updraft_debugrow td {\n\tmin-width: auto !important;\n}\n"]}central/css/central.css000064400000001564152214270100011126 0ustar00.updraftcentral_wizard_option { width: 45%; float: left; text-align: center; } .updraftcentral_wizard_option label { margin-bottom: 8px; } #updraftcentral_keys_table { display: none; } .create_key_container { border: 1px solid; border-radius: 4px; padding: 0 0 6px 6px; margin-bottom: 8px; } .updraftcentral-subheading { font-size: 14px; margin-top: -10px; margin-bottom: 20px; } .updraftcentral-data-consent { font-size: 13px; margin-bottom: 10px; } #updraftcentral_keys_table { width: 100%; } #updraftcentral_stage1_go { cursor: pointer; } .updraftcentral_wizard_option > div { margin-top: 5px; } #updraftcentral_keys_table td { line-height: 1.4em; } #updraftcentral_keys_table .updraftcentral_key_delete { display: inline-block; margin-top: 4px; margin-bottom: 4px; } #updraftcentral_keys_table .updraft_debugrow td { min-width: auto !important; } central/images/ud-logo.png000064400000015205152214270100011512 0ustar00PNG  IHDR<q OiCCPPhotoshop ICC profilexڝSgTS=BKKoR RB&*! J!QEEȠQ, !{kּ> H3Q5 B.@ $pd!s#~<<+"x M0B\t8K@zB@F&S`cbP-`'{[! eDh;VEX0fK9-0IWfH  0Q){`##xFW<+*x<$9E[-qWW.(I+6aa@.y24x6_-"bbϫp@t~,/;m%h^ uf@Wp~<5j>{-]cK'Xto(hw?G%fIq^D$.Tʳ?D*A, `6B$BB dr`)B(Ͱ*`/@4Qhp.U=pa( Aa!ڈbX#!H$ ɈQ"K5H1RT UH=r9\F;2G1Q= C7F dt1r=6Ыhڏ>C03l0.B8, c˱" VcϱwE 6wB aAHXLXNH $4 7 Q'"K&b21XH,#/{C7$C2'ITFnR#,4H#dk9, +ȅ3![ b@qS(RjJ4e2AURݨT5ZBRQ4u9̓IKhhitݕNWGw Ljg(gwLӋT071oUX**| J&*/Tު UUT^S}FU3S ԖUPSSg;goT?~YYLOCQ_ cx,!k u5&|v*=9C3J3WRf?qtN (~))4L1e\kXHQG6EYAJ'\'GgSSݧ M=:.kDwn^Loy}/TmG X $ <5qo</QC]@Caaᄑ.ȽJtq]zۯ6iܟ4)Y3sCQ? 0k߬~OCOg#/c/Wװwa>>r><72Y_7ȷOo_C#dz%gA[z|!?:eAAA!h쐭!ΑiP~aa~ 'W?pX15wCsDDDޛg1O9-J5*>.j<74?.fYXXIlK9.*6nl {/]py.,:@LN8A*%w% yg"/6шC\*NH*Mz쑼5y$3,幄'L Lݛ:v m2=:1qB!Mggfvˬen/kY- BTZ(*geWf͉9+̳ې7ᒶKW-X潬j9(xoʿܔĹdff-[n ڴ VE/(ۻCɾUUMfeI?m]Nmq#׹=TR+Gw- 6 U#pDy  :v{vg/jBFS[b[O>zG499?rCd&ˮ/~јѡ򗓿m|x31^VwwO| (hSЧc3-bKGD pHYs.#.#x?vtIME  l6eIDATx{_Eu?_rsC < 0N1#(BAWT]vJ|BKBʣU^T%=-4M$ycޛ}wkݕܛ=3sٳgUSI5wTUҦg)oIW6_UZ`fX~q[c $i/`O`5nf;A +cJgG{oсo 7o+m5VCA&cshWX lS 4͒҆$GפTڬh \MXf'ְ o ,*m~^w jT9K5';`fe]nX <\|+^Jhok̬X6lޅF~:uM} 3}E$MVXj6~D]<ѧ8:\Mkxju$L"`Mk+U>JJm%qtCGW|zGSW $VX@GQ `Ch|͎'q4lJc9wzXiWJ{^$.vPPHr!#|$$շ풠]8Sv2w6;:yW7$$-v PM< Bi)zbDg$q4hCpvCc#Go`fI5z9kG֙4BGBrя]:'$q գOcJ9#͖|;GDr^,7TZO2}'~FۛދS[8*s;;zgJfz6Τ |:eV-Jߦ$nsSߠ뻚v{|> Rkkn`ݝyp/a`+XϠ: {~ci`A#u 6P,XWP~:p՚D_5Y(q"QX)UX} K+d7!a# ֏w3,PD^,` G֗Y–nZGH_T1dVvB`mEj $Bo_6-YD,`m=U+5kf@X = P#EfW՚AWXiZ^X[B8>p=k`+Ih2Qy2e%(,/ zZy f+#<5ZBMz_+\ *x v 6䌬o<+$ X8X^"ؐO 9rjJABH)>$߶$ Tšڈ=#sW`2xz - ;z?2YwXoUYJYK3zP(xoI`m]Axk|M竦;%>/9 GA],4Nؓ]7Wgdmg$BpxKLY I$>"wxY˪J2SYہgYXigI&7ZPqG^Rdp"s).љ%6;6+Kj%0Cil(Xb* ٘RVCP܍Rd*V,NV`ɑZ`ą2WsI-t=2μ xfq.s&0KEBH-F o8{GGs? xAݣelL(mD y$>^V*Q >åVlѽfp͓ے8ڻJHbV}s5ߐ`+ x"_ &7+9+2x ٘UXa.dsN͂<ιXѱdJ\sj.Ϲb7O, 7Sy*mj.E>"ߩ=I}+{nxAP-*b)Uԛѻsj؍ ka,GY-،I³Ey:셂O>u<[%򸅆w7+B.V,.ͭ:!^[`I bnV؝ٳ np/i&q4:8Ճj4GQ=$sC%N5.{q`uWKsXJ[F=VW3Ö;zvl\%ϭ! ,PPHPIg8뽪\(gRd2gpj9qH tjHIFe&cL.m5RO򌶒K[s7"|}~xqviL.JcrzhkaO A,Rf 7 &EX{Դvw3MϮ((4[ޛIc֦CtVPKA нe2"V%J;Ѥ#*\Qm#;|5{ :CCyJG}f)5C-]a4 [ 2쵗}RlٵZݢ5KSKT˕b X5xҠtVbŅxl+._Gs\5 ]t0iQNQEai{ͷ/ڑ0fŽMC! ,OPH-H 8ɧ`t$%VD08 ,e g+rAȐU%UKW+\D9yjX4O2p]_s݌Ժ}|JGtxwjzK5J_N8LC3#yVKBoPɕΫCTُԭܤә"0rtsmlP`J PT`h 0 n4` [>];2 ;x.=ٸ'zHAD$b$oa6+]1QF KY$&o lqO,e⥺m,nŒWDy FO3( i'T馣n`Z RdzIŝ<{t.8^aS *{$zS>E *K`I* Nk5ꕥ@asҖ(tt7Djmqb%%! ,PPH.I%8M'hhk n]q<欞 (SҬr kͪ1dU؅ E/gw~P%625.Kt--p''#p+y-},4&u{Dk/(dIĹ(Z$­s[֡YNR᥿a[ھ^溘_HsNc 'n:|O]C(2,8b2,i$ cK/ mcʊܭ7q2jGҔ Lh#Q޼T랚9[גM8Ű.WFD+r5=յ̀ U};߶rd@ZOo yo>؉dFEX?787O._(t; ,6q |M#lT%Jy-.|P·ȾhVȸ&[RԨ`ҳ=ʗڹaDm %~8 1%sOݺdƕͰ}H8*h^Nj PE&O΂/9<iA#OΞ%AB|5U =эK]̈Ě*wz h"9v&TzZOqs|\[ҍҽ +`΄;6ƆbBHJNO2ӽܜE@bM} !_u+$ ! ,OOH0 89&hhv*?<:o bȢ$eJJ ,hJAdTd#um1mLʇEC}8=L?>>~S4S=78`B9$8/1w. 6'X.k-gT.q(-T¾ͪZYQbvYf`O^ WF JVMwp":]zpvEV\ʖ`z8FJ""'x$5SXdM[4QhODLָLMݬ#XjN( kXbv5Tl~| 5..'#nWmP@Zv &lP:\vZR7=yh…OBGNŮ/%y! ,PPH.I%8=E&hE*+?ߠ7D7 _DqyJ^P>vz< AmeՌ>$;8 ak,SST}wH r4@8O770u0zR+ m.-M# i"jLɆ%VӲ=k&ۭQMZRgKoTb  z-$B^'~2214xnC$9tۇ^`Qf>Rs2L KSQg"͟!/f<r*K\ Ҭæέ5r ! ` ,رJRh֫qm*fO=VnԺy+!+>5:$.G;;@*y姯<%'P1})w_ (ԉ9%! ,PPX/I&8뭦čXclt*uߤM+~qJ6P3Z$jG7]bUZT,M9r!8~5| zB:3J/4gOJ -@% 6/>yt&i;PnVu\)*Wp`x铇ܶ.J C+z@8M?dA<ƄcF$a`#-eCRɐș"5idU opgk#C 5<3^F" KWŸ%\ʂW9 '4uXX\[ 'Z\ZBhp!)=CDʻ͡/o=(x* >GJdh&EX;:ΧU~ ۔O$y4m5;/%,U<{ƘڬY 5KF_pÛ7)߾6IeTgC&fTt^d楄?s&%҆NJ! ,OOX*I8 `pdhjd+;o- ڼ:No fHU IDS(hq.Vg-ųmY֝qy%Ͼ'{|}t.BO6/GJ/w84ql5L.@ZryVm;NOb*/|zV &4#da"}E ͘ϪhYEPSaʕ>݋05X;(prJ!@ln؋(Qd*bAY@#&[P| 56(-髕NB? ʜY҄>Q1}I$OF'Q&jؤjX\-e1GEAN:%6&]WpZb"B(bCXrSam-kH! ,PPH/I8M'hd*,Q+,rV mFYl.m{ ԶTfFS-!7~6)qjzBa \P iODI3~'}c2(p,RJ; 1Ľ¾ʓ&UυԌҍ 8S : < !ѩ raEumgaC)g8±f*+zyM<) =g軦 M>9CT:Z=u֭\.ke#ˌ+R m۔=Q͙%ّ-{W&O Vq2f.F'ήpt֌Ix1ڜ&!,PPH.I'8k=E&hh{*_ޟ7:[1aXd4FK5a{HmkU<wUSt:~g|nx2)t.{I%mFc=6+V(~+hYaħ6]zoςӁW}զoۖjeɸ?wTg?>_;)R;Ȥ114X.ĉ!H/FO*2)QF\ ̼EBkINJnk(B6? K͚%a8vdQD5$t/*Y%߄wv skӱ pY+k/DV٠%ЎOkG),f ^L37b} )&weѭR۫Ds`X;central/js/central.js000064400000036707152214270100010605 0ustar00/** * Send an action over AJAX. A wrapper around jQuery.ajax. In future, all consumers can be reviewed to simplify some of the options, where there is historical cruft. * N.B. updraft_iframe_modal() below uses the AJAX URL for the iframe's src attribute * * @param {string} action - the action to send * @param {*} data - data to send * @param {Function} callback - will be called with the results * @param {object} options -further options. Relevant properties include: * - [json_parse=true] - whether to JSON parse the results * - [alert_on_error=true] - whether to show an alert box if there was a problem (otherwise, suppress it) * - [action='updraft_ajax'] - what to send as the action parameter on the AJAX request (N.B. action parameter to this function goes as the 'subaction' parameter on the AJAX request) * - [nonce=updraft_credentialtest_nonce] - the nonce value to send. * - [nonce_key='nonce'] - the key value for the nonce field * - [timeout=null] - set a timeout after this number of seconds (or if null, none is set) * - [async=true] - control whether the request is asynchronous (almost always wanted) or blocking (would need to have a specific reason) * - [type='POST'] - GET or POST */ function updraftcentral_send_command(action, data, callback, options) { default_options = { json_parse: true, alert_on_error: true, action: 'updraft_central_ajax', nonce_key: 'nonce', timeout: null, async: true, type: 'POST' } if ('undefined' !== typeof uclion.updraftcentral_request_nonce && uclion.updraftcentral_request_nonce) { default_options.nonce = uclion.updraftcentral_request_nonce; } if ('undefined' === typeof options) options = {}; for (var opt in default_options) { if (!options.hasOwnProperty(opt)) { options[opt] = default_options[opt]; } } var ajax_data = { action: options.action, subaction: action, }; ajax_data[options.nonce_key] = options.nonce; ajax_data.action_data = data; var ajax_opts = { type: options.type, url: ajaxurl, data: ajax_data, success: function(response, status) { if (options.json_parse) { try { var resp = central_parse_json(response); } catch (e) { if ('function' == typeof options.error_callback) { return options.error_callback(response, e, 502, resp); } else { console.log(e); console.log(response); if (options.alert_on_error) { alert(uclion.unexpectedresponse+' '+response); } return; } } if (resp.hasOwnProperty('fatal_error')) { if ('function' == typeof options.error_callback) { // 500 is internal server error code return options.error_callback(response, status, 500, resp); } else { console.error(resp.fatal_error_message); if (options.alert_on_error) { alert(resp.fatal_error_message); } return false; } } if ('function' == typeof callback) callback(resp, status, response); } else { if ('function' == typeof callback) callback(response, status); } }, error: function(response, status, error_code) { if ('function' == typeof options.error_callback) { options.error_callback(response, status, error_code); } else { console.log("updraftcentral_send_command: error: "+status+" ("+error_code+")"); console.log(response); } }, dataType: 'text', async: options.async }; if (null != options.timeout) { ajax_opts.timeout = options.timeout; } jQuery.ajax(ajax_opts); } /** * Parse JSON string, including automatically detecting unwanted extra input and skipping it * * @param {string} json_mix_str - JSON string which need to parse and convert to object * @param {boolean} analyse - if true, then the return format will contain information on the parsing, and parsing will skip attempting to JSON.parse() the entire string (will begin with trying to locate the actual JSON) * * @throws SyntaxError|String (including passing on what JSON.parse may throw) if a parsing error occurs. * * @returns Mixed parsed JSON object. Will only return if parsing is successful (otherwise, will throw). If analyse is true, then will rather return an object with properties (mixed)parsed, (integer)json_start_pos and (integer)json_end_pos */ function central_parse_json(json_mix_str, analyse) { analyse = ('undefined' === typeof analyse) ? false : true; // Just try it - i.e. the 'default' case where things work (which can include extra whitespace/line-feeds, and simple strings, etc.). if (!analyse) { try { var result = JSON.parse(json_mix_str); return result; } catch (e) { console.log(uclion.plugin_name+': Exception when trying to parse JSON (1) - will attempt to fix/re-parse based upon first/last curly brackets'); console.log(json_mix_str); } } var json_start_pos = json_mix_str.indexOf('{'); var json_last_pos = json_mix_str.lastIndexOf('}'); // Case where some php notice may be added after or before json string if (json_start_pos > -1 && json_last_pos > -1) { var json_str = json_mix_str.slice(json_start_pos, json_last_pos + 1); try { var parsed = JSON.parse(json_str); if (!analyse) { console.log(uclion.plugin_name+': JSON re-parse successful'); } return analyse ? { parsed: parsed, json_start_pos: json_start_pos, json_last_pos: json_last_pos + 1 } : parsed; } catch (e) { console.log(uclion.plugin_name+': Exception when trying to parse JSON (2) - will attempt to fix/re-parse based upon bracket counting'); var cursor = json_start_pos; var open_count = 0; var last_character = ''; var inside_string = false; // Don't mistake this for a real JSON parser. Its aim is to improve the odds in real-world cases seen, not to arrive at universal perfection. while ((open_count > 0 || cursor == json_start_pos) && cursor <= json_last_pos) { var current_character = json_mix_str.charAt(cursor); if (!inside_string && '{' == current_character) { open_count++; } else if (!inside_string && '}' == current_character) { open_count--; } else if ('"' == current_character && '\\' != last_character) { inside_string = inside_string ? false : true; } last_character = current_character; cursor++; } console.log("Started at cursor="+json_start_pos+", ended at cursor="+cursor+" with result following:"); console.log(json_mix_str.substring(json_start_pos, cursor)); try { var parsed = JSON.parse(json_mix_str.substring(json_start_pos, cursor)); console.log(uclion.plugin_name+': JSON re-parse successful'); return analyse ? { parsed: parsed, json_start_pos: json_start_pos, json_last_pos: cursor } : parsed; } catch (e) { // Throw it again, so that our function works just like JSON.parse() in its behaviour. throw e; } } } throw uclion.plugin_name+": could not parse the JSON"; } jQuery(function($) { $('#updraftcentral_keys').on('click', 'a.updraftcentral_keys_show', function(e) { e.preventDefault(); $(this).remove(); $('#updraftcentral_keys_table').slideDown(); }); $('#updraftcentral_keycreate_altmethod_moreinfo_get').on('click', function(e) { e.preventDefault(); $(this).remove(); $('#updraftcentral_keycreate_altmethod_moreinfo').slideDown(); }); function updraftcentral_keys_setupform(on_page_load) { var is_other = jQuery('#updraftcentral_mothership_other').is(':checked') ? true : false; if (is_other) { jQuery('#updraftcentral_keycreate_mothership').prop('disabled', false); if (on_page_load) { jQuery('#updraftcentral_keycreate_mothership_firewalled_container').show(); } else { jQuery('.updraftcentral_wizard_self_hosted_stage2').show(); jQuery('#updraftcentral_keycreate_mothership_firewalled_container').slideDown(); jQuery('#updraftcentral_keycreate_mothership').trigger('focus'); } } else { jQuery('#updraftcentral_keycreate_mothership').prop('disabled', true); if (!on_page_load) { jQuery('.updraftcentral_wizard_self_hosted_stage2').hide(); updraftcentral_stage2_go(); } } } function updraftcentral_stage2_go() { // Reset the error message before we continue jQuery('#updraftcentral_wizard_stage1_error').text(''); var host = ''; if (jQuery('#updraftcentral_mothership_updraftpluscom').is(':checked')) { jQuery('.updraftcentral_keycreate_description').hide(); host = 'updraftplus.com'; } else if (jQuery('#updraftcentral_mothership_other').is(':checked')) { jQuery('.updraftcentral_keycreate_description').show(); var mothership = jQuery('#updraftcentral_keycreate_mothership').val(); if ('' == mothership) { jQuery('#updraftcentral_wizard_stage1_error').text(uclion.updraftcentral_wizard_empty_url); return; } try { var url = new URL(mothership); host = url.hostname; } catch (e) { // Try and grab the host name a different way if it failed because of no URL object (e.g. Firefox version 25 and below). if ('undefined' === typeof URL) { host = jQuery('').prop('href', mothership).prop('hostname'); } if (!host || 'undefined' !== typeof URL) { jQuery('#updraftcentral_wizard_stage1_error').text(uclion.updraftcentral_wizard_invalid_url); return; } } } jQuery('#updraftcentral_keycreate_description').val(host); jQuery('.updraftcentral_wizard_stage1').hide(); jQuery('.updraftcentral_wizard_stage2').show(); } jQuery('#updraftcentral_keys').on('click', 'input[type="radio"]', function() { updraftcentral_keys_setupform(false); }); // Initial setup (for browsers, e.g. Firefox, that remember form selection state but not DOM state, which can leave an inconsistent state) updraftcentral_keys_setupform(true); jQuery('#updraftcentral_keys').on('click', '#updraftcentral_view_log', function(e) { e.preventDefault(); jQuery('#updraftcentral_view_log_container').block({ message: '

'+uclion.fetching+'
'}); try { updraftcentral_send_command('get_log', null, function(response) { jQuery('#updraftcentral_view_log_container').unblock(); if (response.hasOwnProperty('log_contents')) { jQuery('#updraftcentral_view_log_contents').html('
'+response.log_contents+'
'); } else { console.log(response); } }, { error_callback: function(response, status, error_code, resp) { jQuery('#updraftcentral_view_log_container').unblock(); if (typeof resp !== 'undefined' && resp.hasOwnProperty('fatal_error')) { console.error(resp.fatal_error_message); alert(resp.fatal_error_message); } else { var error_message = "updraftcentral_send_command: error: "+status+" ("+error_code+")"; console.log(error_message); alert(error_message); console.log(response); } } }); } catch (err) { jQuery('#updraft_central_key').html(); console.log(err); } }); // UpdraftCentral jQuery('#updraftcentral_keys').on('click', '#updraftcentral_wizard_go', function(e) { jQuery('#updraftcentral_wizard_go').hide(); jQuery('.updraftcentral_wizard_success').remove(); jQuery('.create_key_container').show(); }); jQuery('#updraftcentral_keys').on('click', '#updraftcentral_stage1_go', function(e) { e.preventDefault(); jQuery('.updraftcentral_wizard_stage2').hide(); jQuery('.updraftcentral_wizard_stage1').show(); }); jQuery('#updraftcentral_keys').on('click', '#updraftcentral_stage2_go', function(e) { e.preventDefault(); updraftcentral_stage2_go(); }); jQuery('#updraftcentral_keys').on('click', '#updraftcentral_keycreate_go', function(e) { e.preventDefault(); var is_other = jQuery('#updraftcentral_mothership_other').is(':checked') ? true : false; var key_description = jQuery('#updraftcentral_keycreate_description').val(); var key_size = jQuery('#updraftcentral_keycreate_keysize').val(); var where_send = '__updraftpluscom'; data = { key_description: key_description, key_size: key_size, }; if (is_other) { where_send = jQuery('#updraftcentral_keycreate_mothership').val(); if (where_send.substring(0, 4) != 'http') { alert(uclion.enter_mothership_url); return; } } data.mothership_firewalled = jQuery('#updraftcentral_keycreate_mothership_firewalled').is(':checked') ? 1 : 0; data.where_send = where_send; jQuery('.create_key_container').hide(); jQuery('.updraftcentral_wizard_stage1').show(); jQuery('.updraftcentral_wizard_stage2').hide(); jQuery('#updraftcentral_keys').block({ message: '

'+uclion.creating_please_allow+'
'}); try { updraftcentral_send_command('create_key', data, function(resp) { jQuery('#updraftcentral_keys').unblock(); try { if (resp.hasOwnProperty('error')) { alert(resp.error); console.log(resp); return; } alert(resp.r); if (resp.hasOwnProperty('bundle') && resp.hasOwnProperty('keys_guide')) { jQuery('#updraftcentral_keys_content').html(resp.keys_guide); jQuery('#updraftcentral_keys_content').append('
'+resp.r+'
'); } else { console.log(resp); } if (resp.hasOwnProperty('keys_table')) { jQuery('#updraftcentral_keys_content').append(resp.keys_table); } jQuery('#updraftcentral_wizard_go').show(); } catch (err) { alert(uclion.unexpectedresponse+' '+response); console.log(err); } }, { error_callback: function(response, status, error_code, resp) { jQuery('#updraftcentral_keys').unblock(); if (typeof resp !== 'undefined' && resp.hasOwnProperty('fatal_error')) { console.error(resp.fatal_error_message); alert(resp.fatal_error_message); } else { var error_message = "updraftcentral_send_command: error: "+status+" ("+error_code+")"; console.log(error_message); alert(error_message); console.log(response); } } }); } catch (err) { jQuery('#updraft_central_key').html(); console.log(err); } }); jQuery('#updraftcentral_keys').on('click', '.updraftcentral_key_delete', function(e) { e.preventDefault(); var key_id = jQuery(this).data('key_id'); if ('undefined' == typeof key_id) { console.log("UpdraftPlus: .updraftcentral_key_delete clicked, but no key ID found"); return; } jQuery('#updraftcentral_keys').block({ message: '

'+uclion.deleting+'
'}); updraftcentral_send_command('delete_key', { key_id: key_id }, function(response) { jQuery('#updraftcentral_keys').unblock(); if (response.hasOwnProperty('keys_table')) { jQuery('#updraftcentral_keys_content').html(response.keys_table); } }, { error_callback: function(response, status, error_code, resp) { jQuery('#updraftcentral_keys').unblock(); if (typeof resp !== 'undefined' && resp.hasOwnProperty('fatal_error')) { console.error(resp.fatal_error_message); alert(resp.fatal_error_message); } else { var error_message = "updraftcentral_send_command: error: "+status+" ("+error_code+")"; console.log(error_message); alert(error_message); console.log(response); } } }); }); });central/js/central-2-23-7.min.js000064400000021266152214270100012106 0ustar00function updraftcentral_send_command(e,r,a,o){for(var t in default_options={json_parse:!0,alert_on_error:!0,action:"updraft_central_ajax",nonce_key:"nonce",timeout:null,async:!0,type:"POST"},void 0!==uclion.updraftcentral_request_nonce&&uclion.updraftcentral_request_nonce&&(default_options.nonce=uclion.updraftcentral_request_nonce),void 0===o&&(o={}),default_options)o.hasOwnProperty(t)||(o[t]=default_options[t]);e={action:o.action,subaction:e},e[o.nonce_key]=o.nonce,e.action_data=r,r={type:o.type,url:ajaxurl,data:e,success:function(r,e){if(o.json_parse){try{var t=central_parse_json(r)}catch(e){return"function"==typeof o.error_callback?o.error_callback(r,e,502,t):(console.log(e),console.log(r),void(o.alert_on_error&&alert(uclion.unexpectedresponse+" "+r)))}if(t.hasOwnProperty("fatal_error"))return"function"==typeof o.error_callback?o.error_callback(r,e,500,t):(console.error(t.fatal_error_message),o.alert_on_error&&alert(t.fatal_error_message),!1);"function"==typeof a&&a(t,e,r)}else"function"==typeof a&&a(r,e)},error:function(e,r,t){"function"==typeof o.error_callback?o.error_callback(e,r,t):(console.log("updraftcentral_send_command: error: "+r+" ("+t+")"),console.log(e))},dataType:"text",async:o.async};null!=o.timeout&&(r.timeout=o.timeout),jQuery.ajax(r)}function central_parse_json(r,t){if(!(t=void 0!==t))try{return JSON.parse(r)}catch(e){console.log(uclion.plugin_name+": Exception when trying to parse JSON (1) - will attempt to fix/re-parse based upon first/last curly brackets"),console.log(r)}var a=r.indexOf("{"),o=r.lastIndexOf("}");if(-1").prop("href",t).prop("hostname"):r)||"undefined"!=typeof URL)return void jQuery("#updraftcentral_wizard_stage1_error").text(uclion.updraftcentral_wizard_invalid_url)}}jQuery("#updraftcentral_keycreate_description").val(r),jQuery(".updraftcentral_wizard_stage1").hide(),jQuery(".updraftcentral_wizard_stage2").show()}r("#updraftcentral_keys").on("click","a.updraftcentral_keys_show",function(e){e.preventDefault(),r(this).remove(),r("#updraftcentral_keys_table").slideDown()}),r("#updraftcentral_keycreate_altmethod_moreinfo_get").on("click",function(e){e.preventDefault(),r(this).remove(),r("#updraftcentral_keycreate_altmethod_moreinfo").slideDown()}),jQuery("#updraftcentral_keys").on("click",'input[type="radio"]',function(){e(!1)}),e(!0),jQuery("#updraftcentral_keys").on("click","#updraftcentral_view_log",function(e){e.preventDefault(),jQuery("#updraftcentral_view_log_container").block({message:'

'+uclion.fetching+"
"});try{updraftcentral_send_command("get_log",null,function(e){jQuery("#updraftcentral_view_log_container").unblock(),e.hasOwnProperty("log_contents")?jQuery("#updraftcentral_view_log_contents").html('
'+e.log_contents+"
"):console.log(e)},{error_callback:function(e,r,t,a){jQuery("#updraftcentral_view_log_container").unblock(),void 0!==a&&a.hasOwnProperty("fatal_error")?(console.error(a.fatal_error_message),alert(a.fatal_error_message)):(a="updraftcentral_send_command: error: "+r+" ("+t+")",console.log(a),alert(a),console.log(e))}})}catch(e){jQuery("#updraft_central_key").html(),console.log(e)}}),jQuery("#updraftcentral_keys").on("click","#updraftcentral_wizard_go",function(e){jQuery("#updraftcentral_wizard_go").hide(),jQuery(".updraftcentral_wizard_success").remove(),jQuery(".create_key_container").show()}),jQuery("#updraftcentral_keys").on("click","#updraftcentral_stage1_go",function(e){e.preventDefault(),jQuery(".updraftcentral_wizard_stage2").hide(),jQuery(".updraftcentral_wizard_stage1").show()}),jQuery("#updraftcentral_keys").on("click","#updraftcentral_stage2_go",function(e){e.preventDefault(),t()}),jQuery("#updraftcentral_keys").on("click","#updraftcentral_keycreate_go",function(e){e.preventDefault();var e=!!jQuery("#updraftcentral_mothership_other").is(":checked"),r=jQuery("#updraftcentral_keycreate_description").val(),t=jQuery("#updraftcentral_keycreate_keysize").val(),a="__updraftpluscom";if(data={key_description:r,key_size:t},e&&"http"!=(a=jQuery("#updraftcentral_keycreate_mothership").val()).substring(0,4))alert(uclion.enter_mothership_url);else{data.mothership_firewalled=jQuery("#updraftcentral_keycreate_mothership_firewalled").is(":checked")?1:0,data.where_send=a,jQuery(".create_key_container").hide(),jQuery(".updraftcentral_wizard_stage1").show(),jQuery(".updraftcentral_wizard_stage2").hide(),jQuery("#updraftcentral_keys").block({message:'

'+uclion.creating_please_allow+"
"});try{updraftcentral_send_command("create_key",data,function(e){jQuery("#updraftcentral_keys").unblock();try{e.hasOwnProperty("error")?(alert(e.error),console.log(e)):(alert(e.r),e.hasOwnProperty("bundle")&&e.hasOwnProperty("keys_guide")?(jQuery("#updraftcentral_keys_content").html(e.keys_guide),jQuery("#updraftcentral_keys_content").append('
'+e.r+'
")):console.log(e),e.hasOwnProperty("keys_table")&&jQuery("#updraftcentral_keys_content").append(e.keys_table),jQuery("#updraftcentral_wizard_go").show())}catch(e){alert(uclion.unexpectedresponse+" "+response),console.log(e)}},{error_callback:function(e,r,t,a){jQuery("#updraftcentral_keys").unblock(),void 0!==a&&a.hasOwnProperty("fatal_error")?(console.error(a.fatal_error_message),alert(a.fatal_error_message)):(a="updraftcentral_send_command: error: "+r+" ("+t+")",console.log(a),alert(a),console.log(e))}})}catch(e){jQuery("#updraft_central_key").html(),console.log(e)}}}),jQuery("#updraftcentral_keys").on("click",".updraftcentral_key_delete",function(e){e.preventDefault();e=jQuery(this).data("key_id");void 0===e?console.log("UpdraftPlus: .updraftcentral_key_delete clicked, but no key ID found"):(jQuery("#updraftcentral_keys").block({message:'

'+uclion.deleting+"
"}),updraftcentral_send_command("delete_key",{key_id:e},function(e){jQuery("#updraftcentral_keys").unblock(),e.hasOwnProperty("keys_table")&&jQuery("#updraftcentral_keys_content").html(e.keys_table)},{error_callback:function(e,r,t,a){jQuery("#updraftcentral_keys").unblock(),void 0!==a&&a.hasOwnProperty("fatal_error")?(console.error(a.fatal_error_message),alert(a.fatal_error_message)):(a="updraftcentral_send_command: error: "+r+" ("+t+")",console.log(a),alert(a),console.log(e))}}))})});central/modules/users.php000064400000045247152214270100011524 0ustar00ID === $b->ID) { return 0; } return ($a->ID < $b->ID) ? -1 : 1; } /** * Searches users based from the keyword submitted * * @internal * @param array $query Parameter array containing the filter and keyword fields * @return array Contains the list of users found as well as the total users count */ private function _search_users($query) { $this->_admin_include('user.php'); $query1 = new WP_User_Query(array( 'orderby' => 'ID', 'order' => 'ASC', 'role'=> $query["role"], 'search' => '*' . esc_attr($query["search"]) . '*', 'search_columns' => array('user_login', 'user_email') )); $query2 = new WP_User_Query(array( 'orderby' => 'ID', 'order' => 'ASC', 'role'=> $query["role"], 'meta_query'=>array( 'relation' => 'OR', array( 'key' => 'first_name', 'value' => $query["search"], 'compare' => 'LIKE' ), array( 'key' => 'last_name', 'value' => $query["search"], 'compare' => 'LIKE' ), ) )); if (empty($query1->results) && empty($query2->results)) { return array("message" => "users_not_found"); } else { $found_users = array_merge($query1->results, $query2->results); $temp = array(); foreach ($found_users as $new_user) { if (!isset($temp[$new_user->ID])) { $temp[$new_user->ID] = $new_user; } }; $users = array_values($temp); // Sort users: usort($users, array($this, 'compare_user_id')); $offset = ((int) $query['page_no'] * (int) $query['per_page']) - (int) $query['per_page']; $user_list = array_slice($users, $offset, $query['per_page']); return array( 'users' => $user_list, 'total_users' => count($users) ); } } /** * Calculates the number of pages needed to construct the pagination links * * @internal * @param array $query * @param array $total_users The total number of users found from the WP_User_Query query * @return array Contains information needed to construct the pagination links */ private function _calculate_pages($query, $total_users) { $per_page_options = array(10, 20, 30, 40, 50); if (!empty($query)) { $pages = array(); $page_count = ceil($total_users / $query["per_page"]); if ($page_count > 1) { for ($i = 0; $i < $page_count; $i++) { if ($i + 1 == $query['page_no']) { $paginator_item = array( "value"=>$i+1, "setting"=>"disabled" ); } else { $paginator_item = array( "value"=>$i+1 ); } array_push($pages, $paginator_item); }; if ($query['page_no'] >= $page_count) { $page_next = array( "value"=>$page_count, "setting"=>"disabled" ); } else { $page_next = array( "value"=>$query['page_no'] + 1 ); }; if (1 === $query['page_no']) { $page_prev = array( "value"=>1, "setting"=>"disabled" ); } else { $page_prev = array( "value"=>$query['page_no'] - 1 ); }; return array( "page_no" => $query['page_no'], "per_page" => $query["per_page"], "page_count" => $page_count, "pages" => $pages, "page_next" => $page_next, "page_prev" => $page_prev, "total_results" => $total_users, "per_page_options" => $per_page_options ); } else { return array( "page_no" => $query['page_no'], "per_page" => $query["per_page"], "page_count" => $page_count, "total_results" => $total_users, "per_page_options" => $per_page_options ); } } else { return array( "per_page_options" => $per_page_options ); } } /** * Validates whether the username exists * * @param array $params Contains the user name to check and validate * @return array An array containing the result of the current process */ public function check_username($params) { $this->_admin_include('user.php'); $username = $params['user_name']; $blog_id = get_current_blog_id(); if (!empty($params['site_id'])) { $blog_id = $params['site_id']; } // Here, we're switching to the actual blog that we need // to pull users from. $switched = function_exists('switch_to_blog') ? switch_to_blog($blog_id) : false; if (username_exists($username) && is_user_member_of_blog(username_exists($username), $blog_id)) { $result = array("valid" => false, "message" => 'username_exists'); return $this->_response($result); } if (!validate_username($username)) { $result = array("valid" => false, "message" => 'username_invalid'); return $this->_response($result); } // Here, we're restoring to the current (default) blog before we // do the switched. if (function_exists('restore_current_blog') && $switched) { restore_current_blog(); } $result = array("valid" => true, "message" => 'username_valid'); return $this->_response($result); } /** * Pulls blog sites available * for the current WP instance. * If the site is a multisite, then sites under the network * will be pulled, otherwise, it will return an empty array. * * @return Array - an array of sites */ private function _get_blog_sites() { if (!is_multisite()) return array(); // Initialize array container $sites = $network_sites = array(); // Check to see if latest get_sites (available on WP version >= 4.6) function is // available to pull any available sites from the current WP instance. If not, then // we're going to use the fallback function wp_get_sites (for older version). if (function_exists('get_sites') && class_exists('WP_Site_Query')) { $network_sites = get_sites(); } else { if (function_exists('wp_get_sites')) { $network_sites = wp_get_sites(); } } // We only process if sites array is not empty, otherwise, bypass // the next block. if (!empty($network_sites)) { foreach ($network_sites as $site) { // Here we're checking if the site type is an array, because // we're pulling the blog_id property based on the type of // site returned. // get_sites returns an array of object, whereas the wp_get_sites // function returns an array of array. $blog_id = is_array($site) ? $site['blog_id'] : $site->blog_id; // We're saving the blog_id and blog name as an associative item // into the sites array, that will be used as "Sites" option in // the frontend. $sites[$blog_id] = get_blog_details($blog_id)->blogname; } } return $sites; } /** * Validates whether the email exists * * @param array $params Contains the email to check and validate * @return array An array containing the result of the current process */ public function check_email($params) { $this->_admin_include('user.php'); $email = $params['email']; $blog_id = get_current_blog_id(); if (isset($params['site_id']) && 0 !== $params['site_id']) { $blog_id = $params['site_id']; } // Here, we're switching to the actual blog that we need // to pull users from. $switched = false; if (function_exists('switch_to_blog')) { $switched = switch_to_blog($blog_id); } if (is_email($email) === false) { $result = array("valid" => false, "message" => 'email_invalid'); return $this->_response($result); } if (email_exists($email) && is_user_member_of_blog(email_exists($email), $blog_id)) { $result = array("valid" => false, "message" => 'email_exists'); return $this->_response($result); } // Here, we're restoring to the current (default) blog before we // do the switched. if (function_exists('restore_current_blog') && $switched) { restore_current_blog(); } $result = array("valid" => true, "message" => 'email_valid'); return $this->_response($result); } /** * The get_users function pull all the users from the database * based on the current search parameters/filters. Please see _search_users * for the breakdown of these parameters. * * @param array $query Parameter array containing the filter and keyword fields * @return array An array containing the result of the current process */ public function get_users($query) { $this->_admin_include('user.php'); // Here, we're getting the current blog id. If blog id // is passed along with the parameters then we override // that current (default) value with the parameter blog id value. $blog_id = get_current_blog_id(); if (isset($query['site_id']) && 0 !== $query['site_id']) $blog_id = $query['site_id']; // Here, we're switching to the actual blog that we need // to pull users from. $switched = false; if (function_exists('switch_to_blog')) { $switched = switch_to_blog($blog_id); } // Set default: if (empty($query["per_page"])) { $query["per_page"] = 10; } if (empty($query['page_no'])) { $query['page_no'] = 1; } if (empty($query["role"])) { $query["role"] = ""; } $users = array(); $total_users = 0; if (!empty($query["search"])) { $search_results = $this->_search_users($query); if (isset($search_results['users'])) { $users = $search_results['users']; $total_users = $search_results['total_users']; } } else { $user_query = new WP_User_Query(array( 'orderby' => 'ID', 'order' => 'ASC', 'number' => $query["per_page"], 'paged'=> $query['page_no'], 'role'=> $query["role"] )); if (empty($user_query->results)) { $result = array("message" => 'users_not_found'); return $this->_response($result); } $users = $user_query->results; $total_users = $user_query->get_total(); } foreach ($users as &$user) { $user_object = get_userdata($user->ID); if (method_exists($user_object, 'to_array')) { $user = $user_object->to_array(); $user["roles"] = $user_object->roles; $user["first_name"] = $user_object->first_name; $user["last_name"] = $user_object->last_name; $user["description"] = $user_object->description; } else { $user = $user_object; } } $result = array( "users"=>$users, "paging" => $this->_calculate_pages($query, $total_users) ); // Here, we're restoring to the current (default) blog before we // do the switched. if (function_exists('restore_current_blog') && $switched) { restore_current_blog(); } return $this->_response($result); } /** * Creates new user for the current blog * * @param array $user User information to add * @return array An array containing the result of the current process */ public function add_user($user) { $this->_admin_include('user.php'); // Here, we're getting the current blog id. If blog id // is passed along with the parameters then we override // that current (default) value with the parameter blog id value. $blog_id = get_current_blog_id(); if (isset($user['site_id']) && 0 !== $user['site_id']) $blog_id = $user['site_id']; // Here, we're switching to the actual blog that we need // to pull users from. $switched = false; if (function_exists('switch_to_blog')) { $switched = switch_to_blog($blog_id); } if (!current_user_can('create_users') && !is_super_admin()) { $result = array('error' => true, 'message' => 'user_create_no_permission', 'data' => array('multisite' => is_multisite())); return $this->_response($result); } if (is_email($user["user_email"]) === false) { $result = array("error" => true, "message" => "email_invalid"); return $this->_response($result); } if (email_exists($user["user_email"]) && is_user_member_of_blog(email_exists($user["user_email"]), $blog_id)) { $result = array("error" => true, "message" => "email_exists"); return $this->_response($result); } if (username_exists($user["user_login"]) && is_user_member_of_blog(username_exists($user["user_login"]), $blog_id)) { $result = array("error" => true, "message" => "username_exists"); return $this->_response($result); } if (!validate_username($user["user_login"])) { $result = array("error" => true, "message" => 'username_invalid'); return $this->_response($result); } if (isset($user['site_id']) && !current_user_can('manage_network_users')) { $result = array("error" => true, "message" => 'user_create_no_permission'); return $this->_response($result); } if (email_exists($user["user_email"]) && !is_user_member_of_blog(email_exists($user["user_email"]), $blog_id)) { $user_id = email_exists($user["user_email"]); } else { $user_id = wp_insert_user($user); } $role = $user['role']; if (is_multisite()) { add_existing_user_to_blog(array('user_id' => $user_id, 'role' => $role)); } // Here, we're restoring to the current (default) blog before we // do the switched. if (function_exists('restore_current_blog') && $switched) { restore_current_blog(); } if ($user_id > 0) { $result = array("error" => false, "message" => "user_created_with_user_name", "values" => array($user['user_login'])); return $this->_response($result); } else { $result = array("error" => true, "message" => "user_create_failed", "values" => array($user)); } return $this->_response($result); } /** * [delete_user - UCP: users.delete_user] * * This function is used to check to make sure the user_id is valid and that it has has user delete permissions. * If there are no issues, the user is deleted. * * current_user_can: This check the user permissions from UCP * get_userdata: This get the user data on the data from user_id in the $user_id array * wp_delete_user: Deleting users on the User ID (user_id) and, IF Specified, the Assigner ID (assign_user_id). * * @param [type] $params [description] THis is an Array of params sent over from UpdraftCentral * @return [type] Array [description] This will send back an error array along with message if there are any issues with the user_id */ public function delete_user($params) { $this->_admin_include('user.php'); $user_id = $params['user_id']; $assign_user_id = $params["assign_user_id"]; // Here, we're getting the current blog id. If blog id // is passed along with the parameters then we override // that current (default) value with the parameter blog id value. $blog_id = get_current_blog_id(); if (isset($params['site_id']) && 0 !== $params['site_id']) $blog_id = $params['site_id']; $switched = false; if (function_exists('switch_to_blog')) { $switched = switch_to_blog($blog_id); } if (!current_user_can('delete_users') && !is_super_admin()) { $result = array('error' => true, 'message' => 'user_delete_no_permission', 'data' => array('multisite' => is_multisite())); return $this->_response($result); } if (get_userdata($user_id) === false) { $result = array("error" => true, "message" => "user_not_found"); return $this->_response($result); } if (wp_delete_user($user_id, $assign_user_id)) { $result = array("error" => false, "message" => "user_deleted"); } else { $result = array("error" => true, "message" => "user_delete_failed"); } // Here, we're restoring to the current (default) blog before we // do the switched. if (function_exists('restore_current_blog') && $switched) { restore_current_blog(); } return $this->_response($result); } /** * Edits existing user information * * @param array $user User information to save * @return array An array containing the result of the current process */ public function edit_user($user) { $this->_admin_include('user.php'); // Here, we're getting the current blog id. If blog id // is passed along with the parameters then we override // that current (default) value with the parameter blog id value. $blog_id = get_current_blog_id(); if (isset($user['site_id']) && 0 !== $user['site_id']) $blog_id = $user['site_id']; // Here, we're switching to the actual blog that we need // to apply our changes. $switched = false; if (function_exists('switch_to_blog')) { $switched = switch_to_blog($blog_id); } if (!current_user_can('edit_users') && !is_super_admin() && get_current_user_id() !== $user["ID"]) { $result = array('error' => true, 'message' => 'user_edit_no_permission', 'data' => array('multisite' => is_multisite())); return $this->_response($result); } if (false === get_userdata($user["ID"])) { $result = array("error" => true, "message" => "user_not_found"); return $this->_response($result); } if (get_current_user_id() == $user["ID"]) { unset($user["role"]); } /* Validate Username*/ if (!validate_username($user["user_login"])) { $result = array("error" => true, "message" => 'username_invalid'); return $this->_response($result); } /* Validate Email if not the same*/ $remote_user = get_userdata($user["ID"]); $old_email = $remote_user->user_email; if ($user['user_email'] !== $old_email) { if (is_email($user['user_email']) === false) { $result = array("error" => true, "message" => 'email_invalid'); return $this->_response($result); } if (email_exists($user['user_email'])) { $result = array("error" => true, "message" => 'email_exists'); return $this->_response($result); } } $user_id = wp_update_user($user); if (is_wp_error($user_id)) { $result = array("error" => true, "message" => "user_edit_failed_with_error", "values" => array($user_id)); } else { $result = array("error" => false, "message" => "user_edited_with_user_name", "values" => array($user["user_login"])); } // Here, we're restoring to the current (default) blog before we // do the switched. if (function_exists('restore_current_blog') && $switched) { restore_current_blog(); } return $this->_response($result); } /** * Retrieves available roles to be used as filter options * * @return array An array containing all available roles */ public function get_roles() { $this->_admin_include('user.php'); $roles = array_reverse(get_editable_roles()); return $this->_response($roles); } /** * Retrieves information to be use as filters * * @return array An array containing the filter fields and their data */ public function get_user_filters() { $this->_admin_include('user.php'); // Pull sites options if available. $sites = $this->_get_blog_sites(); $result = array( "sites" => $sites, "roles" => array_reverse(get_editable_roles()), "paging" => $this->_calculate_pages(null, 0), ); return $this->_response($result); } } central/modules/theme.php000064400000057451152214270100011465 0ustar00switched = switch_to_blog($blog_id); } } /** * Function that gets called after every action * * @param string $command a string that corresponds to UDC command to call a certain method for this class. * @param array $data an array of data post or get fields * @param array $extra_info extrainfo use in the udrpc_action, e.g. user_id * * link to udrpc_action main function in class UpdraftCentral_Listener */ public function _post_action($command, $data, $extra_info) {// phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable -- Unused parameter is present because the caller from UpdraftCentral_Listener class uses 3 arguments. // Here, we're restoring to the current (default) blog before we switched if ($this->switched) restore_current_blog(); } /** * Constructor */ public function __construct() { $this->_admin_include('theme.php', 'file.php', 'template.php', 'class-wp-upgrader.php', 'theme-install.php', 'update.php'); } /** * Installs and activates a theme through upload * * @param array $params Parameter array containing information pertaining the currently uploaded theme * @return array Contains the result of the current process */ public function upload_theme($params) { return $this->process_chunk_upload($params, 'theme'); } /** * Checks whether the theme is currently installed and activated. * * @param array $query Parameter array containing the name of the theme to check * @return array Contains the result of the current process */ public function is_theme_installed($query) { if (!isset($query['theme'])) return $this->_generic_error_response('theme_name_required'); $result = $this->_get_theme_info($query['theme']); return $this->_response($result); } /** * Applies currently requested action for theme processing * * @param string $action The action to apply (e.g. activate or install) * @param array $query Parameter array containing information for the currently requested action * * @return array */ private function _apply_theme_action($action, $query) { $result = array(); switch ($action) { case 'activate': $info = $this->_get_theme_info($query['theme']); if ($info['installed']) { switch_theme($info['slug']); if (wp_get_theme()->get_stylesheet() === $info['slug']) { $result = array('activated' => true, 'info' => $this->_get_theme_info($query['theme']), 'last_state' => $info); } else { $result = $this->_generic_error_response('theme_not_activated', array( 'theme' => $query['theme'], 'error_code' => 'theme_not_activated', 'error_message' => __('There appears to be a problem activating or switching to the intended theme. Please kindly check your permission and try again.', 'updraftplus'), 'info' => $this->_get_theme_info($query['theme']) )); } } else { $result = $this->_generic_error_response('theme_not_installed', array( 'theme' => $query['theme'], 'error_code' => 'theme_not_installed', 'error_message' => __('The theme you wish to activate is either not installed or has been removed recently.', 'updraftplus'), 'info' => $info )); } break; case 'network_enable': $info = $this->_get_theme_info($query['theme']); if ($info['installed']) { if (current_user_can('manage_network_themes')) { // Make sure that network_enable_theme is present and callable since // it is only available at 4.6. If not, we'll do things the old fashion way if (is_callable(array('WP_Theme', 'network_enable_theme'))) { WP_Theme::network_enable_theme($info['slug']); } else { $allowed_themes = get_site_option('allowedthemes'); $allowed_themes[$info['slug']] = true; update_site_option('allowedthemes', $allowed_themes); } } $allowed = WP_Theme::get_allowed_on_network(); if (is_array($allowed) && !empty($allowed[$info['slug']])) { $result = array('enabled' => true, 'info' => $this->_get_theme_info($query['theme']), 'last_state' => $info); } else { $result = $this->_generic_error_response('theme_not_enabled', array( 'theme' => $query['theme'], 'error_code' => 'theme_not_enabled', 'error_message' => __('There appears to be a problem enabling the intended theme on your network. Please kindly check your permission and try again.', 'updraftplus'), 'info' => $this->_get_theme_info($query['theme']) )); } } else { $result = $this->_generic_error_response('theme_not_installed', array( 'theme' => $query['theme'], 'error_code' => 'theme_not_installed', 'error_message' => __('The theme you wish to enable on your network is either not installed or has been removed recently.', 'updraftplus'), 'info' => $info )); } break; case 'network_disable': $info = $this->_get_theme_info($query['theme']); if ($info['installed']) { if (current_user_can('manage_network_themes')) { // Make sure that network_disable_theme is present and callable since // it is only available at 4.6. If not, we'll do things the old fashion way if (is_callable(array('WP_Theme', 'network_disable_theme'))) { WP_Theme::network_disable_theme($info['slug']); } else { $allowed_themes = get_site_option('allowedthemes'); if (isset($allowed_themes[$info['slug']])) { unset($allowed_themes[$info['slug']]); } update_site_option('allowedthemes', $allowed_themes); } } $allowed = WP_Theme::get_allowed_on_network(); if (is_array($allowed) && empty($allowed[$info['slug']])) { $result = array('disabled' => true, 'info' => $this->_get_theme_info($query['theme']), 'last_state' => $info); } else { $result = $this->_generic_error_response('theme_not_disabled', array( 'theme' => $query['theme'], 'error_code' => 'theme_not_disabled', 'error_message' => __('There appears to be a problem disabling the intended theme from your network. Please kindly check your permission and try again.', 'updraftplus'), 'info' => $this->_get_theme_info($query['theme']) )); } } else { $result = $this->_generic_error_response('theme_not_installed', array( 'theme' => $query['theme'], 'error_code' => 'theme_not_installed', 'error_message' => __('The theme you wish to disable from your network is either not installed or has been removed recently.', 'updraftplus'), 'info' => $info )); } break; case 'install': $api = themes_api('theme_information', array( 'slug' => $query['slug'], 'fields' => array( 'description' => true, 'sections' => false, 'rating' => true, 'ratings' => true, 'downloaded' => true, 'downloadlink' => true, 'last_updated' => true, 'screenshot_url' => true, 'parent' => true, ) )); $info = $this->_get_theme_info($query['theme']); if (is_wp_error($api)) { $result = $this->_generic_error_response('generic_response_error', array( 'theme' => $query['theme'], 'error_code' => 'theme_not_installed', 'error_message' => $api->get_error_message(), 'info' => $info )); } else { $installed = $info['installed']; $error_code = $error_message = ''; if (!$installed) { // WP < 3.7 if (!class_exists('Automatic_Upgrader_Skin')) include_once(dirname(dirname(__FILE__)).'/classes/class-automatic-upgrader-skin.php'); $skin = new Automatic_Upgrader_Skin(); $upgrader = new Theme_Upgrader($skin); $download_link = $api->download_link; $installed = $upgrader->install($download_link); if (is_wp_error($installed)) { $error_code = $installed->get_error_code(); $error_message = $installed->get_error_message(); } elseif (is_wp_error($skin->result)) { $error_code = $skin->result->get_error_code(); $error_message = $skin->result->get_error_message(); $error_data = $skin->result->get_error_data($error_code); if (!empty($error_data)) { if (is_array($error_data)) $error_data = json_encode($error_data); $error_message .= ' '.$error_data; } } elseif (is_null($installed) || !$installed) { global $wp_filesystem; $upgrade_messages = $skin->get_upgrade_messages(); if (!class_exists('WP_Filesystem_Base')) include_once(ABSPATH.'/wp-admin/includes/class-wp-filesystem-base.php'); // Pass through the error from WP_Filesystem if one was raised. if ($wp_filesystem instanceof WP_Filesystem_Base && is_wp_error($wp_filesystem->errors) && $wp_filesystem->errors->get_error_code()) { $error_code = $wp_filesystem->errors->get_error_code(); $error_message = $wp_filesystem->errors->get_error_message(); } elseif (!empty($upgrade_messages)) { // We're only after for the last feedback that we received from the install process. Mostly, // that is where the last error has been inserted. $messages = $skin->get_upgrade_messages(); $error_code = 'install_failed'; $error_message = end($messages); } else { $error_code = 'unable_to_connect_to_filesystem'; $error_message = __('Unable to connect to the filesystem. Please confirm your credentials.'); } } } if (!$installed || is_wp_error($installed)) { $result = $this->_generic_error_response('theme_install_failed', array( 'theme' => $query['theme'], 'error_code' => $error_code, 'error_message' => $error_message, 'info' => $this->_get_theme_info($query['theme']) )); } else { $result = array('installed' => true, 'info' => $this->_get_theme_info($query['theme']), 'last_state' => $info); } } break; } return $result; } /** * Preloads the submitted credentials to the global $_POST variable * * @param array $query Parameter array containing information for the currently requested action */ private function _preload_credentials($query) { if (!empty($query) && isset($query['filesystem_credentials'])) { parse_str($query['filesystem_credentials'], $filesystem_credentials); if (is_array($filesystem_credentials)) { foreach ($filesystem_credentials as $key => $value) { // Put them into $_POST, which is where request_filesystem_credentials() checks for them. $_POST[$key] = $value; } } } } /** * Checks whether we have the required fields submitted and the user has * the capabilities to execute the requested action * * @param array $query The submitted information * @param array $fields The required fields to check * @param array $capabilities The capabilities to check and validate * * @return array|string */ private function _validate_fields_and_capabilities($query, $fields, $capabilities) { $error = ''; if (!empty($fields)) { for ($i=0; $i_generic_error_response('keyword_required'); } else { $error = $this->_generic_error_response('theme_'.$query[$field].'_required'); } break; } } } if (empty($error) && !empty($capabilities)) { for ($i=0; $i_generic_error_response('theme_insufficient_permission'); break; } } } return $error; } /** * Processing an action for multiple items * * @param array $query Parameter array containing a list of themes to process * @return array Contains the results of the bulk process */ public function process_action_in_bulk($query) { $action = isset($query['action']) ? $query['action'] : ''; $items = isset($query['args']) ? $query['args']['items'] : array(); $results = array(); if (!empty($action) && !empty($items) && is_array($items)) { foreach ($items as $value) { if (method_exists($this, $action)) { $results[] = $this->$action($value); } } } return $this->_response($results); } /** * Activates the theme * * @param array $query Parameter array containing the name of the theme to activate * @return array Contains the result of the current process */ public function activate_theme($query) { $fields = array('theme'); $permissions = array('switch_themes'); $error = $this->_validate_fields_and_capabilities($query, $fields, $permissions); if (!empty($error)) { return $error; } $this->_preload_credentials($query); $result = $this->_apply_theme_action('activate', $query); if (empty($result['activated'])) { return $result; } return $this->_response($result); } /** * Enables theme for network * * @param array $query Parameter array containing the name of the theme to activate * @return array Contains the result of the current process */ public function network_enable_theme($query) { $fields = array('theme'); $permissions = array('switch_themes'); $error = $this->_validate_fields_and_capabilities($query, $fields, $permissions); if (!empty($error)) { return $error; } $this->_preload_credentials($query); $result = $this->_apply_theme_action('network_enable', $query); if (empty($result['enabled'])) { return $result; } return $this->_response($result); } /** * Disables theme from network * * @param array $query Parameter array containing the name of the theme to activate * @return array Contains the result of the current process */ public function network_disable_theme($query) { $fields = array('theme'); $permissions = array('switch_themes'); $error = $this->_validate_fields_and_capabilities($query, $fields, $permissions); if (!empty($error)) { return $error; } $this->_preload_credentials($query); $result = $this->_apply_theme_action('network_disable', $query); if (empty($result['disabled'])) { return $result; } return $this->_response($result); } /** * Download, install and activates the theme * * @param array $query Parameter array containing the filesystem credentials entered by the user along with the theme name and slug * @return array Contains the result of the current process */ public function install_activate_theme($query) { $fields = array('theme', 'slug'); $permissions = array('install_themes', 'switch_themes'); $error = $this->_validate_fields_and_capabilities($query, $fields, $permissions); if (!empty($error)) { return $error; } $this->_preload_credentials($query); $result = $this->_apply_theme_action('install', $query); if (!empty($result['installed']) && $result['installed']) { $result = $this->_apply_theme_action('activate', $query); if (empty($result['activated'])) { return $result; } } else { return $result; } return $this->_response($result); } /** * Download, install the theme * * @param array $query Parameter array containing the filesystem credentials entered by the user along with the theme name and slug * @return array Contains the result of the current process */ public function install_theme($query) { $fields = array('theme', 'slug'); $permissions = array('install_themes'); $error = $this->_validate_fields_and_capabilities($query, $fields, $permissions); if (!empty($error)) { return $error; } $this->_preload_credentials($query); $result = $this->_apply_theme_action('install', $query); if (empty($result['installed'])) { return $result; } return $this->_response($result); } /** * Uninstall/delete the theme * * @param array $query Parameter array containing the filesystem credentials entered by the user along with the theme name and slug * @return array Contains the result of the current process */ public function delete_theme($query) { $fields = array('theme'); $permissions = array('delete_themes'); $error = $this->_validate_fields_and_capabilities($query, $fields, $permissions); if (!empty($error)) { return $error; } $this->_preload_credentials($query); $info = $this->_get_theme_info($query['theme']); if ($info['installed']) { $deleted = delete_theme($info['slug']); if ($deleted) { $result = array('deleted' => true, 'info' => $this->_get_theme_info($query['theme']), 'last_state' => $info); } else { return $this->_generic_error_response('delete_theme_failed', array( 'theme' => $query['theme'], 'error_code' => 'delete_theme_failed', 'info' => $info )); } } else { return $this->_generic_error_response('theme_not_installed', array( 'theme' => $query['theme'], 'error_code' => 'theme_not_installed', 'info' => $info )); } return $this->_response($result); } /** * Updates/upgrade the theme * * @param array $query Parameter array containing the filesystem credentials entered by the user along with the theme name and slug * @return array Contains the result of the current process */ public function update_theme($query) { $fields = array('theme'); $permissions = array('update_themes'); $error = $this->_validate_fields_and_capabilities($query, $fields, $permissions); if (!empty($error)) { return $error; } $this->_preload_credentials($query); // Make sure that we still have the theme installed before running // the update process $info = $this->_get_theme_info($query['theme']); if ($info['installed']) { // Load the updates command class if not existed if (!class_exists('UpdraftCentral_Updates_Commands')) include_once('updates.php'); $update_command = new UpdraftCentral_Updates_Commands($this->rc); $result = $update_command->update_theme($info['slug']); if (!empty($result['error'])) { $result['values'] = array('theme' => $query['theme'], 'info' => $info); } } else { return $this->_generic_error_response('theme_not_installed', array( 'theme' => $query['theme'], 'error_code' => 'theme_not_installed', 'info' => $info )); } return $this->_response($result); } /** * Gets the theme information along with its active and install status * * @internal * @param array $theme The name of the theme to pull the information from * @return array Contains the theme information */ private function _get_theme_info($theme) { $info = array( 'active' => false, 'installed' => false ); // Clear theme cache so that newly installed/downloaded themes // gets reflected when calling "get_themes" if (function_exists('wp_clean_themes_cache')) { wp_clean_themes_cache(); } // Gets all themes available. $themes = wp_get_themes(); $current_theme_slug = basename(get_stylesheet_directory()); // Loops around each theme available. foreach ($themes as $slug => $value) { $name = $value->get('Name'); $theme_name = !empty($name) ? $name : $slug; // If the theme name matches that of the specified name, it will gather details. if ($theme_name === $theme) { $info['installed'] = true; $info['active'] = ($slug === $current_theme_slug) ? true : false; $info['slug'] = $slug; $info['data'] = $value; $info['name'] = $theme_name; break; } } return $info; } /** * Loads all available themes with additional attributes and settings needed by UpdraftCentral * * @param array $query Parameter array Any available parameters needed for this action * @return array Contains the result of the current process */ public function load_themes($query) { $permissions = array('install_themes', 'switch_themes'); $args = array(); if (is_multisite() && !is_super_admin(get_current_user_id())) { $permissions = array('switch_themes'); $args = array('allowed' => true, 'blog_id' => get_current_blog_id()); } $error = $this->_validate_fields_and_capabilities($query, array(), $permissions); if (!empty($error)) { return $error; } $website = get_bloginfo('name'); $results = array(); // Load the updates command class if not existed if (!class_exists('UpdraftCentral_Updates_Commands')) include_once('updates.php'); $updates = new UpdraftCentral_Updates_Commands($this->rc); // Get themes for update $theme_updates = (array) $updates->get_item_updates('themes'); // Get all themes $themes = wp_get_themes($args); $current_theme_slug = basename(get_stylesheet_directory()); foreach ($themes as $slug => $value) { $name = $value->get('Name'); $theme_name = !empty($name) ? $name : $slug; $theme = new stdClass(); $theme->name = $theme_name; $theme->description = $value->get('Description'); $theme->slug = $slug; $theme->version = $value->get('Version'); $theme->author = $value->get('Author'); $theme->status = ($slug === $current_theme_slug) ? 'active' : 'inactive'; $template = $value->get('Template'); $theme->child_theme = !empty($template) ? true : false; $theme->website = $website; $theme->multisite = is_multisite(); $theme->site_url = trailingslashit(get_bloginfo('url')); if ($theme->child_theme) { $parent_theme = wp_get_theme($template); $parent_name = $parent_theme->get('Name'); $theme->parent = !empty($parent_name) ? $parent_name : $parent_theme->get_stylesheet(); } if (!empty($theme_updates[$slug])) { $update_info = $theme_updates[$slug]; if (version_compare($theme->version, $update_info->update['new_version'], '<')) { if (!empty($update_info->update['new_version'])) $theme->latest_version = $update_info->update['new_version']; if (!empty($update_info->update['package'])) $theme->download_link = $update_info->update['package']; } } if (empty($theme->short_description) && !empty($theme->description)) { // Only pull the first sentence as short description, it should be enough rather than displaying // an empty description or a full blown one which the user can access anytime if they press on // the view details link in UpdraftCentral. $temp = explode('.', $theme->description); $short_description = $temp[0]; // Adding the second sentence wouldn't hurt, in case the first sentence is too short. if (isset($temp[1])) $short_description .= '.'.$temp[1]; $theme->short_description = $short_description.'.'; } $results[] = $theme; } $result = array( 'themes' => $results, 'theme_updates' => $theme_updates, 'is_super_admin' => is_super_admin(), ); $result = array_merge($result, $this->_get_backup_credentials_settings(get_theme_root())); return $this->_response($result); } /** * Gets the backup and security credentials settings for this website * * @param array $query Parameter array Any available parameters needed for this action * @return array Contains the result of the current process */ public function get_theme_requirements() { return $this->_response($this->_get_backup_credentials_settings(get_theme_root())); } } central/modules/updates.php000064400000074022152214270100012021 0ustar00_generic_error_response('invalid_data'); if (!empty($updates['plugins']) && !current_user_can('update_plugins')) return $this->_generic_error_response('updates_permission_denied', 'update_plugins'); if (!empty($updates['themes']) && !current_user_can('update_themes')) return $this->_generic_error_response('updates_permission_denied', 'update_themes'); if (!empty($updates['core']) && !current_user_can('update_core')) return $this->_generic_error_response('updates_permission_denied', 'update_core'); if (!empty($updates['translations']) && !$this->user_can_update_translations()) return $this->_generic_error_response('updates_permission_denied', 'update_translations'); $this->_admin_include('plugin.php', 'update.php', 'file.php', 'template.php'); $this->_frontend_include('update.php'); if (!empty($updates['meta']) && isset($updates['meta']['filesystem_credentials'])) { parse_str($updates['meta']['filesystem_credentials'], $filesystem_credentials); if (is_array($filesystem_credentials)) { foreach ($filesystem_credentials as $key => $value) { // Put them into $_POST, which is where request_filesystem_credentials() checks for them. $_POST[$key] = $value; } } } $plugins = empty($updates['plugins']) ? array() : $updates['plugins']; $plugin_updates = array(); foreach ($plugins as $plugin_info) { $plugin_updates[] = $this->_update_plugin($plugin_info['plugin'], $plugin_info['slug']); } $themes = empty($updates['themes']) ? array() : $updates['themes']; $theme_updates = array(); foreach ($themes as $theme_info) { $theme = $theme_info['theme']; $theme_updates[] = $this->_update_theme($theme); } $cores = empty($updates['core']) ? array() : $updates['core']; $core_updates = array(); foreach ($cores as $core) { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable -- We dont use $core but we need the AS in the foreach so it needs to stay $core_updates[] = $this->_update_core(null); // Only one (and always we go to the latest version) - i.e. we ignore the passed parameters break; } $translation_updates = array(); if (!empty($updates['translations'])) { $translation_updates[] = $this->_update_translation(); } return $this->_response(array( 'plugins' => $plugin_updates, 'themes' => $theme_updates, 'core' => $core_updates, 'translations' => $translation_updates, )); } /** * Updates a plugin. A facade method that exposes a private updates * feature for other modules to consume. * * @param string $plugin Specific plugin to be updated * @param string $slug Unique key passed for updates * * @return array */ public function update_plugin($plugin, $slug) { return $this->_update_plugin($plugin, $slug); } /** * Updates a theme. A facade method that exposes a private updates * feature for other modules to consume. * * @param string $theme Specific theme to be updated * * @return array */ public function update_theme($theme) { return $this->_update_theme($theme); } /** * Gets available updates for a certain entity (e.g. plugin or theme). A facade method that * exposes a private updates feature for other modules to consume. * * @param string $entity The name of the entity that this request is intended for (e.g. themes or plugins) * * @return array */ public function get_item_updates($entity) { $updates = array(); switch ($entity) { case 'themes': wp_update_themes(); $updates = $this->maybe_add_third_party_items(get_theme_updates(), 'theme'); break; case 'plugins': wp_update_plugins(); $updates = $this->maybe_add_third_party_items(get_plugin_updates(), 'plugin'); break; } return $updates; } /** * Mostly from wp_ajax_update_plugin() in wp-admin/includes/ajax-actions.php (WP 4.5.2) * Code-formatting style has been retained from the original, for ease of comparison/updating * * @param string $plugin Specific plugin to be updated * @param string $slug Unique key passed for updates * @return array */ private function _update_plugin($plugin, $slug) { $status = array( 'update' => 'plugin', 'plugin' => $plugin, 'slug' => sanitize_key($slug), 'oldVersion' => '', 'newVersion' => '', ); if (false !== strpos($plugin, '..') || false !== strpos($plugin, ':') || !preg_match('#^[^\/]#i', $plugin)) { $status['error'] = 'not_found'; return $status; } $plugin_data = get_plugin_data(WP_PLUGIN_DIR . '/' . $plugin); if (!isset($plugin_data['Name']) || !isset($plugin_data['Author']) || ('' == $plugin_data['Name'] && '' == $plugin_data['Author'])) { $status['error'] = 'not_found'; return $status; } if ($plugin_data['Version']) { $status['oldVersion'] = $plugin_data['Version']; } if (!current_user_can('update_plugins')) { $status['error'] = 'updates_permission_denied'; return $status; } include_once(ABSPATH . 'wp-admin/includes/class-wp-upgrader.php'); wp_update_plugins(); // WP < 3.7 if (!class_exists('Automatic_Upgrader_Skin')) include_once(UPDRAFTCENTRAL_CLIENT_DIR.'/classes/class-automatic-upgrader-skin.php'); $skin = new Automatic_Upgrader_Skin(); $upgrader = new Plugin_Upgrader($skin); $result = $upgrader->bulk_upgrade(array($plugin)); if (is_array($result) && empty($result[$plugin]) && is_wp_error($skin->result)) { $result = $skin->result; } $status['messages'] = $upgrader->skin->get_upgrade_messages(); if (is_array($result) && !empty($result[$plugin])) { $plugin_update_data = current($result); /* * If the `update_plugins` site transient is empty (e.g. when you update * two plugins in quick succession before the transient repopulates), * this may be the return. * * Preferably something can be done to ensure `update_plugins` isn't empty. * For now, surface some sort of error here. */ if (true === $plugin_update_data) { $status['error'] = 'update_failed'; return $status; } if (is_wp_error($result[$plugin])) { $status['error'] = $result[$plugin]->get_error_code(); $status['error_message'] = $result[$plugin]->get_error_message(); return $status; } $plugin_data = get_plugins('/' . $result[$plugin]['destination_name']); $plugin_data = reset($plugin_data); if ($plugin_data['Version']) { $status['newVersion'] = $plugin_data['Version']; } return $status; } elseif (is_wp_error($result)) { $status['error'] = $result->get_error_code(); $status['error_message'] = $result->get_error_message(); return $status; } elseif (is_bool($result) && !$result) { $status['error'] = 'unable_to_connect_to_filesystem'; global $wp_filesystem; // Pass through the error from WP_Filesystem if one was raised if (isset($wp_filesystem->errors) && is_wp_error($wp_filesystem->errors) && $wp_filesystem->errors->get_error_code()) { $status['error'] = $wp_filesystem->errors->get_error_code(); $status['error_message'] = $wp_filesystem->errors->get_error_message(); } return $status; } else { // An unhandled error occurred $status['error'] = 'update_failed'; return $status; } } /** * Adapted from _update_theme (above) * * @param string $core * @return array */ private function _update_core($core) { global $wp_filesystem; $status = array( 'update' => 'core', 'core' => $core, 'oldVersion' => '', 'newVersion' => '', ); // THis is included so we can get $wp_version include(ABSPATH.WPINC.'/version.php'); $status['oldVersion'] = $wp_version;// phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UndefinedVariable -- The variable is defined inside the ABSPATH.WPINC.'/version.php'. if (!current_user_can('update_core')) { $status['error'] = 'updates_permission_denied'; return $status; } include_once(ABSPATH . 'wp-admin/includes/class-wp-upgrader.php'); wp_version_check(); $locale = get_locale();// phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable -- Unused variable is for future use. $core_update_key = false; $core_update_latest_version = false; $get_core_updates = get_core_updates(); // THis is included so we can get $wp_version @include(ABSPATH.WPINC.'/version.php');// phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged -- Silenced to suppress errors that may arise because of the function. foreach ($get_core_updates as $k => $core_update) { if (isset($core_update->version) && version_compare($core_update->version, $wp_version, '>') && version_compare($core_update->version, $core_update_latest_version, '>')) {// phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UndefinedVariable -- The variable is defined inside the ABSPATH.WPINC.'/version.php'. $core_update_latest_version = $core_update->version; $core_update_key = $k; } } if (false === $core_update_key) { $status['error'] = 'no_update_found'; return $status; } $update = $get_core_updates[$core_update_key]; // WP < 3.7 if (!class_exists('Automatic_Upgrader_Skin')) include_once(UPDRAFTCENTRAL_CLIENT_DIR.'/classes/class-automatic-upgrader-skin.php'); $skin = new Automatic_Upgrader_Skin(); $upgrader = new Core_Upgrader($skin); $result = $upgrader->upgrade($update); $status['messages'] = $upgrader->skin->get_upgrade_messages(); if (is_wp_error($result)) { $status['error'] = $result->get_error_code(); $status['error_message'] = $result->get_error_message(); return $status; } elseif (is_bool($result) && !$result) { $status['error'] = 'unable_to_connect_to_filesystem'; // Pass through the error from WP_Filesystem if one was raised if (is_wp_error($wp_filesystem->errors) && $wp_filesystem->errors->get_error_code()) { $status['error'] = $wp_filesystem->errors->get_error_code(); $status['error_message'] = $wp_filesystem->errors->get_error_message(); } return $status; } elseif (preg_match('/^[0-9]/', $result)) { $status['newVersion'] = $result; return $status; } else { // An unhandled error occurred $status['error'] = 'update_failed'; return $status; } } private function _update_theme($theme) { global $wp_filesystem; $status = array( 'update' => 'theme', 'theme' => $theme, 'oldVersion' => '', 'newVersion' => '', ); if (false !== strpos($theme, '/') || false !== strpos($theme, '\\')) { $status['error'] = 'not_found'; return $status; } $theme_version = $this->get_theme_version($theme); if (false === $theme_version) { $status['error'] = 'not_found'; return $status; } $status['oldVersion'] = $theme_version; if (!current_user_can('update_themes')) { $status['error'] = 'updates_permission_denied'; return $status; } include_once(ABSPATH . 'wp-admin/includes/class-wp-upgrader.php'); wp_update_themes(); // WP < 3.7 if (!class_exists('Automatic_Upgrader_Skin')) include_once(UPDRAFTCENTRAL_CLIENT_DIR.'/classes/class-automatic-upgrader-skin.php'); $skin = new Automatic_Upgrader_Skin(); $upgrader = new Theme_Upgrader($skin); $upgrader->init(); $result = $upgrader->bulk_upgrade(array($theme)); if (is_array($result) && empty($result[$theme]) && is_wp_error($skin->result)) { $result = $skin->result; } $status['messages'] = $upgrader->skin->get_upgrade_messages(); if (is_array($result) && !empty($result[$theme])) { $theme_update_data = current($result); /* * If the `update_themes` site transient is empty (e.g. when you update * two plugins in quick succession before the transient repopulates), * this may be the return. * * Preferably something can be done to ensure `update_themes` isn't empty. * For now, surface some sort of error here. */ if (true === $theme_update_data) { $status['error'] = 'update_failed'; return $status; } $new_theme_version = $this->get_theme_version($theme); if (false === $new_theme_version) { $status['error'] = 'update_failed'; return $status; } $status['newVersion'] = $new_theme_version; return $status; } elseif (is_wp_error($result)) { $status['error'] = $result->get_error_code(); $status['error_message'] = $result->get_error_message(); return $status; } elseif (is_bool($result) && !$result) { $status['error'] = 'unable_to_connect_to_filesystem'; // Pass through the error from WP_Filesystem if one was raised if (is_wp_error($wp_filesystem->errors) && $wp_filesystem->errors->get_error_code()) { $status['error'] = $wp_filesystem->errors->get_error_code(); $status['error_message'] = $wp_filesystem->errors->get_error_message(); } return $status; } else { // An unhandled error occurred $status['error'] = 'update_failed'; return $status; } } /** * Updates available translations for this website * * @return Array */ private function _update_translation() { global $wp_filesystem; $status = array(); include_once(ABSPATH . 'wp-admin/includes/class-wp-upgrader.php'); if (!class_exists('Automatic_Upgrader_Skin')) include_once(UPDRAFTCENTRAL_CLIENT_DIR.'/classes/class-automatic-upgrader-skin.php'); $skin = new Automatic_Upgrader_Skin(); $upgrader = new Language_Pack_Upgrader($skin); $result = $upgrader->bulk_upgrade(); if (is_array($result) && !empty($result)) { $status['success'] = true; } elseif (is_wp_error($result)) { $status['error'] = $result->get_error_code(); $status['error_message'] = $result->get_error_message(); } elseif (is_bool($result) && !$result) { $status['error'] = 'unable_to_connect_to_filesystem'; // Pass through the error from WP_Filesystem if one was raised if (is_wp_error($wp_filesystem->errors) && $wp_filesystem->errors->get_error_code()) { $status['error'] = $wp_filesystem->errors->get_error_code(); $status['error_message'] = $wp_filesystem->errors->get_error_message(); } } elseif (is_bool($result) && $result) { $status['error'] = 'up_to_date'; } else { // An unhandled error occurred $status['error'] = 'update_failed'; } return $status; } private function get_theme_version($theme) { if (function_exists('wp_get_theme')) { // Since WP 3.4.0 $theme = wp_get_theme($theme); if (is_a($theme, 'WP_Theme')) { return $theme->Version; } else { return false; } } else { $theme_data = get_theme_data(WP_CONTENT_DIR . '/themes/'.$theme.'/style.css'); if (isset($theme_data['Version'])) { return $theme_data['Version']; } else { return false; } } } /** * Adding third-party plugins/theme for UDC automatic updates, for some updaters which store their information when the transient is set, instead of (like most) when it is fetched * * @param Array $items A collection of plugins or themes for updates * @param String $type A string indicating which type of collection to process (e.g. 'plugin' or 'theme') * @return Array An updated collection of plugins or themes for updates */ private function maybe_add_third_party_items($items, $type) { // Here we're preparing a dummy transient object that will be pass to the filter // and gets populated by those plugins or themes that hooked into the "pre_set_site_transient_*" filter. // // We're setting some default properties so that plugins and themes won't be able to bypass populating them, // because most of the plugins and themes updater scripts checks whether or not these properties are set and // non-empty or passed the 12 hour period (where WordPress re-starts the process of checking updates for // these plugins and themes), otherwise, they bypass populating the update/upgrade info for these items. $transient = (object) array( 'last_checked' => time() - (13 * 3600), /* Making sure that we passed the 12 hour period check */ 'checked' => array('default' => 'none'), 'response' => array('default' => 'none') ); // Most of the premium plugin developers are hooking into the "pre_set_site_transient_update_plugins" and // "pre_set_site_transient_update_themes" filters if they want their plugins or themes to support automatic // updates. Thus, we're making sure here that if for some reason, those plugins or themes didn't get through // and added to the "update_plugins" or "update_themes" transients when calling the get_site_transient('update_plugins') // or get_site_transient('update_themes') we add them here manually. $filters = apply_filters("pre_set_site_transient_update_{$type}s", $transient, "update_{$type}s"); $all_items = array(); switch ($type) { case 'plugin': $all_items = get_plugins(); break; case 'theme': $this->_frontend_include('theme.php'); if (function_exists('wp_get_themes')) { $themes = wp_get_themes(); if (!empty($themes)) { // We make sure that the return key matched the previous // key from "get_themes", otherwise, no updates will be found // even if it does have one. "get_themes" returns the name of the // theme as the key while "wp_get_themes" returns the slug. foreach ($themes as $theme) { $all_items[$theme->Name] = $theme; } } } else { $all_items = get_themes(); } break; default: break; } if (!empty($all_items)) { $all_items = (array) $all_items; foreach ($all_items as $key => $data) { if (!isset($items[$key]) && isset($filters->response[$key])) { $update_info = ('plugin' === $type) ? $filters->response[$key] : $data; // If "package" is empty, it means that this plugin or theme does not support automatic updates // currently, since the "package" field is the one holding the download link of these plugins/themes // and WordPress is using this field to download the latest version of these items. // // Most of the time, this "package" field is not empty, but for premium plugins/themes this can be // conditional, only then if the user provides a legit access or api key can this field be populated or available. // // We set this variable to "false" by default, as plugins/themes hosted in wordpress.org always sets this // to the downloadable zip file of the plugin/theme. // // N.B. We only add premium plugins/themes that has this "package" field set and non-empty, otherwise, it // does not support automatic updates as explained above. $is_package_empty = false; if (is_object($update_info)) { if (!isset($update_info->package) || empty($update_info->package)) { $is_package_empty = true; } } elseif (is_array($update_info)) { if (!isset($update_info['package']) || empty($update_info['package'])) { $is_package_empty = true; } } // Add this plugin/theme to the current updates collection if (!$is_package_empty) { $items[$key] = ('plugin' === $type) ? (object) $data : $this->get_theme_info($key); $items[$key]->update = $update_info; } } } } return $this->prep_items_for_updates($items, $type); } /** * Extracts theme's data or information * * @param string $theme A string representing a theme's name or slug. * @return object|boolean If successful, an object containing the theme data or information, "false" otherwise. */ private function get_theme_info($theme) { if (function_exists('wp_get_theme')) { $theme = wp_get_theme($theme); if (is_a($theme, 'WP_Theme')) { return $theme; } } else { $theme_data = get_theme_data(WP_CONTENT_DIR.'/themes/'.$theme.'/style.css'); if (isset($theme_data['Version'])) { if (!isset($theme_data['ThemeURI'])) $theme_data['ThemeURI'] = $theme_data['URI']; return (object) $theme_data; } } return false; } /** * Fix items for update with missing "plugin" or "theme" field if applicable * * @param Array $items A collection of plugins or themes for updates * @param String $type A string indicating which type of collection to process (e.g. 'plugin' or 'theme') * @return Array An updated collection of plugins or themes for updates */ private function prep_items_for_updates($items, $type) { foreach ($items as $key => $data) { $update_info = $data->update; // Some plugins and/or themes does not adhere to the standard WordPress updates meta // properties/fields. Thus, missing some fields such as "plugin" or "theme" // in their update information results in "Automatic updates is unavailable for this item" // in UDC since we're using these fields to process the updates. // // As a workaround, we're filling these missing fields in order to solve the above issue // in case the developer of these plugins/themes forgot to include them. if (is_object($update_info)) { $update_info = (array) $update_info; if (!isset($update_info[$type])) { $update_info[$type] = $key; } $update_info = (object) $update_info; } elseif (is_array($update_info)) { if (!isset($update_info[$type])) { $update_info[$type] = $key; } } // Re-assign the updated info to the original "update" property $items[$key]->update = $update_info; } return $items; } /** * Custom validation for translation permission. Since the 'install_languages' capability insn't available until 4.9 * therefore, we wrapped the validation check in this block to support older version of WP. * * @return Boolean */ private function user_can_update_translations() { global $updraftcentral_main; $wp_version = $updraftcentral_main->get_wordpress_version(); if (version_compare($wp_version, '4.9', '<')) { if (current_user_can('update_core') || current_user_can('update_plugins') || current_user_can('update_themes')) return true; } else { if (current_user_can('install_languages')) return true; } return false; } public function get_updates($options) { // Forcing Elegant Themes (Divi) updates component to load if it exist. if (function_exists('et_register_updates_component')) et_register_updates_component(); if (!current_user_can('update_plugins') && !current_user_can('update_themes') && !current_user_can('update_core')) return $this->_generic_error_response('updates_permission_denied'); $this->_admin_include('plugin.php', 'update.php', 'file.php', 'template.php'); $this->_frontend_include('update.php'); if (!is_array($options)) $options = array(); // Normalise it $plugin_updates = array(); if (current_user_can('update_plugins')) { // Detect if refresh needed $transient = get_site_transient('update_plugins'); if (!empty($options['force_refresh']) || false === $transient) { delete_site_transient('update_plugins'); wp_update_plugins(); } $get_plugin_updates = $this->maybe_add_third_party_items(get_plugin_updates(), 'plugin'); if (is_array($get_plugin_updates)) { foreach ($get_plugin_updates as $update) { // For some reason, some 3rd-party (premium) plugins are returning the same version // with that of the currently installed version in WordPress. Thus, we're making sure here to // only return those items for update that has new versions greater than the currently installed version. if (version_compare($update->Version, $update->update->new_version, '>=')) continue; $plugin_updates[] = array( 'name' => $update->Name, 'plugin_uri' => $update->PluginURI, 'version' => $update->Version, 'description' => $update->Description, 'author' => $update->Author, 'author_uri' => $update->AuthorURI, 'title' => $update->Title, 'author_name' => $update->AuthorName, 'update' => array( // With Affiliates-WP, if you have not connected, this is null. 'plugin' => isset($update->update->plugin) ? $update->update->plugin : null, 'slug' => $update->update->slug, 'new_version' => $update->update->new_version, 'package' => $update->update->package, 'tested' => isset($update->update->tested) ? $update->update->tested : null, 'compatibility' => isset($update->update->compatibility) ? (array) $update->update->compatibility : null, 'sections' => isset($update->update->sections) ? (array) $update->update->sections : null, ), ); } } } $theme_updates = array(); if (current_user_can('update_themes')) { // Detect if refresh needed $transient = get_site_transient('update_themes'); if (!empty($options['force_refresh']) || false === $transient) { delete_site_transient('update_themes'); wp_update_themes(); } $get_theme_updates = $this->maybe_add_third_party_items(get_theme_updates(), 'theme'); if (is_array($get_theme_updates)) { foreach ($get_theme_updates as $update) { // We're making sure here to only return those items for update that has new // versions greater than the currently installed version. if (version_compare($update->Version, $update->update['new_version'], '>=')) continue; $name = $update->Name; $theme_name = !empty($name) ? $name : $update->update['theme']; $theme_updates[] = array( 'name' => $theme_name, 'theme_uri' => $update->ThemeURI, 'version' => $update->Version, 'description' => $update->Description, 'author' => $update->Author, 'author_uri' => $update->AuthorURI, 'update' => array( 'theme' => $update->update['theme'], 'new_version' => $update->update['new_version'], 'package' => $update->update['package'], 'url' => $update->update['url'], ), ); } } } $core_updates = array(); if (current_user_can('update_core')) { // Detect if refresh needed $transient = get_site_transient('update_core'); if (!empty($options['force_refresh']) || false === $transient) { // The next line is only needed for older WP versions - otherwise, the parameter to wp_version_check forces a check. delete_site_transient('update_core'); wp_version_check(array(), true); } $get_core_updates = get_core_updates(); if (is_array($get_core_updates)) { $core_update_key = false; $core_update_latest_version = false; // THis is included so we can get $wp_version @include(ABSPATH.WPINC.'/version.php');// phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged -- Silenced to suppress errors that may arise because of the function. foreach ($get_core_updates as $k => $core_update) { if (isset($core_update->version) && version_compare($core_update->version, $wp_version, '>') && version_compare($core_update->version, $core_update_latest_version, '>')) {// phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UndefinedVariable -- The variable is defined inside the ABSPATH.WPINC.'/version.php'. $core_update_latest_version = $core_update->version; $core_update_key = $k; } } if (false !== $core_update_key) { $update = $get_core_updates[$core_update_key]; global $wpdb; $mysql_version = $wpdb->db_version(); $is_mysql = (file_exists(WP_CONTENT_DIR . '/db.php') && empty($wpdb->is_mysql)) ? false : true; // We're making sure here to only return those items for update that has new // versions greater than the currently installed version. if (version_compare($wp_version, $update->version, '<')) {// phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UndefinedVariable -- The variable is defined inside the ABSPATH.WPINC.'/version.php'. $core_updates[] = array( 'download' => $update->download, 'version' => $update->version, 'php_version' => $update->php_version, 'mysql_version' => $update->mysql_version, 'installed' => array( 'version' => $wp_version,// phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UndefinedVariable -- The variable is defined inside the ABSPATH.WPINC.'/version.php'. 'mysql' => $mysql_version, 'php' => PHP_VERSION, 'is_mysql' => $is_mysql, ), 'sufficient' => array( 'mysql' => version_compare($mysql_version, $update->mysql_version, '>='), 'php' => version_compare(PHP_VERSION, $update->php_version, '>='), ), ); } } } } $translation_updates = array(); if (function_exists('wp_get_translation_updates') && $this->user_can_update_translations()) { $translations = wp_get_translation_updates(); $translation_updates = array( 'items' => $translations ); } // Do we need to ask the user for filesystem credentials? $request_filesystem_credentials = array(); $check_fs = array( 'plugins' => WP_PLUGIN_DIR, 'themes' => WP_CONTENT_DIR.'/themes', 'core' => untrailingslashit(ABSPATH) ); if (!empty($translation_updates)) { // 'en_US' don't usually have the "languages" folder, thus, we // check if there's a need to ask for filesystem credentials for that // folder if it exists, most especially for locale other than 'en_US'. $language_dir = WP_CONTENT_DIR.'/languages'; if ('en_US' !== get_locale() && is_dir($language_dir)) { $check_fs['translations'] = $language_dir; } } foreach ($check_fs as $entity => $dir) { $filesystem_method = get_filesystem_method(array(), $dir); ob_start(); $filesystem_credentials_are_stored = request_filesystem_credentials(site_url()); $filesystem_form = strip_tags(ob_get_contents(), '

'); ob_end_clean(); $request_filesystem_credentials[$entity] = ('direct' != $filesystem_method && !$filesystem_credentials_are_stored); } $automatic_backups = (class_exists('UpdraftPlus_Options') && class_exists('UpdraftPlus_Addon_Autobackup') && UpdraftPlus_Options::get_updraft_option('updraft_autobackup_default', true)) ? true : false; return $this->_response(array( 'plugins' => $plugin_updates, 'themes' => $theme_updates, 'core' => $core_updates, 'translations' => $translation_updates, 'meta' => array( 'request_filesystem_credentials' => $request_filesystem_credentials, 'filesystem_form' => $filesystem_form, 'automatic_backups' => $automatic_backups ), )); } } central/modules/comments.php000064400000065711152214270100012206 0ustar00 'ID', 'order' => 'DESC', 'type' => $query['type'], 'status' => $query['status'], 'search' => esc_attr($query['search']), ); $query = new WP_Comment_Query; $found_comments = $query->query($args); $comments = array(); foreach ($found_comments as $comment) { // We're returning a collection of comment in an array, // in sync with the originator of the request on the ui side // so, we're pulling it one by one into the array before // returning it. if (!in_array($comment, $comments)) { array_push($comments, $comment); } } return $comments; } /** * The _calculate_pages function generates and builds the pagination links * based on the current search parameters/filters. Please see _search_comments * for the breakdown of these parameters. * * @param array $query Query to generate pagination links * @return array */ private function _calculate_pages($query) { $per_page_options = array(10, 20, 30, 40, 50); if (!empty($query)) { if (!empty($query['search'])) { return array( 'page_count' => 1, 'page_no' => 1 ); } $pages = array(); $page_query = new WP_Comment_Query; // Here, we're pulling the comments based on the // two parameters namely type and status. // // The number of results/comments found will then // be use to compute for the number of pages to be // displayed as navigation links when browsing all // comments from the frontend. $comments = $page_query->query(array( 'type' => $query['type'], 'status' => $query['status'] )); $total_comments = count($comments); $page_count = ceil($total_comments / $query['per_page']); if ($page_count > 1) { for ($i = 0; $i < $page_count; $i++) { if ($i + 1 == $query['page_no']) { $paginator_item = array( 'value' => $i+1, 'setting' => 'disabled' ); } else { $paginator_item = array( 'value' => $i+1 ); } array_push($pages, $paginator_item); } if ($query['page_no'] >= $page_count) { $page_next = array( 'value' => $page_count, 'setting' => 'disabled' ); } else { $page_next = array( 'value' => $query['page_no'] + 1 ); } if (1 === $query['page_no']) { $page_prev = array( 'value' => 1, 'setting' => 'disabled' ); } else { $page_prev = array( 'value' => $query['page_no'] - 1 ); } return array( 'page_no' => $query['page_no'], 'per_page' => $query['per_page'], 'page_count' => $page_count, 'pages' => $pages, 'page_next' => $page_next, 'page_prev' => $page_prev, 'total_results' => $total_comments, 'per_page_options' => $per_page_options ); } else { return array( 'page_no' => $query['page_no'], 'per_page' => $query['per_page'], 'page_count' => $page_count, 'total_results' => $total_comments, 'per_page_options' => $per_page_options ); } } else { return array( 'per_page_options' => $per_page_options ); } } /** * The get_blog_sites function pulls blog sites available for the current WP instance. * If Multisite is enabled on the server, then sites under the network will be pulled, otherwise, it will return an empty array. * * @return array */ private function get_blog_sites() { if (!is_multisite()) return array(); // Initialize array container $sites = $network_sites = array(); // Check to see if latest get_sites (available on WP version >= 4.6) function is // available to pull any available sites from the current WP instance. If not, then // we're going to use the fallback function wp_get_sites (for older version). if (function_exists('get_sites') && class_exists('WP_Site_Query')) { $network_sites = get_sites(); } else { if (function_exists('wp_get_sites')) { $network_sites = wp_get_sites(); } } // We only process if sites array is not empty, otherwise, bypass // the next block. if (!empty($network_sites)) { foreach ($network_sites as $site) { // Here we're checking if the site type is an array, because // we're pulling the blog_id property based on the type of // site returned. // get_sites returns an array of object, whereas the wp_get_sites // function returns an array of array. $blog_id = (is_array($site)) ? $site['blog_id'] : $site->blog_id; // We're saving the blog_id and blog name as an associative item // into the sites array, that will be used as "Sites" option in // the frontend. $sites[$blog_id] = get_blog_details($blog_id)->blogname; } } return $sites; } /** * The get_wp_option function pulls current blog options * from the database using either following functions: * - get_blog_option (for multisite) * - get_option (for ordinary blog) * * @param array $blog_id This is the specific blog ID * @param array $setting specifies settings * @return array */ private function _get_wp_option($blog_id, $setting) { return is_multisite() ? get_blog_option($blog_id, $setting) : get_option($setting); } /** * The get_comments function pull all the comments from the database * based on the current search parameters/filters. Please see _search_comments * for the breakdown of these parameters. * * @param array $query Specific query to pull comments * @return array */ public function get_comments($query) { // Here, we're getting the current blog id. If blog id // is passed along with the parameters then we override // that current (default) value with the parameter blog id value. $blog_id = get_current_blog_id(); if (isset($query['blog_id'])) $blog_id = $query['blog_id']; // Here, we're switching to the actual blog that we need // to pull comments from. $switched = false; if (function_exists('switch_to_blog')) { $switched = switch_to_blog($blog_id); } if (!empty($query['search'])) { // If a search keyword is present, then we'll call the _search_comments // function to process the query. $comments = $this->_search_comments($query); } else { // Set default parameter values if the designated // parameters are empty. if (empty($query['per_page'])) { $query['per_page'] = 10; } if (empty($query['page_no'])) { $query['page_no'] = 1; } if (empty($query['type'])) { $query['type'] = ''; } if (empty($query['status'])) { $query['status'] = ''; } // Since WP_Comment_Query parameters doesn't have a "page" attribute, we // need to compute for the offset to get the exact content based on the // current page and the number of items per page. $offset = ((int) $query['page_no'] - 1) * (int) $query['per_page']; $args = array( 'orderby' => 'ID', 'order' => 'DESC', 'number' => $query['per_page'], 'offset' => $offset, 'type' => $query['type'], 'status' => $query['status'] ); $comments_query = new WP_Comment_Query; $comments = $comments_query->query($args); } // If no comments are found based on the current query then // we return with error. if (empty($comments)) { $result = array('message' => 'comments_not_found'); return $this->_response($result); } // Otherwise, we're going to process each comment // before we return it to the one issuing the request. // // Process in the sense that we add additional related info // such as the post tile where the comment belongs to, the // comment status, a formatted date field, and to which parent comment // does the comment was intended to be as a reply. foreach ($comments as &$comment) { $comment = get_comment($comment->comment_ID, ARRAY_A); if ($comment) { $post = get_post($comment['comment_post_ID']); if ($post) $comment['in_response_to'] = $post->post_title; if (!empty($comment['comment_parent'])) { $parent_comment = get_comment($comment['comment_parent'], ARRAY_A); if ($parent_comment) $comment['in_reply_to'] = $parent_comment['comment_author']; } // We're formatting the comment_date to be exactly the same // with that of WP Comments table (e.g. 2016/12/21 at 10:30 PM) $comment['comment_date'] = date('Y/m/d \a\t g:i a', strtotime($comment['comment_date'])); $status = wp_get_comment_status($comment['comment_ID']); if ($status) { $comment['comment_status'] = $status; } } } // We return the following to the one issuing // the request. $result = array( 'comments' => $comments, 'paging' => $this->_calculate_pages($query) ); // Here, we're restoring to the current (default) blog before we // do the switched. if (function_exists('restore_current_blog') && $switched) { restore_current_blog(); } return $this->_response($result); } /** * The get_comment_filters function builds a array of options * to be use as filters for the search function on the frontend. */ public function get_comment_filters() { // Options for comment_types field $comment_types = apply_filters('admin_comment_types_dropdown', array( 'comment' => __('Comments'), 'pings' => __('Pings'), )); // Options for comment_status field $comment_statuses = array( 'approve' => __('Approve'), 'hold' => __('Hold or Unapprove'), 'trash' => __('Trash'), 'spam' => __('Spam'), ); // Pull sites options if available. $sites = $this->get_blog_sites(); $result = array( 'sites' => $sites, 'types' => $comment_types, 'statuses' => $comment_statuses, 'paging' => $this->_calculate_pages(null), ); return $this->_response($result); } /** * The get_settings function pulls the current discussion settings * option values. * * @param array $params Passing specific params for getting current discussion settings * @return array */ public function get_settings($params) { global $updraftcentral_main; // Here, we're getting the current blog id. If blog id // is passed along with the parameters then we override // that current (default) value with the parameter blog id value. $blog_id = get_current_blog_id(); if (isset($params['blog_id'])) $blog_id = $params['blog_id']; // If user does not have sufficient privileges to manage and edit // WP options then we return with error. if (!current_user_can_for_blog($blog_id, 'manage_options')) { $result = array('error' => true, 'message' => 'insufficient_permission'); return $this->_response($result); } // Pull sites options if available. $sites = $this->get_blog_sites(); // Wrap current discussion settings values into an array item // named settings. $result = array( 'settings' => array( 'default_pingback_flag' => $this->_get_wp_option($blog_id, 'default_pingback_flag'), 'default_ping_status' => $this->_get_wp_option($blog_id, 'default_ping_status'), 'default_comment_status' => $this->_get_wp_option($blog_id, 'default_comment_status'), 'require_name_email' => $this->_get_wp_option($blog_id, 'require_name_email'), 'comment_registration' => $this->_get_wp_option($blog_id, 'comment_registration'), 'close_comments_for_old_posts' => $this->_get_wp_option($blog_id, 'close_comments_for_old_posts'), 'close_comments_days_old' => $this->_get_wp_option($blog_id, 'close_comments_days_old'), 'thread_comments' => $this->_get_wp_option($blog_id, 'thread_comments'), 'thread_comments_depth' => $this->_get_wp_option($blog_id, 'thread_comments_depth'), 'page_comments' => $this->_get_wp_option($blog_id, 'page_comments'), 'comments_per_page' => $this->_get_wp_option($blog_id, 'comments_per_page'), 'default_comments_page' => $this->_get_wp_option($blog_id, 'default_comments_page'), 'comment_order' => $this->_get_wp_option($blog_id, 'comment_order'), 'comments_notify' => $this->_get_wp_option($blog_id, 'comments_notify'), 'moderation_notify' => $this->_get_wp_option($blog_id, 'moderation_notify'), 'comment_moderation' => $this->_get_wp_option($blog_id, 'comment_moderation'), 'comment_max_links' => $this->_get_wp_option($blog_id, 'comment_max_links'), 'moderation_keys' => $this->_get_wp_option($blog_id, 'moderation_keys'), ), 'sites' => $sites, ); $wp_version = $updraftcentral_main->get_wordpress_version(); if (version_compare($wp_version, '5.5.0', '<')) { $result['settings']['comment_whitelist'] = $this->_get_wp_option($blog_id, 'comment_whitelist'); $result['settings']['blacklist_keys'] = $this->_get_wp_option($blog_id, 'blacklist_keys'); } else { $result['settings']['comment_previously_approved'] = $this->_get_wp_option($blog_id, 'comment_previously_approved'); $result['settings']['disallowed_keys'] = $this->_get_wp_option($blog_id, 'disallowed_keys'); } return $this->_response($result); } /** * The update_settings function updates the discussion settings * basing on the user generated content/option from the frontend * form. * * @param array $params Specific params to update settings based on discussion * @return array */ public function update_settings($params) { // Extract settings values from passed parameters. $settings = $params['settings']; // Here, we're getting the current blog id. If blog id // is passed along with the parameters then we override // that current (default) value with the parameter blog id value. $blog_id = get_current_blog_id(); if (isset($params['blog_id'])) $blog_id = $params['blog_id']; // If user does not have sufficient privileges to manage and edit // WP options then we return with error. if (!current_user_can_for_blog($blog_id, 'manage_options')) { $result = array('error' => true, 'message' => 'insufficient_permission'); return $this->_response($result); } // Here, we're sanitizing the input fields before we save them to the database // for safety and security reason. The "explode" and "implode" functions are meant // to maintain the line breaks associated with a textarea input/value. foreach ($settings as $key => $value) { // We're using update_blog_option and update_option altogether to update the current // discussion settings. if (is_multisite()) { update_blog_option($blog_id, $key, implode("\n", array_map('sanitize_text_field', explode("\n", $value)))); } else { update_option($key, implode("\n", array_map('sanitize_text_field', explode("\n", $value)))); } } // We're not checking for errors here, but instead we're directly returning a success (error = false) // status always, because WP's update_option will return fail if values were not changed, meaning // previous values were not changed by the user's current request, not an actual exception thrown. // Thus, giving a false positive message or report to the frontend. $result = array('error' => false, 'message' => 'settings_updated', 'values' => array()); return $this->_response($result); } /** * The get_comment function pulls a single comment based * on a comment ID. * * @param array $params Specific params for getting a single comment * @return array */ public function get_comment($params) { // Here, we're getting the current blog id. If blog id // is passed along with the parameters then we override // that current (default) value with the parameter blog id value. $blog_id = get_current_blog_id(); if (isset($params['blog_id'])) $blog_id = $params['blog_id']; // If user does not have sufficient privileges to moderate or edit // a comment then we return with error. if (!current_user_can_for_blog($blog_id, 'moderate_comments')) { $result = array('error' => true, 'message' => 'insufficient_permission'); return $this->_response($result); } // Here, we're switching to the actual blog that we need // to pull comments from. $switched = false; if (function_exists('switch_to_blog')) { $switched = switch_to_blog($blog_id); } // Get comment by comment_ID parameter and return result as an array. $result = array( 'comment' => get_comment($params['comment_id'], ARRAY_A) ); // Here, we're restoring to the current (default) blog before we // do the switched. if (function_exists('restore_current_blog') && $switched) { restore_current_blog(); } return $this->_response($result); } /** * The reply_comment function creates a new comment as a reply * to a certain/selected comment. * * @param array $params Specific params to create a new comment reply * @return array */ public function reply_comment($params) { // Extract reply info from the passed parameters $reply = $params['comment']; // Here, we're getting the current blog id. If blog id // is passed along with the parameters then we override // that current (default) value with the parameter blog id value. $blog_id = get_current_blog_id(); if (isset($params['blog_id'])) $blog_id = $params['blog_id']; // If user does not have sufficient privileges to moderate or edit // a comment then we return with error. if (!current_user_can_for_blog($blog_id, 'moderate_comments')) { $result = array('error' => true, 'message' => 'comment_reply_no_permission'); return $this->_response($result); } // Here, we're switching to the actual blog that we need // to apply our changes. $switched = false; if (function_exists('switch_to_blog')) { $switched = switch_to_blog($blog_id); } // Get comment by comment_ID parameter. $comment = get_comment($reply['comment_id']); if ($comment) { // Get the currently logged in user $user = wp_get_current_user(); // If the current comment was not approved yet then // we need to approve it before we create a reply to // to the comment, mimicking exactly the WP behaviour // in terms of creating a reply to a comment. if (empty($comment->comment_approved)) { $update_data = array( 'comment_ID' => $reply['comment_id'], 'comment_approved' => 1 ); wp_update_comment($update_data); } // Build new comment parameters based on current user info and // the target comment for the reply. $data = array( 'comment_post_ID' => $comment->comment_post_ID, 'comment_author' => $user->display_name, 'comment_author_email' => $user->user_email, 'comment_author_url' => $user->user_url, 'comment_content' => $reply['message'], 'comment_parent' => $reply['comment_id'], 'user_id' => $user->ID, 'comment_date' => current_time('mysql'), 'comment_approved' => 1 ); // Create new comment based on the parameters above, and return // the status accordingly. if (wp_insert_comment($data)) { $result = array('error' => false, 'message' => 'comment_replied_with_comment_author', 'values' => array($comment->comment_author)); } else { $result = array('error' => true, 'message' => 'comment_reply_failed_with_error', 'values' => array($comment->comment_ID)); } } else { $result = array('error' => true, 'message' => 'comment_does_not_exists_error', 'values' => array($reply['comment_id'])); } // Here, we're restoring to the current (default) blog before we // do the switched. if (function_exists('restore_current_blog') && $switched) { restore_current_blog(); } return $this->_response($result); } /** * The edit_comment function saves new information for the * currently selected comment. * * @param array $params Specific params for editing a comment * @return array */ public function edit_comment($params) { // Extract new comment info from the passed parameters $comment = $params['comment']; // Here, we're getting the current blog id. If blog id // is passed along with the parameters then we override // that current (default) value with the parameter blog id value. $blog_id = get_current_blog_id(); if (isset($params['blog_id'])) $blog_id = $params['blog_id']; // If user does not have sufficient privileges to moderate or edit // a comment then we return with error. if (!current_user_can_for_blog($blog_id, 'moderate_comments')) { $result = array('error' => true, 'message' => 'comment_edit_no_permission'); return $this->_response($result); } // Here, we're switching to the actual blog that we need // to apply our changes. $switched = false; if (function_exists('switch_to_blog')) { $switched = switch_to_blog($blog_id); } // Get current comment details $original_comment = get_comment($comment['comment_id']); if ($original_comment) { $data = array(); // Replace "comment_id" with "comment_ID" since WP does not recognize // the small case "id". $comment['comment_ID'] = $original_comment->comment_ID; unset($comment['comment_id']); // Here, we're sanitizing the input fields before we save them to the database // for safety and security reason. The "explode" and "implode" functions are meant // to maintain the line breaks associated with a textarea input/value. foreach ($comment as $key => $value) { $data[$key] = implode("\n", array_map('sanitize_text_field', explode("\n", $value))); } // Update existing comment based on the passed parameter fields and // return the status accordingly. if (wp_update_comment($data)) { $result = array('error' => false, 'message' => 'comment_edited_with_comment_author', 'values' => array($original_comment->comment_author)); } else { $result = array('error' => true, 'message' => 'comment_edit_failed_with_error', 'values' => array($original_comment->comment_ID)); } } else { $result = array('error' => true, 'message' => 'comment_does_not_exists_error', 'values' => array($comment['comment_id'])); } // Here, we're restoring to the current (default) blog before we // do the switched. if (function_exists('restore_current_blog') && $switched) { restore_current_blog(); } return $this->_response($result); } /** * The update_comment_status function is a generic handler for the following * comment actions: * * - approve comment * - unapprove comment * - set comment as spam * - move comment to trash * - delete comment permanently * - unset comment as spam * - restore comment * * @param array $params Specific params to update comment status * @return array */ public function update_comment_status($params) { // Here, we're getting the current blog id. If blog id // is passed along with the parameters then we override // that current (default) value with the parameter blog id value. $blog_id = get_current_blog_id(); if (isset($params['blog_id'])) $blog_id = $params['blog_id']; // If user does not have sufficient privileges to moderate or edit // a comment then we return with error. if (!current_user_can_for_blog($blog_id, 'moderate_comments')) { $result = array('error' => true, 'message' => 'comment_change_status_no_permission'); return $this->_response($result); } // Here, we're switching to the actual blog that we need // to apply our changes. $switched = false; if (function_exists('switch_to_blog')) { $switched = switch_to_blog($blog_id); } // We make sure that we still have a valid comment from the server // before we apply the currently selected action. $comment = get_comment($params['comment_id']); if ($comment) { $post = get_post($comment->comment_post_ID); if ($post) $comment->in_response_to = $post->post_title; if (!empty($comment->comment_parent)) { $parent_comment = get_comment($comment->comment_parent); if ($parent_comment) $comment->in_reply_to = $parent_comment->comment_author; } // We're formatting the comment_date to be exactly the same // with that of WP Comments table (e.g. 2016/12/21 at 10:30 PM) $comment->comment_date = date('Y/m/d \a\t g:i a', strtotime($comment->comment_date)); $status = wp_get_comment_status($comment->comment_ID); if ($status) { $comment->comment_status = $status; } $succeeded = false; $message = ''; // Here, we're using WP's wp_set_comment_status function to change the state // of the selected comment based on the current action, except for the "delete" action // where we use the wp_delete_comment to delete the comment permanently by passing // "true" to the second argument. switch ($params['action']) { case 'approve': $succeeded = wp_set_comment_status($params['comment_id'], 'approve'); $message = 'comment_approve_with_comment_author'; break; case 'unapprove': $succeeded = wp_set_comment_status($params['comment_id'], 'hold'); $message = 'comment_unapprove_with_comment_author'; break; case 'spam': $succeeded = wp_set_comment_status($params['comment_id'], 'spam'); $message = 'comment_spam_with_comment_author'; break; case 'trash': $succeeded = wp_set_comment_status($params['comment_id'], 'trash'); $message = 'comment_trash_with_comment_author'; break; case 'delete': $succeeded = wp_delete_comment($params['comment_id'], true); $message = 'comment_delete_with_comment_author'; break; case 'notspam': $succeeded = wp_set_comment_status($params['comment_id'], 'hold'); $message = 'comment_not_spam_with_comment_author'; break; case 'restore': $succeeded = wp_set_comment_status($params['comment_id'], 'hold'); $message = 'comment_restore_with_comment_author'; break; } // If the current action succeeded, then we return a success message, otherwise, // we return an error message to the user issuing the request. if ($succeeded) { $result = array('error' => false, 'message' => $message, 'values' => array($comment->comment_author), 'status' => $comment->comment_status, 'approved' => $comment->comment_approved); } else { $result = array('error' => true, 'message' => 'comment_change_status_failed_with_error', 'values' => array($comment->comment_ID)); } } else { $result = array('error' => true, 'message' => 'comment_does_not_exists_error', 'values' => array($params['comment_id'])); } // Here, we're restoring to the current (default) blog before we // do the switched. if (function_exists('restore_current_blog') && $switched) { restore_current_blog(); } return $this->_response($result); } } central/modules/plugin.php000064400000056335152214270100011661 0ustar00switched = switch_to_blog($blog_id); } } /** * Function that gets called after every action * * @param string $command a string that corresponds to UDC command to call a certain method for this class. * @param array $data an array of data post or get fields * @param array $extra_info extrainfo use in the udrpc_action, e.g. user_id * * link to udrpc_action main function in class UpdraftCentral_Listener */ public function _post_action($command, $data, $extra_info) {// phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable -- Unused parameter is present because the caller from UpdraftCentral_Listener class uses 3 arguments. // Here, we're restoring to the current (default) blog before we switched if ($this->switched) restore_current_blog(); } /** * Constructor */ public function __construct() { $this->_admin_include('plugin.php', 'file.php', 'template.php', 'class-wp-upgrader.php', 'plugin-install.php', 'update.php'); } /** * Installs and activates a plugin through upload * * @param array $params Parameter array containing information pertaining the currently uploaded plugin * @return array Contains the result of the current process */ public function upload_plugin($params) { return $this->process_chunk_upload($params, 'plugin'); } /** * Checks whether the plugin is currently installed and activated. * * @param array $query Parameter array containing the name of the plugin to check * @return array Contains the result of the current process */ public function is_plugin_installed($query) { if (!isset($query['plugin'])) return $this->_generic_error_response('plugin_name_required'); $result = $this->_get_plugin_info($query); return $this->_response($result); } /** * Applies currently requested action for plugin processing * * @param string $action The action to apply (e.g. activate or install) * @param array $query Parameter array containing information for the currently requested action * * @return array */ private function _apply_plugin_action($action, $query) { $result = array(); switch ($action) { case 'activate': case 'network_activate': $info = $this->_get_plugin_info($query); if ($info['installed']) { $activate = activate_plugin($info['plugin_path']); if (is_wp_error($activate)) { $result = $this->_generic_error_response('generic_response_error', array( 'plugin' => $query['plugin'], 'error_code' => 'generic_response_error', 'error_message' => $activate->get_error_message(), 'info' => $this->_get_plugin_info($query) )); } else { $result = array('activated' => true, 'info' => $this->_get_plugin_info($query), 'last_state' => $info); } } else { $result = $this->_generic_error_response('plugin_not_installed', array( 'plugin' => $query['plugin'], 'error_code' => 'plugin_not_installed', 'error_message' => __('The plugin you wish to activate is either not installed or has been removed recently.', 'updraftplus'), 'info' => $info )); } break; case 'deactivate': case 'network_deactivate': $info = $this->_get_plugin_info($query); if ($info['active']) { deactivate_plugins($info['plugin_path']); if (!is_plugin_active($info['plugin_path'])) { $result = array('deactivated' => true, 'info' => $this->_get_plugin_info($query), 'last_state' => $info); } else { $result = $this->_generic_error_response('deactivate_plugin_failed', array( 'plugin' => $query['plugin'], 'error_code' => 'deactivate_plugin_failed', 'error_message' => __('There appears to be a problem deactivating the intended plugin. Please kindly check your permission and try again.', 'updraftplus'), 'info' => $this->_get_plugin_info($query) )); } } else { $result = $this->_generic_error_response('not_active', array( 'plugin' => $query['plugin'], 'error_code' => 'not_active', 'error_message' => __('The plugin you wish to deactivate is currently not active or is already deactivated.', 'updraftplus'), 'info' => $info )); } break; case 'install': $api = plugins_api('plugin_information', array( 'slug' => $query['slug'], 'fields' => array( 'short_description' => false, 'sections' => false, 'requires' => false, 'rating' => false, 'ratings' => false, 'downloaded' => false, 'last_updated' => false, 'added' => false, 'tags' => false, 'compatibility' => false, 'homepage' => false, 'donate_link' => false, ) )); $info = $this->_get_plugin_info($query); if (is_wp_error($api)) { $result = $this->_generic_error_response('generic_response_error', array( 'plugin' => $query['plugin'], 'error_code' => 'generic_response_error', 'error_message' => $api->get_error_message(), 'info' => $info )); } else { $installed = $info['installed']; $error_code = $error_message = ''; if (!$installed) { // WP < 3.7 if (!class_exists('Automatic_Upgrader_Skin')) include_once(dirname(dirname(__FILE__)).'/classes/class-automatic-upgrader-skin.php'); $skin = new Automatic_Upgrader_Skin(); $upgrader = new Plugin_Upgrader($skin); $download_link = $api->download_link; $installed = $upgrader->install($download_link); if (is_wp_error($installed)) { $error_code = $installed->get_error_code(); $error_message = $installed->get_error_message(); } elseif (is_wp_error($skin->result)) { $error_code = $skin->result->get_error_code(); $error_message = $skin->result->get_error_message(); $error_data = $skin->result->get_error_data($error_code); if (!empty($error_data)) { if (is_array($error_data)) $error_data = json_encode($error_data); $error_message .= ' '.$error_data; } } elseif (is_null($installed) || !$installed) { global $wp_filesystem; $upgrade_messages = $skin->get_upgrade_messages(); if (!class_exists('WP_Filesystem_Base')) include_once(ABSPATH.'/wp-admin/includes/class-wp-filesystem-base.php'); // Pass through the error from WP_Filesystem if one was raised. if ($wp_filesystem instanceof WP_Filesystem_Base && is_wp_error($wp_filesystem->errors) && $wp_filesystem->errors->get_error_code()) { $error_code = $wp_filesystem->errors->get_error_code(); $error_message = $wp_filesystem->errors->get_error_message(); } elseif (!empty($upgrade_messages)) { // We're only after for the last feedback that we received from the install process. Mostly, // that is where the last error has been inserted. $messages = $skin->get_upgrade_messages(); $error_code = 'install_failed'; $error_message = end($messages); } else { $error_code = 'unable_to_connect_to_filesystem'; $error_message = __('Unable to connect to the filesystem. Please confirm your credentials.'); } } } if (!$installed || is_wp_error($installed)) { $result = $this->_generic_error_response('plugin_install_failed', array( 'plugin' => $query['plugin'], 'error_code' => $error_code, 'error_message' => $error_message, 'info' => $this->_get_plugin_info($query) )); } else { $result = array('installed' => true, 'info' => $this->_get_plugin_info($query), 'last_state' => $info); } } break; } return $result; } /** * Preloads the submitted credentials to the global $_POST variable * * @param array $query Parameter array containing information for the currently requested action */ private function _preload_credentials($query) { if (!empty($query) && isset($query['filesystem_credentials'])) { parse_str($query['filesystem_credentials'], $filesystem_credentials); if (is_array($filesystem_credentials)) { foreach ($filesystem_credentials as $key => $value) { // Put them into $_POST, which is where request_filesystem_credentials() checks for them. $_POST[$key] = $value; } } } } /** * Checks whether we have the required fields submitted and the user has * the capabilities to execute the requested action * * @param array $query The submitted information * @param array $fields The required fields to check * @param array $capabilities The capabilities to check and validate * * @return array|string */ private function _validate_fields_and_capabilities($query, $fields, $capabilities) { $error = ''; if (!empty($fields)) { for ($i=0; $i_generic_error_response('keyword_required'); } else { $error = $this->_generic_error_response('plugin_'.$query[$field].'_required'); } break; } } } if (empty($error) && !empty($capabilities)) { for ($i=0; $i_generic_error_response('plugin_insufficient_permission'); break; } } } return $error; } /** * Processing an action for multiple items * * @param array $query Parameter array containing a list of plugins to process * @return array Contains the results of the bulk process */ public function process_action_in_bulk($query) { $action = isset($query['action']) ? $query['action'] : ''; $items = isset($query['args']) ? $query['args']['items'] : array(); $results = array(); if (!empty($action) && !empty($items) && is_array($items)) { foreach ($items as $value) { if (method_exists($this, $action)) { $results[] = $this->$action($value); } } } return $this->_response($results); } /** * Activates the plugin * * @param array $query Parameter array containing the name of the plugin to activate * @return array Contains the result of the current process */ public function activate_plugin($query) { $fields = array('plugin'); $permissions = array('activate_plugins'); $error = $this->_validate_fields_and_capabilities($query, $fields, $permissions); if (!empty($error)) { return $error; } $this->_preload_credentials($query); $result = $this->_apply_plugin_action((!empty($query['multisite']) && (bool) $query['multisite']) ? 'network_activate' : 'activate', $query); if (empty($result['activated'])) { return $result; } return $this->_response($result); } /** * Deactivates the plugin * * @param array $query Parameter array containing the name of the plugin to deactivate * @return array Contains the result of the current process */ public function deactivate_plugin($query) { $fields = array('plugin'); $permissions = array('activate_plugins'); $error = $this->_validate_fields_and_capabilities($query, $fields, $permissions); if (!empty($error)) { return $error; } $this->_preload_credentials($query); $result = $this->_apply_plugin_action((!empty($query['multisite']) && (bool) $query['multisite']) ? 'network_deactivate' : 'deactivate', $query); if (empty($result['deactivated'])) { return $result; } return $this->_response($result); } /** * Download, install and activates the plugin * * @param array $query Parameter array containing the filesystem credentials entered by the user along with the plugin name and slug * @return array Contains the result of the current process */ public function install_activate_plugin($query) { $fields = array('plugin', 'slug'); $permissions = array('install_plugins', 'activate_plugins'); $error = $this->_validate_fields_and_capabilities($query, $fields, $permissions); if (!empty($error)) { return $error; } $this->_preload_credentials($query); $result = $this->_apply_plugin_action('install', $query); if (!empty($result['installed']) && $result['installed']) { $result = $this->_apply_plugin_action((!empty($query['multisite']) && (bool) $query['multisite']) ? 'network_activate' : 'activate', $query); if (empty($result['activated'])) { return $result; } } else { return $result; } return $this->_response($result); } /** * Download, install the plugin * * @param array $query Parameter array containing the filesystem credentials entered by the user along with the plugin name and slug * @return array Contains the result of the current process */ public function install_plugin($query) { $fields = array('plugin', 'slug'); $permissions = array('install_plugins'); $error = $this->_validate_fields_and_capabilities($query, $fields, $permissions); if (!empty($error)) { return $error; } $this->_preload_credentials($query); $result = $this->_apply_plugin_action('install', $query); if (empty($result['installed'])) { return $result; } return $this->_response($result); } /** * Uninstall/delete the plugin * * @param array $query Parameter array containing the filesystem credentials entered by the user along with the plugin name and slug * @return array Contains the result of the current process */ public function delete_plugin($query) { $fields = array('plugin'); $permissions = array('delete_plugins'); $error = $this->_validate_fields_and_capabilities($query, $fields, $permissions); if (!empty($error)) { return $error; } $this->_preload_credentials($query); $info = $this->_get_plugin_info($query); if ($info['installed']) { // Deactivate first before delete to invalidate the activate // state/status prior to deleting the item. Otherwise, WordPress will keep // that state, and as soon as you install the same plugin it will be automatically // activated since it's previous state was kept. deactivate_plugins($info['plugin_path']); $deleted = delete_plugins(array($info['plugin_path'])); if ($deleted) { $result = array('deleted' => true, 'info' => $this->_get_plugin_info($query), 'last_state' => $info); } else { return $this->_generic_error_response('delete_plugin_failed', array( 'plugin' => $query['plugin'], 'error_code' => 'delete_plugin_failed', 'info' => $info )); } } else { return $this->_generic_error_response('plugin_not_installed', array( 'plugin' => $query['plugin'], 'error_code' => 'plugin_not_installed', 'info' => $info )); } return $this->_response($result); } /** * Updates/upgrade the plugin * * @param array $query Parameter array containing the filesystem credentials entered by the user along with the plugin name and slug * @return array Contains the result of the current process */ public function update_plugin($query) { $fields = array('plugin', 'slug'); $permissions = array('update_plugins'); $error = $this->_validate_fields_and_capabilities($query, $fields, $permissions); if (!empty($error)) { return $error; } $this->_preload_credentials($query); // Make sure that we still have the plugin installed before running // the update process $info = $this->_get_plugin_info($query); if ($info['installed']) { // Load the updates command class if not existed if (!class_exists('UpdraftCentral_Updates_Commands')) include_once('updates.php'); $update_command = new UpdraftCentral_Updates_Commands($this->rc); $result = $update_command->update_plugin($info['plugin_path'], $query['slug']); if (!empty($result['error'])) { $result['values'] = array('plugin' => $query['plugin'], 'info' => $info); } } else { return $this->_generic_error_response('plugin_not_installed', array( 'plugin' => $query['plugin'], 'error_code' => 'plugin_not_installed', 'info' => $info )); } return $this->_response($result); } /** * Gets the plugin information along with its active and install status * * @internal * @param array $query Contains either the plugin name or slug or both to be used when retrieving information * @return array */ private function _get_plugin_info($query) { $info = array( 'active' => false, 'installed' => false ); // Clear plugin cache so that newly installed/downloaded plugins // gets reflected when calling "get_plugins" if (function_exists('wp_clean_plugins_cache')) { wp_clean_plugins_cache(); } // Gets all plugins available. $get_plugins = get_plugins(); // Loops around each plugin available. foreach ($get_plugins as $key => $value) { $slug = $this->extract_slug_from_info($key, $value); // If the plugin name matches that of the specified name, it will gather details. // In case name check isn't enough, we'll use slug to verify if the plugin being queried is actually installed. // // Reason for name check failure: // Due to plugin name inconsistencies - where wordpress.org registered plugin name is different // from the actual plugin files's metadata (found inside the plugin's PHP file itself). if ((!empty($query['plugin']) && html_entity_decode($value['Name']) === html_entity_decode($query['plugin'])) || (!empty($query['slug']) && $slug === $query['slug'])) { $info['installed'] = true; $info['active'] = is_plugin_active($key); $info['plugin_path'] = $key; $info['data'] = $value; $info['name'] = $value['Name']; $info['slug'] = $slug; break; } } return $info; } /** * Extract the slug from the plugin data * * @param string $key They key of the current info * @param array $info Data pulled from the plugin file * * @return string */ private function extract_slug_from_info($key, $info) { if (!is_array($info) || empty($info) || empty($key)) return ''; $temp = explode('/', $key); $slug = !empty($info['TextDomain']) ? $info['TextDomain'] : basename($temp[0], '.php'); // If in case the user kept the hello-dolly plugin then we'll make sure that it gets // the proper slug for it, otherwise, we'll end up with the wrong slug 'hello' instead of // 'hello-dolly'. Wrong slug will produce error in UpdraftCentral when running it against // wordpress.org for further information retrieval. $slug = ('Hello Dolly' === $info['Name']) ? 'hello-dolly' : $slug; return $slug; } /** * Loads all available plugins with additional attributes and settings needed by UpdraftCentral * * @param array $query Parameter array Any available parameters needed for this action * @return array Contains the result of the current process */ public function load_plugins($query) { $permissions = array('install_plugins', 'activate_plugins'); if (is_multisite() && !is_super_admin(get_current_user_id())) $permissions = array('activate_plugins'); $error = $this->_validate_fields_and_capabilities($query, array(), $permissions); if (!empty($error)) { return $error; } $website = get_bloginfo('name'); $results = array(); // Load the updates command class if not existed if (!class_exists('UpdraftCentral_Updates_Commands')) include_once('updates.php'); $updates = new UpdraftCentral_Updates_Commands($this->rc); // Get plugins for update $plugin_updates = $updates->get_item_updates('plugins'); // Get all plugins $plugins = get_plugins(); if (is_multisite() && !is_super_admin(get_current_user_id())) { // If the "Plugins" menu is disabled for the subsites on a multisite // network then we return an empty "plugins" array. $menu_items = get_site_option('menu_items'); if (empty($menu_items) || !isset($menu_items['plugins'])) { $plugins = array(); } else { $show_network_active = apply_filters('show_network_active_plugins', current_user_can('manage_network_plugins')); $filtered_plugins = array(); foreach ($plugins as $file => $data) { if (is_network_only_plugin($file) && !is_plugin_active($file)) { if ($show_network_active) $filtered_plugins[$file] = $data; } elseif (is_plugin_active_for_network($file)) { if ($show_network_active) $filtered_plugins[$file] = $data; } else { $filtered_plugins[$file] = $data; } } $plugins = $filtered_plugins; } } foreach ($plugins as $key => $value) { $slug = $this->extract_slug_from_info($key, $value); $plugin = new stdClass(); $plugin->name = $value['Name']; $plugin->description = $value['Description']; $plugin->slug = $slug; $plugin->version = $value['Version']; $plugin->author = $value['Author']; $plugin->status = is_plugin_active($key) ? 'active' : 'inactive'; $plugin->website = $website; $plugin->multisite = is_multisite(); $plugin->site_url = trailingslashit(get_bloginfo('url')); if (!empty($plugin_updates[$key])) { $update_info = $plugin_updates[$key]; if (version_compare($update_info->Version, $update_info->update->new_version, '<')) { if (!empty($update_info->update->new_version)) $plugin->latest_version = $update_info->update->new_version; if (!empty($update_info->update->package)) $plugin->download_link = $update_info->update->package; if (!empty($update_info->update->sections)) $plugin->sections = $update_info->update->sections; } } if (empty($plugin->short_description) && !empty($plugin->description)) { // Only pull the first sentence as short description, it should be enough rather than displaying // an empty description or a full blown one which the user can access anytime if they press on // the view details link in UpdraftCentral. $temp = explode('.', $plugin->description); $short_description = $temp[0]; // Adding the second sentence wouldn't hurt, in case the first sentence is too short. if (isset($temp[1])) $short_description .= '.'.$temp[1]; $plugin->short_description = $short_description.'.'; } $results[] = $plugin; } $result = array( 'plugins' => $results, 'is_super_admin' => is_super_admin(), ); $result = array_merge($result, $this->_get_backup_credentials_settings(WP_PLUGIN_DIR)); return $this->_response($result); } /** * Gets the backup and security credentials settings for this website * * @param array $query Parameter array Any available parameters needed for this action * @return array Contains the result of the current process */ public function get_plugin_requirements() { return $this->_response($this->_get_backup_credentials_settings(WP_PLUGIN_DIR)); } } central/modules/pages.php000064400000000713152214270100011447 0ustar00switched = switch_to_blog($blog_id); } } /** * Function that gets called after every action * * @param string $command a string that corresponds to UDC command to call a certain method for this class. * @param array $data an array of data post or get fields * @param array $extra_info extrainfo use in the udrpc_action, e.g. user_id * * link to udrpc_action main function in class UpdraftCentral_Listener */ public function _post_action($command, $data, $extra_info) {// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.Found, VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable // Here, we're restoring to the current (default) blog before we switched if ($this->switched) restore_current_blog(); } /** * Returns the keys and fields names that are associated to a particular module type * * @param string $type The type of the module that the current request is processing * * @return array */ private function get_state_fields_by_type($type) { $state_fields = array( 'post' => array( 'validation_fields' => array('publish_posts', 'edit_posts', 'delete_posts'), 'items_key' => 'posts', 'count_key' => 'posts_count', 'list_key' => 'posts', 'result_key' => 'get', 'error_key' => 'post_state_change_failed' ), 'page' => array( 'validation_fields' => array('publish_pages', 'edit_pages', 'delete_pages'), 'items_key' => 'pages', 'count_key' => 'pages_count', 'list_key' => 'pages', 'result_key' => 'get', 'error_key' => 'page_state_change_failed' ) ); if (!isset($state_fields[$type])) return array(); return $state_fields[$type]; } /** * Fetch and retrieves posts based from the submitted parameters * * @param array $params Containing all the needed information to filter the results of the current request * @return array */ public function get($params) { $state_fields = $this->get_state_fields_by_type($this->post_type); if (empty($state_fields)) return $this->_generic_error_response('unsupported_type_on_get_posts'); $error = $this->_validate_capabilities($state_fields['validation_fields']); if (!empty($error)) return $error; // check paged parameter; if empty set to defaults $paged = !empty($params['paged']) ? (int) $params['paged'] : 1; $numberposts = !empty($params['numberposts']) ? (int) $params['numberposts'] : 10; $offset = ($paged - 1) * $numberposts; $args = array( 'posts_per_page' => $numberposts, 'paged' => $paged, 'offset' => $offset, 'post_type' => $this->post_type, 'post_status' => 'publish,private,draft,pending,future', ); if (!empty($params['keyword'])) { $args['s'] = $params['keyword']; } if ('post' == $this->post_type) { if (!empty($params['category'])) { $args['cat'] = (int) $params['category']; } } if (!empty($params['date'])) { list($monthnum, $year) = explode(':', $params['date']); $args['monthnum'] = $monthnum; $args['year'] = $year; } if (!empty($params['status']) && 'all' !== $params['status']) { $args['post_status'] = $params['status']; } $query = new WP_Query($args); $result = $query->posts; $count_posts = (int) $query->found_posts; $page_count = 0; if ($count_posts > 0) { $page_count = absint($count_posts / $numberposts); $remainder = absint($count_posts % $numberposts); $page_count = ($remainder > 0) ? ++$page_count : $page_count; } $info = array( 'page' => $paged, 'pages' => $page_count, 'results' => $count_posts, 'items_from' => (($paged * $numberposts) - $numberposts) + 1, 'items_to' => ($paged == $page_count) ? $count_posts : $paged * $numberposts, ); $posts = array(); if (!empty($result)) { foreach ($result as $post) { // Pulling any other relevant and additional information regarding // the post before returning it in the response. $postdata = $this->get_postdata($post, false); if (!empty($postdata)) { array_push($posts, $postdata); } } } $response = array( $state_fields['items_key'] => $posts, 'options' => $this->get_options($this->post_type), 'info' => $info, $state_fields['count_key'] => $this->get_post_status_counts($this->post_type) ); // Load any additional information if preload parameter is set. Will only be // requested on initial load of items in UpdraftCentral. if (isset($params['preload']) && $params['preload']) { $timeout = !empty($params['timeout']) ? $params['timeout'] : 30; $response = array_merge($response, $this->get_preload_data($timeout, $this->post_type)); } return $this->_response($response); } /** * Extracts public properties from complex object and return a simple * object (stdClass) that contains the public properties of the original object. * * @param object $obj Any type of complex objects that needs converting (e.g. WP_Taxonomy, WP_Term or WP_User) * @return stdClass */ protected function trim_object($obj) { // To preserve the object's accessibility through its properties we recreate // the object using the stdClass and fill it with the public properties // that will be extracted from the original object ($obj). $newObj = new stdClass(); if (is_object($obj)) { // Making sure that we only extract those publicly accessible properties excluding // the private, protected, static ones and methods. $props = get_object_vars($obj); if (!empty($props)) { foreach ($props as $key => $value) { $newObj->{$key} = $value; } } } return $newObj; } /** * Retrieves information that will be preloaded in UC for quick and easy access * when editing a certain page or post * * @param int $timeout The user-defined timeout from UpdraftCentral * @param string $type The type of the module that the current request is processing * * @return array */ protected function get_preload_data($timeout, $type = 'post') { global $updraftcentral_host_plugin, $updraftcentral_main; if (!function_exists('get_page_templates')) { require_once(ABSPATH.'wp-admin/includes/theme.php'); } $templates = ('post' == $type) ? get_page_templates(null, 'post') : get_page_templates(); if (!empty($templates)) { $templates = array_flip($templates); if (!isset($templates['default'])) { $templates['default'] = $updraftcentral_host_plugin->retrieve_show_message('default_template'); } } // Preloading elements saves time and avoid unnecessary round trips to fetch // these information individually. $authors = $this->get_authors(); $parent_pages = $this->get_parent_pages(); $data = array( 'authors' => $authors['data']['authors'], 'parent_pages' => $parent_pages['data']['pages'], 'templates' => $templates, 'editor_styles' => $this->get_editor_styles($timeout), 'wp_version' => $updraftcentral_main->get_wordpress_version() ); if ('post' == $type) { $categories = $this->get_categories(); $tags = $this->get_tags(); $data['taxonomies'] = $this->get_taxonomies(); $data['categories'] = $categories['data']; $data['tags'] = $tags['data']; } global $post; $context = class_exists('WP_Block_Editor_Context') ? new WP_Block_Editor_Context(array('post' => $post)) : $post; // Load block patterns from w.org. if (function_exists('_load_remote_block_patterns')) _load_remote_block_patterns(); if (function_exists('_load_remote_featured_patterns')) _load_remote_featured_patterns(); $block_types = class_exists('WP_Block_Type_Registry') ? WP_Block_Type_Registry::get_instance()->get_all_registered() : array(); $block_patterns = class_exists('WP_Block_Patterns_Registry') ? WP_Block_Patterns_Registry::get_instance()->get_all_registered() : array(); $block_pattern_categories = class_exists('WP_Block_Pattern_Categories_Registry') ? WP_Block_Pattern_Categories_Registry::get_instance()->get_all_registered() : array(); $block_styles = class_exists('WP_Block_Styles_Registry') ? WP_Block_Styles_Registry::get_instance()->get_all_registered() : array(); $block_data = array( 'block_categories' => get_block_categories($context), 'block_definitions' => get_block_editor_server_block_settings(), 'block_types' => $block_types, 'block_patterns' => $block_patterns, 'block_pattern_categories' => $block_pattern_categories, 'block_styles' => $block_styles ); $data = array_merge($data, $block_data); return array( 'preloaded' => json_encode($data) ); } /** * Extract content from the given css path * * @param string $style CSS file path * @param int $timeout The user-defined timeout from UpdraftCentral * @return array */ protected function extract_css_content($style, $timeout) { $content = ''; if (1 === preg_match('~^(https?:)?//~i', $style)) { $response = wp_remote_get($style, array('timeout' => $timeout)); if (!is_wp_error($response)) { $result = trim(wp_remote_retrieve_body($response)); if (!empty($result)) $content = $result; } } else { // Editor styles that resides in "css/dist" if (false !== ($pos = stripos($style, 'css/dist'))) { $file = ABSPATH.WPINC.substr_replace($style, '/', 0, $pos); } else { // Styles that resides in "wp-content/themes" (coming from $editor_styles global var) $file = get_theme_file_path($style); } $is_valid = (function_exists('is_file')) ? is_file($file) : file_exists($file); if ($is_valid) { $result = trim(file_get_contents($file)); if (!empty($result)) $content = $result; } } return $this->extract_custom_fonts($this->filter_url($content)); } /** * Extract custom fonts defined within the css content. Basically, * separating custom font (@font-face) rules from the Style/css content. * * @param string $content Style content * @return array */ protected function extract_custom_fonts($content) { $fonts = array(); while ($start = strpos($content, '@font-face')) { $end = strpos($content, '}', $start) + 1; $length = $end - $start; $font = substr($content, $start, $length); $fonts[]= $this->update_font_src($font); $content = str_replace($font, '', $content); } return array( 'content' => $content, 'fonts' => $fonts ); } /** * Updates the font URL to point to the UpdraftCentral "load_font" action * * @param string $font Font-face definition/content * @return string */ protected function update_font_src($font) { $start = strpos($font, 'src:') + 4; $end = strpos($font, ';', $start); $length = $end - $start; $src = trim(substr($font, $start, $length)); $temp = explode(' ', $src); preg_match('/^url\((.*)\)$/i', $temp[0], $matches); $url = ''; if (!empty($matches)) { $url = trim(trim($matches[1], "'"), '"'); if (strlen($url)) { $font_url = 'CENTRAL_URL/?udcentral_action=load_font&font='.urlencode($url); $font = str_replace($url, $font_url, $font); } } return $font; } /** * Convert URL entries contained in the CSS content to absolute URLs * * @param string $content The content of the CSS file * @return string */ protected function filter_url($content) { // Replace with valid URL (absolute) preg_match_all('~url\((.+?)\)~i', $content, $all_matches); if (!empty($all_matches) && isset($all_matches[1])) { $urls = array_unique($all_matches[1]); foreach ($urls as $url) { $url = str_replace('"', '', $url); if (false !== strpos($url, 'data:')) continue; if (1 !== preg_match('~^(https?:)?//~i', $url)) { if (1 === preg_match('~(plugins|themes)~i', $url, $matches)) { if (false !== ($pos = stripos($url, $matches[1]))) { if (!function_exists('content_url')) { require_once ABSPATH.WPINC.'/link-template.php'; } $absolute_url = rtrim(content_url(), '/').substr_replace($url, '/', 0, $pos); $content = str_replace($url, $absolute_url, $content); } } else { $path = preg_replace('~(\.+\/)~', '', $url); $dirpath = trailingslashit(get_stylesheet_directory()); if (!file_exists($dirpath.$url)) $path = $this->resolve_path($path); $absolute_url = (!empty($path)) ? trailingslashit(get_stylesheet_directory_uri()).ltrim($path, '/') : ''; $content = str_replace($url, $absolute_url, $content); } } } } return $content; } /** * Resolve URL to its actual absolute path * * @param string $path Some relative path to check * @return string */ protected function resolve_path($path) { $dir = trailingslashit(get_stylesheet_directory()); // Some relative paths declared within the css file (e.g. only has '../fonts/etc/', called deep down from a subfolder) where parent // subfolder is not articulated needs to be resolve further to get its actual absolute path. Using glob will pinpoint its actual location // rather than iterating through a series of sublevels just to find the actual file. $result = str_replace($dir, '', glob($dir.'{,*/}{'.$path.'}', GLOB_BRACE)); if (!empty($result)) return $result[0]; return false; } /** * Retrieves block editor assets for iframe. * * @return string */ protected function get_iframed_editor_assets() { $script_handles = array(); $style_handles = array( 'wp-block-editor', 'wp-block-library', 'wp-block-library-theme', 'wp-edit-blocks', ); if (class_exists('WP_Block_Type_Registry')) { $block_registry = WP_Block_Type_Registry::get_instance(); foreach ($block_registry->get_all_registered() as $block_type) { if (!empty($block_type->style)) { if (is_array($block_type->style)) { $style_handles = array_merge($style_handles, $block_type->style); } else { $style_handles[] = $block_type->style; } } if (!empty($block_type->editor_style)) { if (is_array($block_type->editor_style)) { $style_handles = array_merge($style_handles, $block_type->editor_style); } else { $style_handles[] = $block_type->editor_style; } } if (!empty($block_type->script)) { if (is_array($block_type->script)) { $script_handles = array_merge($script_handles, $block_type->script); } else { $script_handles[] = $block_type->script; } } } } $style_handles = array_unique($style_handles); $done = wp_styles()->done; ob_start(); // We do not need reset styles for the iframed editor. wp_styles()->done = array('wp-reset-editor-styles'); wp_styles()->do_items($style_handles); wp_styles()->done = $done; $styles = ob_get_clean(); $script_handles = array_unique($script_handles); $done = wp_scripts()->done; ob_start(); wp_scripts()->done = array(); wp_scripts()->do_items($script_handles); wp_scripts()->done = $done; $scripts = ob_get_clean(); return wp_json_encode(array( 'styles' => $styles, 'scripts' => $scripts, )); } /** * Retrieve the editor styles/assets to be use by UpdraftCentral when editing a post * * @param int $timeout The user-defined timeout from UpdraftCentral * @return array() */ protected function get_editor_styles($timeout) { global $editor_styles, $wp_styles; $editing_styles = $loaded = array(); $fonts = ''; $required = array('css/dist/editor/style.css', 'css/dist/block-library/style.css', 'css/dist/block-library/theme.css'); foreach ($required as $style) { $result = $this->extract_css_content($style, $timeout); if (!empty($result['fonts'])) $fonts .= implode('', $result['fonts']); $editing_styles[] = array('css' => $result['content'], 'inline' => ''); }; do_action('enqueue_block_assets'); do_action('enqueue_block_editor_assets'); do_action('wp_enqueue_scripts'); // Checking for editor styles support since styles may vary from theme to theme if ($editor_styles) { foreach ($editor_styles as $style) { if (false !== array_search($style, $loaded)) continue; $result = $this->extract_css_content($style, $timeout); if (!empty($result['fonts'])) $fonts .= implode('', $result['fonts']); $editing_styles[] = array('css' => $result['content'], 'inline' => ''); $loaded[] = $style; } } if ($wp_styles) { foreach ($wp_styles->queue as $handle) { $style = $wp_styles->registered[$handle]->src; if (false !== array_search($style, $loaded)) continue; $result = $this->extract_css_content($style, $timeout); if (!empty($result['fonts'])) $fonts .= implode('', $result['fonts']); $inline_style = $wp_styles->print_inline_style($handle, false); if ($inline_style) { $inline_result = $this->extract_custom_fonts($inline_style); if (!empty($inline_result['fonts'])) $fonts .= implode('', $inline_result['fonts']); } $editing_styles[] = array( 'css' => $result['content'], 'inline' => (!$inline_style) ? '' : $inline_result['content'] ); $loaded[] = $style; } } // Introduced in 5.9.0 if (function_exists('wp_get_global_stylesheet')) { $result = $this->extract_custom_fonts(wp_get_global_stylesheet()); if (!empty($result['fonts'])) $fonts .= implode('', $result['fonts']); $editing_styles[] = array('css' => $result['content'], 'inline' => ''); } // Introduced in 5.8.0 if (function_exists('get_block_editor_settings')) { $block_editor_context = new WP_Block_Editor_Context(); $settings = get_block_editor_settings(array(), $block_editor_context); // Don't render but instead attached to the editor before load. // We let the editor render these kind of styles as they need to be prefixed // by the editor based on the current context. // // N.B. Leave the 'css' property empty. It is used for downward compatibility. $editing_styles[] = array('editor_css' => $settings['styles'], 'inline' => '', 'css' => ''); // Get editor assets (e.g. styles) for iframe, mostly used for previewing blocks and patterns $editing_styles[] = array('editor_assets' => $this->get_iframed_editor_assets(), 'inline' => '', 'css' => ''); } $result = $this->extract_css_content('/style.css', $timeout); if (!empty($result['fonts'])) $fonts .= implode('', $result['fonts']); $editing_styles[] = array('css' => $result['content'], 'inline' => ''); if (strlen($fonts)) { $editing_styles[] = array('font_css' => $fonts, 'inline' => '', 'css' => ''); } // These styles are used if the "no theme styles" options is triggered or on // themes without their own editor styles. $default_editor_styles_file = ABSPATH.WPINC.'/css/dist/block-editor/default-editor-styles.css'; if (file_exists($default_editor_styles_file)) { $editing_styles[] = array('default_editor_css' => file_get_contents($default_editor_styles_file), 'inline' => '', 'css' => ''); } // Extract fonts from theme.json if the current theme supports it $resolver = ABSPATH.WPINC.'/class-wp-theme-json-resolver.php'; if (!class_exists('WP_Theme_JSON_Resolver') && file_exists($resolver)) { require_once($resolver); } if (class_exists('WP_Theme_JSON_Resolver') && WP_Theme_JSON_Resolver::theme_has_support()) { $theme_json = ABSPATH.WPINC.'/class-wp-theme-json.php'; if (!class_exists('WP_Theme_JSON') && file_exists($theme_json)) require_once($theme_json); $theme_json_instance = WP_Theme_JSON_Resolver::get_theme_data(); if ($theme_json_instance) { $settings = $theme_json_instance->get_settings(); $theme_fonts = ''; if (isset($settings['typography']) && isset($settings['typography']['fontFamilies'])) { $font_families = $settings['typography']['fontFamilies']; if (isset($font_families['theme'])) { foreach ($font_families['theme'] as $theme) { if (isset($theme['fontFace'])) { foreach ($theme['fontFace'] as $font) { $theme_fonts .= '@font-face {'; $keys = array_keys($font); foreach ($keys as $key) { if (false !== stripos($key, 'font')) { $prop = 'font-'.strtolower(str_replace('font', '', $key)); $theme_fonts .= $prop.': '.$font[$key].';'; } elseif (false !== stripos($key, 'src')) { foreach ($font['src'] as $src_file) { $url = trailingslashit(get_stylesheet_directory_uri()).str_replace('file:./', '', $src_file); $theme_fonts .= 'src: url(CENTRAL_URL/?udcentral_action=load_font&font='.urlencode($url).');'; } } } $theme_fonts .= '}'; } } } } } $editing_styles[] = array('theme_json_fonts' => $theme_fonts, 'inline' => '', 'css' => ''); } } return $editing_styles; } /** * Retrieves the total number of items found under each post statuses * * @param string $type The type of the module that the current request is processing * * @return array */ protected function get_post_status_counts($type = 'post') { $posts = wp_count_posts($type); $publish = (int) $posts->publish; $private = (int) $posts->private; $draft = (int) $posts->draft; $pending = (int) $posts->pending; $future = (int) $posts->future; $trash = (int) $posts->trash; // We exclude "trash" from the overall total as WP doesn't actually // consider or include it in the total count. $all = $publish + $private + $draft + $pending + $future; return array( 'all' => $all, 'publish' => $publish, 'private' => $private, 'draft' => $draft, 'pending' => $pending, 'future' => $future, 'trash' => $trash, ); } /** * Retrieves a collection of formatted dates found for the given post statuses. * It will be used as options for the date filter when managing the posts in UpdraftCentral. * * @param string $type The type of the module that the current request is processing * * @return array */ protected function get_date_options($type = 'post') { global $wpdb; $date_options = $wpdb->get_col("SELECT DATE_FORMAT(`post_date`, '%M %Y') as `formatted_post_date` FROM {$wpdb->posts} WHERE `post_type` = '{$type}' AND `post_status` IN ('publish', 'private', 'draft', 'pending', 'future') GROUP BY `formatted_post_date` ORDER BY `post_date` DESC"); return $date_options; } /** * Make sure that we have the required fields to use in UpdraftCentral for * displaying the categories and tags sections. Add if missing. * * @param object $item Taxonomy item to check * @return object */ protected function map_tax($item) { $taxs = array('category' => 'categories', 'post_tag' => 'tags'); if (array_key_exists($item->name, $taxs)) { if (!isset($item->show_in_rest)) $item->show_in_rest = true; if (!isset($item->rest_base)) $item->rest_base = $taxs[$item->name]; } return $item; } /** * Fetch and retrieves available taxonomies for this site and some capabilities specific * to tags and categories when managing them. * * @return array */ protected function get_taxonomies() { $taxonomies = get_taxonomies(array(), 'objects'); $taxonomies = array_map(array($this, 'map_tax'), $taxonomies); $response = array( 'taxonomies' => $taxonomies, 'current_user_cap' => array( 'manage_categories' => current_user_can('manage_categories'), 'edit_categories' => current_user_can('edit_categories'), 'delete_categories' => current_user_can('delete_categories'), 'assign_categories' => current_user_can('assign_categories'), 'manage_post_tags' => current_user_can('manage_post_tags'), 'edit_post_tags' => current_user_can('edit_post_tags'), 'delete_post_tags' => current_user_can('delete_post_tags'), 'assign_post_tags' => current_user_can('assign_post_tags'), ) ); return $response; } /** * Fetch and retrieves categories based from the submitted parameters * * @param array $query Containing all the needed information to filter the results of the current request * @return array */ public function get_categories($query = array()) { $page = !empty($query['page']) ? (int) $query['page'] : 1; $items_per_page = !empty($query['per_page']) ? (int) $query['per_page'] : 100; $offset = ($page - 1) * $items_per_page; $order = !empty($query['order']) ? $query['order'] : 'asc'; $orderby = !empty($query['orderby']) ? $query['orderby'] : 'name'; $args = array( 'hide_empty' => false, 'orderby' => $orderby, 'order' => $order, 'number' => $items_per_page, 'offset' => $offset ); $categories = get_categories($args); $category_options = array(); if (!empty($categories)) { foreach ($categories as $key => $term) { $parent_term = get_term((int) $term->parent, $term->taxonomy); if (!is_wp_error($parent_term) && !is_null($parent_term)) { $parent_term = json_encode($this->trim_object($parent_term)); } else { $parent_term = ''; } $category_options[] = array( 'id' => $term->term_id, 'name' => $term->name, 'parent' => $term->parent ); $categories[$key] = array( 'term' => json_encode($this->trim_object($term)), 'misc' => array( 'link' => get_term_link($term), 'parent_term' => $parent_term, 'taxonomy' => $term->taxonomy ) ); } } $categorytax = get_taxonomy('category'); $parent_dropdown_args = array( 'taxonomy' => 'category', 'hide_empty' => 0, 'name' => 'newcategory_parent', 'orderby' => 'name', 'hierarchical' => 1, 'show_option_none' => '— '.$categorytax->labels->parent_item.' —', 'echo' => false ); $parent_dropdown_args = apply_filters('post_edit_category_parent_dropdown_args', $parent_dropdown_args); $parent_dropdown = wp_dropdown_categories($parent_dropdown_args); if (!function_exists('wp_popular_terms_checklist')) { require_once ABSPATH . 'wp-admin/includes/template.php'; } ob_start(); wp_popular_terms_checklist('category'); $popular_terms_checklist = ob_get_contents(); ob_end_clean(); return $this->_response(array( 'terms' => $categories, 'misc' => array( 'formatted' => $category_options, 'raw' => $categories, 'tax' => json_encode($this->trim_object($categorytax)), 'popular' => $popular_terms_checklist, 'parent_dropdown' => $parent_dropdown, 'capabilities' => array( 'can_edit_terms' => current_user_can($categorytax->cap->edit_terms) ) ) )); } /** * Fetch and retrieves tags based from the submitted parameters * * @param array $query Containing all the needed information to filter the results of the current request * @return array */ public function get_tags($query = array()) { $page = !empty($query['page']) ? (int) $query['page'] : 1; $items_per_page = !empty($query['per_page']) ? (int) $query['per_page'] : 100; $offset = ($page - 1) * $items_per_page; $order = !empty($query['order']) ? $query['order'] : 'desc'; $orderby = !empty($query['orderby']) ? $query['orderby'] : 'count'; $args = array( 'hide_empty' => false, 'orderby' => $orderby, 'order' => $order, 'number' => $items_per_page, 'offset' => $offset ); $tags = get_tags($args); $tag_options = array(); $tag_cloud = ''; if (!empty($tags)) { $tags_for_cloud = array(); foreach ($tags as $key => $term) { if (!isset($term->link)) $term->link = get_tag_link($term->term_id); array_push($tags_for_cloud, $term); $parent_term = get_term((int) $term->parent, $term->taxonomy); if (!is_wp_error($parent_term) && !is_null($parent_term)) { $parent_term = json_encode($this->trim_object($parent_term)); } else { $parent_term = ''; } $tag_options[] = array( 'id' => $term->term_id, 'name' => $term->name, ); $tags[$key] = array( 'term' => json_encode($this->trim_object($term)), 'misc' => array( 'link' => get_term_link($term), 'parent_term' => $parent_term, 'taxonomy' => $term->taxonomy ) ); } add_filter('tag_cloud_sort', array($this, 'sort_tag_cloud'), 9, 2); if (!function_exists('wp_generate_tag_cloud')) { require_once ABSPATH.WPINC.'/category-template.php'; } $tag_cloud = wp_generate_tag_cloud($tags_for_cloud, array( 'smallest' => 10, 'largest' => 22, 'unit' => 'pt', 'number' => 10, 'format' => 'flat', 'separator' => " ", 'orderby' => 'count', 'order' => 'DESC', 'show_count' => 1, 'echo' => false )); } $tagtax = get_taxonomy('post_tag'); return $this->_response(array( 'terms' => $tags, 'misc' => array( 'formatted' => $tag_options, 'raw' => $tags, 'tax' => json_encode($this->trim_object($tagtax)), 'tag_cloud' => $tag_cloud, 'capabilities' => array( 'can_assign_terms' => current_user_can($tagtax->cap->assign_terms) ) ) )); } /** * Sorts the tag items that are to be shown within the tag cloud * * @param array $tags The array to be sorted. Contains the tag items * @param array $args Additional parameters needed for the sorting process * @return array */ public function sort_tag_cloud($tags, $args) { uasort($tags, array($this, '_wp_object_count_sort_cb')); if ('DESC' === $args['order']) { $tags = array_reverse($tags, true); } return $tags; } /** * Serves as a callback for comparing objects based on count. Copied from WordPress 5.7 * core (wp-includes/category-template.php) and tweaked to return integer instead of boolean * because returning boolean using uasort is now DEPRECATED in PHP 8. * * Used with `uasort()`. * * @since 3.1.0 * @access private * * @param object $a The first object to compare. * @param object $b The second object to compare. * @return bool Whether the count value for `$a` is greater than the count value for `$b`. */ public function _wp_object_count_sort_cb($a, $b) { if ($a->count == $b->count) { return 0; } return ( $a->count > $b->count ) ? 1 : -1; } /** * Fetch all available taxonomies and terms information for the given post object * * @param array $post The "Post" object to use when retrieving the information * @return array */ protected function get_taxonomies_terms($post) { $taxonomies = get_object_taxonomies($post->post_type, 'objects'); $taxonomies = array_map(array($this, 'map_tax'), $taxonomies); $taxonomy_names = array(); $taxonomy_terms = array(); $taxonomy_caps = array(); foreach ($taxonomies as $taxonomy) { $terms = get_the_terms($post->ID, $taxonomy->name); $terms = !is_array($terms) ? (array) $terms : $terms; $taxonomy_terms[$taxonomy->name] = $terms; $taxonomy_caps[$taxonomy->name] = array( 'hierarchical' => is_taxonomy_hierarchical($taxonomy->name), 'edit_terms' => current_user_can($taxonomy->cap->edit_terms), 'assign_terms' => current_user_can($taxonomy->cap->assign_terms), ); array_push($taxonomy_names, $taxonomy->name); } return array( 'objects' => $taxonomies, 'names' => $taxonomy_names, 'terms' => $taxonomy_terms, 'caps' => $taxonomy_caps, ); } /** * Take over the current editing of the post * * @param array $params An array of data that serves as parameters for the given request * @return array */ public function take_over($params) { $error = $this->_validate_capabilities(array('edit_'.$this->post_type.'s')); if (!empty($error)) return $error; $result = array('lock_acquired' => false); if (!empty($params['post_id'])) { if (!function_exists('wp_set_post_lock')) { require_once ABSPATH.'wp-admin/includes/post.php'; } $lock = wp_set_post_lock($params['post_id']); if (!empty($lock)) { $result = array( 'lock_acquired' => true, 'details' => $lock ); } } return $this->_response($result); } /** * Retrieves the underlying data for the given post. Some extra information are * passed along that will be consumed by the editor in UpdraftCentral * * @param int|object $param Post object or a post ID * @param boolean $encode True to encode the post object, false otherwise * @return array */ public function get_postdata($param, $encode = true) { $response = array(); if (is_object($param) && isset($param->ID)) { $post = $param; } elseif (is_numeric($param)) { $post = get_post($param); } if ($post) { $post_type_obj = get_post_type_object($post->post_type); $is_post_type_viewable = false; if (!empty($post_type_obj)) { $is_post_type_viewable = $post_type_obj->publicly_queryable || ($post_type_obj->_builtin && $post_type_obj->public); } if (!function_exists('get_sample_permalink')) { require_once ABSPATH.'wp-admin/includes/post.php'; } // Validate template exists on the current theme, otherwise, // reset the template to default. $template = get_page_template_slug($post->ID); if (!empty($template)) { $page_templates = wp_get_theme()->get_page_templates($post); if ('default' != $template && !isset($page_templates[$template])) { update_post_meta($post->ID, '_wp_page_template', 'default'); } } $published_date = array( 'jj' => date('d', strtotime($post->post_date)), 'mm' => date('m', strtotime($post->post_date)), 'aa' => date('Y', strtotime($post->post_date)), 'hh' => date('H', strtotime($post->post_date)), 'mn' => date('i', strtotime($post->post_date)), 'ss' => date('s', strtotime($post->post_date)) ); $sample_permalink = get_sample_permalink($post->ID, $post->post_title, ''); $permalink = get_permalink($post->ID); $slug = $post->post_name; if (!empty($sample_permalink) && !empty($slug)) { if (isset($sample_permalink[0])) { if (false !== stripos($sample_permalink[0], '%pagename%/') || false !== stripos($sample_permalink[0], '%postname%/')) { $token = (false !== stripos($sample_permalink[0], '%pagename%/')) ? '%pagename%/' : '%postname%/'; $permalink = str_replace($token, '', $sample_permalink[0]).$slug; } } } $editor = null; $editor_id = wp_check_post_lock($post->ID); if ($editor_id) { $editor = get_userdata($editor_id); if (!$editor) { // The user with lock does not exist. This can happen if you created a backup or clone // where you excluded the users table during the process and you restore this backup to // a different site or the user was deleted or removed more recently. Thus, we will // release the lock so that other users with the right permission can edit the post. delete_post_meta($post->ID, '_edit_lock'); } } $response = array( 'post' => $encode ? json_encode($post) : $post, 'misc' => array( 'guid_rendered' => apply_filters('get_the_guid', $post->guid, $post->ID), 'link' => $permalink, 'slug' => $slug, 'site_url' => site_url('/'), 'title_rendered' => get_the_title($post->ID), 'content_rendered' => apply_filters('the_content', $post->post_content), 'excerpt' => $post->post_excerpt, 'featured_media' => 0, 'sticky' => is_sticky($post->ID), 'template' => get_page_template_slug($post->ID), 'permalink_template' => get_permalink($post->ID, true), 'author_name' => get_the_author_meta('display_name', $post->post_author), 'publish_month_year' => date('F Y', strtotime($post->post_date)), 'published_date' => $published_date, 'format' => get_post_format($post->ID), 'post_type_name' => $post_type_obj->name, 'post_type_viewable' => $is_post_type_viewable, 'post_type_public' => $post_type_obj->public, 'post_type_hierarchical' => $post_type_obj->hierarchical, 'sample_permalink' => get_sample_permalink($post->ID, $post->post_title, ''), 'post_password_required' => post_password_required($post), 'post_type_supports_authors' => post_type_supports($post->post_type, 'author'), 'post_type_supports_comments' => post_type_supports($post->post_type, 'comments'), 'post_type_supports_revisions' => post_type_supports($post->post_type, 'revisions'), 'post_revisions' => array(), // N.B. We're not going to allow revisions editing for now 'post_thumbnail_id' => get_post_thumbnail_id($post->ID), 'can_publish_posts' => current_user_can($post_type_obj->cap->publish_posts), 'can_edit_others_posts' => current_user_can($post_type_obj->cap->edit_others_posts), 'can_unfiltered_html' => current_user_can('unfiltered_html'), 'is_edited' => $editor ? 1 : 0, 'editor_id' => $editor_id, 'editor' => $editor, 'edited_by_id' => $editor ? $editor->ID : 0, 'edited_by_display_name' => $editor ? $editor->display_name : '', ) ); if ('post' == $post->post_type) { $taxonomies = $this->get_taxonomies_terms($post); $response['misc']['taxonomy_objects'] = $taxonomies['objects']; $response['misc']['taxonomy_names'] = $taxonomies['names']; $response['misc']['taxonomy_terms'] = $taxonomies['terms']; $response['misc']['taxonomy_caps'] = $taxonomies['caps']; if (!function_exists('wp_popular_terms_checklist') || !function_exists('get_terms_to_edit')) { require_once ABSPATH . 'wp-admin/includes/template.php'; require_once ABSPATH . 'wp-admin/includes/taxonomy.php'; } if (!function_exists('wp_get_post_categories')) { require_once(ABSPATH.WPINC.'/post.php'); } $categories = wp_get_post_categories($post->ID, array('fields' => 'ids')); if (!is_wp_error($categories)) { $response['misc']['categories'] = empty($categories) ? array() : $categories; $terms_to_edit = get_terms_to_edit($post->ID, 'category'); if (!empty($terms_to_edit)) { $response['misc']['categories_list'] = str_replace(',', ', ', $terms_to_edit); } $popular_ids = wp_popular_terms_checklist('category', 0, 10, false); // On WP 3.4 the "wp_terms_checklist" doesn't have an "echo" parameter and will automatically // display the rendered checklist. Therefore, we're going to pull the terms so that all // versions starting from WP 3.4 will pull the content instead of displaying them. ob_start(); // In this call we'll have to set the "echo" parameter to true so that later version of WP // will be able to catch and process it. wp_terms_checklist($post->ID, array('taxonomy' => 'category', 'popular_cats' => $popular_ids, 'echo' => true)); $popular_checklist = ob_get_contents(); ob_end_clean(); $response['misc']['categories_checklist'] = $popular_checklist; ob_start(); wp_terms_checklist($post->ID, array('taxonomy' => 'category', 'checked_ontop' => 0, 'echo' => true)); $quickedit_checklist = ob_get_contents(); ob_end_clean(); $response['misc']['categories_quickedit_checklist'] = $quickedit_checklist; } $tags = wp_get_post_tags($post->ID, array('fields' => 'ids')); if (!is_wp_error($tags)) { $response['misc']['tags'] = empty($tags) ? array() : $tags; $terms_to_edit = get_terms_to_edit($post->ID, 'post_tag'); if (!empty($terms_to_edit)) { $response['misc']['tags_list'] = str_replace(',', ', ', $terms_to_edit); } } } // Naturally, the "featured_media" will suffice when loading the image (media) in // UpdraftCentral since the value in this field is the actual image id of the featured // media used in UC. If we currently don't have an entry in the "featured_media_updraftcentral" meta, // then UC will need to download the featured media (image) for this current post/page // using the "featured_media_url" field (below) if not empty. $featured_media = get_post_meta($post->ID, 'featured_media_updraftcentral', true); if (!empty($featured_media)) { $response['misc']['featured_media'] = $featured_media; } // Retrieve featured media if currently present for the given post/page. // If present, we pull the image (media) URL in case there's a need for // UpdraftCentral to download the image upon loading the editor (e.g. the featured_media id // above no longer exists). $media_id = (int) get_post_thumbnail_id($post->ID); if (!empty($media_id)) { $response['misc']['featured_media_url'] = wp_get_attachment_url($media_id); } else { // The post/page no longer has a "featured_media" or doesn't have one currently, therefore, // we're going to set the "featured_media" and "featured_media_url" fields to both empty to // to avoid any further actions (e.g. download media). $response['misc']['featured_media'] = 0; $response['misc']['featured_media_url'] = ''; } } return $response; } /** * Changes the state/status of the submitted post(s) * * @param array $params An array of data that serves as parameters for the given request * @return array */ public function set_state($params) { $state_fields = $this->get_state_fields_by_type($this->post_type); if (empty($state_fields)) return $this->_generic_error_response('unsupported_type_on_set_state'); $error = $this->_validate_capabilities($state_fields['validation_fields']); if (!empty($error)) return $error; $result = array(); if (!empty($params['list'])) { $posts = array(); foreach ($params['list'] as $id) { $post = $this->apply_state($id, $params['action'], $this->post_type); if (!empty($post)) { array_push($posts, $post); } } if (!empty($posts)) { $result = array($state_fields['list_key'] => $posts); } } elseif (!empty($params['id'])) { $post = $this->apply_state($params['id'], $params['action'], $this->post_type); if (!empty($post)) $result = $post; } if (!empty($result)) { $response = $this->get($params); if (!empty($response['response']) && 'rpcok' === $response['response']) { $result[$state_fields['result_key']] = $response['data']; } return $this->_response($result); } else { return $this->_generic_error_response($state_fields['error_key'], array('action' => $params['action'])); } } /** * Creates new category * * @param array $params An array of data that serves as parameters for the given request * @param boolean $wrap_response Indicates whether to wrap the response based on local or UpdraftCentral calls. Default true. * @return array */ public function add_category($params, $wrap_response = true) { $error = $this->_validate_capabilities(array('manage_categories')); if (!empty($error)) return $error; $name = sanitize_text_field($params['name']); $args = array(); if (!empty($params['parent'])) { $args['parent'] = $params['parent']; } $result = wp_insert_term($name, 'category', $args); if (!is_wp_error($result)) { $term_id = $result['term_id']; $term = get_term($term_id, 'category'); $data = array(); if (!is_wp_error($term)) { $data = array( 'id' => $term->term_id, 'count' => $term->count, 'description' => $term->description, 'link' => get_term_link($term->term_id, 'category'), 'name' => $term->name, 'slug' => $term->slug, 'taxonomy' => $term->taxonomy, 'parent' => $term->parent, 'meta' => array() ); $categories = $this->get_categories(); if ($wrap_response) $data['categories'] = json_encode($categories['data']); } return $wrap_response ? $this->_response($data) : $data; } else { $error = array( 'message' => $result->get_error_message() ); return $wrap_response ? $this->_generic_error_response('post_add_category_failed', $error) : $error; } } /** * Assigns categories to a certain post object * * @param int $post_id The ID of the post object * @param array $category_ids A collection of category IDs to assign to the post object * @return void */ protected function assign_category_to_post($post_id, $category_ids) { if (!empty($category_ids)) { // Making sure that we have the correct type to use and we // don't have any redundant IDs before saving. $category_ids = array_unique(array_map('intval', $category_ids)); // Attach (new) categories to post wp_set_object_terms($post_id, $category_ids, 'category'); } else { wp_set_object_terms($post_id, get_option('default_category'), 'category'); } } /** * Creates new tag * * @param array $params An array of data that serves as parameters for the given request * @param boolean $wrap_response Indicates whether to wrap the response based on local or UpdraftCentral calls. Default true. * @return array */ public function add_tag($params, $wrap_response = true) { // N.B. Since the "manage_post_tags" capability does not exist in WP 3.4. We'll use the "manage_categories" instead. Besides, the "manage_post_tags" along with the other tag-related capabilities in the latest versions are actually mapped to the "manage_categories" capability (refer to wp-includes/capabilities.php under the "map_meta_cap" function). $error = $this->_validate_capabilities(array('manage_categories')); if (!empty($error)) return $error; $name = sanitize_text_field($params['name']); $result = wp_insert_term($name, 'post_tag'); if (!is_wp_error($result)) { $term_id = $result['term_id']; $term = get_term($term_id, 'post_tag'); $data = array(); if (!is_wp_error($term)) { $data = array( 'id' => $term->term_id, 'count' => $term->count, 'description' => $term->description, 'link' => get_term_link($term->term_id, 'post_tag'), 'name' => $term->name, 'slug' => $term->slug, 'taxonomy' => $term->taxonomy, 'meta' => array() ); $tags = $this->get_tags(); if ($wrap_response) $data['tags'] = json_encode($tags['data']); } return $wrap_response ? $this->_response($data) : $data; } else { $error = array( 'message' => $result->get_error_message() ); return $wrap_response ? $this->_generic_error_response('post_add_tag_failed', $error) : $error; } } /** * Assigns tags to a certain post object * * @param int $post_id The ID of the post object * @param array $tag_ids A collection of tag IDs to assign to the post object * @return void */ protected function assign_tag_to_post($post_id, $tag_ids) { if (!empty($tag_ids)) { // Making sure that we have the correct type to use and we // don't have any redundant IDs before saving. $tag_ids = array_unique(array_map('intval', $tag_ids)); // Attach (new) tags to post wp_set_object_terms($post_id, $tag_ids, 'post_tag'); } else { wp_set_object_terms($post_id, null, 'post_tag'); } } /** * Pre-validates data before running the save process * * @param WP_Post $post The post object to validate * @param array $params An array of data that serves as parameters for the given request * * @return array|void */ private function pre_validation($post, $params) { if (empty($post) || empty($params)) return; if (!empty($params['password'])) { if (!empty($params['sticky'])) { return $this->_generic_error_response('post_save_failed', array( 'message' => __('A post can not be sticky and have a password.'), 'args' => $params )); } if (!isset($params['sticky']) && is_sticky($post->ID)) { return $this->_generic_error_response('post_save_failed', array( 'message' => __('A sticky post can not be password protected.'), 'args' => $params )); } } if (!empty($params['sticky'])) { if (!isset($params['password']) && post_password_required($post->ID)) { return $this->_generic_error_response('post_save_failed', array( 'message' => __('A password protected post can not be set to sticky.'), 'args' => $params )); } } } /** * Saves or updates post/page information based from the submitted data * * @param array $params An array of data that serves as parameters for the given request * @return array */ public function save($params) { global $updraftcentral_host_plugin; $validation_fields = array( 'post' => array('publish_posts', 'edit_posts', 'delete_posts'), 'page' => array('publish_pages', 'edit_pages', 'delete_pages') ); if (!isset($validation_fields[$this->post_type])) return $this->_generic_error_response('unsupported_type_on_save_post'); $error = $this->_validate_capabilities($validation_fields[$this->post_type]); if (!empty($error)) return $error; if (!empty($params['id']) || !empty($params['new'])) { $args = array(); if (!empty($params['id'])) { $post = get_post($params['id']); if (!empty($post)) { $result = $this->pre_validation($post, $params); if (isset($result['response']) && 'rpcerror' == $result['response']) { return $result; } } } // post_content if (!empty($params['content'])) $args['post_content'] = $params['content']; // post_excerpt if (!empty($params['excerpt'])) $args['post_excerpt'] = $params['excerpt']; // menu_order if (isset($params['order'])) $args['menu_order'] = (int) $params['order']; // post_parent if (isset($params['parent'])) { $args['post_parent'] = empty($params['parent']) ? 0 : $params['parent']; } // post_name if (!empty($params['slug'])) $args['post_name'] = $params['slug']; // post_status if (!empty($params['status'])) { $args['post_status'] = $params['status']; } // post_title if (!empty($params['title'])) $args['post_title'] = $params['title']; // post_author if (!empty($params['author'])) $args['post_author'] = $params['author']; // comment_status if (!empty($params['comment_status'])) $args['comment_status'] = $params['comment_status']; // ping_status if (!empty($params['ping_status'])) $args['ping_status'] = $params['ping_status']; // visibility if (!empty($params['visibility'])) { switch ($params['visibility']) { case 'public': $args['post_status'] = 'publish'; $args['post_password'] = ''; break; case 'password': $args['post_status'] = 'publish'; $args['post_password'] = $params['password']; break; case 'private': $args['post_status'] = 'private'; $args['post_password'] = ''; break; default: break; } } else { if (!empty($params['password'])) { $args['post_status'] = 'publish'; $args['post_password'] = $params['password']; } elseif (isset($params['password']) && '' == $params['password']) { $args['post_status'] = 'publish'; $args['post_password'] = ''; } } // post/publish date if (!empty($params['date'])) { $datetime = strtotime($params['date']); $post_date = date('Y-m-d H:i:s', $datetime); $args['post_date'] = $post_date; $args['post_date_gmt'] = gmdate('Y-m-d H:i:s', $datetime); // We only change the status to "future" based from the submitted date if the post status // is not empty and equal to 'publish' and the date is for the coming future. if (!empty($params['status']) && 'publish' == $params['status']) { if (strtotime($post_date) > strtotime(date('Y-m-d H:i:s'))) $args['post_status'] = 'future'; } } // Make sure we have a slug/post_name generated before insert/update if (empty($params['slug']) && !empty($params['title'])) { $args['post_name'] = sanitize_title_with_dashes($params['title']); } if (!empty($params['new'])) { $args['post_type'] = $this->post_type; $post_id = wp_insert_post($args, true); } else { $args['ID'] = $params['id']; $args['post_modified'] = date('Y-m-d H:i:s'); $args['post_modified_gmt'] = gmdate('Y-m-d H:i:s'); $post_id = wp_update_post($args, true); } // We have successfully created/updated a post at this point, thus, we'll continue // with implementing the other requested processes and return the result. if (!is_wp_error($post_id)) { // sticky post if (isset($params['sticky'])) { $sticky = (bool) $params['sticky']; if ($sticky) { stick_post($post_id); } else { if (is_sticky($post_id)) { unstick_post($post_id); } } } // template if (!empty($params['template'])) { update_post_meta($post_id, '_wp_page_template', $params['template']); } // featured_media if (isset($params['featured_media'])) { if (!empty($params['featured_media'])) { $featured_media = (int) $params['featured_media']; $attach_continue = true; $url = wp_get_attachment_url($featured_media); if (!empty($url) && !empty($params['featured_media_url']) && $url == $params['featured_media_url']) { set_post_thumbnail($post_id, $featured_media); update_post_meta($post_id, 'featured_media_updraftcentral', $params['featured_media']); $attach_continue = false; } if ($attach_continue) { $featured_media_data = !empty($params['featured_media_data']) ? $params['featured_media_data'] : null; $media_id = $this->attach_remote_image($params['featured_media_url'], $featured_media_data, $post_id); if (!empty($media_id)) { // If we have a successful attachment then add reference to UC's media id update_post_meta($post_id, 'featured_media_updraftcentral', $params['featured_media']); } } } else { // Remove featured image. delete_post_meta($post_id, '_thumbnail_id'); delete_post_meta($post_id, 'featured_media_updraftcentral'); } } // categories $categories_updated = false; if (!empty($params['categories'])) { $term_ids = array(); foreach ($params['categories'] as $value) { $category = sanitize_text_field($value); $parent = 0; if (false !== strpos($category, ':')) { list($parent, $category) = explode(':', $category); $result = $this->add_category(array('name' => $category, 'parent' => $parent), false); if (!empty($result)) { array_push($term_ids, $result['id']); } } else { $term = get_term_by('id', $category, 'category'); if (!empty($term)) { $term_id = $term->term_id; array_push($term_ids, $term_id); } } } $this->assign_category_to_post($post_id, $term_ids); $categories_updated = true; } // tags $tags_updated = false; if (!empty($params['tags'])) { $term_ids = array(); foreach ($params['tags'] as $value) { $tag = sanitize_text_field($value); $field = is_numeric($tag) ? 'id' : 'name'; $term = get_term_by($field, $tag, 'post_tag'); if (!empty($term)) { $term_id = $term->term_id; array_push($term_ids, $term_id); } else { $result = $this->add_tag(array('name' => $tag), false); if (!empty($result)) { array_push($term_ids, $result['id']); } } } $this->assign_tag_to_post($post_id, $term_ids); $tags_updated = true; } // Pulling any other relevant and additional information regarding // the post before returning it in the response. $postdata = $this->get_postdata($post_id); if (!empty($params['new'])) { $timeout = !empty($params['timeout']) ? $params['timeout'] : 30; $postdata = array_merge($postdata, $this->get_preload_data($timeout, $this->post_type)); } else { if ($categories_updated || $tags_updated) { $categories = $this->get_categories(); $tags = $this->get_tags(); $postdata['preloaded'] = json_encode(array( 'categories' => $categories['data'], 'tags' => $tags['data'] )); } } $postdata['options'] = $this->get_options($this->post_type); return $this->_response($postdata); } else { // ERROR: error creating or updating post return $this->_generic_error_response('post_save_failed', array( 'message' => $post_id->get_error_message(), 'args' => $args )); } } else { // ERROR: no id parameter, invalid request return $this->_generic_error_response('post_invalid_request', array('message' => $updraftcentral_host_plugin->retrieve_show_message('parameters_missing'))); } } /** * Fetch and retrieves authors based from the submitted parameters * * @param array $params Containing all the needed information to filter the results of the current request * @return array */ public function get_authors($params = array()) { global $updraftcentral_main; // If expected parameters are empty or does not exists then set them to some default values $page = !empty($params['page']) ? (int) $params['page'] : 1; $per_page = !empty($params['per_page']) ? (int) $params['per_page'] : 15; $offset = ($page - 1) * $per_page; $who = !empty($params['who']) ? $params['who'] : 'authors'; $order = !empty($params['order']) ? strtoupper($params['order']) : 'ASC'; $orderby = !empty($params['orderby']) ? $params['orderby'] : 'display_name'; $get_user_params = array( 'number' => $per_page, 'paged' => $page, 'offset' => $offset, 'order' => $order, 'orderby' => $orderby, ); // WP 5.9 deprecated the 'who' parameter and introduces the 'capability' // parameter, thus we'll be replacing the 'who' parameter in 5.9 or higher if (version_compare($updraftcentral_main->get_wordpress_version(), '5.9', '<')) { $get_user_params['who'] = $who; } else { $get_user_params['capability'] = array('edit_posts'); } $users = get_users($get_user_params); $authors = array(); $locale = get_locale(); foreach ($users as $user) { $data = array( 'user' => json_encode($this->trim_object($user)), 'misc' => array( 'link' => get_author_posts_url($user->ID, $user->user_nicename), 'locale' => function_exists('get_user_locale') ? get_user_locale($user) : $locale, 'registered_date' => date('c', strtotime($user->user_registered)), ) ); array_push($authors, $data); } return $this->_response(array( 'authors' => $authors )); } /** * Fetch and retrieves parent pages based from the submitted parameters * * @param array $params Containing all the needed information to filter the results of the current request * @return array */ public function get_parent_pages($params = array()) { // If expected parameters are empty or does not exists then set them to some default values $page = !empty($params['page']) ? (int) $params['page'] : 1; $per_page = !empty($params['per_page']) ? (int) $params['per_page'] : 100; $offset = ($page - 1) * $per_page; $exclude = !empty($params['exclude']) ? $params['exclude'] : array(); $order = !empty($params['order']) ? strtoupper($params['order']) : 'ASC'; $orderby = !empty($params['orderby']) ? $params['orderby'] : 'menu_order'; $status = !empty($params['status']) ? $params['status'] : 'publish'; $args = array( 'posts_per_page' => $per_page, 'paged' => $page, 'offset' => $offset, 'post__not_in' => $exclude, 'order' => $order, 'orderby' => $orderby, 'post_type' => 'page', 'post_status' => $status, ); $query = new WP_Query($args); $posts = $query->posts; $pages = array(); if (!empty($posts)) { foreach ($posts as $post) { // Get additional information and merge with the response $postdata = $this->get_postdata($post, true); if (!empty($postdata)) array_push($pages, $this->trim_parent_info($postdata)); } } return $this->_response(array( 'pages' => $pages )); } /** * Trim down return data for parent pages * * @param array $postdata The array containing the data to process * @return array */ protected function trim_parent_info($postdata) { if (isset($postdata['post'])) { $post = json_decode($postdata['post']); $page = new stdClass(); $page->ID = $post->ID; $page->post_title = $post->post_title; $page->post_parent = $post->post_parent; $page->post_type = $post->post_type; $page->post_status = $post->post_status; $postdata['post'] = json_encode($page); } return $postdata; } /** * Retrieves pages, templates, authors, categories and tags data that will be * used as options when displayed on the editor in UpdraftCentral * * @param string $type The type of the module that the current request is processing * * @return array */ protected function get_options($type = 'post') { // Primarily used for editor consumption so we don't include trash here. Besides, // trash posts/pages aren't included as parent options. $parent_pages = $this->get_parent_pages(); $pages = $parent_pages['data']['pages']; // Add flexibility by letting users filter the default roles and add their own // custom page/post "author" role(s) if need be. $author_roles = apply_filters('updraftcentral_author_roles', array('administrator', 'editor', 'author', 'contributor')); $authors = get_users(array('role__in' => $author_roles)); if (!function_exists('get_page_templates')) { require_once(ABSPATH.'wp-admin/includes/theme.php'); } $templates = ('post' == $type) ? get_page_templates(null, 'post') : get_page_templates(); $template_options = array(); foreach ($templates as $template => $filename) { $item = array( 'filename' => $filename, 'template' => $template, ); $template_options[] = $item; } $page_options = array(); foreach ($pages as $page_item) { if (isset($page_item['post'])) { $page = json_decode($page_item['post']); $item = array( 'id' => $page->ID, 'title' => $page->post_title, 'parent' => $page->post_parent ); $page_options[] = $item; } } $author_options = array(); foreach ($authors as $user) { $item = array( 'id' => $user->ID, 'name' => $user->display_name, ); $author_options[] = $item; } $response = array( 'page' => $page_options, 'author' => $author_options, 'template' => $template_options, 'date' => $this->get_date_options($type), ); if ('post' == $type) { $categories = get_categories(array('hide_empty' => false, 'orderby' => 'name', 'order' => 'ASC')); $tags = get_tags(array('hide_empty' => false)); $category_options = array(); foreach ($categories as $category) { $item = array( 'id' => $category->term_id, 'name' => $category->name, 'parent' => $category->parent ); $category_options[] = $item; } $tag_options = array(); foreach ($tags as $tag) { $item = array( 'id' => $tag->term_id, 'name' => $tag->name, ); $tag_options[] = $item; } $response['category'] = $category_options; $response['tag'] = $tag_options; } return $response; } /** * Changes the state/status of the given post based from the submitted action/request * * @param int $id The ID of the current page to work on * @param string $action The type of change that the current request is going to apply * @param string $type The type of the module that the current request is processing * * @return array */ protected function apply_state($id, $action, $type = 'post') { if (empty($id)) return false; $post = get_post($id); if (!empty($post)) { $previous_status = $post->post_status; $deleted = false; switch ($action) { case 'draft': $args = array('ID' => $id, 'post_status' => 'draft'); wp_update_post($args); break; case 'trash': wp_trash_post($id); break; case 'publish': $args = array('ID' => $id, 'post_status' => 'publish'); wp_update_post($args); break; case 'restore': $args = array('ID' => $id, 'post_status' => 'pending'); wp_update_post($args); break; case 'delete': $result = wp_delete_post($id, true); if (!empty($result)) $deleted = true; break; default: break; } $postdata = $this->get_postdata($post); if (!empty($postdata) || $deleted) { $data = $deleted ? $id : $postdata; $result = array( 'id' => $id, 'previous_status' => $previous_status ); $result[$type] = $data; return $result; } } return false; } /** * Imports image from UpdraftCentral's page/post editor * * @param string $image_url The URL of the image to import * @param string $image_data The image data to save. If empty, image_url will be used to download the image * @param int $post_id The ID of the page where this image is to be attached * * @return integer */ protected function attach_remote_image($image_url, $image_data, $post_id) { if (empty($image_url) || empty($post_id)) return; $image = pathinfo($image_url); $image_name = $image['basename']; $upload_dir = wp_upload_dir(); if (empty($image_data)) { $response = wp_remote_get($image_url); if (!is_wp_error($response)) { $image_data = wp_remote_retrieve_body($response); } } else { $image_data = base64_decode($image_data); } $media_id = 0; if (!empty($image_data)) { $unique_file_name = wp_unique_filename($upload_dir['path'], $image_name); $filename = basename($unique_file_name); if (wp_mkdir_p($upload_dir['path'])) { $file = $upload_dir['path'] . '/' . $filename; } else { $file = $upload_dir['basedir'] . '/' . $filename; } file_put_contents($file, $image_data); $wp_filetype = wp_check_filetype($filename, null); $attachment = array( 'post_mime_type' => $wp_filetype['type'], 'post_title' => sanitize_file_name($filename), 'post_content' => '', 'post_status' => 'inherit' ); $media_id = wp_insert_attachment($attachment, $file, $post_id); require_once(ABSPATH . 'wp-admin/includes/image.php'); $attach_data = wp_generate_attachment_metadata($media_id, $file); wp_update_attachment_metadata($media_id, $attach_data); set_post_thumbnail($post_id, $media_id); } return $media_id; } /** * Checks whether we have the required fields submitted and the user has * the capabilities to execute the requested action * * @param array $capabilities The capabilities to check and validate * * @return array|void */ protected function _validate_capabilities($capabilities) { foreach ($capabilities as $capability) { if (!current_user_can($capability)) return $this->_generic_error_response('insufficient_permission'); } } } central/modules/analytics.php000064400000032150152214270100012337 0ustar00auth_endpoint = defined('UPDRAFTPLUS_GOOGLECLOUD_CALLBACK_URL') ? UPDRAFTPLUS_GOOGLECLOUD_CALLBACK_URL : 'https://auth.updraftplus.com/auth/googleanalytics'; $this->client_id = defined('UPDRAFTPLUS_GOOGLECLOUD_CLIENT_ID') ? UPDRAFTPLUS_GOOGLECLOUD_CLIENT_ID : '306245874349-6s896c3tjpra26ns3dpplhqcl6rv6qlb.apps.googleusercontent.com'; // Set transient expiration - default for 24 hours $this->expiration = 86400; } /** * Checks whether Google Analytics (GA) is installed or setup * * N.B. This check assumes GA is installed either using "wp_head" or "wp_footer" (e.g. attached * to the or somewhere before ). It does not recursively check all the pages * of the website to find if GA is installed on each or one of those pages, but only on the main/root page. * * @return array $result An array containing "ga_installed" property which returns "true" if GA (Google Analytics) is installed, "false" otherwise. */ public function ga_checker() { try { // Retrieves the tracking code/id if available $tracking_id = $this->get_tracking_id(); $installed = true; // If tracking code/id is currently not available then we // parse the needed information from the buffered content through // the "wp_head" and "wp_footer" hooks. if (false === $tracking_id) { $info = $this->extract_tracking_id(); $installed = $info['installed']; $tracking_id = $info['tracking_id']; } // Get access token to be use to generate the report. $access_token = $this->_get_token(); if (empty($access_token)) { // If we don't get a valid access token then that would mean // the access has been revoked by the user or UpdraftCentral was not authorized yet // to access the user's analytics data, thus, we're clearing // any previously stored user access so we're doing some housekeeping here. $this->clear_user_access(); } // Wrap and combined information for the requesting // client's consumption $result = array( 'ga_installed' => $installed, 'tracking_id' => $tracking_id, 'client_id' => $this->client_id, 'redirect_uri' => $this->auth_endpoint, 'scope' => $this->scope, 'access_token' => $access_token, 'endpoint' => $this->endpoint ); } catch (Exception $e) { $result = array('error' => true, 'message' => 'generic_response_error', 'values' => array($e->getMessage())); } return $this->_response($result); } /** * Extracts Google Tracking ID from contents rendered through the "wp_head" and "wp_footer" action hooks * * @internal * @return array $result An array containing the result of the extraction. */ private function extract_tracking_id() { // Define result array $result = array(); // Retrieve header content ob_start(); do_action('wp_head'); $header_content = ob_get_clean(); // Extract analytics information if available. $output = $this->parse_content($header_content); $result['installed'] = $output['installed']; $result['tracking_id'] = $output['tracking_id']; // If it was not found, then now try the footer if (empty($result['tracking_id'])) { // Retrieve footer content ob_start(); do_action('wp_footer'); $footer_content = ob_get_clean(); $output = $this->parse_content($footer_content); $result['installed'] = $output['installed']; $result['tracking_id'] = $output['tracking_id']; } if (!empty($result['tracking_id'])) { set_transient($this->tracking_id_key, $result['tracking_id'], $this->expiration); } return $result; } /** * Gets access token * * Validates whether the system currently have a valid token to use when connecting to Google Analytics API. * If not, then it will send a token request based on the authorization code we stored during the * authorization phase. Otherwise, it will return an empty token. * * @return array $result An array containing the Google Analytics API access token. */ public function get_access_token() { try { // Loads or request a valid token to use $access_token = $this->_get_token(); if (!empty($access_token)) { $result = array('access_token' => $access_token); } else { $result = array('error' => true, 'message' => 'ga_token_retrieval_failed', 'values' => array()); } } catch (Exception $e) { $result = array('error' => true, 'message' => 'generic_response_error', 'values' => array($e->getMessage())); } return $this->_response($result); } /** * Clears any previously stored user access * * @return bool */ public function clear_user_access() { return delete_option($this->access_key); } /** * Saves user is and access token received from the auth server * * @param array $query Parameter array containing the user id and access token from the auth server. * @return array $result An array containing a "success" or "failure" message as a result of the current process. */ public function save_user_access($query) { try { $token = get_option($this->access_key, false); $result = array(); if (false === $token) { $token = array( 'user_id' => base64_decode(urldecode($query['user_id'])), 'access_token' => base64_decode(urldecode($query['access_token'])) ); if (false !== update_option($this->access_key, $token)) { $result = array('error' => false, 'message' => 'ga_access_saved', 'values' => array()); } else { $result = array('error' => true, 'message' => 'ga_access_saving_failed', 'values' => array($query['access_token'])); } } } catch (Exception $e) { $result = array('error' => true, 'message' => 'generic_response_error', 'values' => array($e->getMessage())); } return $this->_response($result); } /** * Saves the tracking code/id manually (user input) * * @param array $query Parameter array containing the tracking code/id to save. * @return array $result An array containing the result of the process. */ public function save_tracking_id($query) { try { $tracking_id = $query['tracking_id']; $saved = false; if (!empty($tracking_id)) { $saved = set_transient($this->tracking_id_key, $tracking_id, $this->expiration); } $result = array('saved' => $saved); } catch (Exception $e) { $result = array('error' => true, 'message' => 'generic_response_error', 'values' => array($e->getMessage())); } return $this->_response($result); } /** * Retrieves any available access token either previously saved info or * from a new request from the Google Server. * * @internal * @return string $authorization_code */ private function _get_token() { // Retrieves the tracking code/id if available $tracking_id = $this->get_tracking_id(); $access_token = ''; $token = get_option($this->access_key, false); if (false !== $token) { $access_token = isset($token['access_token']) ? $token['access_token'] : ''; $user_id = isset($token['user_id']) ? $token['user_id'] : ''; if ((!empty($access_token) && !$this->_token_valid($access_token)) || (!empty($user_id) && empty($access_token) && !empty($tracking_id))) { if (!empty($user_id)) { $args = array( 'headers' => apply_filters('updraftplus_auth_headers', array()) ); $response = wp_remote_get($this->auth_endpoint.'?user_id='.$user_id.'&code=ud_googleanalytics_code', $args); if (is_wp_error($response)) { throw new Exception($response->get_error_message()); } else { if (is_array($response)) { $body = json_decode($response['body'], true); $token_response = array(); if (is_array($body) && !isset($body['error'])) { $token_response = json_decode(base64_decode($body[0]), true); } if (is_array($token_response) && isset($token_response['access_token'])) { $access_token = $token_response['access_token']; } else { // If we don't get any valid response then that would mean that the // permission was already revoked. Thus, we need to re-authorize the // user before using the analytics feature once again. $access_token = ''; } $token['access_token'] = $access_token; update_option($this->access_key, $token); } } } } } return $access_token; } /** * Verifies whether the access token is still valid for use * * @internal * @param string $token The access token to be check and validated * @return bool * @throws Exception If an error has occurred while connecting to the Google Server. */ private function _token_valid($token) { $response = wp_remote_get($this->token_info_endpoint.'?access_token='.$token); if (is_wp_error($response)) { throw new Exception($response->get_error_message()); } else { if (is_array($response)) { $response = json_decode($response['body'], true); if (!empty($response)) { if (!isset($response['error']) && !isset($response['error_description'])) { return true; } } } } return false; } /** * Parses and extracts the google analytics information (NEEDED) * * @internal * @param string $content The content to parse * @return array An array containing the status of the process along with the tracking code/id */ private function parse_content($content) { $installed = false; $gtm_installed = false; $tracking_id = ''; $script_file_found = false; $tracking_id_found = false; // Pull google analytics script file(s) preg_match_all('/]*>([\s\S]*?)<\/script>/i', $content, $scripts); for ($i=0; $i < count($scripts[0]); $i++) { // Check for Google Analytics file if (stristr($scripts[0][$i], 'ga.js') || stristr($scripts[0][$i], 'analytics.js')) { $script_file_found = true; } // Check for Google Tag Manager file // N.B. We are not checking for GTM but this check will be useful when // showing the notice to the user if we haven't found Google Analytics // directly being installed on the page. if (stristr($scripts[0][$i], 'gtm.js')) { $gtm_installed = true; } } // Pull tracking code preg_match_all('/UA-[0-9]{5,}-[0-9]{1,}/i', $content, $codes); if (count($codes) > 0) { if (!empty($codes[0])) { $tracking_id_found = true; $tracking_id = $codes[0][0]; } } // If we found both the script and the tracking code then it is safe // to say that Google Analytics (GA) is installed. Thus, we're returning // "true" as a response. if ($script_file_found && $tracking_id_found) { $installed = true; } // Return result of process. return array( 'installed' => $installed, 'gtm_installed' => $gtm_installed, 'tracking_id' => $tracking_id ); } /** * Retrieves the "analytics_tracking_id" transient * * @internal * @return mixed Returns the value of the saved transient. Returns "false" if the transient does not exist. */ private function get_tracking_id() { return get_transient($this->tracking_id_key); } /** * Returns the current tracking id * * @return array $result An array containing the Google Tracking ID. */ public function get_current_tracking_id() { try { // Get current site transient stored for this key $tracking_id = get_transient($this->tracking_id_key); // Checks whether we have a valid token $access_token = $this->_get_token(); if (empty($access_token)) { $tracking_id = ''; } if (false === $tracking_id) { $result = $this->extract_tracking_id(); } else { $result = array( 'installed' => true, 'tracking_id' => $tracking_id ); } } catch (Exception $e) { $result = array('error' => true, 'message' => 'generic_response_error', 'values' => array($e->getMessage())); } return $this->_response($result); } /** * Clears user access from database * * @return array $result An array containing the "Remove" confirmation whether the action succeeded or not. */ public function remove_user_access() { try { // Clear user access $is_cleared = $this->clear_user_access(); if (false !== $is_cleared) { $result = array('removed' => true); } else { $result = array('error' => true, 'message' => 'user_access_remove_failed', 'values' => array()); } } catch (Exception $e) { $result = array('error' => true, 'message' => 'generic_response_error', 'values' => array($e->getMessage())); } return $this->_response($result); } } central/modules/media.php000064400000047021152214270100011432 0ustar00switched = switch_to_blog($blog_id); } } /** * Function that gets called after every action * * @param string $command a string that corresponds to UDC command to call a certain method for this class. * @param array $data an array of data post or get fields * @param array $extra_info extrainfo use in the udrpc_action, e.g. user_id * * link to udrpc_action main function in class UpdraftCentral_Listener */ public function _post_action($command, $data, $extra_info) {// phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable -- Unused parameter is present because the caller from UpdraftCentral_Listener class uses 3 arguments. // Here, we're restoring to the current (default) blog before we switched if ($this->switched) restore_current_blog(); } /** * Fetch and retrieves posts based from the submitted parameters * * @param array $params Containing all the needed information to filter the results of the current request * @return array */ public function get_media_items($params) { $error = $this->_validate_capabilities(array('upload_files', 'edit_posts')); if (!empty($error)) return $error; // check paged parameter; if empty set to defaults $paged = !empty($params['paged']) ? (int) $params['paged'] : 1; $numberposts = !empty($params['numberposts']) ? (int) $params['numberposts'] : 10; $offset = ($paged - 1) * $numberposts; $args = array( 'posts_per_page' => $numberposts, 'paged' => $paged, 'offset' => $offset, 'post_type' => 'attachment', 'post_status' => 'inherit', ); if (!empty($params['keyword'])) { $args['s'] = $params['keyword']; } if (!empty($params['category'])) { if (in_array($params['category'], array('detached', 'unattached'))) { $attachment_ids = $this->get_unattached_ids(); } else { $attachment_ids = $this->get_type_ids($params['category']); } $args['post__in'] = $attachment_ids; } if (!empty($params['date'])) { list($monthnum, $year) = explode(':', $params['date']); $args['monthnum'] = $monthnum; $args['year'] = $year; } $query = new WP_Query($args); $result = $query->posts; $count_posts = (int) $query->found_posts; $page_count = 0; if ($count_posts > 0) { $page_count = absint($count_posts / $numberposts); $remainder = absint($count_posts % $numberposts); $page_count = ($remainder > 0) ? ++$page_count : $page_count; } $info = array( 'page' => $paged, 'pages' => $page_count, 'results' => $count_posts, 'items_from' => (($paged * $numberposts) - $numberposts) + 1, 'items_to' => ($paged == $page_count) ? $count_posts : $paged * $numberposts, ); $media_items = array(); if (!empty($result)) { foreach ($result as $item) { $media = $this->get_media_item($item, null, true); if (!empty($media)) { array_push($media_items, $media); } } } $response = array( 'items' => $media_items, 'has_image_editor' => $this->has_image_editor(isset($media_items[0]) ? $media_items[0] : null), 'info' => $info, 'options' => array( 'date' => $this->get_date_options(), 'type' => $this->get_type_options() ) ); return $this->_response($response); } /** * Check whether we have an image editor (e.g. GD, Imagick, etc.) set in place to handle the basic editing * functions such as rotate, crop, etc. If not, then we hide that feature in UpdraftCentral * * @param object $media The media item/object to check * @return boolean */ private function has_image_editor($media) { // Most of the time image library are enabled by default in the php.ini but there's a possbility that users don't // enable them as they have no need for them at the moment or for some other reasons. Thus, we need to confirm // that here through the wp_get_image_editor method. $has_image_editor = true; if (!empty($media)) { if (!function_exists('wp_get_image_editor')) { require_once(ABSPATH.'wp-includes/media.php'); } if (!function_exists('_load_image_to_edit_path')) { require_once(ABSPATH.'wp-admin/includes/image.php'); } $image_editor = wp_get_image_editor(_load_image_to_edit_path($media->ID)); if (is_wp_error($image_editor)) { $has_image_editor = false; } } return $has_image_editor; } /** * Fetch a single media item information * * @param array $params Containing all the needed information to filter the results of the current request * @param array|null $extra_info Additional information from the current request * @param boolean $raw If set, returns the result of the fetch process unwrapped by the response array * @return array */ public function get_media_item($params, $extra_info = null, $raw = false) { $error = $this->_validate_capabilities(array('upload_files', 'edit_posts')); if (!empty($error)) return $error; // Raw means that we need to return the result without wrapping it // with the "$this->_response" function which indicates that the call // was done locally (within the class) and not directly from UpdraftCentral. if ($raw && is_object($params) && isset($params->ID)) { $media = $params; } elseif (is_array($params) && !empty($params['id'])) { $media = get_post($params['id']); } if (!function_exists('get_post_mime_types')) { global $updraftcentral_main; // For a much later version of WP the "get_post_mime_types" is located // in a different folder. So, we make sure that we have it loaded before // actually using it. if (version_compare($updraftcentral_main->get_wordpress_version(), '3.5', '>=')) { require_once(ABSPATH.WPINC.'/post.php'); } else { // For WP 3.4, the "get_post_mime_types" is located in the location provided below. require_once(ABSPATH.'wp-admin/includes/post.php'); } } if (!function_exists('wp_image_editor')) { require_once(ABSPATH.'wp-admin/includes/image-edit.php'); } if (!function_exists('get_media_item')) { require_once(ABSPATH.'wp-admin/includes/template.php'); require_once(ABSPATH.'wp-admin/includes/media.php'); } if ($media) { $thumb = wp_get_attachment_image_src($media->ID, 'thumbnail', true); if (!empty($thumb)) $media->thumb_url = $thumb[0]; $media->url = wp_get_attachment_url($media->ID); $media->parent_post_title = get_the_title($media->post_parent); $media->author = get_the_author_meta('display_name', $media->post_author); $media->filename = basename($media->url); $media->date = date('Y/m/d', strtotime($media->post_date)); $media->upload_date = mysql2date(get_option('date_format'), $media->post_date); $media->filesize = 0; $file = get_attached_file($media->ID); if (!empty($file) && file_exists($file)) { $media->filesize = size_format(filesize($file)); } $media->nonce = wp_create_nonce('image_editor-'.$media->ID); if (false !== strpos($media->post_mime_type, 'image/')) { $meta = wp_get_attachment_metadata($media->ID); $thumb = image_get_intermediate_size($media->ID, 'thumbnail'); $sub_sizes = isset($meta['sizes']) && is_array($meta['sizes']); // Pulling details $sizer = 1; if (isset($meta['width'], $meta['height'])) { $big = max($meta['width'], $meta['height']); $sizer = $big > 400 ? 400 / $big : 1; } $constrained_dims = array(); if ($thumb && $sub_sizes) { $constrained_dims = wp_constrain_dimensions($thumb['width'], $thumb['height'], 160, 120); } $rotate_supported = false; if (function_exists('imagerotate') || wp_image_editor_supports(array('mime_type' => get_post_mime_type($media->ID), 'methods' => array('rotate')))) { $rotate_supported = true; } // Check for alternative text if present $alt = get_post_meta($media->ID, '_wp_attachment_image_alt', true); $media->alt = !empty($alt) ? $alt : ''; // Check whether edited images are restorable $backup_sizes = get_post_meta($media->ID, '_wp_attachment_backup_sizes', true); $can_restore = !empty($backup_sizes) && isset($backup_sizes['full-orig']) && basename($meta['file']) != $backup_sizes['full-orig']['file']; $image_edit_overwrite = (!defined('IMAGE_EDIT_OVERWRITE') || !IMAGE_EDIT_OVERWRITE) ? 0 : 1; $media->misc = array( 'sizer' => $sizer, 'rand' => rand(1, 99999), 'constrained_dims' => $constrained_dims, 'rotate_supported' => (int) $rotate_supported, 'thumb' => $thumb, 'meta' => $meta, 'alt_text' => $alt, 'can_restore' => $can_restore, 'image_edit_overwrite' => $image_edit_overwrite ); } } return $raw ? $media : $this->_response(array('item' => $media)); } /** * Fetch and retrieves posts based from the submitted parameters * * @param array $params Containing all the needed information to filter the results of the current request * @return array */ public function get_posts($params) { $error = $this->_validate_capabilities(array('edit_posts')); if (!empty($error)) return $error; // check paged parameter; if empty set to defaults $paged = !empty($params['paged']) ? (int) $params['paged'] : 1; $numberposts = !empty($params['numberposts']) ? (int) $params['numberposts'] : 10; $offset = ($paged - 1) * $numberposts; $args = array( 'posts_per_page' => $numberposts, 'paged' => $paged, 'offset' => $offset, 'post_type' => 'post', 'post_status' => 'publish,private,draft,pending,future', ); if (!empty($params['keyword'])) { $args['s'] = $params['keyword']; } $query = new WP_Query($args); $result = $query->posts; $count_posts = (int) $query->found_posts; $page_count = 0; if ($count_posts > 0) { $page_count = absint($count_posts / $numberposts); $remainder = absint($count_posts % $numberposts); $page_count = ($remainder > 0) ? ++$page_count : $page_count; } $info = array( 'page' => $paged, 'pages' => $page_count, 'results' => $count_posts, 'items_from' => (($paged * $numberposts) - $numberposts) + 1, 'items_to' => ($paged == $page_count) ? $count_posts : $paged * $numberposts, ); $posts = array(); if (!empty($result)) { foreach ($result as $post) { array_push($posts, array('ID' => $post->ID, 'title' => $post->post_title)); } } $response = array( 'posts' => $posts, 'info' => $info ); return $this->_response($response); } /** * Saves media changes from UpdraftCentral * * @param array $params Containing all the needed information to filter the results of the current request * @return array */ public function save_media_item($params) { $error = $this->_validate_capabilities(array('upload_files', 'edit_posts')); if (!empty($error)) return $error; $args = array( 'post_title' => $params['image_title'], 'post_excerpt' => $params['image_caption'], 'post_content' => $params['image_description'] ); if (!empty($params['new'])) { $args['post_type'] = 'attachment'; $media_id = wp_insert_post($args, true); } else { $args['ID'] = $params['id']; $args['post_modified'] = date('Y-m-d H:i:s'); $args['post_modified_gmt'] = gmdate('Y-m-d H:i:s'); $media_id = wp_update_post($args, true); } if (!empty($media_id)) { // Update alternative text if not empty if (!empty($params['image_alternative_text'])) { update_post_meta($media_id, '_wp_attachment_image_alt', $params['image_alternative_text']); } $result = array( 'status' => 'success', 'item' => $this->get_media_item(array('id' => $media_id), null, true) ); } else { $result = array('status' => 'failed'); } return $this->_response($result); } /** * Executes media action (e.g. attach, detach and delete) * * @param array $params Containing all the needed information to filter the results of the current request * @return array */ public function execute_media_action($params) { global $updraftcentral_host_plugin; $error = $this->_validate_capabilities(array('upload_files', 'edit_posts')); if (!empty($error)) return $error; $result = array(); switch ($params['do']) { case 'attach': global $wpdb; $query_result = $wpdb->query($wpdb->prepare("UPDATE {$wpdb->posts} SET `post_parent` = %d WHERE `post_type` = 'attachment' AND ID = %d", $params['parent_id'], $params['id'])); if (false === $query_result) { $result['error'] = $updraftcentral_host_plugin->retrieve_show_message('failed_to_attach_media'); } else { $result['msg'] = $updraftcentral_host_plugin->retrieve_show_message('media_attached'); } break; case 'detach': global $wpdb; $query_result = $wpdb->query($wpdb->prepare("UPDATE {$wpdb->posts} SET `post_parent` = 0 WHERE `post_type` = 'attachment' AND ID = %d", $params['id'])); if (false === $query_result) { $result['error'] = $updraftcentral_host_plugin->retrieve_show_message('failed_to_detach_media'); } else { $result['msg'] = $updraftcentral_host_plugin->retrieve_show_message('media_detached'); } break; case 'delete': $failed_items = array(); foreach ($params['ids'] as $id) { // Delete permanently if (false === wp_delete_attachment($id, true)) { $failed_items[] = $id; } } if (!empty($failed_items)) { $result['error'] = $updraftcentral_host_plugin->retrieve_show_message('failed_to_delete_media'); $result['items'] = $failed_items; } else { $result['msg'] = $updraftcentral_host_plugin->retrieve_show_message('selected_media_deleted'); } break; default: break; } return $this->_response($result); } /** * Retrieves a collection of formatted dates found for the given post statuses. * It will be used as options for the date filter when managing the media items in UpdraftCentral. * * @return array */ private function get_date_options() { global $wpdb; $options = array(); $date_options = $wpdb->get_col("SELECT DATE_FORMAT(`post_date`, '%M %Y') as `formatted_post_date` FROM {$wpdb->posts} WHERE `post_type` = 'attachment' AND `post_status` = 'inherit' GROUP BY `formatted_post_date` ORDER BY `post_date` DESC"); if (!empty($date_options)) { foreach ($date_options as $monthyear) { $timestr = strtotime($monthyear); $options[] = array('label' => date('F Y', $timestr), 'value' => date('n:Y', $timestr)); } } return $options; } /** * Retrieves mime types that will be use as filter option in UpdraftCentral * * @return array */ private function get_type_options() { global $wpdb, $updraftcentral_host_plugin, $updraftcentral_main; $options = array(); if (!function_exists('get_post_mime_types')) { // For a much later version of WP the "get_post_mime_types" is located // in a different folder. So, we make sure that we have it loaded before // actually using it. if (version_compare($updraftcentral_main->get_wordpress_version(), '3.5', '>=')) { require_once(ABSPATH.WPINC.'/post.php'); } else { // For WP 3.4, the "get_post_mime_types" is located in the location provided below. require_once(ABSPATH.'wp-admin/includes/post.php'); } } $post_mime_types = get_post_mime_types(); $type_options = $wpdb->get_col("SELECT `post_mime_type` FROM {$wpdb->posts} WHERE `post_type` = 'attachment' AND `post_status` = 'inherit' GROUP BY `post_mime_type` ORDER BY `post_mime_type` DESC"); foreach ($post_mime_types as $mime_type => $label) { if (!wp_match_mime_types($mime_type, $type_options)) continue; $options[] = array('label' => $label[0], 'value' => esc_attr($mime_type)); } $options[] = array('label' => $updraftcentral_host_plugin->retrieve_show_message('unattached'), 'value' => 'detached'); return $options; } /** * Retrieves media items that haven't been attached to any posts * * @return array */ private function get_unattached_ids() { global $wpdb; return $wpdb->get_col("SELECT `ID` FROM {$wpdb->posts} WHERE `post_type` = 'attachment' AND `post_status` = 'inherit' AND `post_parent` = '0'"); } /** * Retrieves IDs of media items that has the given mime type * * @param string $type The mime type to search for * @return array */ private function get_type_ids($type) { global $wpdb; return $wpdb->get_col($wpdb->prepare("SELECT `ID` FROM {$wpdb->posts} WHERE `post_type` = 'attachment' AND `post_status` = 'inherit' AND `post_mime_type` LIKE %s", $type.'/%')); } /** * Checks whether we have the required fields submitted and the user has * the capabilities to execute the requested action * * @param array $capabilities The capabilities to check and validate * * @return array|void */ private function _validate_capabilities($capabilities) { foreach ($capabilities as $capability) { if (!current_user_can($capability)) { return $this->_generic_error_response('insufficient_permission'); } } } /** * Populates the $_REQUEST global variable with the submitted data * * @param array $params Submitted data received from UpdraftCentral * @return array */ private function populate_request($params) { if (!empty($params)) { foreach ($params as $key => $value) { $_REQUEST[$key] = $value; } } } /** * Handles image editing requests coming from UpdraftCentral * * @param array $params Containing all the needed information to filter the results of the current request * @return array */ public function image_editor($params) { $error = $this->_validate_capabilities(array('edit_posts')); if (!empty($error)) return $error; $attachment_id = (int) $params['postid']; $this->populate_request($params); if (!function_exists('load_image_to_edit')) { require_once(ABSPATH.'wp-admin/includes/image.php'); } include_once(ABSPATH.'wp-admin/includes/image-edit.php'); $msg = false; switch ($params['do']) { case 'save': case 'scale': $msg = wp_save_image($attachment_id); break; case 'restore': $msg = wp_restore_image($attachment_id); break; } $msg = (false !== $msg) ? json_encode($msg) : $msg; return $this->_response(array('content' => $msg)); } /** * Handles image preview requests coming from UpdraftCentral * * @param array $params Containing all the needed information to filter the results of the current request * @return array */ public function image_preview($params) { $error = $this->_validate_capabilities(array('edit_posts')); if (!empty($error)) return $error; if (!function_exists('load_image_to_edit')) { require_once(ABSPATH.'wp-admin/includes/image.php'); } include_once(ABSPATH.'wp-admin/includes/image-edit.php'); $this->populate_request($params); $post_id = (int) $params['postid']; ob_start(); stream_preview_image($post_id); $content = ob_get_contents(); ob_end_clean(); return $this->_response(array('content' => base64_encode($content))); } } central/modules/core.php000064400000036641152214270100011311 0ustar00 (string - a code), 'data' => (mixed)); * * RPC commands are not allowed to begin with an underscore. So, any private methods can be prefixed with an underscore. */ class UpdraftCentral_Core_Commands extends UpdraftCentral_Commands { /** * Executes a list of submitted commands (multiplexer) * * @param Array $query An array containing the commands to execute and a flag to indicate how to handle command execution failure. * @return Array An array containing the results of the process. */ public function execute_commands($query) { try { $commands = $query['commands']; $command_results = array(); $error_count = 0; /** * Should be one of the following options: * 1 = Abort on first failure * 2 = Abort if any command fails * 3 = Abort if all command fails (default) */ $error_flag = isset($query['error_flag']) ? (int) $query['error_flag'] : 3; foreach ($commands as $command => $params) { $command_info = apply_filters('updraftcentral_get_command_info', false, $command); if (!$command_info) { list($_prefix, $_command) = explode('.', $command); $command_results[$_prefix][$_command] = array('response' => 'rpcerror', 'data' => array('code' => 'unknown_rpc_command', 'data' => $command)); $error_count++; if (1 === $error_flag) break; } else { $action = $command_info['command']; $command_php_class = $command_info['command_php_class']; // Instantiate the command class and execute the needed action if (class_exists($command_php_class)) { $instance = new $command_php_class($this->rc); if (method_exists($instance, $action)) { $params = empty($params) ? array() : $params; $call_result = call_user_func(array($instance, $action), $params); $command_results[$command] = $call_result; if ('rpcerror' === $call_result['response'] || (isset($call_result['data']['error']) && $call_result['data']['error'])) { $error_count++; if (1 === $error_flag) break; } } } } } if (0 !== $error_count) { // N.B. These error messages should be defined in UpdraftCentral's translation file (dashboard-translations.php) // before actually using this multiplexer function. $message = 'general_command_execution_error'; switch ($error_flag) { case 1: $message = 'command_execution_aborted'; break; case 2: $message = 'failed_to_execute_some_commands'; break; case 3: if (count($commands) === $error_count) { $message = 'failed_to_execute_all_commands'; } break; default: break; } $result = array('error' => true, 'message' => $message, 'values' => $command_results); } else { $result = $command_results; } } catch (Exception $e) { $result = array('error' => true, 'message' => $e->getMessage()); } return $this->_response($result); } /** * Validates the credentials entered by the user * * @param array $creds an array of filesystem credentials * @return array An array containing the result of the validation process. */ public function validate_credentials($creds) { try { $entity = $creds['entity']; if (isset($creds['filesystem_credentials'])) { parse_str($creds['filesystem_credentials'], $filesystem_credentials); if (is_array($filesystem_credentials)) { foreach ($filesystem_credentials as $key => $value) { // Put them into $_POST, which is where request_filesystem_credentials() checks for them. $_POST[$key] = $value; } } } // Include the needed WP Core file(s) // template.php needed for submit_button() which is called by request_filesystem_credentials() $this->_admin_include('file.php', 'template.php'); // Directory entities that we currently need permissions // to update. $entity_directories = array( 'plugins' => WP_PLUGIN_DIR, 'themes' => WP_CONTENT_DIR.'/themes', 'core' => untrailingslashit(ABSPATH) ); if ('translations' === $entity) { // 'en_US' don't usually have the "languages" folder, thus, we // check if there's a need to ask for filesystem credentials for that // folder if it exists, most especially for locale other than 'en_US'. $language_dir = WP_CONTENT_DIR.'/languages'; if ('en_US' !== get_locale() && is_dir($language_dir)) { $entity_directories['translations'] = $language_dir; } } $url = wp_nonce_url(site_url()); $passed = false; if (isset($entity_directories[$entity])) { $directory = $entity_directories[$entity]; // Check if credentials are valid and have sufficient // privileges to create and delete (e.g. write) ob_start(); $credentials = request_filesystem_credentials($url, '', false, $directory); ob_end_clean(); // The "WP_Filesystem" will suffice in validating the inputted credentials // from UpdraftCentral, as it is already attempting to connect to the filesystem // using the chosen transport (e.g. ssh, ftp, etc.) $passed = WP_Filesystem($credentials, $directory); } if ($passed) { $result = array('error' => false, 'message' => 'credentials_ok', 'values' => array()); } else { // We're adding some useful error information to help troubleshooting any problems // that may arise in the future. If the user submitted a wrong password or username // it usually falls through here. global $wp_filesystem; $errors = array(); if (isset($wp_filesystem->errors) && is_wp_error($wp_filesystem->errors)) { $errors = $wp_filesystem->errors->errors; } $result = array('error' => true, 'message' => 'failed_credentials', 'values' => array('errors' => $errors)); } } catch (Exception $e) { $result = array('error' => true, 'message' => $e->getMessage(), 'values' => array()); } return $this->_response($result); } /** * Gets the FileSystem Credentials * * Extract the needed filesystem credentials (permissions) to be used * to update/upgrade the plugins, themes and the WP core. * * @return array $result - An array containing the creds form and some flags * to determine whether we need to extract the creds * manually from the user. */ public function get_credentials() { try { // Check whether user has enough permission to update entities if (!current_user_can('update_plugins') && !current_user_can('update_themes') && !current_user_can('update_core')) return $this->_generic_error_response('updates_permission_denied'); // Include the needed WP Core file(s) $this->_admin_include('file.php', 'template.php'); // A container that will hold the state (in this case, either true or false) of // each directory entities (plugins, themes, core) that will be used to determine // whether or not there's a need to show a form that will ask the user for their credentials // manually. $request_filesystem_credentials = array(); // A container for the filesystem credentials form if applicable. $filesystem_form = ''; // Directory entities that we currently need permissions // to update. $check_fs = array( 'plugins' => WP_PLUGIN_DIR, 'themes' => WP_CONTENT_DIR.'/themes', 'core' => untrailingslashit(ABSPATH) ); // Here, we're looping through each entities and find output whether // we have sufficient permissions to update objects belonging to them. foreach ($check_fs as $entity => $dir) { // We're determining which method to use when updating // the files in the filesystem. $filesystem_method = get_filesystem_method(array(), $dir); // Buffering the output to pull the actual credentials form // currently being used by this WP instance if no sufficient permissions // is found. $url = wp_nonce_url(site_url()); ob_start(); $filesystem_credentials_are_stored = request_filesystem_credentials($url, $filesystem_method); $form = strip_tags(ob_get_contents(), '');e&&s.append("

"+e+"

"),t&&s.append("

"+t+"

"),void 0===o&&(o=3e3),i(),s.css("opacity"),s.on("mouseover",function(){i({fadeIn:0,timeout:3e4});var e=p(".blockMsg");e.stop(),e.fadeTo(300,1)}).on("mouseout",function(){p(".blockMsg").fadeOut(1e3)})},p.fn.block=function(e){var t;return this[0]===window?(p.blockUI(e),this):(t=p.extend({},p.blockUI.defaults,e||{}),this.each(function(){var e=p(this);t.ignoreIfBlocked&&e.data("blockUI.isBlocked")||e.unblock({fadeOut:0})}),this.each(function(){"static"==p.css(this,"position")&&(this.style.position="relative",p(this).data("blockUI.static",!0)),this.style.zoom=1,o(this,e)}))},p.fn.unblock=function(e){return this[0]===window?(p.unblockUI(e),this):this.each(function(){v(this,e)})},p.blockUI.version=2.7,p.blockUI.defaults={message:"

Please wait...

",title:null,draggable:!0,theme:!1,css:{padding:0,margin:0,width:"30%",top:"40%",left:"35%",textAlign:"center",color:"#000",border:"3px solid #aaa",backgroundColor:"#fff",cursor:"wait"},themedCSS:{width:"30%",top:"40%",left:"35%"},overlayCSS:{backgroundColor:"#000",opacity:.6,cursor:"wait"},cursorReset:"default",growlCSS:{width:"350px",top:"10px",left:"",right:"10px",border:"none",padding:"5px",opacity:.6,cursor:"default",color:"#fff",backgroundColor:"#000","-webkit-border-radius":"10px","-moz-border-radius":"10px","border-radius":"10px"},iframeSrc:/^https/i.test(window.location.href||"")?"javascript:false":"about:blank",forceIframe:!1,baseZ:1e3,centerX:!0,centerY:!0,allowBodyStretch:!0,bindEvents:!0,constrainTabKey:!0,fadeIn:200,fadeOut:400,timeout:0,showOverlay:!0,focusInput:!0,focusableElements:":input:enabled:visible",onBlock:null,onUnblock:null,onOverlayClick:null,quirksmodeOffsetHack:4,blockMsgClass:"blockMsg",ignoreIfBlocked:!1},null),g=[];function o(e,o){var n,i,t,s,l,a,d,c,r,u=e==window,f=o&&void 0!==o.message?o.message:void 0;(o=p.extend({},p.blockUI.defaults,o||{})).ignoreIfBlocked&&p(e).data("blockUI.isBlocked")||(o.overlayCSS=p.extend({},p.blockUI.defaults.overlayCSS,o.overlayCSS||{}),l=p.extend({},p.blockUI.defaults.css,o.css||{}),o.onOverlayClick&&(o.overlayCSS.cursor="pointer"),a=p.extend({},p.blockUI.defaults.themedCSS,o.themedCSS||{}),f=void 0===f?o.message:f,u&&y&&v(window,{fadeOut:0}),f&&"string"!=typeof f&&(f.parentNode||f.jquery)&&(r=f.jquery?f[0]:f,t={},p(e).data("blockUI.history",t),t.el=r,t.parent=r.parentNode,t.display=r.style.display,t.position=r.style.position,t.parent)&&t.parent.removeChild(r),p(e).data("blockUI.onUnblock",o.onUnblock),t=o.baseZ,r=h||o.forceIframe?p(''):p(''),c=o.theme?p(''):p(''),o.theme&&u?(d=''):o.theme?(d=''):d=u?'':'',t=p(d),f&&(o.theme?(t.css(a),t.addClass("ui-widget-content")):t.css(l)),o.theme||c.css(o.overlayCSS),c.css("position",u?"fixed":"absolute"),(h||o.forceIframe)&&r.css("opacity",0),d=[r,c,t],s=p(u?"body":e),p.each(d,function(){this.appendTo(s)}),o.theme&&o.draggable&&p.fn.draggable&&t.draggable({handle:".ui-dialog-titlebar",cancel:"li"}),a=k&&("CSS1Compat"!==document.compatMode||0 .blockUI"):s.find(">.blockUI"),t.cursorReset&&(1

'); if (!empty($form)) { $filesystem_form = $form; } ob_end_clean(); // Save the state whether or not there's a need to show the // credentials form to the user. $request_filesystem_credentials[$entity] = ('direct' !== $filesystem_method && !$filesystem_credentials_are_stored); } // Wrapping the credentials info before passing it back // to the client issuing the request. $result = array( 'request_filesystem_credentials' => $request_filesystem_credentials, 'filesystem_form' => $filesystem_form ); } catch (Exception $e) { $result = array('error' => true, 'message' => $e->getMessage(), 'values' => array()); } return $this->_response($result); } /** * Fetches a browser-usable URL which will automatically log the user in to the site * * @param String $redirect_to - the URL to got to after logging in * @param Array $extra_info - valid keys are user_id, which should be a numeric user ID to log in as. */ public function get_login_url($redirect_to, $extra_info) { if (is_array($extra_info) && !empty($extra_info['user_id']) && is_numeric($extra_info['user_id'])) { $user_id = $extra_info['user_id']; if (false == ($login_key = $this->_get_autologin_key($user_id))) return $this->_generic_error_response('user_key_failure'); // Default value $redirect_url = network_admin_url(); if (is_array($redirect_to) && !empty($redirect_to['module'])) { switch ($redirect_to['module']) { case 'updraftplus': if ('initiate_restore' == $redirect_to['action'] && class_exists('UpdraftPlus_Options')) { $redirect_url = UpdraftPlus_Options::admin_page_url().'?page=updraftplus&udaction=initiate_restore&entities='.urlencode($redirect_to['data']['entities']).'&showdata='.urlencode($redirect_to['data']['showdata']).'&backup_timestamp='.(int) $redirect_to['data']['backup_timestamp']; } elseif ('download_file' == $redirect_to['action']) { $findex = empty($redirect_to['data']['findex']) ? 0 : (int) $redirect_to['data']['findex']; // e.g. ?udcentral_action=dl&action=updraftplus_spool_file&backup_timestamp=1455101696&findex=0&what=plugins $redirect_url = site_url().'?udcentral_action=spool_file&action=updraftplus_spool_file&findex='.$findex.'&what='.urlencode($redirect_to['data']['what']).'&backup_timestamp='.(int) $redirect_to['data']['backup_timestamp']; } break; case 'direct_url': $redirect_url = $redirect_to['url']; break; } } $login_key = apply_filters('updraftplus_remotecontrol_login_key', array( 'key' => $login_key, 'created' => time(), 'redirect_url' => $redirect_url ), $redirect_to, $extra_info); // Over-write any previous value - only one can be valid at a time) update_user_meta($user_id, 'updraftcentral_login_key', $login_key); return $this->_response(array( 'login_url' => network_site_url('?udcentral_action=login&login_id='.$user_id.'&login_key='.$login_key['key']) )); } else { return $this->_generic_error_response('user_unknown'); } } /** * Get information derived from phpinfo() * * @return Array */ public function phpinfo() { $phpinfo = $this->_get_phpinfo_array(); if (!empty($phpinfo)) { return $this->_response($phpinfo); } return $this->_generic_error_response('phpinfo_fail'); } /** * The key obtained is only intended to be short-lived. Hence, there's no intention other than that it is random and only used once - only the most recent one is valid. * * @param Integer $user_id Specific user ID to get the autologin key * @return Array */ public function _get_autologin_key($user_id) { $secure_auth_key = defined('SECURE_AUTH_KEY') ? SECURE_AUTH_KEY : hash('sha256', DB_PASSWORD).'_'.rand(0, 999999999); if (!defined('SECURE_AUTH_KEY')) return false; $hash_it = $user_id.'_'.microtime(true).'_'.rand(0, 999999999).'_'.$secure_auth_key; $hash = hash('sha256', $hash_it); return $hash; } public function site_info() { global $wpdb; // THis is included so we can get $wp_version @include(ABSPATH.WPINC.'/version.php');// phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged -- Silenced to suppress errors that may arise because of the function. $ud_version = is_a($this->ud, 'UpdraftPlus') ? $this->ud->version : 'none'; return $this->_response(array( 'versions' => array( 'ud' => $ud_version, 'php' => PHP_VERSION, 'wp' => $wp_version,// phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UndefinedVariable -- The variable is defined inside the ABSPATH.WPINC.'/version.php'. 'mysql' => $wpdb->db_version(), 'udrpc_php' => $this->rc->udrpc_version, ), 'bloginfo' => array( 'url' => network_site_url(), 'name' => get_bloginfo('name'), ) )); } /** * This calls the WP_Action within WP * * @param array $data Array of Data to be used within call_wp_action * @return array */ public function call_wordpress_action($data) { if (false === ($updraftplus_admin = $this->_load_ud_admin())) return $this->_generic_error_response('no_updraftplus'); $response = $updraftplus_admin->call_wp_action($data); if (empty($data["wpaction"])) { return $this->_generic_error_response("error", "no command sent"); } return $this->_response(array( "response" => $response['response'], "status" => $response['status'], "log" => $response['log'] )); } /** * Get disk space used * * @uses UpdraftPlus_Filesystem_Functions::get_disk_space_used() * * @param String $entity - the entity to count (e.g. 'plugins', 'themes') * * @return Array - response */ public function count($entity) { if (!class_exists('UpdraftPlus_Filesystem_Functions')) return $this->_generic_error_response('no_updraftplus'); $response = UpdraftPlus_Filesystem_Functions::get_disk_space_used($entity); return $this->_response($response); } /** * https://secure.php.net/phpinfo * * @return null|array */ private function _get_phpinfo_array() { if (!function_exists('phpinfo')) return null; ob_start(); phpinfo(INFO_GENERAL|INFO_CREDITS|INFO_MODULES); $phpinfo = array('phpinfo' => array()); if (preg_match_all('#(?:

(?:)?(.*?)(?:)?

)|(?:(.*?)\s*(?:(.*?)\s*(?:(.*?)\s*)?)?)#s', ob_get_clean(), $matches, PREG_SET_ORDER)) { foreach ($matches as $match) { if (strlen($match[1])) { $phpinfo[$match[1]] = array(); } elseif (isset($match[3])) { $keys1 = array_keys($phpinfo); $phpinfo[end($keys1)][$match[2]] = isset($match[4]) ? array($match[3], $match[4]) : $match[3]; } else { $keys1 = array_keys($phpinfo); $phpinfo[end($keys1)][] = $match[2]; } } return $phpinfo; } return false; } /** * Return an UpdraftPlus_Admin object * * @return UpdraftPlus_Admin|Boolean - false in case of failure */ private function _load_ud_admin() { if (!defined('UPDRAFTPLUS_DIR') || !is_file(UPDRAFTPLUS_DIR.'/admin.php')) return false; updraft_try_include_file('admin.php', 'include_once'); global $updraftplus_admin; return $updraftplus_admin; } } central/host.php000064400000021205152214270100007654 0ustar00plugin_name; } /** * Retrieves or shows a message from the translations collection based on its identifier key * * @param string $key The ID of the the message * @param bool $echo Indicate whether the message is to be shown directly (echoed) or just for retrieval * * @return string/void */ public function retrieve_show_message($key, $echo = false) { if (empty($key) || !isset($this->translations[$key])) return ''; if ($echo) { echo $this->translations[$key]; return; } return $this->translations[$key]; } /** * Adds a section to a designated area primarily used for generating UpdraftCentral keys * * @return void */ public function debugtools_dashboard() { if (!current_user_can('manage_options')) return; global $updraftcentral_main; if (!class_exists('UpdraftCentral_Main')) { if (defined('UPDRAFTCENTRAL_CLIENT_DIR') && file_exists(UPDRAFTCENTRAL_CLIENT_DIR.'/bootstrap.php')) { include_once(UPDRAFTCENTRAL_CLIENT_DIR.'/bootstrap.php'); $updraftcentral_main = new UpdraftCentral_Main(); } } if ($updraftcentral_main) { $updraftcentral_main->debugtools_dashboard(); } } /** * Whether the current user can perform key control AJAX actions * * @return Boolean */ public function current_user_can_ajax() { return current_user_can('manage_options'); } /** * Handles ajax requests coming from the section or area generated by the * "debugtools_dashboard" method (below) * * @return void */ public function updraft_central_ajax_handler() { global $updraftcentral_main; $nonce = empty($_REQUEST['nonce']) ? '' : $_REQUEST['nonce']; if (empty($nonce) || !wp_verify_nonce($nonce, 'updraftcentral-request-nonce') || !$this->current_user_can_ajax() || empty($_REQUEST['subaction'])) die('Security check'); if (is_a($updraftcentral_main, 'UpdraftCentral_Main')) { $subaction = $_REQUEST['subaction']; if ($this->is_action_whitelisted($subaction) && is_callable(array($updraftcentral_main, $subaction))) { // Undo WP's slashing of POST data $data = $this->wp_unslash($_POST); // TODO: Once all commands come through here and through updraft_send_command(), the data should always come from this attribute (once updraft_send_command() is modified appropriately). if (isset($data['action_data'])) $data = $data['action_data']; try { $results = call_user_func(array($updraftcentral_main, $subaction), $data); } catch (Exception $e) { $log_message = 'PHP Fatal Exception error ('.get_class($e).') has occurred during '.$subaction.' subaction. Error Message: '.$e->getMessage().' (Code: '.$e->getCode().', line '.$e->getLine().' in '.$e->getFile().')'; error_log($log_message); echo json_encode(array( 'fatal_error' => true, 'fatal_error_message' => $log_message )); die; // @codingStandardsIgnoreLine } catch (Error $e) { $log_message = 'PHP Fatal error ('.get_class($e).') has occurred during '.$subaction.' subaction. Error Message: '.$e->getMessage().' (Code: '.$e->getCode().', line '.$e->getLine().' in '.$e->getFile().')'; error_log($log_message); echo json_encode(array( 'fatal_error' => true, 'fatal_error_message' => $log_message )); die; } if (is_wp_error($results)) { $results = array( 'result' => false, 'error_code' => $results->get_error_code(), 'error_message' => $results->get_error_message(), 'error_data' => $results->get_error_data(), ); } if (is_string($results)) { // A handful of legacy methods, and some which are directly the source for iframes, for which JSON is not appropriate. echo $results; } else { echo json_encode($results); } die; } } die; } /** * Verifies whether the submitted action is valid and allowed for execution over AJAX * * @param string $action The action to execute * * @return bool */ private function is_action_whitelisted($action) { $allowed_actions = array('delete_key', 'get_log', 'create_key'); return in_array($action, $allowed_actions); } /** * Retrieves the filter used by UpdraftCentral to log errors or certain events * * @return string */ public function get_logline_filter() { return 'updraftcentral_logline'; } /** * Gets an RPC object, and sets some defaults on it that we always want * * @param string $indicator_name indicator name * @return array */ public function get_udrpc($indicator_name = 'migrator.updraftplus.com') { if (!class_exists('UpdraftPlus_Remote_Communications')) include_once($this->get_host_dir().'/vendor/team-updraft/common-libs/src/updraft-rpc/class-udrpc.php'); $ud_rpc = new UpdraftPlus_Remote_Communications($indicator_name); $ud_rpc->set_can_generate(true); return $ud_rpc; } /** * Noop method. * Depending on the host plugin this method may or may not be used. * * N.B. The UpdraftPlus plugin is using and overriding this method in its host file. * * @param boolean $register Indicate whether to add or remote filter hooks * @ignore */ // @codingStandardsIgnoreLine public function register_wp_http_option_hooks($register = true) {} /** * Remove slashes from a string or array of strings. * * The function wp_unslash() is WP 3.6+, so therefore we have a compatibility method here * * @param String|Array $value String or array of strings to unslash. * @return String|Array Unslashed $value */ public function wp_unslash($value) { return function_exists('wp_unslash') ? wp_unslash($value) : stripslashes_deep($value); } /** * Generate a log line based from the PHP error information * * @param Integer $errno Error number * @param String $errstr Error string * @param String $errfile Error file * @param String $errline Line number where the error occurred * * @return string|bool */ public function php_error_to_logline($errno, $errstr, $errfile, $errline) { switch ($errno) { case 1: $e_type = 'E_ERROR'; break; case 2: $e_type = 'E_WARNING'; break; case 4: $e_type = 'E_PARSE'; break; case 8: $e_type = 'E_NOTICE'; break; case 16: $e_type = 'E_CORE_ERROR'; break; case 32: $e_type = 'E_CORE_WARNING'; break; case 64: $e_type = 'E_COMPILE_ERROR'; break; case 128: $e_type = 'E_COMPILE_WARNING'; break; case 256: $e_type = 'E_USER_ERROR'; break; case 512: $e_type = 'E_USER_WARNING'; break; case 1024: $e_type = 'E_USER_NOTICE'; break; case 2048: $e_type = 'E_STRICT'; break; case 4096: $e_type = 'E_RECOVERABLE_ERROR'; break; case 8192: $e_type = 'E_DEPRECATED'; break; case 16384: $e_type = 'E_USER_DEPRECATED'; break; case 30719: $e_type = 'E_ALL'; break; default: $e_type = "E_UNKNOWN ($errno)"; break; } if (false !== stripos($errstr, 'table which is not valid in this version of Gravity Forms')) return false; if (!is_string($errstr)) $errstr = serialize($errstr); if (0 === strpos($errfile, ABSPATH)) $errfile = substr($errfile, strlen(ABSPATH)); if ('E_DEPRECATED' == $e_type && !empty($this->no_deprecation_warnings)) { return false; } return "PHP event: code $e_type: $errstr (line $errline, $errfile)"; } /** * PHP error handler * * @param Integer $errno Error number * @param String $errstr Error string * @param String $errfile Error file * @param String $errline Line number where the error occurred * * @return bool */ public function php_error($errno, $errstr, $errfile, $errline) { if (0 == error_reporting()) return true; $logline = $this->php_error_to_logline($errno, $errstr, $errfile, $errline); if (false !== $logline) $this->log($logline, 'notice', 'php_event'); // Pass it up the chain return $this->error_reporting_stop_when_logged; } } central/updraftplus.php000064400000014670152214270100011260 0ustar00maybe_initialize_required_objects(); } /** * Loads the UpdraftCentral_Main instance * * @return void */ public function load_updraftcentral() { $central_path = $this->is_host_dir_set() ? trailingslashit(UPDRAFTPLUS_DIR) : ''; if (file_exists($central_path.'central/bootstrap.php')) { include_once($central_path.'central/bootstrap.php'); } } /** * Whether the current user can perform key control AJAX actions * * @return Boolean */ public function current_user_can_ajax() { return UpdraftPlus_Options::user_can_manage(); } /** * Below are interface methods' implementations that are required by UpdraftCentral to function properly. Please * see the "interface.php" to check all the required interface methods. */ /** * Checks whether the plugin's DIR constant is currently define or not * * @return bool */ public function is_host_dir_set() { return defined('UPDRAFTPLUS_DIR') ? true : false; } /** * Get the host plugin's dir path * * @return string */ public function get_host_dir() { return defined('UPDRAFTPLUS_DIR') ? UPDRAFTPLUS_DIR : dirname(dirname(__FILE__)); } /** * Retrieves the filter used by UpdraftPlus to log errors or certain events * * @return string */ public function get_logline_filter() { return 'updraftplus_logline'; } /** * Checks whether debug mod is set * * @return bool */ public function get_debug_mode() { if (class_exists('UpdraftPlus_Options')) { return UpdraftPlus_Options::get_updraft_option('updraft_debug_mode'); } return false; } /** * Used as a central location (to avoid repetition) to register or de-register hooks into the WP HTTP API * * @param bool $register True to register, false to de-register * @return void */ public function register_wp_http_option_hooks($register = true) { global $updraftplus; if ($updraftplus) { $updraftplus->register_wp_http_option_hooks($register); } } /** * Retrieves the class name of the host plugin * * @return string|bool */ public function get_class_name() { global $updraftplus; if ($updraftplus) { return get_class($updraftplus); } return false; } /** * Returns the instance of the host plugin * * @return object|bool */ public function get_instance() { global $updraftplus; if ($updraftplus) { return $updraftplus; } return false; } /** * Returns the admin instance of the host plugin * * @return object|bool */ public function get_admin_instance() { global $updraftplus_admin; if ($updraftplus_admin) { return $updraftplus_admin; } else { if (defined('UPDRAFTPLUS_DIR') && file_exists(UPDRAFTPLUS_DIR.'/admin.php')) { updraft_try_include_file('admin.php', 'include_once'); $updraftplus_admin = new UpdraftPlus_Admin(); return $updraftplus_admin; } } return false; } /** * Logs the given line * * @param string $line The log line * @param string $level The log level: notice, warning, error, etc. * @param boolean|string $uniq_id Each of these will only be logged once * * @return void */ public function log($line, $level = 'notice', $uniq_id = false) { global $updraftplus; if ($updraftplus) { if (is_callable(array($updraftplus, 'log'))) { call_user_func(array($updraftplus, 'log'), $line, $level, $uniq_id); } } } /** * Returns the current version of the host plugin * * @return string|bool */ public function get_version() { global $updraftplus; if ($updraftplus) { return $updraftplus->version; } return false; } /** * Returns the filesystem class of the host's plugin * * @return class|bool */ public function get_filesystem_functions() { if ($this->has_filesystem_functions()) { return UpdraftPlus_Filesystem_Functions; } return false; } /** * Checks whether the filesystem class of the host plugin exists * * @return bool */ public function has_filesystem_functions() { return class_exists('UpdraftPlus_Filesystem_Functions'); } /** * Checks whether force debugging is set * * @return bool */ public function is_force_debug() { return (defined('UPDRAFTPLUS_UDRPC_FORCE_DEBUG') && UPDRAFTPLUS_UDRPC_FORCE_DEBUG) ? true : false; } /** * Initializes required objects (if not yet initialized) for UpdraftCentral usage * * @return void */ private function maybe_initialize_required_objects() { global $updraftplus; if (!class_exists('UpdraftPlus')) { if (defined('UPDRAFTPLUS_DIR') && file_exists(UPDRAFTPLUS_DIR.'/class-updraftplus.php')) { updraft_try_include_file('class-updraftplus.php', 'include_once'); if (empty($updraftplus) || !is_a($updraftplus, 'UpdraftPlus')) { $updraftplus = new UpdraftPlus(); } } } if (!class_exists('UpdraftPlus_Options')) { if (defined('UPDRAFTPLUS_DIR') && file_exists(UPDRAFTPLUS_DIR.'/options.php')) { updraft_try_include_file('options.php', 'require_once'); } } if (!class_exists('UpdraftPlus_Filesystem_Functions')) { if (defined('UPDRAFTPLUS_DIR') && file_exists(UPDRAFTPLUS_DIR.'/includes/class-filesystem-functions.php')) { updraft_try_include_file('includes/class-filesystem-functions.php', 'require_once'); } } // Load updraftplus translations if (defined('UPDRAFTCENTRAL_CLIENT_DIR') && file_exists(UPDRAFTCENTRAL_CLIENT_DIR.'/translations-central.php')) { $this->translations = include_once(UPDRAFTCENTRAL_CLIENT_DIR.'/translations-central.php'); } } } central/commands.php000064400000032067152214270100010510 0ustar00 (string - a code), 'data' => (mixed)); * * RPC commands are not allowed to begin with an underscore. So, any private methods can be prefixed with an underscore. */ abstract class UpdraftCentral_Commands { protected $rc; protected $ud; protected $installed_data; /** * Class constructor * * @param string $rc */ public function __construct($rc) { $this->rc = $rc; global $updraftplus; $this->ud = $updraftplus; $this->installed_data = array(); } /** * Include a file or files from wp-admin/includes */ final protected function _admin_include() { $files = func_get_args(); foreach ($files as $file) { include_once(ABSPATH.'/wp-admin/includes/'.$file); } } /** * Include a file or files from wp-includes */ final protected function _frontend_include() { $files = func_get_args(); foreach ($files as $file) { include_once(ABSPATH.WPINC.'/'.$file); } } /** * Return a response in the expected format * * @param Mixed $data * @param String $code * * @return Array */ final protected function _response($data = null, $code = 'rpcok') { return array( 'response' => $code, 'data' => $data ); } /** * Return an error in the expected format * * @param String $code * @param Mixed $data * * @return Array */ final protected function _generic_error_response($code = 'central_unspecified', $data = null) { return $this->_response( array( 'code' => $code, 'data' => $data ), 'rpcerror' ); } /** * Checks whether a backup and a security credentials is required for the given request * * @param array $dir The directory location to check * @return array */ final protected function _get_backup_credentials_settings($dir) { // Do we need to ask the user for filesystem credentials? when installing and/or deleting items in the given directory $filesystem_method = get_filesystem_method(array(), $dir); ob_start(); $filesystem_credentials_are_stored = request_filesystem_credentials(site_url(), $filesystem_method); ob_end_clean(); $request_filesystem_credentials = ('direct' != $filesystem_method && !$filesystem_credentials_are_stored); // Do we need to execute a backup process before installing/managing items $automatic_backups = (class_exists('UpdraftPlus_Options') && class_exists('UpdraftPlus_Addon_Autobackup') && UpdraftPlus_Options::get_updraft_option('updraft_autobackup_default', true)) ? true : false; return array( 'request_filesystem_credentials' => $request_filesystem_credentials, 'automatic_backups' => $automatic_backups ); } /** * Retrieves the information of the currently installed item (e.g. plugin or theme) through filter * * @param bool $response Indicates whether the installation was a success or failure * @param array $args Extra argument for the hook * @param array $data Contains paths used and other relevant information regarding the file * @return array */ final public function get_install_data($response, $args, $data) { if ($response) { switch ($args['type']) { case 'plugin': $plugin_data = get_plugins('/'.$data['destination_name']); if (!empty($plugin_data)) { $info = reset($plugin_data); $key = key($plugin_data); $info['slug'] = $data['destination_name'].'/'.$key; $this->installed_data = $info; } break; case 'theme': $theme = wp_get_theme($data['destination_name']); if ($theme->exists()) { // Minimalistic info here, if you need to add additional information // you can add them here. For now, the "Name" and "slug" fields will suffice // in the succeeding process. $this->installed_data = array( 'Name' => $theme->get('Name'), 'slug' => $data['destination_name'], 'template' => $theme->get_template() ); } break; default: break; } } return $response; } /** * Installs and activates either a plugin or theme through zip file upload * * @param array $params Parameter array containing information pertaining the currently uploaded item * @param string $type Indicates whether this current process is intended for a 'plugin' or a 'theme' item * @return array */ final protected function process_chunk_upload($params, $type) { global $updraftcentral_host_plugin, $updraftcentral_main; if (!in_array($type, array('plugin', 'theme'))) { return $this->_generic_error_response('upload_type_not_supported'); } $permission_error = false; if ('plugin' === $type) { if (!current_user_can('install_plugins') || !current_user_can('activate_plugins')) $permission_error = true; } else { if (!current_user_can('install_themes') || !current_user_can('switch_themes')) $permission_error = true; } if ($permission_error) { return $this->_generic_error_response($type.'_insufficient_permission'); } // Pull any available and writable directory where we can store // our data/file temporarily before running the installation process. $upload_dir = untrailingslashit(get_temp_dir()); if (!is_writable($upload_dir)) { $upload_dir = WP_CONTENT_DIR.'/upgrade'; if (!is_dir($upload_dir)) { $wp_dir = wp_upload_dir(); if (!empty($wp_dir['basedir'])) $upload_dir = $wp_dir['basedir']; } } // If we haven't found any writable directory to temporarily store our file then // we bail and send an error back to the caller. if (!is_dir($upload_dir) || !is_writable($upload_dir)) { return $this->_generic_error_response('upload_dir_not_available'); } // Preloads the submitted credentials to the global $_POST variable if (!empty($params) && isset($params['filesystem_credentials'])) { parse_str($params['filesystem_credentials'], $filesystem_credentials); if (is_array($filesystem_credentials)) { foreach ($filesystem_credentials as $key => $value) { // Put them into $_POST, which is where request_filesystem_credentials() checks for them. $_POST[$key] = $value; } } } // Save uploaded file $filename = basename($params['filename']); $is_chunked = false; if (isset($params['chunks']) && 1 < (int) $params['chunks']) { $filename = basename($params['filename']).'.part'; $is_chunked = true; } if (!$is_chunked || ($is_chunked && isset($params['chunk']) && 0 === (int) $params['chunk'])) { // if it's not a chunk upload or if it's a chunk upload operation and the current chunk variable is zero, then it means a new upload operation has just begun therefore we should remove previous left-over file (if any and due to error during the previous upload of the same file), because it can lead to a corrupt/invalid zip file (we use file_put_contents a few lines below with FILE_APPEND attribute) if (file_exists($upload_dir.'/'.$filename) && !unlink($upload_dir.'/'.$filename)) return $this->_generic_error_response('unable_to_delete_existing_file'); } if (empty($params['data'])) { return $this->_generic_error_response('data_empty_or_invalid'); } $result = file_put_contents($upload_dir.'/'.$filename, base64_decode($params['data']), FILE_APPEND | LOCK_EX); if (false === $result) { return $this->_generic_error_response('unable_to_write_content'); } // Set $install_now to true for single upload and for the last chunk of a multi-chunks upload process $install_now = true; if ($is_chunked) { if ($params['chunk'] == (int) $params['chunks'] - 1) { // If this is the last chunk of the request, then we're going to restore the // original filename of the file (without the '.part') since our upload is now complete. $orig_filename = basename($filename, '.part'); $success = rename($upload_dir.'/'.$filename, $upload_dir.'/'.$orig_filename); // If renaming the file was successful then restore the original name and override the $filename variable. // Overriding the $filename variable makes it easy for us to use the same variable for both // non-chunked and chunked zip file for the installation process. if ($success) { $filename = $orig_filename; } else { return $this->_generic_error_response('unable_to_rename_file'); } } else { // Bypass installation for now since we're waiting for the last chunk to arrive // to complete the uploading of the zip file. $install_now = false; } } // Everything is already good (upload completed), thus, we proceed with the installation if ($install_now) { // We have successfully uploaded the zip file in this location with its original filename intact. $zip_filepath = $upload_dir.'/'.$filename; // Making sure that the file does actually exists, since we've just run through // a renaming process above. if (file_exists($zip_filepath)) { add_filter('upgrader_post_install', array($this, 'get_install_data'), 10, 3); // WP < 3.7 if (!class_exists('Automatic_Upgrader_Skin')) include_once(UPDRAFTCENTRAL_CLIENT_DIR.'/classes/class-automatic-upgrader-skin.php'); $skin = new Automatic_Upgrader_Skin(); $upgrader = ('plugin' === $type) ? new Plugin_Upgrader($skin) : new Theme_Upgrader($skin); $install_result = $upgrader->install($zip_filepath); remove_filter('upgrader_post_install', array($this, 'get_install_data'), 10, 3); // Remove zip file on success and on error (cleanup) if ($install_result || is_null($install_result) || is_wp_error($install_result)) { @unlink($zip_filepath);// phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged -- Silenced to suppress errors that may arise because of the function. } if (false === $install_result || is_wp_error($install_result)) { $message = $updraftcentral_host_plugin->retrieve_show_message('unable_to_connect'); if (is_wp_error($install_result)) $message = $install_result->get_error_message(); return $this->_generic_error_response($type.'_install_failed', array('message' => $message)); } else { // Pull installed data $data = $this->installed_data; // For WP 3.4 the intended filter hook isn't working or not available // so we're going to pull the data manually. if ($install_result && empty($data)) { $result = $this->get_install_data($install_result, array('type' => $type), $skin->result); if ($result) { // Getting the installed data one more time after manually calling // the "get_install_data" function. $data = $this->installed_data; } } if (!empty($data)) { // Activate item if set $is_active = ('plugin' === $type) ? is_plugin_active($data['slug']) : ((wp_get_theme()->get('Name') === $data['Name']) ? true : false); if ((bool) $params['activate'] && !$is_active) { if ('plugin' === $type) { if (is_multisite()) { $activate = activate_plugin($data['slug'], '', true); } else { $activate = activate_plugin($data['slug']); } } else { // In order to make it compatible with older versions of switch_theme which takes two // arguments we're going to pass two arguments instead of one. Latest versions have backward // compatibility so it's safe to do it this way. switch_theme($data['template'], $data['slug']); $activate = (wp_get_theme()->get_stylesheet() === $data['slug']) ? true : false; } if (false === $activate || is_wp_error($activate)) { $wp_version = $updraftcentral_main->get_wordpress_version(); $message = is_wp_error($activate) ? array('message' => $activate->get_error_message()) : array('message' => sprintf($updraftcentral_host_plugin->retrieve_show_message('unable_to_activate'), $type, $type, $wp_version)); return $this->_generic_error_response('unable_to_activate_'.$type, $message); } } return $this->_response( array( 'installed' => true, 'installed_data' => $data, ) ); } if (is_wp_error($skin->result)) { $code = $skin->result->get_error_code(); $message = $skin->result->get_error_message(); $error_data = $skin->result->get_error_data($code); if (!empty($error_data)) { if (is_array($error_data)) $error_data = json_encode($error_data); $message .= ' '.$error_data; } return $this->_generic_error_response($code, $message); } else { return $this->_response( array( 'installed' => false, 'message' => sprintf($updraftcentral_host_plugin->retrieve_show_message('unable_to_install'), $type, $type, $type, $type, 'wp-content/'.$type.'s'), ) ); } } } } else { // Returning response to a chunk requests while still processing and // completing the file upload process. If we don't return a positive response // for every chunk requests then the caller will assumed an error has occurred // and will eventually stop the upload process. return $this->_response(array('in_progress' => true)); } } } central/wp-optimize.php000064400000007471152214270100011174 0ustar00translations = include_once(UPDRAFTCENTRAL_CLIENT_DIR.'/translations-central.php'); } } /** * Whether the current user can perform key control AJAX actions * * @return Boolean */ public function current_user_can_ajax() { return current_user_can(WP_Optimize()->capability_required()); } /** * Loads the UpdraftCentral_Main instance * * @return void */ public function load_updraftcentral() { $central_path = $this->is_host_dir_set() ? trailingslashit(WPO_PLUGIN_MAIN_PATH) : ''; if (!empty($central_path) && file_exists($central_path.'central/bootstrap.php')) { include_once($central_path.'central/bootstrap.php'); } } /** * Checks whether the plugin's DIR constant is currently define or not * * @return bool */ public function is_host_dir_set() { return defined('WPO_PLUGIN_MAIN_PATH') ? true : false; } /** * Get the host plugin's dir path * * @return string */ public function get_host_dir() { return defined('WPO_PLUGIN_MAIN_PATH') ? WPO_PLUGIN_MAIN_PATH : dirname(dirname(__FILE__)); } /** * Returns the current version of the host plugin * * @return string|bool */ public function get_version() { return defined('WPO_VERSION') ? WPO_VERSION : false; } /** * Returns the instance of the host plugin * * @return object|bool */ public function get_instance() { global $wp_optimize; if ($wp_optimize) { return $wp_optimize; } return false; } /** * Checks whether debug mod is set * * @return bool */ public function get_debug_mode() { return (defined('WP_OPTIMIZE_DEBUG_OPTIMIZATIONS') && WP_OPTIMIZE_DEBUG_OPTIMIZATIONS); } /** * Logs the given line * * @param string $line The log line * @param string $level The log level: notice, warning, error, etc. * @param boolean|string $uniq_id Each of these will only be logged once * * @return void */ public function log($line, $level = 'notice', $uniq_id = false) {// phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable -- Unused parameter is present because the the abstract UpdraftCentral_Host class uses 3 arguments. global $wp_optimize; if ($wp_optimize) { if (is_callable(array($wp_optimize, 'log'))) { call_user_func(array($wp_optimize, 'log'), $line); } } } /** * Developer Note: * * You can add your class methods below if ever you want to extend or modify * the module handlers of UpdraftCentral located at central/modules. Just be * sure to use this class to abstract any functionality that would link to the * wp-optimize plugin. * * N.B. All custom methods added here will then be available from the global * variable $updraftcentral_host_plugin (e.g. $updraftcentral_host_plugin->YOUR_METHOD) */ } central/bootstrap.php000064400000105275152214270100010726 0ustar00is_host_dir_set()) die('No access.'); // This file is included during plugins_loaded // Load the listener class that we rely on to pick up messages if (!class_exists('UpdraftCentral_Listener')) require_once('listener.php'); // We exit if class already exists. More common if two or more plugins integrated // the same `UpdraftCentral` client folder. if (!class_exists('UpdraftCentral_Main')) : class UpdraftCentral_Main { /** * Class constructor */ public function __construct() { add_action('udrpc_log', array($this, 'udrpc_log'), 10, 3); add_action('wp_ajax_updraftcentral_receivepublickey', array($this, 'wp_ajax_updraftcentral_receivepublickey')); add_action('wp_ajax_nopriv_updraftcentral_receivepublickey', array($this, 'wp_ajax_updraftcentral_receivepublickey')); // The host plugin's command class is registered in its "plugins_loaded" method (e.g. UpdraftPlus::plugins_loaded()). // // N.B. The new filter "updraftcentral_remotecontrol_command_classes" was introduced on Jan. 2021 and will soon replace the // old filter "updraftplus_remotecontrol_command_classes" (below). This was done in order to synchronize all available filters // and actions related to UpdraftCentral so that we can easily port the UpdraftCentral client code into our other plugins. // // If you happened to use the old filter from any of your projects then you might as well update it with the new filter as the // old filter has already been marked as deprecated, though currently supported as can be seen below but will soon be remove // from this code block. $command_classes = apply_filters('updraftcentral_remotecontrol_command_classes', array( 'core' => 'UpdraftCentral_Core_Commands', 'updates' => 'UpdraftCentral_Updates_Commands', 'users' => 'UpdraftCentral_Users_Commands', 'comments' => 'UpdraftCentral_Comments_Commands', 'analytics' => 'UpdraftCentral_Analytics_Commands', 'plugin' => 'UpdraftCentral_Plugin_Commands', 'theme' => 'UpdraftCentral_Theme_Commands', 'posts' => 'UpdraftCentral_Posts_Commands', 'media' => 'UpdraftCentral_Media_Commands', 'pages' => 'UpdraftCentral_Pages_Commands' )); // N.B. This "updraftplus_remotecontrol_command_classes" filter has been marked as deprecated and will be remove after May 2021. // Please see above code comment for further explanation and its alternative. $command_classes = apply_filters('updraftplus_remotecontrol_command_classes', $command_classes); // If nothing was sent, then there is no incoming message, so no need to set up a listener (or CORS request, etc.). This avoids a DB SELECT query on the option below in the case where it didn't get autoloaded, which is the case when there are no keys. if (!empty($_SERVER['REQUEST_METHOD']) && ('GET' == $_SERVER['REQUEST_METHOD'] || 'POST' == $_SERVER['REQUEST_METHOD']) && (empty($_REQUEST['action']) || 'updraft_central' !== $_REQUEST['action']) && empty($_REQUEST['udcentral_action']) && empty($_REQUEST['udrpc_message'])) return; // Remote control keys // These are different from the remote send keys, which are set up in the Migrator add-on $our_keys = $this->get_central_localkeys(); if (is_array($our_keys) && !empty($our_keys)) { new UpdraftCentral_Listener($our_keys, $command_classes); } } /** * Enqueues the needed styles and scripts for UpdraftCentral * * @return void */ public function enqueue_central_scripts() { // This is an additional check; the caller is assumed to have already run checks before painting its page in general if (!current_user_can('manage_options')) return; global $updraftcentral_host_plugin; $version = $updraftcentral_host_plugin->get_version(); $enqueue_version = (defined('WP_DEBUG') && WP_DEBUG) ? $version.'.'.time() : $version; $min_or_not = (defined('SCRIPT_DEBUG') && SCRIPT_DEBUG) ? '' : '.min'; // Fallback to unminified version if the minified version is not found. if (!empty($min_or_not) && !file_exists(UPDRAFTCENTRAL_CLIENT_DIR.'/js/central'.$min_or_not.'.js')) { $min_or_not = ''; } wp_enqueue_script('updraft-central', UPDRAFTCENTRAL_CLIENT_URL.'/js/central'.$min_or_not.'.js', array(), $enqueue_version); wp_enqueue_style('updraft-central', UPDRAFTCENTRAL_CLIENT_URL.'/css/central'.$min_or_not.'.css', array(), $enqueue_version); $localize = array_merge( array( 'central_url' => UPDRAFTCENTRAL_CLIENT_URL, 'plugin_name' => $updraftcentral_host_plugin->get_plugin_name(), 'updraftcentral_request_nonce' => wp_create_nonce('updraftcentral-request-nonce'), ), $updraftcentral_host_plugin->translations ); wp_localize_script('updraft-central', 'uclion', apply_filters('updraftcentral_uclion', $localize)); } /** * Retrieves current clean url for anchor link where href attribute value is not url (for ex. #div) or empty. Output is not escaped (caller should escape). * * @return String - current clean url */ public function get_current_clean_url() { // Within an UpdraftCentral context, there should be no prefix on the anchor link if (defined('UPDRAFTCENTRAL_COMMAND') && UPDRAFTCENTRAL_COMMAND || defined('WP_CLI') && WP_CLI) return ''; if (defined('DOING_AJAX') && DOING_AJAX && !empty($_SERVER['HTTP_REFERER'])) { $current_url = $_SERVER['HTTP_REFERER']; } else { $url_prefix = is_ssl() ? 'https' : 'http'; $host = empty($_SERVER['HTTP_HOST']) ? parse_url(network_site_url(), PHP_URL_HOST) : $_SERVER['HTTP_HOST']; $current_url = $url_prefix."://".$host.$_SERVER['REQUEST_URI']; } $remove_query_args = array('state', 'action', 'oauth_verifier', 'nonce', 'updraftplus_instance', 'access_token', 'user_id', 'updraftplus_googledriveauth'); $query_string = remove_query_arg($remove_query_args, $current_url); return function_exists('wp_unslash') ? wp_unslash($query_string) : stripslashes_deep($query_string); } /** * Get the WordPress version * * @return String - the version */ public function get_wordpress_version() { static $got_wp_version = false; if (!$got_wp_version) { @include(ABSPATH.WPINC.'/version.php');// phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged -- Silenced to suppress errors that may arise because of the function. $got_wp_version = $wp_version;// phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UndefinedVariable -- The variable is defined inside the ABSPATH.WPINC.'/version.php'. } return $got_wp_version; } /** * Retrieves the UpdraftCentral generated keys * * @param Mixed $default default value to return when option is not found * * @return Mixed */ private function get_central_localkeys($default = null) { $option = 'updraft_central_localkeys'; $ret = get_option($option, $default); return apply_filters('updraftcentral_get_option', $ret, $option, $default); } /** * Updates the UpdraftCentral's keys * * @param string $value Specify option value * @param bool $use_cache Whether or not to use the WP options cache * @param string $autoload Whether to autoload (only takes effect on a change of value) * * @return bool */ private function update_central_localkeys($value, $use_cache = true, $autoload = 'yes') { $option = 'updraft_central_localkeys'; return update_option($option, apply_filters('updraftcentral_update_option', $value, $option, $use_cache), $autoload); } /** * Receive a new public key in $_GET, and echo a response. Will die() if called. */ public function wp_ajax_updraftcentral_receivepublickey() { global $updraftcentral_host_plugin; // The actual nonce check is done in the method below if (empty($_GET['_wpnonce']) || empty($_GET['public_key']) || !isset($_GET['updraft_key_index'])) die; $result = $this->receive_public_key(); if (!is_array($result) || empty($result['responsetype'])) die; $style = 'body {text-align: center;font-family: Helvetica,Arial,Lucida,sans-serif;background-color: #A64C1A;color: #FFF;height: 100%;width: 100%;margin: 0;padding: 0;}#main {height: 100%;width: 100%;display: table;}#wrapper {display: table-cell;height: 100%;vertical-align: middle;}h1 {margin-bottom: 5px;}h2 {margin-top: 0;font-size: 22px;color: #FFF;}#btn-close {color: #FFF;font-size: 20px;font-weight: 500;padding: .3em 1em;line-height: 1.7em !important;background-color: transparent;background-size: cover;background-position: 50%;background-repeat: no-repeat;border: 2px solid;border-radius: 3px;-webkit-transition-duration: .2s;transition-duration: .2s;-webkit-transition-property: all !important;transition-property: all !important;text-decoration: none;}#btn-close:hover {background-color: #DE6726;}'; echo 'UpdraftCentral

'.$updraftcentral_host_plugin->retrieve_show_message('updraftcentral_connection').'

'.htmlspecialchars(network_site_url()).'

'; if ('ok' == $result['responsetype']) { $updraftcentral_host_plugin->retrieve_show_message('updraftcentral_connection_successful', true); } else { echo ''.$updraftcentral_host_plugin->retrieve_show_message('updraftcentral_connection_failed').'
'; switch ($result['code']) { case 'unknown_key': $updraftcentral_host_plugin->retrieve_show_message('unknown_key', true); break; case 'not_logged_in': echo $updraftcentral_host_plugin->retrieve_show_message('not_logged_in').' '.$updraftcentral_host_plugin->retrieve_show_message('must_visit_url'); break; case 'nonce_failure': $updraftcentral_host_plugin->retrieve_show_message('security_check', true); $updraftcentral_host_plugin->retrieve_show_message('must_visit_link', true); break; case 'already_have': $updraftcentral_host_plugin->retrieve_show_message('connection_already_made', true); break; case 'insufficient_privilege': $updraftcentral_host_plugin->retrieve_show_message('insufficient_privilege', true); break; default: echo htmlspecialchars(print_r($result, true)); break; } } echo '

'.$updraftcentral_host_plugin->retrieve_show_message('close').'

'; die; } /** * Checks _wpnonce, and if successful, saves the public key found in $_GET * * @return Array - with keys responsetype (can be 'error' or 'ok') and code, indicating whether the parse was successful */ private function receive_public_key() { if (!is_user_logged_in()) { return array('responsetype' => 'error', 'code' => 'not_logged_in'); } if (!wp_verify_nonce($_GET['_wpnonce'], 'updraftcentral_receivepublickey')) return array('responsetype' => 'error', 'code' => 'nonce_failure'); $updraft_key_index = $_GET['updraft_key_index']; $our_keys = $this->get_central_localkeys(); if (!is_array($our_keys)) $our_keys = array(); if (!isset($our_keys[$updraft_key_index])) { return array('responsetype' => 'error', 'code' => 'unknown_key'); } if (!empty($our_keys[$updraft_key_index]['publickey_remote'])) { return array('responsetype' => 'error', 'code' => 'already_have'); } $our_keys[$updraft_key_index]['publickey_remote'] = base64_decode(stripslashes($_GET['public_key'])); $this->update_central_localkeys($our_keys, true, 'no'); return array('responsetype' => 'ok', 'code' => 'ok'); } /** * Action parameters, from udrpc: $message, $level, $this->key_name_indicator, $this->debug, $this * * @param string $message The log message * @param string $level Log level * @param string $key_name_indicator This indicates the key name */ public function udrpc_log($message, $level, $key_name_indicator) { $udrpc_log = get_site_option('updraftcentral_client_log'); if (!is_array($udrpc_log)) $udrpc_log = array(); $new_item = array( 'time' => time(), 'level' => $level, 'message' => $message, 'key_name_indicator' => $key_name_indicator ); if (!empty($_SERVER['REMOTE_ADDR'])) { $new_item['remote_ip'] = $_SERVER['REMOTE_ADDR']; } if (!empty($_SERVER['HTTP_USER_AGENT'])) { $new_item['http_user_agent'] = $_SERVER['HTTP_USER_AGENT']; } if (!empty($_SERVER['HTTP_X_SECONDARY_USER_AGENT'])) { $new_item['http_secondary_user_agent'] = $_SERVER['HTTP_X_SECONDARY_USER_AGENT']; } $udrpc_log[] = $new_item; if (count($udrpc_log) > 50) array_shift($udrpc_log); update_site_option('updraftcentral_client_log', $udrpc_log); } /** * Delete UpdraftCentral Key * * @param array $key_id key_id of UpdraftCentral * * @return array which contains deleted flag and key table. If error, Returns array which contains fatal_error flag and fatal_error_message */ public function delete_key($key_id) { $our_keys = $this->get_central_localkeys(); if (is_array($key_id) && isset($key_id['key_id'])) { $key_id = $key_id['key_id']; } if (!is_array($our_keys)) $our_keys = array(); if (isset($our_keys[$key_id])) { unset($our_keys[$key_id]); $this->update_central_localkeys($our_keys); } return array('deleted' => 1, 'keys_table' => $this->get_keys_table()); } /** * Get UpdraftCentral Log * * @return array which contains log_contents. If error, Returns array which contains fatal_error flag and fatal_error_message */ public function get_log() { global $updraftcentral_host_plugin; $udrpc_log = get_site_option('updraftcentral_client_log'); if (!is_array($udrpc_log)) $udrpc_log = array(); $log_contents = ''; // Events are appended to the array in the order they happen. So, reversing the order gets them into most-recent-first order. rsort($udrpc_log); if (empty($udrpc_log)) { $log_contents = ''.$updraftcentral_host_plugin->retrieve_show_message('nothing_yet_logged').''; } foreach ($udrpc_log as $m) { // Skip invalid data if (!isset($m['time'])) continue; $time = gmdate('Y-m-d H:i:s O', $m['time']); // $level is not used yet. We could put the message in different colours for different levels, if/when it becomes used. $key_name_indicator = empty($m['key_name_indicator']) ? '' : $m['key_name_indicator']; $log_contents .= ''."$time "; if (!empty($m['remote_ip'])) $log_contents .= '['.htmlspecialchars($m['remote_ip']).'] '; $log_contents .= "[".htmlspecialchars($key_name_indicator)."] ".htmlspecialchars($m['message'])."\n"; } return array('log_contents' => $log_contents); } public function create_key($params) { global $updraftcentral_host_plugin; // Use the site URL - this means that if the site URL changes, communication ends; which is the case anyway $user = wp_get_current_user(); if (!is_object($user) || empty($user->ID)) return array('error' => $updraftcentral_host_plugin->retrieve_show_message('insufficient_privilege')); if (!current_user_can('manage_options')) return array('error' => $updraftcentral_host_plugin->retrieve_show_message('insufficient_privilege')); $where_send = empty($params['where_send']) ? '' : (string) $params['where_send']; if ('__updraftpluscom' != $where_send) { $purl = parse_url($where_send); if (empty($purl) || !array($purl) || empty($purl['scheme']) || empty($purl['host'])) return array('error' => $updraftcentral_host_plugin->retrieve_show_message('invalid_url')); } // ENT_HTML5 exists only on PHP 5.4+ // @codingStandardsIgnoreLine $flags = defined('ENT_HTML5') ? ENT_QUOTES | ENT_HTML5 : ENT_QUOTES; $extra_info = array( 'user_id' => $user->ID, 'user_login' => $user->user_login, 'ms_id' => get_current_blog_id(), 'site_title' => html_entity_decode(get_bloginfo('name'), $flags), ); if ($where_send) { $extra_info['mothership'] = $where_send; if (!empty($params['mothership_firewalled'])) { $extra_info['mothership_firewalled'] = true; } } if (!empty($params['key_description'])) { $extra_info['name'] = (string) $params['key_description']; } $key_size = (empty($params['key_size']) || !is_numeric($params['key_size']) || $params['key_size'] < 512) ? 2048 : (int) $params['key_size']; $extra_info['key_size'] = $key_size; $created = $this->create_remote_control_key(false, $extra_info, $where_send); if (is_array($created)) { $created['keys_table'] = $this->get_keys_table(); $created['keys_guide'] = '

'. $updraftcentral_host_plugin->retrieve_show_message('updraftcentral_key_created') .'

'; if ('__updraftpluscom' != $where_send) { $created['keys_guide'] .= '

'.sprintf($updraftcentral_host_plugin->retrieve_show_message('need_to_copy_key'), 'UpdraftCentral dashboard').'

'.$updraftcentral_host_plugin->retrieve_show_message('press_add_site_button').'

'.sprintf($updraftcentral_host_plugin->retrieve_show_message('detailed_instructions'), 'UpdraftPlus.com').'

'; } else { $created['keys_guide'] .= '

'. sprintf($updraftcentral_host_plugin->retrieve_show_message('control_this_site'), 'UpdraftPlus.com').'

'; } } return $created; } /** * Given an index, return the indicator name * * @param String $index * * @return String */ private function indicator_name_from_index($index) { return $index.'.central.updraftplus.com'; } /** * Gets an RPC object, and sets some defaults on it that we always want * * @param string $indicator_name indicator name * * @return array */ public function get_udrpc($indicator_name = 'migrator.updraftplus.com') { global $updraftcentral_host_plugin; if (!class_exists('UpdraftPlus_Remote_Communications')) include_once($updraftcentral_host_plugin->get_host_dir().'/vendor/team-updraft/common-libs/src/updraft-rpc/class-udrpc.php'); $ud_rpc = new UpdraftPlus_Remote_Communications($indicator_name); $ud_rpc->set_can_generate(true); return $ud_rpc; } private function create_remote_control_key($index = false, $extra_info = array(), $post_it = false) { global $updraftcentral_host_plugin; $our_keys = $this->get_central_localkeys(); if (!is_array($our_keys)) $our_keys = array(); if (false === $index) { if (empty($our_keys)) { $index = 0; } else { $index = max(array_keys($our_keys))+1; } } $name_hash = $index; if (isset($our_keys[$name_hash])) { unset($our_keys[$name_hash]); } $indicator_name = $this->indicator_name_from_index($name_hash); $ud_rpc = $this->get_udrpc($indicator_name); if ('__updraftpluscom' == $post_it) { $post_it = defined('UPDRAFTPLUS_OVERRIDE_UDCOM_DESTINATION') ? UPDRAFTPLUS_OVERRIDE_UDCOM_DESTINATION : 'https://updraftplus.com/?updraftcentral_action=receive_key'; $post_it_description = 'UpdraftPlus.Com'; } else { $post_it_description = $post_it; } // Normally, key generation takes seconds, even on a slow machine. However, some Windows machines appear to have a setup in which it takes a minute or more. And then, if you're on a double-localhost setup on slow hardware - even worse. It doesn't hurt to just raise the maximum execution time. if (function_exists('set_time_limit')) @set_time_limit(UPDRAFTCENTRAL_SET_TIME_LIMIT);// phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged -- Silenced to suppress errors that may arise because of the function. $key_size = (empty($extra_info['key_size']) || !is_numeric($extra_info['key_size']) || $extra_info['key_size'] < 512) ? 2048 : (int) $extra_info['key_size']; if (is_object($ud_rpc) && $ud_rpc->generate_new_keypair($key_size)) { if ($post_it && empty($extra_info['mothership_firewalled'])) { $p_url = parse_url($post_it); if (is_array($p_url) && !empty($p_url['user'])) { $http_username = $p_url['user']; $http_password = empty($p_url['pass']) ? '' : $p_url['pass']; $post_it = $p_url['scheme'].'://'.$p_url['host']; if (!empty($p_url['port'])) $post_it .= ':'.$p_url['port']; $post_it .= $p_url['path']; if (!empty($p_url['query'])) $post_it .= '?'.$p_url['query']; } $post_options = array( 'timeout' => 90, 'body' => array( 'updraftcentral_action' => 'receive_key', 'key' => $ud_rpc->get_key_remote() ) ); if (!empty($http_username)) { $post_options['headers'] = array( 'Authorization' => 'Basic '.base64_encode($http_username.':'.$http_password) ); } // This option allows the key to be sent to the other side via a known-secure channel (e.g. http over SSL), rather than potentially allowing it to travel over an unencrypted channel (e.g. http back to the user's browser). As such, if specified, it is compulsory for it to work. $updraftcentral_host_plugin->register_wp_http_option_hooks(); $sent_key = wp_remote_post( $post_it, $post_options ); $updraftcentral_host_plugin->register_wp_http_option_hooks(false); $connection_troubleshooting_url = 'https://updraftplus.com/troubleshooting-updraftcentral-connection-issues/'; if (is_wp_error($sent_key) || empty($sent_key)) { $err_msg = sprintf($updraftcentral_host_plugin->retrieve_show_message('attempt_to_register_failed'), (string) $post_it_description, $connection_troubleshooting_url); if (is_wp_error($sent_key)) $err_msg .= ' '.$sent_key->get_error_message().' ('.$sent_key->get_error_code().')'; return array( 'r' => $err_msg ); } $response = json_decode(wp_remote_retrieve_body($sent_key), true); if (!is_array($response) || !isset($response['key_id']) || !isset($response['key_public'])) { return array( 'r' => sprintf($updraftcentral_host_plugin->retrieve_show_message('attempt_to_register_failed'), (string) $post_it_description, $connection_troubleshooting_url), 'raw' => wp_remote_retrieve_body($sent_key) ); } $key_hash = hash('sha256', $ud_rpc->get_key_remote()); $local_bundle = $ud_rpc->get_portable_bundle('base64_with_count', $extra_info, array('key' => array('key_hash' => $key_hash, 'key_id' => $response['key_id']))); } elseif ($post_it) { // Don't send; instead, include in the bundle info that the mothership is firewalled; this will then tell the mothership to try the reverse connection instead if (is_array($extra_info)) { $extra_info['mothership_firewalled_callback_url'] = wp_nonce_url(admin_url('admin-ajax.php'), 'updraftcentral_receivepublickey'); $extra_info['updraft_key_index'] = $index; } $local_bundle = $ud_rpc->get_portable_bundle('base64_with_count', $extra_info, array('key' => $ud_rpc->get_key_remote())); } if (isset($extra_info['name'])) { $name = (string) $extra_info['name']; unset($extra_info['name']); } else { $name = 'UpdraftCentral Remote Control'; } $our_keys[$name_hash] = array( 'name' => $name, 'key' => $ud_rpc->get_key_local(), 'extra_info' => $extra_info, 'created' => time(), ); // Store the other side's public key if (!empty($response) && is_array($response) && !empty($response['key_public'])) { $our_keys[$name_hash]['publickey_remote'] = $response['key_public']; } $this->update_central_localkeys($our_keys, true, 'no'); return array( 'bundle' => $local_bundle, 'r' => $updraftcentral_host_plugin->retrieve_show_message('key_created_successfully').' '.$updraftcentral_host_plugin->retrieve_show_message('copy_paste_key'), ); } return false; } /** * Get the HTML for the keys table * * @return String */ public function get_keys_table() { // This is an additional check - it implies requirement for a dashboard context if (!current_user_can('manage_options')) return; global $updraftcentral_host_plugin; $ret = ''; $our_keys = $this->get_central_localkeys(); if (!is_array($our_keys)) $our_keys = array(); if (empty($our_keys)) { $ret .= ''.$updraftcentral_host_plugin->retrieve_show_message('no_updraftcentral_dashboards').''; } foreach ($our_keys as $i => $key) { if (empty($key['extra_info'])) continue; $user_id = $key['extra_info']['user_id']; if (!empty($key['extra_info']['mothership'])) { $mothership_url = $key['extra_info']['mothership']; if ('__updraftpluscom' == $mothership_url) { $reconstructed_url = 'https://updraftplus.com'; } else { $purl = parse_url($mothership_url); $path = empty($purl['path']) ? '' : $purl['path']; $reconstructed_url = $purl['scheme'].'://'.$purl['host'].(!empty($purl['port']) ? ':'.$purl['port'] : '').$path; } } else { $reconstructed_url = $updraftcentral_host_plugin->retrieve_show_message('unknown'); } $name = $key['name']; $user = get_user_by('id', $user_id); $user_display = is_a($user, 'WP_User') ? $user->user_login.' ('.$user->user_email.')' : $updraftcentral_host_plugin->retrieve_show_message('unknown'); $ret .= ''.htmlspecialchars($name).' ('.htmlspecialchars($i).')'.$updraftcentral_host_plugin->retrieve_show_message('access_as_user')." ".htmlspecialchars($user_display)."
".$updraftcentral_host_plugin->retrieve_show_message('public_key_sent').' '.htmlspecialchars($reconstructed_url).'
'; if (!empty($key['created'])) { $ret .= $updraftcentral_host_plugin->retrieve_show_message('created').' '.date_i18n(get_option('date_format').' '.get_option('time_format'), $key['created']).'.'; if (!empty($key['extra_info']['key_size'])) { $ret .= ' '.sprintf($updraftcentral_host_plugin->retrieve_show_message('key_size'), $key['extra_info']['key_size']).'.'; } $ret .= '
'; } $ret .= ''.$updraftcentral_host_plugin->retrieve_show_message('delete').''; } ob_start(); ?>
retrieve_show_message('manage_keys'), count($our_keys)); ?>
retrieve_show_message('key_description', true); ?> retrieve_show_message('details', true); ?>

retrieve_show_message('connect_to_updraftcentral_dashboard', true); ?>



retrieve_show_message('website_installed'), 'UpdraftCentral'); ?>
enqueue_central_scripts(); global $updraftcentral_host_plugin; $including_desc = ''; if (function_exists('get_current_screen')) { $screen = get_current_screen(); $hosts = apply_filters('updraftcentral_host_plugins', array()); $includes = $updraftcentral_host_plugin->retrieve_show_message('including_description'); foreach ($hosts as $plugin) { if (false !== stripos($screen->id, $plugin)) { $key = str_replace('-', '_', strtolower($plugin)).'_desc'; if (isset($includes[$key])) { $including_desc = $includes[$key]; break; } } } } $updraftcentral_description = preg_replace('/\s+/', ' ', sprintf($updraftcentral_host_plugin->retrieve_show_message('updraftcentral_description'), $including_desc)); ?>

retrieve_show_message('updraftcentral_remote_control', true); ?>

'.$updraftcentral_host_plugin->retrieve_show_message('read_more').''; ?>

create_key_markup(); ?> get_keys_table(); ?> get_log_markup(); ?>
__('UpdraftCentral Connection', 'updraftplus'), 'updraftcentral_connection_successful' => __('An UpdraftCentral connection has been made successfully.', 'updraftplus'), 'updraftcentral_connection_failed' => __('A new UpdraftCentral connection has not been made.', 'updraftplus'), 'unknown_key' => __('The key referred to was unknown.', 'updraftplus'), 'not_logged_in' => __('You are not logged into this WordPress site in your web browser.', 'updraftplus'), 'must_visit_url' => __('You must visit this URL in the same browser and login session as you created the key in.', 'updraftplus'), 'security_check' => __('Security check. ', 'updraftplus'), 'must_visit_link' => __('You must visit this link in the same browser and login session as you created the key in.', 'updraftplus'), 'connection_already_made' => __('This connection appears to already have been made.', 'updraftplus'), 'close' => __('Close', 'updraftplus'), 'nothing_yet_logged' => __('(Nothing yet logged)', 'updraftplus'), 'invalid_url' => __('An invalid URL was entered', 'updraftplus'), 'updraftcentral_key_created' => __('UpdraftCentral key created successfully', 'updraftplus'), 'need_to_copy_key' => __('You now need to copy the key below and enter it at your %s.', 'updraftplus'), 'press_add_site_button' => __('At your UpdraftCentral dashboard you should press the "Add Site" button then paste the key in the input box.', 'updraftplus'), 'detailed_instructions' => __('Detailed instructions for this can be found at %s', 'updraftplus'), 'control_this_site' => __('You can now control this site via your UpdraftCentral dashboard at %s.', 'updraftplus'), 'attempt_to_register_failed' => __('A key was created, but the attempt to register it with %1$s was unsuccessful. You can try again, or try using the alternative connection method if the problem persists. For more information visit %2$s', 'updraftplus'), 'key_created_successfully' => __('Key created successfully.', 'updraftplus'), 'copy_paste_key' => __('You must copy and paste this key now - it cannot be shown again.', 'updraftplus'), 'no_updraftcentral_dashboards' => __('There are no UpdraftCentral dashboards that can currently control this site.', 'updraftplus'), 'unknown' => __('Unknown', 'updraftplus'), 'access_as_user' => __('Access this site as user:', 'updraftplus'), 'public_key_sent' => __('Public key was sent to:', 'updraftplus'), 'created' => __('Created:', 'updraftplus'), 'key_size' => __('Key size: %d bits', 'updraftplus'), 'delete' => __('Delete...', 'updraftplus'), 'manage_keys' => __('Manage existing keys (%d)...', 'updraftplus'), 'key_description' => __('Key description', 'updraftplus'), 'details' => __('Details', 'updraftplus'), 'connect_to_updraftcentral_dashboard' => __('Connect this site to an UpdraftCentral dashboard found at...', 'updraftplus'), 'in_example' => __('i.e. if you have %s there', 'updraftplus'), 'an_account' => __('an account', 'updraftplus'), 'self_hosted_dashboard' => __('Self-hosted dashboard', 'updraftplus'), 'website_installed' => __('A website where you have installed %s', 'updraftplus'), 'enter_url' => __('Enter the URL where your self-hosted install of UpdraftCentral is located:', 'updraftplus'), 'updraftcentral_dashboard_url' => __('URL for the site of your UpdraftCentral dashboard', 'updraftplus'), 'next' => __('Next', 'updraftplus'), 'updraftcentral_connection_details' => __('UpdraftCentral dashboard connection details', 'updraftplus'), 'description' => __('Description', 'updraftplus'), 'enter_description' => __('Enter any description', 'updraftplus'), 'encryption_key_size' => __('Encryption key size:', 'updraftplus'), 'bits' => __('%s bits', 'updraftplus'), 'bytes' => __('%s bytes', 'updraftplus'), 'easy_to_break' => __('easy to break, fastest', 'updraftplus'), 'faster' => __('faster (possibility for slow PHP installs)', 'updraftplus'), 'recommended' => __('recommended', 'updraftplus'), 'slower' => __('slower, strongest', 'updraftplus'), 'use_alternative_method' => __('Use the alternative method for making a connection with the dashboard.', 'updraftplus'), 'more_information' => __('More information...', 'updraftplus'), 'this_is_useful' => __('This is useful if the dashboard webserver cannot be contacted with incoming traffic by this website (for example, this is the case if this website is hosted on the public Internet, but the UpdraftCentral dashboard is on localhost, or on an Intranet, or if this website has an outgoing firewall), or if the dashboard website does not have a SSL certificate.', 'updraftplus'), 'create' => __('Create', 'updraftplus'), 'back' => __('Back...', 'updraftplus'), 'view_log_events' => __('View recent UpdraftCentral log events', 'updraftplus'), 'updraftcentral_remote_control' => __('UpdraftCentral (Remote Control)', 'updraftplus'), 'updraftcentral_description' => __('UpdraftCentral enables control of your WordPress sites %s from a central dashboard.', 'updraftplus'), 'including_description' => array( 'wp_optimize_desc' => __('(including management of WP-Optimize)', 'updraftplus'), 'updraftplus_desc' => __('(including management of backups and updates)', 'updraftplus'), ), 'read_more' => __('Read more about it here.', 'updraftplus'), 'create_another_key' => __('Create another key', 'updraftplus'), 'unable_to_connect' => __('Unable to connect to the filesystem', 'updraftplus'), 'unable_to_activate' => __('Unable to activate %s successfully. Make sure that this %s is compatible with your remote WordPress version. WordPress version currently installed in your remote website is %s.', 'updraftplus'), 'unable_to_install' => __('Unable to install %s. Make sure that the zip file is a valid %s file and a previous version of this %s does not exist. If you wish to overwrite an existing %s then you will have to manually delete it from the %s folder on the remote website and try uploading the file again.', 'updraftplus'), 'failed_to_attach_media' => __('Failed to attach media.', 'updraftplus'), 'media_attached' => __('Media has been attached to post.', 'updraftplus'), 'failed_to_detach_media' => __('Failed to detach media.', 'updraftplus'), 'media_detached' => __('Media has been detached from post.', 'updraftplus'), 'failed_to_delete_media' => __('Failed to delete selected media.', 'updraftplus'), 'selected_media_deleted' => __('Selected media has been deleted successfully.', 'updraftplus'), 'unattached' => __('Unattached', 'updraftplus'), 'default_template' => __('Default template', 'updraftplus'), 'parameters_missing' => __('Expected parameter(s) missing.', 'updraftplus'), 'fetching' => __('Fetching...', 'updraftplus'), 'deleting' => __('Deleting...', 'updraftplus'), 'enter_mothership_url' => __('Please enter a valid URL', 'updraftplus'), 'creating_please_allow' => __('Creating...', 'updraftplus').(function_exists('openssl_encrypt') ? '' : ' ('.__('your PHP install lacks the openssl module; as a result, this can take minutes; if nothing has happened by then, then you should either try a smaller key size, or ask your web hosting company how to enable this PHP module on your setup.', 'updraftplus').')'), 'unexpectedresponse' => __('Unexpected response:', 'updraftplus'), 'updraftcentral_wizard_empty_url' => __('Please enter the URL where your UpdraftCentral dashboard is hosted.', 'updraftplus'), 'updraftcentral_wizard_invalid_url' => __('Please enter a valid URL e.g http://example.com', 'updraftplus'), 'insufficient_privilege' => __('Sorry, you do not have enough privilege to execute the requested action.', 'updraftplus'), ); central/listener.php000064400000035055152214270100010534 0ustar00host = $updraftcentral_host_plugin; // It seems impossible for this condition to result in a return; but it seems Plesk can do something odd within the control panel that causes a problem - see HS#6276 if (!is_a($this->host, 'UpdraftCentral_Host')) return; $this->command_classes = $command_classes; foreach ($keys as $name_hash => $key) { // publickey_remote isn't necessarily set yet, depending on the key exchange method if (!is_array($key) || empty($key['extra_info']) || empty($key['publickey_remote'])) continue; $indicator = $name_hash.'.central.updraftplus.com'; $ud_rpc = $this->host->get_udrpc($indicator); $this->udrpc_version = $ud_rpc->version; // Only turn this on if you are comfortable with potentially anything appearing in your PHP error log if (defined('UPDRAFTCENTRAL_UDRPC_FORCE_DEBUG') && UPDRAFTCENTRAL_UDRPC_FORCE_DEBUG) $ud_rpc->set_debug(true); $this->receivers[$indicator] = $ud_rpc; $this->extra_info[$indicator] = isset($key['extra_info']) ? $key['extra_info'] : null; $ud_rpc->set_key_local($key['key']); $ud_rpc->set_key_remote($key['publickey_remote']); // Create listener (which causes WP actions to be fired when messages are received) $ud_rpc->activate_replay_protection(); if (!empty($key['extra_info']) && isset($key['extra_info']['mothership'])) { $mothership = $key['extra_info']['mothership']; $url = ''; if ('__updraftpluscom' == $mothership) { $url = 'https://updraftplus.com'; } elseif (false != ($parsed = parse_url($key['extra_info']['mothership'])) && is_array($parsed)) { $url = $parsed['scheme'].'://'.$parsed['host']; } if (!empty($url)) $ud_rpc->set_allow_cors_from(array($url)); } $ud_rpc->create_listener(); } // If we ever need to expand beyond a single GET action, this can/should be generalised and put into the commands class if (!empty($_GET['udcentral_action']) && 'login' == $_GET['udcentral_action']) { // auth_redirect() does not return, according to the documentation; but the code shows that it can // auth_redirect(); if (!empty($_GET['login_id']) && is_numeric($_GET['login_id']) && !empty($_GET['login_key'])) { $login_user = get_user_by('id', $_GET['login_id']); // THis is included so we can get $wp_version include_once(ABSPATH.WPINC.'/version.php'); if (is_a($login_user, 'WP_User') || (version_compare($wp_version, '3.5', '<') && !empty($login_user->ID))) {// phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UndefinedVariable // Allow site implementers to disable this functionality -- The variable is defined inside the ABSPATH.WPINC.'/version.php'. $allow_autologin = apply_filters('updraftcentral_allow_autologin', true, $login_user); if ($allow_autologin) { $login_key = get_user_meta($login_user->ID, 'updraftcentral_login_key', true); if (is_array($login_key) && !empty($login_key['created']) && $login_key['created'] > time() - 60 && !empty($login_key['key']) && $login_key['key'] == $_GET['login_key']) { $autologin = empty($login_key['redirect_url']) ? network_admin_url() : $login_key['redirect_url']; } } } } if (!empty($autologin)) { // Allow use once only delete_user_meta($login_user->ID, 'updraftcentral_login_key'); $this->autologin_user($login_user, $autologin); } } add_filter('udrpc_action', array($this, 'udrpc_action'), 10, 5); add_filter('updraftcentral_get_command_info', array($this, 'updraftcentral_get_command_info'), 10, 2); add_filter('updraftcentral_get_updraftplus_status', array($this, 'get_updraftplus_status'), 10, 1); } /** * Retrieves the UpdraftPlus plugin status whether it has been installed or activated * * @param mixed $data Default data to return * @return array */ public function get_updraftplus_status($data) { // Handle cases of users who rename their plugin folders if (class_exists('UpdraftPlus')) { $data['is_updraftplus_installed'] = true; $data['is_updraftplus_active'] = true; } else { if (!function_exists('get_plugins')) require_once(ABSPATH.'wp-admin/includes/plugin.php'); $plugins = get_plugins(); $key = 'updraftplus/updraftplus.php'; if (array_key_exists($key, $plugins)) { $data['is_updraftplus_installed'] = true; if (is_plugin_active($key)) $data['is_updraftplus_active'] = true; } } return $data; } /** * Retrieves command class information and includes class file if class * is currently not available. * * @param mixed $response The default response to return if the submitted command does not exists * @param string $command The command to parse and check * @return array Contains the following command information "command_php_class", "class_prefix" and "command" */ public function updraftcentral_get_command_info($response, $command) { if (!preg_match('/^([a-z0-9]+)\.(.*)$/', $command, $matches)) return $response; $class_prefix = $matches[1]; $command = $matches[2]; // Other plugins might have registered the filter rather later so we need to make // sure that we get all the commands intended for UpdraftCentral. $this->command_classes = apply_filters('updraftcentral_remotecontrol_command_classes', $this->command_classes); // We only handle some commands - the others, we let something else deal with if (!isset($this->command_classes[$class_prefix])) return $response; $command_php_class = $this->command_classes[$class_prefix]; $command_base_class_at = apply_filters('updraftcentral_command_base_class_at', UPDRAFTCENTRAL_CLIENT_DIR.'/commands.php'); if (!class_exists('UpdraftCentral_Commands')) include_once($command_base_class_at); // Second parameter has been passed since do_action('updraftcentral_command_class_wanted', $command_php_class); if (!class_exists($command_php_class)) { if (file_exists(UPDRAFTCENTRAL_CLIENT_DIR.'/modules/'.$class_prefix.'.php')) { include_once(UPDRAFTCENTRAL_CLIENT_DIR.'/modules/'.$class_prefix.'.php'); } } return array( 'command_php_class' => $command_php_class, 'class_prefix' => $class_prefix, 'command' => $command ); } /** * Do verification before calling this method * * @param WP_User|Object $user user object for autologin * @param boolean $redirect_url Redirect URL */ private function autologin_user($user, $redirect_url = false) { if (!is_user_logged_in()) { // $user = get_user_by('id', $user_id); // Don't check that it's a WP_User - that's WP 3.5+ only if (!is_object($user) || empty($user->ID)) return; wp_set_current_user($user->ID, $user->user_login); wp_set_auth_cookie($user->ID); do_action('wp_login', $user->user_login, $user); } if ($redirect_url) { wp_safe_redirect($redirect_url); exit; } } /** * WP filter udrpc_action * * @param Array $response - the unfiltered response that will be returned * @param String $command - the command being called * @param Array $data - the parameters to the command * @param String $key_name_indicator - the UC key that is in use * @param Object $ud_rpc - the UDRP object * * @return Array - filtered response */ public function udrpc_action($response, $command, $data, $key_name_indicator, $ud_rpc) { try { if (empty($this->receivers[$key_name_indicator])) return $response; // This can be used to detect an UpdraftCentral context if (!defined('UPDRAFTCENTRAL_COMMAND')) define('UPDRAFTCENTRAL_COMMAND', $command); $this->initialise_listener_error_handling(); // UpdraftCentral needs this extra information especially now that the UpdraftCentral // libraries can be totally embedded in other plugins (e.g. WP-Optimize, etc.) thus, // that makes the UpdraftPlus plugin optional. // // This will give UpdraftCentral a proper way of disabling the backup feature // for this site if the UpdraftPlus plugin is currently not installed or activated. $extra = apply_filters('updraftcentral_get_updraftplus_status', array( 'is_updraftplus_installed' => false, 'is_updraftplus_active' => false )); $command_info = apply_filters('updraftcentral_get_command_info', false, $command); if (!$command_info) { if (isset($response['data']) && is_array($response['data'])) $response['data']['extra'] = $extra; return $response; } $class_prefix = $command_info['class_prefix']; $command = $command_info['command']; $command_php_class = $command_info['command_php_class']; if (empty($this->commands[$class_prefix])) { if (class_exists($command_php_class)) { $this->commands[$class_prefix] = new $command_php_class($this); } } $command_class = isset($this->commands[$class_prefix]) ? $this->commands[$class_prefix] : new stdClass; if ('_' == substr($command, 0, 1) || !is_a($command_class, $command_php_class) || (!method_exists($command_class, $command) && !method_exists($command_class, '__call'))) { if (defined('UPDRAFTCENTRAL_UDRPC_FORCE_DEBUG') && UPDRAFTCENTRAL_UDRPC_FORCE_DEBUG) error_log("Unknown RPC command received: ".$command); return $this->return_rpc_message(array('response' => 'rpcerror', 'data' => array('code' => 'unknown_rpc_command', 'data' => array('prefix' => $class_prefix, 'command' => $command, 'class' => $command_php_class)))); } $extra_info = isset($this->extra_info[$key_name_indicator]) ? $this->extra_info[$key_name_indicator] : null; // Make it so that current_user_can() checks can apply + work if (!empty($extra_info['user_id'])) wp_set_current_user($extra_info['user_id']); $this->current_udrpc = $ud_rpc; do_action('updraftcentral_listener_pre_udrpc_action', $command, $command_class, $data, $extra_info); // Allow the command class to perform any boiler-plate actions. if (is_callable(array($command_class, '_pre_action'))) call_user_func(array($command_class, '_pre_action'), $command, $data, $extra_info); // Despatch $msg = apply_filters('updraftcentral_listener_udrpc_action', call_user_func(array($command_class, $command), $data, $extra_info), $command_class, $class_prefix, $command, $data, $extra_info); if (is_callable(array($command_class, '_post_action'))) call_user_func(array($command_class, '_post_action'), $command, $data, $extra_info); do_action('updraftcentral_listener_post_udrpc_action', $command, $command_class, $data, $extra_info); if (isset($msg['data']) && is_array($msg['data'])) { $msg['data']['extra'] = $extra; } return $this->return_rpc_message($msg); } catch (Exception $e) { $log_message = 'PHP Fatal Exception error ('.get_class($e).') has occurred during UpdraftCentral command execution. Error Message: '.$e->getMessage().' (Code: '.$e->getCode().', line '.$e->getLine().' in '.$e->getFile().')'; error_log($log_message); return $this->return_rpc_message(array('response' => 'rpcerror', 'data' => array('code' => 'rpc_fatal_error', 'data' => array('command' => $command, 'message' => $log_message)))); // @codingStandardsIgnoreLine } catch (Error $e) { $log_message = 'PHP Fatal error ('.get_class($e).') has occurred during UpdraftCentral command execution. Error Message: '.$e->getMessage().' (Code: '.$e->getCode().', line '.$e->getLine().' in '.$e->getFile().')'; error_log($log_message); return $this->return_rpc_message(array('response' => 'rpcerror', 'data' => array('code' => 'rpc_fatal_error', 'data' => array('command' => $command, 'message' => $log_message)))); } } public function get_current_udrpc() { return $this->current_udrpc; } private function initialise_listener_error_handling() { global $updraftcentral_host_plugin; $this->host->error_reporting_stop_when_logged = true; set_error_handler(array($this->host, 'php_error'), E_ALL & ~E_STRICT); $this->php_events = array(); @ob_start();// phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged -- Might be a bigger picture that I am missing but do we need to silence errors here? add_filter($updraftcentral_host_plugin->get_logline_filter(), array($this, 'updraftcentral_logline'), 10, 4); if (!$updraftcentral_host_plugin->get_debug_mode()) return; } public function updraftcentral_logline($line, $nonce, $level, $uniq_id) {// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.Found -- Unused parameter is present because the method is used as a WP filter. if ('notice' === $level && 'php_event' === $uniq_id) { $this->php_events[] = $line; } return $line; } public function return_rpc_message($msg) { if (is_array($msg) && isset($msg['response']) && 'error' == $msg['response']) { $this->host->log('Unexpected response code in remote communications: '.serialize($msg)); } $caught_output = @ob_get_contents();// phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged -- Might be a bigger picture that I am missing but do we need to silence errors here? @ob_end_clean();// phpcs:ignore Generic.PHP.NoSilencedErrors.Discouraged -- Might be a bigger picture that I am missing but do we need to silence errors here? // If turning output-catching off, turn this on instead: // $caught_output = ''; @ob_end_flush(); // If there's higher-level output buffering going on, then get rid of that if (ob_get_level()) ob_end_clean(); if ($caught_output) { if (!isset($msg['data'])) $msg['data'] = null; $msg['data'] = array('caught_output' => $caught_output, 'previous_data' => $msg['data']); $already_rearranged_data = true; } if (!empty($this->php_events)) { if (!isset($msg['data'])) $msg['data'] = null; if (!empty($already_rearranged_data)) { $msg['data']['php_events'] = array(); } else { $msg['data'] = array('php_events' => array(), 'previous_data' => $msg['data']); } foreach ($this->php_events as $logline) { $msg['data']['php_events'][] = $logline; } } restore_error_handler(); return $msg; } } central/factory.php000064400000005363152214270100010355 0ustar00get_plugin_name()) // // N.B. You can add additional host plugins here. Just make sure that you will create // a host class for that particular plugin (see central/wp-optimize.php as an example). $mapped_classes = array( 'updraftplus' => 'UpdraftPlus_Host', 'wp-optimize' => 'WP_Optimize_Host', ); $path = $host_class = ''; foreach ($hosts as $plugin) { // Make sure that we have a registered host class with a valid file that exist $host_file = dirname(__FILE__).'/'.$plugin.'.php'; if (isset($mapped_classes[$plugin]) && file_exists($host_file)) { $path = $host_file; $host_class = $mapped_classes[$plugin]; break; } } // The host file was not found under this plugin thus, we let the other plugins // create or build the host plugin (global) variable instead. if (empty($path)) return null; if (!class_exists($host_class)) include_once($path); // Re-check host class once again just to make sure that we have the desired // class loaded before calling its instance method if (class_exists($host_class)) { return call_user_func(array($host_class, 'instance')); } return null; } } endif; global $updraftcentral_host_plugin; $updraftcentral_host_plugin = UpdraftCentral_Factory::create_host(); if ($updraftcentral_host_plugin) { $updraftcentral_host_plugin->load_updraftcentral(); } css/tether-shepherd/shepherd-theme-arrows-fix.css000064400000001160152214270100016132 0ustar00.shepherd-element-attached-bottom.shepherd-element-attached-right.shepherd-target-attached-top.shepherd-target-attached-left .shepherd-content:before, .shepherd-element-attached-bottom.shepherd-element-attached-left.shepherd-target-attached-top.shepherd-target-attached-right .shepherd-content:before, .shepherd-element-attached-top.shepherd-element-attached-right.shepherd-target-attached-bottom.shepherd-target-attached-left .shepherd-content:before, .shepherd-element-attached-top.shepherd-element-attached-left.shepherd-target-attached-bottom.shepherd-target-attached-right .shepherd-content:before { display: none; } css/tether-shepherd/shepherd-theme-arrows-plain-buttons.css000064400000030366152214270100020155 0ustar00.shepherd-element-attached-bottom.shepherd-element-attached-right.shepherd-target-attached-top.shepherd-target-attached-left .shepherd-content:before, .shepherd-element-attached-bottom.shepherd-element-attached-left.shepherd-target-attached-top.shepherd-target-attached-right .shepherd-content:before, .shepherd-element-attached-top.shepherd-element-attached-right.shepherd-target-attached-bottom.shepherd-target-attached-left .shepherd-content:before, .shepherd-element-attached-top.shepherd-element-attached-left.shepherd-target-attached-bottom.shepherd-target-attached-right .shepherd-content:before { display: none; } .shepherd-element, .shepherd-element:after, .shepherd-element:before, .shepherd-element *, .shepherd-element *:after, .shepherd-element *:before { box-sizing: border-box; } .shepherd-element { position: absolute; display: none; } .shepherd-element.shepherd-open { display: block; } .shepherd-element.shepherd-theme-arrows-plain-buttons { max-width: 100%; max-height: 100%; } .shepherd-element.shepherd-theme-arrows-plain-buttons .shepherd-content { border-radius: 5px; position: relative; font-family: inherit; background: #fff; color: #444; padding: 1em; font-size: 1.1em; line-height: 1.5em; -webkit-transform: translateZ(0); transform: translateZ(0); -webkit-filter: drop-shadow(0 1px 4px rgba(0, 0, 0, 0.2)); filter: drop-shadow(0 1px 4px rgba(0, 0, 0, 0.2)); } .shepherd-element.shepherd-theme-arrows-plain-buttons .shepherd-content:before { content: ""; display: block; position: absolute; width: 0; height: 0; border-color: transparent; border-width: 16px; border-style: solid; pointer-events: none; } .shepherd-element.shepherd-theme-arrows-plain-buttons.shepherd-element-attached-bottom.shepherd-element-attached-center .shepherd-content { margin-bottom: 16px; } .shepherd-element.shepherd-theme-arrows-plain-buttons.shepherd-element-attached-bottom.shepherd-element-attached-center .shepherd-content:before { top: 100%; left: 50%; margin-left: -16px; border-top-color: #fff; } .shepherd-element.shepherd-theme-arrows-plain-buttons.shepherd-element-attached-top.shepherd-element-attached-center .shepherd-content { margin-top: 16px; } .shepherd-element.shepherd-theme-arrows-plain-buttons.shepherd-element-attached-top.shepherd-element-attached-center .shepherd-content:before { bottom: 100%; left: 50%; margin-left: -16px; border-bottom-color: #fff; } .shepherd-element.shepherd-theme-arrows-plain-buttons.shepherd-element-attached-right.shepherd-element-attached-middle .shepherd-content { margin-right: 16px; } .shepherd-element.shepherd-theme-arrows-plain-buttons.shepherd-element-attached-right.shepherd-element-attached-middle .shepherd-content:before { left: 100%; top: 50%; margin-top: -16px; border-left-color: #fff; } .shepherd-element.shepherd-theme-arrows-plain-buttons.shepherd-element-attached-left.shepherd-element-attached-middle .shepherd-content { margin-left: 16px; } .shepherd-element.shepherd-theme-arrows-plain-buttons.shepherd-element-attached-left.shepherd-element-attached-middle .shepherd-content:before { right: 100%; top: 50%; margin-top: -16px; border-right-color: #fff; } .shepherd-element.shepherd-theme-arrows-plain-buttons.shepherd-element-attached-left.shepherd-target-attached-center .shepherd-content { left: -32px; } .shepherd-element.shepherd-theme-arrows-plain-buttons.shepherd-element-attached-right.shepherd-target-attached-center .shepherd-content { left: 32px; } .shepherd-element.shepherd-theme-arrows-plain-buttons.shepherd-element-attached-top.shepherd-element-attached-left.shepherd-target-attached-middle .shepherd-content { margin-top: 16px; } .shepherd-element.shepherd-theme-arrows-plain-buttons.shepherd-element-attached-top.shepherd-element-attached-left.shepherd-target-attached-middle .shepherd-content:before { bottom: 100%; left: 16px; border-bottom-color: #fff; } .shepherd-element.shepherd-theme-arrows-plain-buttons.shepherd-element-attached-top.shepherd-element-attached-right.shepherd-target-attached-middle .shepherd-content { margin-top: 16px; } .shepherd-element.shepherd-theme-arrows-plain-buttons.shepherd-element-attached-top.shepherd-element-attached-right.shepherd-target-attached-middle .shepherd-content:before { bottom: 100%; right: 16px; border-bottom-color: #fff; } .shepherd-element.shepherd-theme-arrows-plain-buttons.shepherd-element-attached-bottom.shepherd-element-attached-left.shepherd-target-attached-middle .shepherd-content { margin-bottom: 16px; } .shepherd-element.shepherd-theme-arrows-plain-buttons.shepherd-element-attached-bottom.shepherd-element-attached-left.shepherd-target-attached-middle .shepherd-content:before { top: 100%; left: 16px; border-top-color: #fff; } .shepherd-element.shepherd-theme-arrows-plain-buttons.shepherd-element-attached-bottom.shepherd-element-attached-right.shepherd-target-attached-middle .shepherd-content { margin-bottom: 16px; } .shepherd-element.shepherd-theme-arrows-plain-buttons.shepherd-element-attached-bottom.shepherd-element-attached-right.shepherd-target-attached-middle .shepherd-content:before { top: 100%; right: 16px; border-top-color: #fff; } .shepherd-element.shepherd-theme-arrows-plain-buttons.shepherd-element-attached-top.shepherd-element-attached-left.shepherd-target-attached-bottom .shepherd-content { margin-top: 16px; } .shepherd-element.shepherd-theme-arrows-plain-buttons.shepherd-element-attached-top.shepherd-element-attached-left.shepherd-target-attached-bottom .shepherd-content:before { bottom: 100%; left: 16px; border-bottom-color: #fff; } .shepherd-element.shepherd-theme-arrows-plain-buttons.shepherd-element-attached-top.shepherd-element-attached-right.shepherd-target-attached-bottom .shepherd-content { margin-top: 16px; } .shepherd-element.shepherd-theme-arrows-plain-buttons.shepherd-element-attached-top.shepherd-element-attached-right.shepherd-target-attached-bottom .shepherd-content:before { bottom: 100%; right: 16px; border-bottom-color: #fff; } .shepherd-element.shepherd-theme-arrows-plain-buttons.shepherd-element-attached-bottom.shepherd-element-attached-left.shepherd-target-attached-top .shepherd-content { margin-bottom: 16px; } .shepherd-element.shepherd-theme-arrows-plain-buttons.shepherd-element-attached-bottom.shepherd-element-attached-left.shepherd-target-attached-top .shepherd-content:before { top: 100%; left: 16px; border-top-color: #fff; } .shepherd-element.shepherd-theme-arrows-plain-buttons.shepherd-element-attached-bottom.shepherd-element-attached-right.shepherd-target-attached-top .shepherd-content { margin-bottom: 16px; } .shepherd-element.shepherd-theme-arrows-plain-buttons.shepherd-element-attached-bottom.shepherd-element-attached-right.shepherd-target-attached-top .shepherd-content:before { top: 100%; right: 16px; border-top-color: #fff; } .shepherd-element.shepherd-theme-arrows-plain-buttons.shepherd-element-attached-top.shepherd-element-attached-right.shepherd-target-attached-left .shepherd-content { margin-right: 16px; } .shepherd-element.shepherd-theme-arrows-plain-buttons.shepherd-element-attached-top.shepherd-element-attached-right.shepherd-target-attached-left .shepherd-content:before { top: 16px; left: 100%; border-left-color: #fff; } .shepherd-element.shepherd-theme-arrows-plain-buttons.shepherd-element-attached-top.shepherd-element-attached-left.shepherd-target-attached-right .shepherd-content { margin-left: 16px; } .shepherd-element.shepherd-theme-arrows-plain-buttons.shepherd-element-attached-top.shepherd-element-attached-left.shepherd-target-attached-right .shepherd-content:before { top: 16px; right: 100%; border-right-color: #fff; } .shepherd-element.shepherd-theme-arrows-plain-buttons.shepherd-element-attached-bottom.shepherd-element-attached-right.shepherd-target-attached-left .shepherd-content { margin-right: 16px; } .shepherd-element.shepherd-theme-arrows-plain-buttons.shepherd-element-attached-bottom.shepherd-element-attached-right.shepherd-target-attached-left .shepherd-content:before { bottom: 16px; left: 100%; border-left-color: #fff; } .shepherd-element.shepherd-theme-arrows-plain-buttons.shepherd-element-attached-bottom.shepherd-element-attached-left.shepherd-target-attached-right .shepherd-content { margin-left: 16px; } .shepherd-element.shepherd-theme-arrows-plain-buttons.shepherd-element-attached-bottom.shepherd-element-attached-left.shepherd-target-attached-right .shepherd-content:before { bottom: 16px; right: 100%; border-right-color: #fff; } .shepherd-element.shepherd-theme-arrows-plain-buttons.shepherd-element-attached-top.shepherd-element-attached-center.shepherd-has-title .shepherd-content:before, .shepherd-element.shepherd-theme-arrows-plain-buttons.shepherd-element-attached-top.shepherd-element-attached-right.shepherd-target-attached-bottom.shepherd-has-title .shepherd-content:before, .shepherd-element.shepherd-theme-arrows-plain-buttons.shepherd-element-attached-top.shepherd-element-attached-left.shepherd-target-attached-bottom.shepherd-has-title .shepherd-content:before { border-bottom-color: #eee; } .shepherd-element.shepherd-theme-arrows-plain-buttons.shepherd-has-title .shepherd-content header { background: #eee; padding: 1em; } .shepherd-element.shepherd-theme-arrows-plain-buttons.shepherd-has-title .shepherd-content header a.shepherd-cancel-link { padding: 0; margin-bottom: 0; } .shepherd-element.shepherd-theme-arrows-plain-buttons.shepherd-has-cancel-link .shepherd-content header h3 { float: left; } .shepherd-element.shepherd-theme-arrows-plain-buttons .shepherd-content { padding: 0; } .shepherd-element.shepherd-theme-arrows-plain-buttons .shepherd-content header { *zoom: 1; border-radius: 5px 5px 0 0; } .shepherd-element.shepherd-theme-arrows-plain-buttons .shepherd-content header:after { content: ""; display: table; clear: both; } .shepherd-element.shepherd-theme-arrows-plain-buttons .shepherd-content header h3 { margin: 0; line-height: 1; font-weight: normal; } .shepherd-element.shepherd-theme-arrows-plain-buttons .shepherd-content header a.shepherd-cancel-link { float: right; text-decoration: none; font-size: 1.25em; line-height: .8em; font-weight: normal; color: rgba(0, 0, 0, 0.5); opacity: 0.25; position: relative; top: .1em; padding: .8em; margin-bottom: -.8em; } .shepherd-element.shepherd-theme-arrows-plain-buttons .shepherd-content header a.shepherd-cancel-link:hover { opacity: 1; } .shepherd-element.shepherd-theme-arrows-plain-buttons .shepherd-content .shepherd-text { padding: 1em; } .shepherd-element.shepherd-theme-arrows-plain-buttons .shepherd-content .shepherd-text p { margin: 0 0 .5em 0; line-height: 1.3em; } .shepherd-element.shepherd-theme-arrows-plain-buttons .shepherd-content .shepherd-text p:last-child { margin-bottom: 0; } .shepherd-element.shepherd-theme-arrows-plain-buttons .shepherd-content footer { padding: 0 1em 1em; } .shepherd-element.shepherd-theme-arrows-plain-buttons .shepherd-content footer .shepherd-buttons { text-align: right; list-style: none; padding: 0; margin: 0; } .shepherd-element.shepherd-theme-arrows-plain-buttons .shepherd-content footer .shepherd-buttons li { display: inline; padding: 0; margin: 0; } .shepherd-element.shepherd-theme-arrows-plain-buttons .shepherd-content footer .shepherd-buttons li .shepherd-button { display: inline-block; vertical-align: middle; *vertical-align: auto; *zoom: 1; *display: inline; cursor: pointer; margin: 0 .5em 0 0; text-decoration: none; } .shepherd-element.shepherd-theme-arrows-plain-buttons .shepherd-content footer .shepherd-buttons li:last-child .shepherd-button { margin-right: 0; } css/tether-shepherd/shepherd-theme-square.min.css000064400000025314152214270100016122 0ustar00.shepherd-element-attached-bottom.shepherd-element-attached-right.shepherd-target-attached-top.shepherd-target-attached-left .shepherd-content:before,.shepherd-element-attached-bottom.shepherd-element-attached-left.shepherd-target-attached-top.shepherd-target-attached-right .shepherd-content:before,.shepherd-element-attached-top.shepherd-element-attached-right.shepherd-target-attached-bottom.shepherd-target-attached-left .shepherd-content:before,.shepherd-element-attached-top.shepherd-element-attached-left.shepherd-target-attached-bottom.shepherd-target-attached-right .shepherd-content:before{display:none}.shepherd-element,.shepherd-element:after,.shepherd-element:before,.shepherd-element *,.shepherd-element *:after,.shepherd-element *:before{box-sizing:border-box}.shepherd-element{position:absolute;display:none}.shepherd-element.shepherd-open{display:block}.shepherd-element.shepherd-theme-square{max-width:100%;max-height:100%}.shepherd-element.shepherd-theme-square .shepherd-content{border-radius:5px;position:relative;font-family:inherit;background:#f6f6f6;color:#444;padding:1em;font-size:1.1em;line-height:1.5em}.shepherd-element.shepherd-theme-square .shepherd-content:before{content:"";display:block;position:absolute;width:0;height:0;border-color:transparent;border-width:16px;border-style:solid;pointer-events:none}.shepherd-element.shepherd-theme-square.shepherd-element-attached-bottom.shepherd-element-attached-center .shepherd-content{margin-bottom:16px}.shepherd-element.shepherd-theme-square.shepherd-element-attached-bottom.shepherd-element-attached-center .shepherd-content:before{top:100%;left:50%;margin-left:-16px;border-top-color:#f6f6f6}.shepherd-element.shepherd-theme-square.shepherd-element-attached-top.shepherd-element-attached-center .shepherd-content{margin-top:16px}.shepherd-element.shepherd-theme-square.shepherd-element-attached-top.shepherd-element-attached-center .shepherd-content:before{bottom:100%;left:50%;margin-left:-16px;border-bottom-color:#f6f6f6}.shepherd-element.shepherd-theme-square.shepherd-element-attached-right.shepherd-element-attached-middle .shepherd-content{margin-right:16px}.shepherd-element.shepherd-theme-square.shepherd-element-attached-right.shepherd-element-attached-middle .shepherd-content:before{left:100%;top:50%;margin-top:-16px;border-left-color:#f6f6f6}.shepherd-element.shepherd-theme-square.shepherd-element-attached-left.shepherd-element-attached-middle .shepherd-content{margin-left:16px}.shepherd-element.shepherd-theme-square.shepherd-element-attached-left.shepherd-element-attached-middle .shepherd-content:before{right:100%;top:50%;margin-top:-16px;border-right-color:#f6f6f6}.shepherd-element.shepherd-theme-square.shepherd-element-attached-left.shepherd-target-attached-center .shepherd-content{left:-32px}.shepherd-element.shepherd-theme-square.shepherd-element-attached-right.shepherd-target-attached-center .shepherd-content{left:32px}.shepherd-element.shepherd-theme-square.shepherd-element-attached-top.shepherd-element-attached-left.shepherd-target-attached-middle .shepherd-content{margin-top:16px}.shepherd-element.shepherd-theme-square.shepherd-element-attached-top.shepherd-element-attached-left.shepherd-target-attached-middle .shepherd-content:before{bottom:100%;left:16px;border-bottom-color:#f6f6f6}.shepherd-element.shepherd-theme-square.shepherd-element-attached-top.shepherd-element-attached-right.shepherd-target-attached-middle .shepherd-content{margin-top:16px}.shepherd-element.shepherd-theme-square.shepherd-element-attached-top.shepherd-element-attached-right.shepherd-target-attached-middle .shepherd-content:before{bottom:100%;right:16px;border-bottom-color:#f6f6f6}.shepherd-element.shepherd-theme-square.shepherd-element-attached-bottom.shepherd-element-attached-left.shepherd-target-attached-middle .shepherd-content{margin-bottom:16px}.shepherd-element.shepherd-theme-square.shepherd-element-attached-bottom.shepherd-element-attached-left.shepherd-target-attached-middle .shepherd-content:before{top:100%;left:16px;border-top-color:#f6f6f6}.shepherd-element.shepherd-theme-square.shepherd-element-attached-bottom.shepherd-element-attached-right.shepherd-target-attached-middle .shepherd-content{margin-bottom:16px}.shepherd-element.shepherd-theme-square.shepherd-element-attached-bottom.shepherd-element-attached-right.shepherd-target-attached-middle .shepherd-content:before{top:100%;right:16px;border-top-color:#f6f6f6}.shepherd-element.shepherd-theme-square.shepherd-element-attached-top.shepherd-element-attached-left.shepherd-target-attached-bottom .shepherd-content{margin-top:16px}.shepherd-element.shepherd-theme-square.shepherd-element-attached-top.shepherd-element-attached-left.shepherd-target-attached-bottom .shepherd-content:before{bottom:100%;left:16px;border-bottom-color:#f6f6f6}.shepherd-element.shepherd-theme-square.shepherd-element-attached-top.shepherd-element-attached-right.shepherd-target-attached-bottom .shepherd-content{margin-top:16px}.shepherd-element.shepherd-theme-square.shepherd-element-attached-top.shepherd-element-attached-right.shepherd-target-attached-bottom .shepherd-content:before{bottom:100%;right:16px;border-bottom-color:#f6f6f6}.shepherd-element.shepherd-theme-square.shepherd-element-attached-bottom.shepherd-element-attached-left.shepherd-target-attached-top .shepherd-content{margin-bottom:16px}.shepherd-element.shepherd-theme-square.shepherd-element-attached-bottom.shepherd-element-attached-left.shepherd-target-attached-top .shepherd-content:before{top:100%;left:16px;border-top-color:#f6f6f6}.shepherd-element.shepherd-theme-square.shepherd-element-attached-bottom.shepherd-element-attached-right.shepherd-target-attached-top .shepherd-content{margin-bottom:16px}.shepherd-element.shepherd-theme-square.shepherd-element-attached-bottom.shepherd-element-attached-right.shepherd-target-attached-top .shepherd-content:before{top:100%;right:16px;border-top-color:#f6f6f6}.shepherd-element.shepherd-theme-square.shepherd-element-attached-top.shepherd-element-attached-right.shepherd-target-attached-left .shepherd-content{margin-right:16px}.shepherd-element.shepherd-theme-square.shepherd-element-attached-top.shepherd-element-attached-right.shepherd-target-attached-left .shepherd-content:before{top:16px;left:100%;border-left-color:#f6f6f6}.shepherd-element.shepherd-theme-square.shepherd-element-attached-top.shepherd-element-attached-left.shepherd-target-attached-right .shepherd-content{margin-left:16px}.shepherd-element.shepherd-theme-square.shepherd-element-attached-top.shepherd-element-attached-left.shepherd-target-attached-right .shepherd-content:before{top:16px;right:100%;border-right-color:#f6f6f6}.shepherd-element.shepherd-theme-square.shepherd-element-attached-bottom.shepherd-element-attached-right.shepherd-target-attached-left .shepherd-content{margin-right:16px}.shepherd-element.shepherd-theme-square.shepherd-element-attached-bottom.shepherd-element-attached-right.shepherd-target-attached-left .shepherd-content:before{bottom:16px;left:100%;border-left-color:#f6f6f6}.shepherd-element.shepherd-theme-square.shepherd-element-attached-bottom.shepherd-element-attached-left.shepherd-target-attached-right .shepherd-content{margin-left:16px}.shepherd-element.shepherd-theme-square.shepherd-element-attached-bottom.shepherd-element-attached-left.shepherd-target-attached-right .shepherd-content:before{bottom:16px;right:100%;border-right-color:#f6f6f6}.shepherd-element.shepherd-theme-square{border-radius:0;z-index:9999;max-width:24em;font-size:1em}.shepherd-element.shepherd-theme-square.shepherd-element-attached-top.shepherd-element-attached-center.shepherd-has-title .shepherd-content:before,.shepherd-element.shepherd-theme-square.shepherd-element-attached-top.shepherd-element-attached-right.shepherd-target-attached-bottom.shepherd-has-title .shepherd-content:before,.shepherd-element.shepherd-theme-square.shepherd-element-attached-top.shepherd-element-attached-left.shepherd-target-attached-bottom.shepherd-has-title .shepherd-content:before{border-bottom-color:#e6e6e6}.shepherd-element.shepherd-theme-square.shepherd-has-title .shepherd-content header{background:#e6e6e6;padding:1em}.shepherd-element.shepherd-theme-square.shepherd-has-title .shepherd-content header a.shepherd-cancel-link{padding:0;margin-bottom:0}.shepherd-element.shepherd-theme-square.shepherd-has-cancel-link .shepherd-content header h3{float:left}.shepherd-element.shepherd-theme-square .shepherd-content{box-shadow:0 0 0 1px rgba(0,0,0,0.17);border-radius:0;padding:0}.shepherd-element.shepherd-theme-square .shepherd-content *{font-size:inherit}.shepherd-element.shepherd-theme-square .shepherd-content header{*zoom:1;border-radius:0}.shepherd-element.shepherd-theme-square .shepherd-content header:after{content:"";display:table;clear:both}.shepherd-element.shepherd-theme-square .shepherd-content header h3{margin:0;line-height:1;font-weight:normal}.shepherd-element.shepherd-theme-square .shepherd-content header a.shepherd-cancel-link{float:right;text-decoration:none;font-size:1.25em;line-height:.8em;font-weight:normal;color:rgba(0,0,0,0.5);opacity:.25;position:relative;top:.1em;padding:.8em;margin-bottom:-.8em}.shepherd-element.shepherd-theme-square .shepherd-content header a.shepherd-cancel-link:hover{opacity:1}.shepherd-element.shepherd-theme-square .shepherd-content .shepherd-text{padding:1em}.shepherd-element.shepherd-theme-square .shepherd-content .shepherd-text p{margin:0 0 .5em 0;line-height:1.3em}.shepherd-element.shepherd-theme-square .shepherd-content .shepherd-text p:last-child{margin-bottom:0}.shepherd-element.shepherd-theme-square .shepherd-content footer{padding:0 1em 1em}.shepherd-element.shepherd-theme-square .shepherd-content footer .shepherd-buttons{text-align:right;list-style:none;padding:0;margin:0}.shepherd-element.shepherd-theme-square .shepherd-content footer .shepherd-buttons li{display:inline;padding:0;margin:0}.shepherd-element.shepherd-theme-square .shepherd-content footer .shepherd-buttons li .shepherd-button{display:inline-block;vertical-align:middle;*vertical-align:auto;*zoom:1;*display:inline;border-radius:0;cursor:pointer;border:0;margin:0 .5em 0 0;font-family:inherit;text-transform:uppercase;letter-spacing:.1em;font-size:.8em;line-height:1em;padding:.75em 2em;background:#3288e6;color:#fff}.shepherd-element.shepherd-theme-square .shepherd-content footer .shepherd-buttons li .shepherd-button.shepherd-button-secondary{background:#eee;color:#888}.shepherd-element.shepherd-theme-square .shepherd-content footer .shepherd-buttons li:last-child .shepherd-button{margin-right:0}.shepherd-start-tour-button.shepherd-theme-square{display:inline-block;vertical-align:middle;*vertical-align:auto;*zoom:1;*display:inline;border-radius:0;cursor:pointer;border:0;margin:0 .5em 0 0;font-family:inherit;text-transform:uppercase;letter-spacing:.1em;font-size:.8em;line-height:1em;padding:.75em 2em;background:#3288e6;color:#fff}css/tether-shepherd/shepherd-theme-default.min.css000064400000025367152214270100016256 0ustar00.shepherd-element-attached-bottom.shepherd-element-attached-right.shepherd-target-attached-top.shepherd-target-attached-left .shepherd-content:before,.shepherd-element-attached-bottom.shepherd-element-attached-left.shepherd-target-attached-top.shepherd-target-attached-right .shepherd-content:before,.shepherd-element-attached-top.shepherd-element-attached-right.shepherd-target-attached-bottom.shepherd-target-attached-left .shepherd-content:before,.shepherd-element-attached-top.shepherd-element-attached-left.shepherd-target-attached-bottom.shepherd-target-attached-right .shepherd-content:before{display:none}.shepherd-element,.shepherd-element:after,.shepherd-element:before,.shepherd-element *,.shepherd-element *:after,.shepherd-element *:before{box-sizing:border-box}.shepherd-element{position:absolute;display:none}.shepherd-element.shepherd-open{display:block}.shepherd-element.shepherd-theme-default{max-width:100%;max-height:100%}.shepherd-element.shepherd-theme-default .shepherd-content{border-radius:5px;position:relative;font-family:inherit;background:#f6f6f6;color:#444;padding:1em;font-size:1.1em;line-height:1.5em}.shepherd-element.shepherd-theme-default .shepherd-content:before{content:"";display:block;position:absolute;width:0;height:0;border-color:transparent;border-width:16px;border-style:solid;pointer-events:none}.shepherd-element.shepherd-theme-default.shepherd-element-attached-bottom.shepherd-element-attached-center .shepherd-content{margin-bottom:16px}.shepherd-element.shepherd-theme-default.shepherd-element-attached-bottom.shepherd-element-attached-center .shepherd-content:before{top:100%;left:50%;margin-left:-16px;border-top-color:#f6f6f6}.shepherd-element.shepherd-theme-default.shepherd-element-attached-top.shepherd-element-attached-center .shepherd-content{margin-top:16px}.shepherd-element.shepherd-theme-default.shepherd-element-attached-top.shepherd-element-attached-center .shepherd-content:before{bottom:100%;left:50%;margin-left:-16px;border-bottom-color:#f6f6f6}.shepherd-element.shepherd-theme-default.shepherd-element-attached-right.shepherd-element-attached-middle .shepherd-content{margin-right:16px}.shepherd-element.shepherd-theme-default.shepherd-element-attached-right.shepherd-element-attached-middle .shepherd-content:before{left:100%;top:50%;margin-top:-16px;border-left-color:#f6f6f6}.shepherd-element.shepherd-theme-default.shepherd-element-attached-left.shepherd-element-attached-middle .shepherd-content{margin-left:16px}.shepherd-element.shepherd-theme-default.shepherd-element-attached-left.shepherd-element-attached-middle .shepherd-content:before{right:100%;top:50%;margin-top:-16px;border-right-color:#f6f6f6}.shepherd-element.shepherd-theme-default.shepherd-element-attached-left.shepherd-target-attached-center .shepherd-content{left:-32px}.shepherd-element.shepherd-theme-default.shepherd-element-attached-right.shepherd-target-attached-center .shepherd-content{left:32px}.shepherd-element.shepherd-theme-default.shepherd-element-attached-top.shepherd-element-attached-left.shepherd-target-attached-middle .shepherd-content{margin-top:16px}.shepherd-element.shepherd-theme-default.shepherd-element-attached-top.shepherd-element-attached-left.shepherd-target-attached-middle .shepherd-content:before{bottom:100%;left:16px;border-bottom-color:#f6f6f6}.shepherd-element.shepherd-theme-default.shepherd-element-attached-top.shepherd-element-attached-right.shepherd-target-attached-middle .shepherd-content{margin-top:16px}.shepherd-element.shepherd-theme-default.shepherd-element-attached-top.shepherd-element-attached-right.shepherd-target-attached-middle .shepherd-content:before{bottom:100%;right:16px;border-bottom-color:#f6f6f6}.shepherd-element.shepherd-theme-default.shepherd-element-attached-bottom.shepherd-element-attached-left.shepherd-target-attached-middle .shepherd-content{margin-bottom:16px}.shepherd-element.shepherd-theme-default.shepherd-element-attached-bottom.shepherd-element-attached-left.shepherd-target-attached-middle .shepherd-content:before{top:100%;left:16px;border-top-color:#f6f6f6}.shepherd-element.shepherd-theme-default.shepherd-element-attached-bottom.shepherd-element-attached-right.shepherd-target-attached-middle .shepherd-content{margin-bottom:16px}.shepherd-element.shepherd-theme-default.shepherd-element-attached-bottom.shepherd-element-attached-right.shepherd-target-attached-middle .shepherd-content:before{top:100%;right:16px;border-top-color:#f6f6f6}.shepherd-element.shepherd-theme-default.shepherd-element-attached-top.shepherd-element-attached-left.shepherd-target-attached-bottom .shepherd-content{margin-top:16px}.shepherd-element.shepherd-theme-default.shepherd-element-attached-top.shepherd-element-attached-left.shepherd-target-attached-bottom .shepherd-content:before{bottom:100%;left:16px;border-bottom-color:#f6f6f6}.shepherd-element.shepherd-theme-default.shepherd-element-attached-top.shepherd-element-attached-right.shepherd-target-attached-bottom .shepherd-content{margin-top:16px}.shepherd-element.shepherd-theme-default.shepherd-element-attached-top.shepherd-element-attached-right.shepherd-target-attached-bottom .shepherd-content:before{bottom:100%;right:16px;border-bottom-color:#f6f6f6}.shepherd-element.shepherd-theme-default.shepherd-element-attached-bottom.shepherd-element-attached-left.shepherd-target-attached-top .shepherd-content{margin-bottom:16px}.shepherd-element.shepherd-theme-default.shepherd-element-attached-bottom.shepherd-element-attached-left.shepherd-target-attached-top .shepherd-content:before{top:100%;left:16px;border-top-color:#f6f6f6}.shepherd-element.shepherd-theme-default.shepherd-element-attached-bottom.shepherd-element-attached-right.shepherd-target-attached-top .shepherd-content{margin-bottom:16px}.shepherd-element.shepherd-theme-default.shepherd-element-attached-bottom.shepherd-element-attached-right.shepherd-target-attached-top .shepherd-content:before{top:100%;right:16px;border-top-color:#f6f6f6}.shepherd-element.shepherd-theme-default.shepherd-element-attached-top.shepherd-element-attached-right.shepherd-target-attached-left .shepherd-content{margin-right:16px}.shepherd-element.shepherd-theme-default.shepherd-element-attached-top.shepherd-element-attached-right.shepherd-target-attached-left .shepherd-content:before{top:16px;left:100%;border-left-color:#f6f6f6}.shepherd-element.shepherd-theme-default.shepherd-element-attached-top.shepherd-element-attached-left.shepherd-target-attached-right .shepherd-content{margin-left:16px}.shepherd-element.shepherd-theme-default.shepherd-element-attached-top.shepherd-element-attached-left.shepherd-target-attached-right .shepherd-content:before{top:16px;right:100%;border-right-color:#f6f6f6}.shepherd-element.shepherd-theme-default.shepherd-element-attached-bottom.shepherd-element-attached-right.shepherd-target-attached-left .shepherd-content{margin-right:16px}.shepherd-element.shepherd-theme-default.shepherd-element-attached-bottom.shepherd-element-attached-right.shepherd-target-attached-left .shepherd-content:before{bottom:16px;left:100%;border-left-color:#f6f6f6}.shepherd-element.shepherd-theme-default.shepherd-element-attached-bottom.shepherd-element-attached-left.shepherd-target-attached-right .shepherd-content{margin-left:16px}.shepherd-element.shepherd-theme-default.shepherd-element-attached-bottom.shepherd-element-attached-left.shepherd-target-attached-right .shepherd-content:before{bottom:16px;right:100%;border-right-color:#f6f6f6}.shepherd-element.shepherd-theme-default{z-index:9999;max-width:24em;font-size:1em}.shepherd-element.shepherd-theme-default.shepherd-element-attached-top.shepherd-element-attached-center.shepherd-has-title .shepherd-content:before,.shepherd-element.shepherd-theme-default.shepherd-element-attached-top.shepherd-element-attached-right.shepherd-target-attached-bottom.shepherd-has-title .shepherd-content:before,.shepherd-element.shepherd-theme-default.shepherd-element-attached-top.shepherd-element-attached-left.shepherd-target-attached-bottom.shepherd-has-title .shepherd-content:before{border-bottom-color:#e6e6e6}.shepherd-element.shepherd-theme-default.shepherd-has-title .shepherd-content header{background:#e6e6e6;padding:1em}.shepherd-element.shepherd-theme-default.shepherd-has-title .shepherd-content header a.shepherd-cancel-link{padding:0;margin-bottom:0}.shepherd-element.shepherd-theme-default.shepherd-has-cancel-link .shepherd-content header h3{float:left}.shepherd-element.shepherd-theme-default .shepherd-content{box-shadow:0 0 0 1px rgba(0,0,0,0.17);padding:0}.shepherd-element.shepherd-theme-default .shepherd-content *{font-size:inherit}.shepherd-element.shepherd-theme-default .shepherd-content header{*zoom:1;border-radius:5px 5px 0 0}.shepherd-element.shepherd-theme-default .shepherd-content header:after{content:"";display:table;clear:both}.shepherd-element.shepherd-theme-default .shepherd-content header h3{margin:0;line-height:1;font-weight:normal}.shepherd-element.shepherd-theme-default .shepherd-content header a.shepherd-cancel-link{float:right;text-decoration:none;font-size:1.25em;line-height:.8em;font-weight:normal;color:rgba(0,0,0,0.5);opacity:.25;position:relative;top:.1em;padding:.8em;margin-bottom:-.8em}.shepherd-element.shepherd-theme-default .shepherd-content header a.shepherd-cancel-link:hover{opacity:1}.shepherd-element.shepherd-theme-default .shepherd-content .shepherd-text{padding:1em}.shepherd-element.shepherd-theme-default .shepherd-content .shepherd-text p{margin:0 0 .5em 0;line-height:1.3em}.shepherd-element.shepherd-theme-default .shepherd-content .shepherd-text p:last-child{margin-bottom:0}.shepherd-element.shepherd-theme-default .shepherd-content footer{padding:0 1em 1em}.shepherd-element.shepherd-theme-default .shepherd-content footer .shepherd-buttons{text-align:right;list-style:none;padding:0;margin:0}.shepherd-element.shepherd-theme-default .shepherd-content footer .shepherd-buttons li{display:inline;padding:0;margin:0}.shepherd-element.shepherd-theme-default .shepherd-content footer .shepherd-buttons li .shepherd-button{display:inline-block;vertical-align:middle;*vertical-align:auto;*zoom:1;*display:inline;border-radius:3px;cursor:pointer;border:0;margin:0 .5em 0 0;font-family:inherit;text-transform:uppercase;letter-spacing:.1em;font-size:.8em;line-height:1em;padding:.75em 2em;background:#3288e6;color:#fff}.shepherd-element.shepherd-theme-default .shepherd-content footer .shepherd-buttons li .shepherd-button.shepherd-button-secondary{background:#eee;color:#888}.shepherd-element.shepherd-theme-default .shepherd-content footer .shepherd-buttons li:last-child .shepherd-button{margin-right:0}.shepherd-start-tour-button.shepherd-theme-default{display:inline-block;vertical-align:middle;*vertical-align:auto;*zoom:1;*display:inline;border-radius:3px;cursor:pointer;border:0;margin:0 .5em 0 0;font-family:inherit;text-transform:uppercase;letter-spacing:.1em;font-size:.8em;line-height:1em;padding:.75em 2em;background:#3288e6;color:#fff}css/tether-shepherd/shepherd-theme-square.css000064400000031122152214270100015332 0ustar00.shepherd-element-attached-bottom.shepherd-element-attached-right.shepherd-target-attached-top.shepherd-target-attached-left .shepherd-content:before, .shepherd-element-attached-bottom.shepherd-element-attached-left.shepherd-target-attached-top.shepherd-target-attached-right .shepherd-content:before, .shepherd-element-attached-top.shepherd-element-attached-right.shepherd-target-attached-bottom.shepherd-target-attached-left .shepherd-content:before, .shepherd-element-attached-top.shepherd-element-attached-left.shepherd-target-attached-bottom.shepherd-target-attached-right .shepherd-content:before { display: none; } .shepherd-element, .shepherd-element:after, .shepherd-element:before, .shepherd-element *, .shepherd-element *:after, .shepherd-element *:before { box-sizing: border-box; } .shepherd-element { position: absolute; display: none; } .shepherd-element.shepherd-open { display: block; } .shepherd-element.shepherd-theme-square { max-width: 100%; max-height: 100%; } .shepherd-element.shepherd-theme-square .shepherd-content { border-radius: 5px; position: relative; font-family: inherit; background: #f6f6f6; color: #444; padding: 1em; font-size: 1.1em; line-height: 1.5em; } .shepherd-element.shepherd-theme-square .shepherd-content:before { content: ""; display: block; position: absolute; width: 0; height: 0; border-color: transparent; border-width: 16px; border-style: solid; pointer-events: none; } .shepherd-element.shepherd-theme-square.shepherd-element-attached-bottom.shepherd-element-attached-center .shepherd-content { margin-bottom: 16px; } .shepherd-element.shepherd-theme-square.shepherd-element-attached-bottom.shepherd-element-attached-center .shepherd-content:before { top: 100%; left: 50%; margin-left: -16px; border-top-color: #f6f6f6; } .shepherd-element.shepherd-theme-square.shepherd-element-attached-top.shepherd-element-attached-center .shepherd-content { margin-top: 16px; } .shepherd-element.shepherd-theme-square.shepherd-element-attached-top.shepherd-element-attached-center .shepherd-content:before { bottom: 100%; left: 50%; margin-left: -16px; border-bottom-color: #f6f6f6; } .shepherd-element.shepherd-theme-square.shepherd-element-attached-right.shepherd-element-attached-middle .shepherd-content { margin-right: 16px; } .shepherd-element.shepherd-theme-square.shepherd-element-attached-right.shepherd-element-attached-middle .shepherd-content:before { left: 100%; top: 50%; margin-top: -16px; border-left-color: #f6f6f6; } .shepherd-element.shepherd-theme-square.shepherd-element-attached-left.shepherd-element-attached-middle .shepherd-content { margin-left: 16px; } .shepherd-element.shepherd-theme-square.shepherd-element-attached-left.shepherd-element-attached-middle .shepherd-content:before { right: 100%; top: 50%; margin-top: -16px; border-right-color: #f6f6f6; } .shepherd-element.shepherd-theme-square.shepherd-element-attached-left.shepherd-target-attached-center .shepherd-content { left: -32px; } .shepherd-element.shepherd-theme-square.shepherd-element-attached-right.shepherd-target-attached-center .shepherd-content { left: 32px; } .shepherd-element.shepherd-theme-square.shepherd-element-attached-top.shepherd-element-attached-left.shepherd-target-attached-middle .shepherd-content { margin-top: 16px; } .shepherd-element.shepherd-theme-square.shepherd-element-attached-top.shepherd-element-attached-left.shepherd-target-attached-middle .shepherd-content:before { bottom: 100%; left: 16px; border-bottom-color: #f6f6f6; } .shepherd-element.shepherd-theme-square.shepherd-element-attached-top.shepherd-element-attached-right.shepherd-target-attached-middle .shepherd-content { margin-top: 16px; } .shepherd-element.shepherd-theme-square.shepherd-element-attached-top.shepherd-element-attached-right.shepherd-target-attached-middle .shepherd-content:before { bottom: 100%; right: 16px; border-bottom-color: #f6f6f6; } .shepherd-element.shepherd-theme-square.shepherd-element-attached-bottom.shepherd-element-attached-left.shepherd-target-attached-middle .shepherd-content { margin-bottom: 16px; } .shepherd-element.shepherd-theme-square.shepherd-element-attached-bottom.shepherd-element-attached-left.shepherd-target-attached-middle .shepherd-content:before { top: 100%; left: 16px; border-top-color: #f6f6f6; } .shepherd-element.shepherd-theme-square.shepherd-element-attached-bottom.shepherd-element-attached-right.shepherd-target-attached-middle .shepherd-content { margin-bottom: 16px; } .shepherd-element.shepherd-theme-square.shepherd-element-attached-bottom.shepherd-element-attached-right.shepherd-target-attached-middle .shepherd-content:before { top: 100%; right: 16px; border-top-color: #f6f6f6; } .shepherd-element.shepherd-theme-square.shepherd-element-attached-top.shepherd-element-attached-left.shepherd-target-attached-bottom .shepherd-content { margin-top: 16px; } .shepherd-element.shepherd-theme-square.shepherd-element-attached-top.shepherd-element-attached-left.shepherd-target-attached-bottom .shepherd-content:before { bottom: 100%; left: 16px; border-bottom-color: #f6f6f6; } .shepherd-element.shepherd-theme-square.shepherd-element-attached-top.shepherd-element-attached-right.shepherd-target-attached-bottom .shepherd-content { margin-top: 16px; } .shepherd-element.shepherd-theme-square.shepherd-element-attached-top.shepherd-element-attached-right.shepherd-target-attached-bottom .shepherd-content:before { bottom: 100%; right: 16px; border-bottom-color: #f6f6f6; } .shepherd-element.shepherd-theme-square.shepherd-element-attached-bottom.shepherd-element-attached-left.shepherd-target-attached-top .shepherd-content { margin-bottom: 16px; } .shepherd-element.shepherd-theme-square.shepherd-element-attached-bottom.shepherd-element-attached-left.shepherd-target-attached-top .shepherd-content:before { top: 100%; left: 16px; border-top-color: #f6f6f6; } .shepherd-element.shepherd-theme-square.shepherd-element-attached-bottom.shepherd-element-attached-right.shepherd-target-attached-top .shepherd-content { margin-bottom: 16px; } .shepherd-element.shepherd-theme-square.shepherd-element-attached-bottom.shepherd-element-attached-right.shepherd-target-attached-top .shepherd-content:before { top: 100%; right: 16px; border-top-color: #f6f6f6; } .shepherd-element.shepherd-theme-square.shepherd-element-attached-top.shepherd-element-attached-right.shepherd-target-attached-left .shepherd-content { margin-right: 16px; } .shepherd-element.shepherd-theme-square.shepherd-element-attached-top.shepherd-element-attached-right.shepherd-target-attached-left .shepherd-content:before { top: 16px; left: 100%; border-left-color: #f6f6f6; } .shepherd-element.shepherd-theme-square.shepherd-element-attached-top.shepherd-element-attached-left.shepherd-target-attached-right .shepherd-content { margin-left: 16px; } .shepherd-element.shepherd-theme-square.shepherd-element-attached-top.shepherd-element-attached-left.shepherd-target-attached-right .shepherd-content:before { top: 16px; right: 100%; border-right-color: #f6f6f6; } .shepherd-element.shepherd-theme-square.shepherd-element-attached-bottom.shepherd-element-attached-right.shepherd-target-attached-left .shepherd-content { margin-right: 16px; } .shepherd-element.shepherd-theme-square.shepherd-element-attached-bottom.shepherd-element-attached-right.shepherd-target-attached-left .shepherd-content:before { bottom: 16px; left: 100%; border-left-color: #f6f6f6; } .shepherd-element.shepherd-theme-square.shepherd-element-attached-bottom.shepherd-element-attached-left.shepherd-target-attached-right .shepherd-content { margin-left: 16px; } .shepherd-element.shepherd-theme-square.shepherd-element-attached-bottom.shepherd-element-attached-left.shepherd-target-attached-right .shepherd-content:before { bottom: 16px; right: 100%; border-right-color: #f6f6f6; } .shepherd-element.shepherd-theme-square { border-radius: 0; z-index: 9999; max-width: 24em; font-size: 1em; } .shepherd-element.shepherd-theme-square.shepherd-element-attached-top.shepherd-element-attached-center.shepherd-has-title .shepherd-content:before, .shepherd-element.shepherd-theme-square.shepherd-element-attached-top.shepherd-element-attached-right.shepherd-target-attached-bottom.shepherd-has-title .shepherd-content:before, .shepherd-element.shepherd-theme-square.shepherd-element-attached-top.shepherd-element-attached-left.shepherd-target-attached-bottom.shepherd-has-title .shepherd-content:before { border-bottom-color: #e6e6e6; } .shepherd-element.shepherd-theme-square.shepherd-has-title .shepherd-content header { background: #e6e6e6; padding: 1em; } .shepherd-element.shepherd-theme-square.shepherd-has-title .shepherd-content header a.shepherd-cancel-link { padding: 0; margin-bottom: 0; } .shepherd-element.shepherd-theme-square.shepherd-has-cancel-link .shepherd-content header h3 { float: left; } .shepherd-element.shepherd-theme-square .shepherd-content { box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.17); border-radius: 0; padding: 0; } .shepherd-element.shepherd-theme-square .shepherd-content * { font-size: inherit; } .shepherd-element.shepherd-theme-square .shepherd-content header { *zoom: 1; border-radius: 0; } .shepherd-element.shepherd-theme-square .shepherd-content header:after { content: ""; display: table; clear: both; } .shepherd-element.shepherd-theme-square .shepherd-content header h3 { margin: 0; line-height: 1; font-weight: normal; } .shepherd-element.shepherd-theme-square .shepherd-content header a.shepherd-cancel-link { float: right; text-decoration: none; font-size: 1.25em; line-height: .8em; font-weight: normal; color: rgba(0, 0, 0, 0.5); opacity: 0.25; position: relative; top: .1em; padding: .8em; margin-bottom: -.8em; } .shepherd-element.shepherd-theme-square .shepherd-content header a.shepherd-cancel-link:hover { opacity: 1; } .shepherd-element.shepherd-theme-square .shepherd-content .shepherd-text { padding: 1em; } .shepherd-element.shepherd-theme-square .shepherd-content .shepherd-text p { margin: 0 0 .5em 0; line-height: 1.3em; } .shepherd-element.shepherd-theme-square .shepherd-content .shepherd-text p:last-child { margin-bottom: 0; } .shepherd-element.shepherd-theme-square .shepherd-content footer { padding: 0 1em 1em; } .shepherd-element.shepherd-theme-square .shepherd-content footer .shepherd-buttons { text-align: right; list-style: none; padding: 0; margin: 0; } .shepherd-element.shepherd-theme-square .shepherd-content footer .shepherd-buttons li { display: inline; padding: 0; margin: 0; } .shepherd-element.shepherd-theme-square .shepherd-content footer .shepherd-buttons li .shepherd-button { display: inline-block; vertical-align: middle; *vertical-align: auto; *zoom: 1; *display: inline; border-radius: 0; cursor: pointer; border: 0; margin: 0 .5em 0 0; font-family: inherit; text-transform: uppercase; letter-spacing: .1em; font-size: .8em; line-height: 1em; padding: .75em 2em; background: #3288e6; color: #fff; } .shepherd-element.shepherd-theme-square .shepherd-content footer .shepherd-buttons li .shepherd-button.shepherd-button-secondary { background: #eee; color: #888; } .shepherd-element.shepherd-theme-square .shepherd-content footer .shepherd-buttons li:last-child .shepherd-button { margin-right: 0; } .shepherd-start-tour-button.shepherd-theme-square { display: inline-block; vertical-align: middle; *vertical-align: auto; *zoom: 1; *display: inline; border-radius: 0; cursor: pointer; border: 0; margin: 0 .5em 0 0; font-family: inherit; text-transform: uppercase; letter-spacing: .1em; font-size: .8em; line-height: 1em; padding: .75em 2em; background: #3288e6; color: #fff; } css/tether-shepherd/shepherd-theme-square-dark.min.css000064400000025775152214270100017054 0ustar00.shepherd-element-attached-bottom.shepherd-element-attached-right.shepherd-target-attached-top.shepherd-target-attached-left .shepherd-content:before,.shepherd-element-attached-bottom.shepherd-element-attached-left.shepherd-target-attached-top.shepherd-target-attached-right .shepherd-content:before,.shepherd-element-attached-top.shepherd-element-attached-right.shepherd-target-attached-bottom.shepherd-target-attached-left .shepherd-content:before,.shepherd-element-attached-top.shepherd-element-attached-left.shepherd-target-attached-bottom.shepherd-target-attached-right .shepherd-content:before{display:none}.shepherd-element,.shepherd-element:after,.shepherd-element:before,.shepherd-element *,.shepherd-element *:after,.shepherd-element *:before{box-sizing:border-box}.shepherd-element{position:absolute;display:none}.shepherd-element.shepherd-open{display:block}.shepherd-element.shepherd-theme-square-dark{max-width:100%;max-height:100%}.shepherd-element.shepherd-theme-square-dark .shepherd-content{border-radius:5px;position:relative;font-family:inherit;background:#232323;color:#eee;padding:1em;font-size:1.1em;line-height:1.5em}.shepherd-element.shepherd-theme-square-dark .shepherd-content:before{content:"";display:block;position:absolute;width:0;height:0;border-color:transparent;border-width:16px;border-style:solid;pointer-events:none}.shepherd-element.shepherd-theme-square-dark.shepherd-element-attached-bottom.shepherd-element-attached-center .shepherd-content{margin-bottom:16px}.shepherd-element.shepherd-theme-square-dark.shepherd-element-attached-bottom.shepherd-element-attached-center .shepherd-content:before{top:100%;left:50%;margin-left:-16px;border-top-color:#232323}.shepherd-element.shepherd-theme-square-dark.shepherd-element-attached-top.shepherd-element-attached-center .shepherd-content{margin-top:16px}.shepherd-element.shepherd-theme-square-dark.shepherd-element-attached-top.shepherd-element-attached-center .shepherd-content:before{bottom:100%;left:50%;margin-left:-16px;border-bottom-color:#232323}.shepherd-element.shepherd-theme-square-dark.shepherd-element-attached-right.shepherd-element-attached-middle .shepherd-content{margin-right:16px}.shepherd-element.shepherd-theme-square-dark.shepherd-element-attached-right.shepherd-element-attached-middle .shepherd-content:before{left:100%;top:50%;margin-top:-16px;border-left-color:#232323}.shepherd-element.shepherd-theme-square-dark.shepherd-element-attached-left.shepherd-element-attached-middle .shepherd-content{margin-left:16px}.shepherd-element.shepherd-theme-square-dark.shepherd-element-attached-left.shepherd-element-attached-middle .shepherd-content:before{right:100%;top:50%;margin-top:-16px;border-right-color:#232323}.shepherd-element.shepherd-theme-square-dark.shepherd-element-attached-left.shepherd-target-attached-center .shepherd-content{left:-32px}.shepherd-element.shepherd-theme-square-dark.shepherd-element-attached-right.shepherd-target-attached-center .shepherd-content{left:32px}.shepherd-element.shepherd-theme-square-dark.shepherd-element-attached-top.shepherd-element-attached-left.shepherd-target-attached-middle .shepherd-content{margin-top:16px}.shepherd-element.shepherd-theme-square-dark.shepherd-element-attached-top.shepherd-element-attached-left.shepherd-target-attached-middle .shepherd-content:before{bottom:100%;left:16px;border-bottom-color:#232323}.shepherd-element.shepherd-theme-square-dark.shepherd-element-attached-top.shepherd-element-attached-right.shepherd-target-attached-middle .shepherd-content{margin-top:16px}.shepherd-element.shepherd-theme-square-dark.shepherd-element-attached-top.shepherd-element-attached-right.shepherd-target-attached-middle .shepherd-content:before{bottom:100%;right:16px;border-bottom-color:#232323}.shepherd-element.shepherd-theme-square-dark.shepherd-element-attached-bottom.shepherd-element-attached-left.shepherd-target-attached-middle .shepherd-content{margin-bottom:16px}.shepherd-element.shepherd-theme-square-dark.shepherd-element-attached-bottom.shepherd-element-attached-left.shepherd-target-attached-middle .shepherd-content:before{top:100%;left:16px;border-top-color:#232323}.shepherd-element.shepherd-theme-square-dark.shepherd-element-attached-bottom.shepherd-element-attached-right.shepherd-target-attached-middle .shepherd-content{margin-bottom:16px}.shepherd-element.shepherd-theme-square-dark.shepherd-element-attached-bottom.shepherd-element-attached-right.shepherd-target-attached-middle .shepherd-content:before{top:100%;right:16px;border-top-color:#232323}.shepherd-element.shepherd-theme-square-dark.shepherd-element-attached-top.shepherd-element-attached-left.shepherd-target-attached-bottom .shepherd-content{margin-top:16px}.shepherd-element.shepherd-theme-square-dark.shepherd-element-attached-top.shepherd-element-attached-left.shepherd-target-attached-bottom .shepherd-content:before{bottom:100%;left:16px;border-bottom-color:#232323}.shepherd-element.shepherd-theme-square-dark.shepherd-element-attached-top.shepherd-element-attached-right.shepherd-target-attached-bottom .shepherd-content{margin-top:16px}.shepherd-element.shepherd-theme-square-dark.shepherd-element-attached-top.shepherd-element-attached-right.shepherd-target-attached-bottom .shepherd-content:before{bottom:100%;right:16px;border-bottom-color:#232323}.shepherd-element.shepherd-theme-square-dark.shepherd-element-attached-bottom.shepherd-element-attached-left.shepherd-target-attached-top .shepherd-content{margin-bottom:16px}.shepherd-element.shepherd-theme-square-dark.shepherd-element-attached-bottom.shepherd-element-attached-left.shepherd-target-attached-top .shepherd-content:before{top:100%;left:16px;border-top-color:#232323}.shepherd-element.shepherd-theme-square-dark.shepherd-element-attached-bottom.shepherd-element-attached-right.shepherd-target-attached-top .shepherd-content{margin-bottom:16px}.shepherd-element.shepherd-theme-square-dark.shepherd-element-attached-bottom.shepherd-element-attached-right.shepherd-target-attached-top .shepherd-content:before{top:100%;right:16px;border-top-color:#232323}.shepherd-element.shepherd-theme-square-dark.shepherd-element-attached-top.shepherd-element-attached-right.shepherd-target-attached-left .shepherd-content{margin-right:16px}.shepherd-element.shepherd-theme-square-dark.shepherd-element-attached-top.shepherd-element-attached-right.shepherd-target-attached-left .shepherd-content:before{top:16px;left:100%;border-left-color:#232323}.shepherd-element.shepherd-theme-square-dark.shepherd-element-attached-top.shepherd-element-attached-left.shepherd-target-attached-right .shepherd-content{margin-left:16px}.shepherd-element.shepherd-theme-square-dark.shepherd-element-attached-top.shepherd-element-attached-left.shepherd-target-attached-right .shepherd-content:before{top:16px;right:100%;border-right-color:#232323}.shepherd-element.shepherd-theme-square-dark.shepherd-element-attached-bottom.shepherd-element-attached-right.shepherd-target-attached-left .shepherd-content{margin-right:16px}.shepherd-element.shepherd-theme-square-dark.shepherd-element-attached-bottom.shepherd-element-attached-right.shepherd-target-attached-left .shepherd-content:before{bottom:16px;left:100%;border-left-color:#232323}.shepherd-element.shepherd-theme-square-dark.shepherd-element-attached-bottom.shepherd-element-attached-left.shepherd-target-attached-right .shepherd-content{margin-left:16px}.shepherd-element.shepherd-theme-square-dark.shepherd-element-attached-bottom.shepherd-element-attached-left.shepherd-target-attached-right .shepherd-content:before{bottom:16px;right:100%;border-right-color:#232323}.shepherd-element.shepherd-theme-square-dark{border-radius:0;z-index:9999;max-width:24em;font-size:1em}.shepherd-element.shepherd-theme-square-dark.shepherd-element-attached-top.shepherd-element-attached-center.shepherd-has-title .shepherd-content:before,.shepherd-element.shepherd-theme-square-dark.shepherd-element-attached-top.shepherd-element-attached-right.shepherd-target-attached-bottom.shepherd-has-title .shepherd-content:before,.shepherd-element.shepherd-theme-square-dark.shepherd-element-attached-top.shepherd-element-attached-left.shepherd-target-attached-bottom.shepherd-has-title .shepherd-content:before{border-bottom-color:#303030}.shepherd-element.shepherd-theme-square-dark.shepherd-has-title .shepherd-content header{background:#303030;padding:1em}.shepherd-element.shepherd-theme-square-dark.shepherd-has-title .shepherd-content header a.shepherd-cancel-link{padding:0;margin-bottom:0}.shepherd-element.shepherd-theme-square-dark.shepherd-has-cancel-link .shepherd-content header h3{float:left}.shepherd-element.shepherd-theme-square-dark .shepherd-content{box-shadow:0 0 0 1px rgba(0,0,0,0.17);border-radius:0;padding:0}.shepherd-element.shepherd-theme-square-dark .shepherd-content *{font-size:inherit}.shepherd-element.shepherd-theme-square-dark .shepherd-content header{*zoom:1;border-radius:0}.shepherd-element.shepherd-theme-square-dark .shepherd-content header:after{content:"";display:table;clear:both}.shepherd-element.shepherd-theme-square-dark .shepherd-content header h3{margin:0;line-height:1;font-weight:normal}.shepherd-element.shepherd-theme-square-dark .shepherd-content header a.shepherd-cancel-link{float:right;text-decoration:none;font-size:1.25em;line-height:.8em;font-weight:normal;color:rgba(0,0,0,0.5);opacity:.25;position:relative;top:.1em;padding:.8em;margin-bottom:-.8em}.shepherd-element.shepherd-theme-square-dark .shepherd-content header a.shepherd-cancel-link:hover{opacity:1}.shepherd-element.shepherd-theme-square-dark .shepherd-content .shepherd-text{padding:1em}.shepherd-element.shepherd-theme-square-dark .shepherd-content .shepherd-text p{margin:0 0 .5em 0;line-height:1.3em}.shepherd-element.shepherd-theme-square-dark .shepherd-content .shepherd-text p:last-child{margin-bottom:0}.shepherd-element.shepherd-theme-square-dark .shepherd-content footer{padding:0 1em 1em}.shepherd-element.shepherd-theme-square-dark .shepherd-content footer .shepherd-buttons{text-align:right;list-style:none;padding:0;margin:0}.shepherd-element.shepherd-theme-square-dark .shepherd-content footer .shepherd-buttons li{display:inline;padding:0;margin:0}.shepherd-element.shepherd-theme-square-dark .shepherd-content footer .shepherd-buttons li .shepherd-button{display:inline-block;vertical-align:middle;*vertical-align:auto;*zoom:1;*display:inline;border-radius:0;cursor:pointer;border:0;margin:0 .5em 0 0;font-family:inherit;text-transform:uppercase;letter-spacing:.1em;font-size:.8em;line-height:1em;padding:.75em 2em;background:#3288e6;color:#fff}.shepherd-element.shepherd-theme-square-dark .shepherd-content footer .shepherd-buttons li .shepherd-button.shepherd-button-secondary{background:#eee;color:#888}.shepherd-element.shepherd-theme-square-dark .shepherd-content footer .shepherd-buttons li:last-child .shepherd-button{margin-right:0}.shepherd-start-tour-button.shepherd-theme-square-dark{display:inline-block;vertical-align:middle;*vertical-align:auto;*zoom:1;*display:inline;border-radius:0;cursor:pointer;border:0;margin:0 .5em 0 0;font-family:inherit;text-transform:uppercase;letter-spacing:.1em;font-size:.8em;line-height:1em;padding:.75em 2em;background:#3288e6;color:#fff}css/tether-shepherd/shepherd-theme-default.css000064400000031163152214270100015463 0ustar00.shepherd-element-attached-bottom.shepherd-element-attached-right.shepherd-target-attached-top.shepherd-target-attached-left .shepherd-content:before, .shepherd-element-attached-bottom.shepherd-element-attached-left.shepherd-target-attached-top.shepherd-target-attached-right .shepherd-content:before, .shepherd-element-attached-top.shepherd-element-attached-right.shepherd-target-attached-bottom.shepherd-target-attached-left .shepherd-content:before, .shepherd-element-attached-top.shepherd-element-attached-left.shepherd-target-attached-bottom.shepherd-target-attached-right .shepherd-content:before { display: none; } .shepherd-element, .shepherd-element:after, .shepherd-element:before, .shepherd-element *, .shepherd-element *:after, .shepherd-element *:before { box-sizing: border-box; } .shepherd-element { position: absolute; display: none; } .shepherd-element.shepherd-open { display: block; } .shepherd-element.shepherd-theme-default { max-width: 100%; max-height: 100%; } .shepherd-element.shepherd-theme-default .shepherd-content { border-radius: 5px; position: relative; font-family: inherit; background: #f6f6f6; color: #444; padding: 1em; font-size: 1.1em; line-height: 1.5em; } .shepherd-element.shepherd-theme-default .shepherd-content:before { content: ""; display: block; position: absolute; width: 0; height: 0; border-color: transparent; border-width: 16px; border-style: solid; pointer-events: none; } .shepherd-element.shepherd-theme-default.shepherd-element-attached-bottom.shepherd-element-attached-center .shepherd-content { margin-bottom: 16px; } .shepherd-element.shepherd-theme-default.shepherd-element-attached-bottom.shepherd-element-attached-center .shepherd-content:before { top: 100%; left: 50%; margin-left: -16px; border-top-color: #f6f6f6; } .shepherd-element.shepherd-theme-default.shepherd-element-attached-top.shepherd-element-attached-center .shepherd-content { margin-top: 16px; } .shepherd-element.shepherd-theme-default.shepherd-element-attached-top.shepherd-element-attached-center .shepherd-content:before { bottom: 100%; left: 50%; margin-left: -16px; border-bottom-color: #f6f6f6; } .shepherd-element.shepherd-theme-default.shepherd-element-attached-right.shepherd-element-attached-middle .shepherd-content { margin-right: 16px; } .shepherd-element.shepherd-theme-default.shepherd-element-attached-right.shepherd-element-attached-middle .shepherd-content:before { left: 100%; top: 50%; margin-top: -16px; border-left-color: #f6f6f6; } .shepherd-element.shepherd-theme-default.shepherd-element-attached-left.shepherd-element-attached-middle .shepherd-content { margin-left: 16px; } .shepherd-element.shepherd-theme-default.shepherd-element-attached-left.shepherd-element-attached-middle .shepherd-content:before { right: 100%; top: 50%; margin-top: -16px; border-right-color: #f6f6f6; } .shepherd-element.shepherd-theme-default.shepherd-element-attached-left.shepherd-target-attached-center .shepherd-content { left: -32px; } .shepherd-element.shepherd-theme-default.shepherd-element-attached-right.shepherd-target-attached-center .shepherd-content { left: 32px; } .shepherd-element.shepherd-theme-default.shepherd-element-attached-top.shepherd-element-attached-left.shepherd-target-attached-middle .shepherd-content { margin-top: 16px; } .shepherd-element.shepherd-theme-default.shepherd-element-attached-top.shepherd-element-attached-left.shepherd-target-attached-middle .shepherd-content:before { bottom: 100%; left: 16px; border-bottom-color: #f6f6f6; } .shepherd-element.shepherd-theme-default.shepherd-element-attached-top.shepherd-element-attached-right.shepherd-target-attached-middle .shepherd-content { margin-top: 16px; } .shepherd-element.shepherd-theme-default.shepherd-element-attached-top.shepherd-element-attached-right.shepherd-target-attached-middle .shepherd-content:before { bottom: 100%; right: 16px; border-bottom-color: #f6f6f6; } .shepherd-element.shepherd-theme-default.shepherd-element-attached-bottom.shepherd-element-attached-left.shepherd-target-attached-middle .shepherd-content { margin-bottom: 16px; } .shepherd-element.shepherd-theme-default.shepherd-element-attached-bottom.shepherd-element-attached-left.shepherd-target-attached-middle .shepherd-content:before { top: 100%; left: 16px; border-top-color: #f6f6f6; } .shepherd-element.shepherd-theme-default.shepherd-element-attached-bottom.shepherd-element-attached-right.shepherd-target-attached-middle .shepherd-content { margin-bottom: 16px; } .shepherd-element.shepherd-theme-default.shepherd-element-attached-bottom.shepherd-element-attached-right.shepherd-target-attached-middle .shepherd-content:before { top: 100%; right: 16px; border-top-color: #f6f6f6; } .shepherd-element.shepherd-theme-default.shepherd-element-attached-top.shepherd-element-attached-left.shepherd-target-attached-bottom .shepherd-content { margin-top: 16px; } .shepherd-element.shepherd-theme-default.shepherd-element-attached-top.shepherd-element-attached-left.shepherd-target-attached-bottom .shepherd-content:before { bottom: 100%; left: 16px; border-bottom-color: #f6f6f6; } .shepherd-element.shepherd-theme-default.shepherd-element-attached-top.shepherd-element-attached-right.shepherd-target-attached-bottom .shepherd-content { margin-top: 16px; } .shepherd-element.shepherd-theme-default.shepherd-element-attached-top.shepherd-element-attached-right.shepherd-target-attached-bottom .shepherd-content:before { bottom: 100%; right: 16px; border-bottom-color: #f6f6f6; } .shepherd-element.shepherd-theme-default.shepherd-element-attached-bottom.shepherd-element-attached-left.shepherd-target-attached-top .shepherd-content { margin-bottom: 16px; } .shepherd-element.shepherd-theme-default.shepherd-element-attached-bottom.shepherd-element-attached-left.shepherd-target-attached-top .shepherd-content:before { top: 100%; left: 16px; border-top-color: #f6f6f6; } .shepherd-element.shepherd-theme-default.shepherd-element-attached-bottom.shepherd-element-attached-right.shepherd-target-attached-top .shepherd-content { margin-bottom: 16px; } .shepherd-element.shepherd-theme-default.shepherd-element-attached-bottom.shepherd-element-attached-right.shepherd-target-attached-top .shepherd-content:before { top: 100%; right: 16px; border-top-color: #f6f6f6; } .shepherd-element.shepherd-theme-default.shepherd-element-attached-top.shepherd-element-attached-right.shepherd-target-attached-left .shepherd-content { margin-right: 16px; } .shepherd-element.shepherd-theme-default.shepherd-element-attached-top.shepherd-element-attached-right.shepherd-target-attached-left .shepherd-content:before { top: 16px; left: 100%; border-left-color: #f6f6f6; } .shepherd-element.shepherd-theme-default.shepherd-element-attached-top.shepherd-element-attached-left.shepherd-target-attached-right .shepherd-content { margin-left: 16px; } .shepherd-element.shepherd-theme-default.shepherd-element-attached-top.shepherd-element-attached-left.shepherd-target-attached-right .shepherd-content:before { top: 16px; right: 100%; border-right-color: #f6f6f6; } .shepherd-element.shepherd-theme-default.shepherd-element-attached-bottom.shepherd-element-attached-right.shepherd-target-attached-left .shepherd-content { margin-right: 16px; } .shepherd-element.shepherd-theme-default.shepherd-element-attached-bottom.shepherd-element-attached-right.shepherd-target-attached-left .shepherd-content:before { bottom: 16px; left: 100%; border-left-color: #f6f6f6; } .shepherd-element.shepherd-theme-default.shepherd-element-attached-bottom.shepherd-element-attached-left.shepherd-target-attached-right .shepherd-content { margin-left: 16px; } .shepherd-element.shepherd-theme-default.shepherd-element-attached-bottom.shepherd-element-attached-left.shepherd-target-attached-right .shepherd-content:before { bottom: 16px; right: 100%; border-right-color: #f6f6f6; } .shepherd-element.shepherd-theme-default { z-index: 9999; max-width: 24em; font-size: 1em; } .shepherd-element.shepherd-theme-default.shepherd-element-attached-top.shepherd-element-attached-center.shepherd-has-title .shepherd-content:before, .shepherd-element.shepherd-theme-default.shepherd-element-attached-top.shepherd-element-attached-right.shepherd-target-attached-bottom.shepherd-has-title .shepherd-content:before, .shepherd-element.shepherd-theme-default.shepherd-element-attached-top.shepherd-element-attached-left.shepherd-target-attached-bottom.shepherd-has-title .shepherd-content:before { border-bottom-color: #e6e6e6; } .shepherd-element.shepherd-theme-default.shepherd-has-title .shepherd-content header { background: #e6e6e6; padding: 1em; } .shepherd-element.shepherd-theme-default.shepherd-has-title .shepherd-content header a.shepherd-cancel-link { padding: 0; margin-bottom: 0; } .shepherd-element.shepherd-theme-default.shepherd-has-cancel-link .shepherd-content header h3 { float: left; } .shepherd-element.shepherd-theme-default .shepherd-content { box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.17); padding: 0; } .shepherd-element.shepherd-theme-default .shepherd-content * { font-size: inherit; } .shepherd-element.shepherd-theme-default .shepherd-content header { *zoom: 1; border-radius: 5px 5px 0 0; } .shepherd-element.shepherd-theme-default .shepherd-content header:after { content: ""; display: table; clear: both; } .shepherd-element.shepherd-theme-default .shepherd-content header h3 { margin: 0; line-height: 1; font-weight: normal; } .shepherd-element.shepherd-theme-default .shepherd-content header a.shepherd-cancel-link { float: right; text-decoration: none; font-size: 1.25em; line-height: .8em; font-weight: normal; color: rgba(0, 0, 0, 0.5); opacity: 0.25; position: relative; top: .1em; padding: .8em; margin-bottom: -.8em; } .shepherd-element.shepherd-theme-default .shepherd-content header a.shepherd-cancel-link:hover { opacity: 1; } .shepherd-element.shepherd-theme-default .shepherd-content .shepherd-text { padding: 1em; } .shepherd-element.shepherd-theme-default .shepherd-content .shepherd-text p { margin: 0 0 .5em 0; line-height: 1.3em; } .shepherd-element.shepherd-theme-default .shepherd-content .shepherd-text p:last-child { margin-bottom: 0; } .shepherd-element.shepherd-theme-default .shepherd-content footer { padding: 0 1em 1em; } .shepherd-element.shepherd-theme-default .shepherd-content footer .shepherd-buttons { text-align: right; list-style: none; padding: 0; margin: 0; } .shepherd-element.shepherd-theme-default .shepherd-content footer .shepherd-buttons li { display: inline; padding: 0; margin: 0; } .shepherd-element.shepherd-theme-default .shepherd-content footer .shepherd-buttons li .shepherd-button { display: inline-block; vertical-align: middle; *vertical-align: auto; *zoom: 1; *display: inline; border-radius: 3px; cursor: pointer; border: 0; margin: 0 .5em 0 0; font-family: inherit; text-transform: uppercase; letter-spacing: .1em; font-size: .8em; line-height: 1em; padding: .75em 2em; background: #3288e6; color: #fff; } .shepherd-element.shepherd-theme-default .shepherd-content footer .shepherd-buttons li .shepherd-button.shepherd-button-secondary { background: #eee; color: #888; } .shepherd-element.shepherd-theme-default .shepherd-content footer .shepherd-buttons li:last-child .shepherd-button { margin-right: 0; } .shepherd-start-tour-button.shepherd-theme-default { display: inline-block; vertical-align: middle; *vertical-align: auto; *zoom: 1; *display: inline; border-radius: 3px; cursor: pointer; border: 0; margin: 0 .5em 0 0; font-family: inherit; text-transform: uppercase; letter-spacing: .1em; font-size: .8em; line-height: 1em; padding: .75em 2em; background: #3288e6; color: #fff; } css/tether-shepherd/shepherd-theme-square-dark.css000064400000031603152214270100016255 0ustar00.shepherd-element-attached-bottom.shepherd-element-attached-right.shepherd-target-attached-top.shepherd-target-attached-left .shepherd-content:before, .shepherd-element-attached-bottom.shepherd-element-attached-left.shepherd-target-attached-top.shepherd-target-attached-right .shepherd-content:before, .shepherd-element-attached-top.shepherd-element-attached-right.shepherd-target-attached-bottom.shepherd-target-attached-left .shepherd-content:before, .shepherd-element-attached-top.shepherd-element-attached-left.shepherd-target-attached-bottom.shepherd-target-attached-right .shepherd-content:before { display: none; } .shepherd-element, .shepherd-element:after, .shepherd-element:before, .shepherd-element *, .shepherd-element *:after, .shepherd-element *:before { box-sizing: border-box; } .shepherd-element { position: absolute; display: none; } .shepherd-element.shepherd-open { display: block; } .shepherd-element.shepherd-theme-square-dark { max-width: 100%; max-height: 100%; } .shepherd-element.shepherd-theme-square-dark .shepherd-content { border-radius: 5px; position: relative; font-family: inherit; background: #232323; color: #eee; padding: 1em; font-size: 1.1em; line-height: 1.5em; } .shepherd-element.shepherd-theme-square-dark .shepherd-content:before { content: ""; display: block; position: absolute; width: 0; height: 0; border-color: transparent; border-width: 16px; border-style: solid; pointer-events: none; } .shepherd-element.shepherd-theme-square-dark.shepherd-element-attached-bottom.shepherd-element-attached-center .shepherd-content { margin-bottom: 16px; } .shepherd-element.shepherd-theme-square-dark.shepherd-element-attached-bottom.shepherd-element-attached-center .shepherd-content:before { top: 100%; left: 50%; margin-left: -16px; border-top-color: #232323; } .shepherd-element.shepherd-theme-square-dark.shepherd-element-attached-top.shepherd-element-attached-center .shepherd-content { margin-top: 16px; } .shepherd-element.shepherd-theme-square-dark.shepherd-element-attached-top.shepherd-element-attached-center .shepherd-content:before { bottom: 100%; left: 50%; margin-left: -16px; border-bottom-color: #232323; } .shepherd-element.shepherd-theme-square-dark.shepherd-element-attached-right.shepherd-element-attached-middle .shepherd-content { margin-right: 16px; } .shepherd-element.shepherd-theme-square-dark.shepherd-element-attached-right.shepherd-element-attached-middle .shepherd-content:before { left: 100%; top: 50%; margin-top: -16px; border-left-color: #232323; } .shepherd-element.shepherd-theme-square-dark.shepherd-element-attached-left.shepherd-element-attached-middle .shepherd-content { margin-left: 16px; } .shepherd-element.shepherd-theme-square-dark.shepherd-element-attached-left.shepherd-element-attached-middle .shepherd-content:before { right: 100%; top: 50%; margin-top: -16px; border-right-color: #232323; } .shepherd-element.shepherd-theme-square-dark.shepherd-element-attached-left.shepherd-target-attached-center .shepherd-content { left: -32px; } .shepherd-element.shepherd-theme-square-dark.shepherd-element-attached-right.shepherd-target-attached-center .shepherd-content { left: 32px; } .shepherd-element.shepherd-theme-square-dark.shepherd-element-attached-top.shepherd-element-attached-left.shepherd-target-attached-middle .shepherd-content { margin-top: 16px; } .shepherd-element.shepherd-theme-square-dark.shepherd-element-attached-top.shepherd-element-attached-left.shepherd-target-attached-middle .shepherd-content:before { bottom: 100%; left: 16px; border-bottom-color: #232323; } .shepherd-element.shepherd-theme-square-dark.shepherd-element-attached-top.shepherd-element-attached-right.shepherd-target-attached-middle .shepherd-content { margin-top: 16px; } .shepherd-element.shepherd-theme-square-dark.shepherd-element-attached-top.shepherd-element-attached-right.shepherd-target-attached-middle .shepherd-content:before { bottom: 100%; right: 16px; border-bottom-color: #232323; } .shepherd-element.shepherd-theme-square-dark.shepherd-element-attached-bottom.shepherd-element-attached-left.shepherd-target-attached-middle .shepherd-content { margin-bottom: 16px; } .shepherd-element.shepherd-theme-square-dark.shepherd-element-attached-bottom.shepherd-element-attached-left.shepherd-target-attached-middle .shepherd-content:before { top: 100%; left: 16px; border-top-color: #232323; } .shepherd-element.shepherd-theme-square-dark.shepherd-element-attached-bottom.shepherd-element-attached-right.shepherd-target-attached-middle .shepherd-content { margin-bottom: 16px; } .shepherd-element.shepherd-theme-square-dark.shepherd-element-attached-bottom.shepherd-element-attached-right.shepherd-target-attached-middle .shepherd-content:before { top: 100%; right: 16px; border-top-color: #232323; } .shepherd-element.shepherd-theme-square-dark.shepherd-element-attached-top.shepherd-element-attached-left.shepherd-target-attached-bottom .shepherd-content { margin-top: 16px; } .shepherd-element.shepherd-theme-square-dark.shepherd-element-attached-top.shepherd-element-attached-left.shepherd-target-attached-bottom .shepherd-content:before { bottom: 100%; left: 16px; border-bottom-color: #232323; } .shepherd-element.shepherd-theme-square-dark.shepherd-element-attached-top.shepherd-element-attached-right.shepherd-target-attached-bottom .shepherd-content { margin-top: 16px; } .shepherd-element.shepherd-theme-square-dark.shepherd-element-attached-top.shepherd-element-attached-right.shepherd-target-attached-bottom .shepherd-content:before { bottom: 100%; right: 16px; border-bottom-color: #232323; } .shepherd-element.shepherd-theme-square-dark.shepherd-element-attached-bottom.shepherd-element-attached-left.shepherd-target-attached-top .shepherd-content { margin-bottom: 16px; } .shepherd-element.shepherd-theme-square-dark.shepherd-element-attached-bottom.shepherd-element-attached-left.shepherd-target-attached-top .shepherd-content:before { top: 100%; left: 16px; border-top-color: #232323; } .shepherd-element.shepherd-theme-square-dark.shepherd-element-attached-bottom.shepherd-element-attached-right.shepherd-target-attached-top .shepherd-content { margin-bottom: 16px; } .shepherd-element.shepherd-theme-square-dark.shepherd-element-attached-bottom.shepherd-element-attached-right.shepherd-target-attached-top .shepherd-content:before { top: 100%; right: 16px; border-top-color: #232323; } .shepherd-element.shepherd-theme-square-dark.shepherd-element-attached-top.shepherd-element-attached-right.shepherd-target-attached-left .shepherd-content { margin-right: 16px; } .shepherd-element.shepherd-theme-square-dark.shepherd-element-attached-top.shepherd-element-attached-right.shepherd-target-attached-left .shepherd-content:before { top: 16px; left: 100%; border-left-color: #232323; } .shepherd-element.shepherd-theme-square-dark.shepherd-element-attached-top.shepherd-element-attached-left.shepherd-target-attached-right .shepherd-content { margin-left: 16px; } .shepherd-element.shepherd-theme-square-dark.shepherd-element-attached-top.shepherd-element-attached-left.shepherd-target-attached-right .shepherd-content:before { top: 16px; right: 100%; border-right-color: #232323; } .shepherd-element.shepherd-theme-square-dark.shepherd-element-attached-bottom.shepherd-element-attached-right.shepherd-target-attached-left .shepherd-content { margin-right: 16px; } .shepherd-element.shepherd-theme-square-dark.shepherd-element-attached-bottom.shepherd-element-attached-right.shepherd-target-attached-left .shepherd-content:before { bottom: 16px; left: 100%; border-left-color: #232323; } .shepherd-element.shepherd-theme-square-dark.shepherd-element-attached-bottom.shepherd-element-attached-left.shepherd-target-attached-right .shepherd-content { margin-left: 16px; } .shepherd-element.shepherd-theme-square-dark.shepherd-element-attached-bottom.shepherd-element-attached-left.shepherd-target-attached-right .shepherd-content:before { bottom: 16px; right: 100%; border-right-color: #232323; } .shepherd-element.shepherd-theme-square-dark { border-radius: 0; z-index: 9999; max-width: 24em; font-size: 1em; } .shepherd-element.shepherd-theme-square-dark.shepherd-element-attached-top.shepherd-element-attached-center.shepherd-has-title .shepherd-content:before, .shepherd-element.shepherd-theme-square-dark.shepherd-element-attached-top.shepherd-element-attached-right.shepherd-target-attached-bottom.shepherd-has-title .shepherd-content:before, .shepherd-element.shepherd-theme-square-dark.shepherd-element-attached-top.shepherd-element-attached-left.shepherd-target-attached-bottom.shepherd-has-title .shepherd-content:before { border-bottom-color: #303030; } .shepherd-element.shepherd-theme-square-dark.shepherd-has-title .shepherd-content header { background: #303030; padding: 1em; } .shepherd-element.shepherd-theme-square-dark.shepherd-has-title .shepherd-content header a.shepherd-cancel-link { padding: 0; margin-bottom: 0; } .shepherd-element.shepherd-theme-square-dark.shepherd-has-cancel-link .shepherd-content header h3 { float: left; } .shepherd-element.shepherd-theme-square-dark .shepherd-content { box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.17); border-radius: 0; padding: 0; } .shepherd-element.shepherd-theme-square-dark .shepherd-content * { font-size: inherit; } .shepherd-element.shepherd-theme-square-dark .shepherd-content header { *zoom: 1; border-radius: 0; } .shepherd-element.shepherd-theme-square-dark .shepherd-content header:after { content: ""; display: table; clear: both; } .shepherd-element.shepherd-theme-square-dark .shepherd-content header h3 { margin: 0; line-height: 1; font-weight: normal; } .shepherd-element.shepherd-theme-square-dark .shepherd-content header a.shepherd-cancel-link { float: right; text-decoration: none; font-size: 1.25em; line-height: .8em; font-weight: normal; color: rgba(0, 0, 0, 0.5); opacity: 0.25; position: relative; top: .1em; padding: .8em; margin-bottom: -.8em; } .shepherd-element.shepherd-theme-square-dark .shepherd-content header a.shepherd-cancel-link:hover { opacity: 1; } .shepherd-element.shepherd-theme-square-dark .shepherd-content .shepherd-text { padding: 1em; } .shepherd-element.shepherd-theme-square-dark .shepherd-content .shepherd-text p { margin: 0 0 .5em 0; line-height: 1.3em; } .shepherd-element.shepherd-theme-square-dark .shepherd-content .shepherd-text p:last-child { margin-bottom: 0; } .shepherd-element.shepherd-theme-square-dark .shepherd-content footer { padding: 0 1em 1em; } .shepherd-element.shepherd-theme-square-dark .shepherd-content footer .shepherd-buttons { text-align: right; list-style: none; padding: 0; margin: 0; } .shepherd-element.shepherd-theme-square-dark .shepherd-content footer .shepherd-buttons li { display: inline; padding: 0; margin: 0; } .shepherd-element.shepherd-theme-square-dark .shepherd-content footer .shepherd-buttons li .shepherd-button { display: inline-block; vertical-align: middle; *vertical-align: auto; *zoom: 1; *display: inline; border-radius: 0; cursor: pointer; border: 0; margin: 0 .5em 0 0; font-family: inherit; text-transform: uppercase; letter-spacing: .1em; font-size: .8em; line-height: 1em; padding: .75em 2em; background: #3288e6; color: #fff; } .shepherd-element.shepherd-theme-square-dark .shepherd-content footer .shepherd-buttons li .shepherd-button.shepherd-button-secondary { background: #eee; color: #888; } .shepherd-element.shepherd-theme-square-dark .shepherd-content footer .shepherd-buttons li:last-child .shepherd-button { margin-right: 0; } .shepherd-start-tour-button.shepherd-theme-square-dark { display: inline-block; vertical-align: middle; *vertical-align: auto; *zoom: 1; *display: inline; border-radius: 0; cursor: pointer; border: 0; margin: 0 .5em 0 0; font-family: inherit; text-transform: uppercase; letter-spacing: .1em; font-size: .8em; line-height: 1em; padding: .75em 2em; background: #3288e6; color: #fff; } css/tether-shepherd/shepherd-theme-arrows.css000064400000027772152214270100015367 0ustar00.shepherd-element-attached-bottom.shepherd-element-attached-right.shepherd-target-attached-top.shepherd-target-attached-left .shepherd-content:before, .shepherd-element-attached-bottom.shepherd-element-attached-left.shepherd-target-attached-top.shepherd-target-attached-right .shepherd-content:before, .shepherd-element-attached-top.shepherd-element-attached-right.shepherd-target-attached-bottom.shepherd-target-attached-left .shepherd-content:before, .shepherd-element-attached-top.shepherd-element-attached-left.shepherd-target-attached-bottom.shepherd-target-attached-right .shepherd-content:before { display: none; } .shepherd-element, .shepherd-element:after, .shepherd-element:before, .shepherd-element *, .shepherd-element *:after, .shepherd-element *:before { box-sizing: border-box; } .shepherd-element { position: absolute; display: none; } .shepherd-element.shepherd-open { display: block; } .shepherd-element.shepherd-theme-arrows { max-width: 100%; max-height: 100%; } .shepherd-element.shepherd-theme-arrows .shepherd-content { border-radius: 5px; position: relative; font-family: inherit; background: #fff; color: #444; padding: 1em; font-size: 1.1em; line-height: 1.5em; -webkit-transform: translateZ(0); transform: translateZ(0); -webkit-filter: drop-shadow(0 1px 4px rgba(0, 0, 0, 0.2)); filter: drop-shadow(0 1px 4px rgba(0, 0, 0, 0.2)); } .shepherd-element.shepherd-theme-arrows .shepherd-content:before { content: ""; display: block; position: absolute; width: 0; height: 0; border-color: transparent; border-width: 16px; border-style: solid; pointer-events: none; } .shepherd-element.shepherd-theme-arrows.shepherd-element-attached-bottom.shepherd-element-attached-center .shepherd-content { margin-bottom: 16px; } .shepherd-element.shepherd-theme-arrows.shepherd-element-attached-bottom.shepherd-element-attached-center .shepherd-content:before { top: 100%; left: 50%; margin-left: -16px; border-top-color: #fff; } .shepherd-element.shepherd-theme-arrows.shepherd-element-attached-top.shepherd-element-attached-center .shepherd-content { margin-top: 16px; } .shepherd-element.shepherd-theme-arrows.shepherd-element-attached-top.shepherd-element-attached-center .shepherd-content:before { bottom: 100%; left: 50%; margin-left: -16px; border-bottom-color: #fff; } .shepherd-element.shepherd-theme-arrows.shepherd-element-attached-right.shepherd-element-attached-middle .shepherd-content { margin-right: 16px; } .shepherd-element.shepherd-theme-arrows.shepherd-element-attached-right.shepherd-element-attached-middle .shepherd-content:before { left: 100%; top: 50%; margin-top: -16px; border-left-color: #fff; } .shepherd-element.shepherd-theme-arrows.shepherd-element-attached-left.shepherd-element-attached-middle .shepherd-content { margin-left: 16px; } .shepherd-element.shepherd-theme-arrows.shepherd-element-attached-left.shepherd-element-attached-middle .shepherd-content:before { right: 100%; top: 50%; margin-top: -16px; border-right-color: #fff; } .shepherd-element.shepherd-theme-arrows.shepherd-element-attached-left.shepherd-target-attached-center .shepherd-content { left: -32px; } .shepherd-element.shepherd-theme-arrows.shepherd-element-attached-right.shepherd-target-attached-center .shepherd-content { left: 32px; } .shepherd-element.shepherd-theme-arrows.shepherd-element-attached-top.shepherd-element-attached-left.shepherd-target-attached-middle .shepherd-content { margin-top: 16px; } .shepherd-element.shepherd-theme-arrows.shepherd-element-attached-top.shepherd-element-attached-left.shepherd-target-attached-middle .shepherd-content:before { bottom: 100%; left: 16px; border-bottom-color: #fff; } .shepherd-element.shepherd-theme-arrows.shepherd-element-attached-top.shepherd-element-attached-right.shepherd-target-attached-middle .shepherd-content { margin-top: 16px; } .shepherd-element.shepherd-theme-arrows.shepherd-element-attached-top.shepherd-element-attached-right.shepherd-target-attached-middle .shepherd-content:before { bottom: 100%; right: 16px; border-bottom-color: #fff; } .shepherd-element.shepherd-theme-arrows.shepherd-element-attached-bottom.shepherd-element-attached-left.shepherd-target-attached-middle .shepherd-content { margin-bottom: 16px; } .shepherd-element.shepherd-theme-arrows.shepherd-element-attached-bottom.shepherd-element-attached-left.shepherd-target-attached-middle .shepherd-content:before { top: 100%; left: 16px; border-top-color: #fff; } .shepherd-element.shepherd-theme-arrows.shepherd-element-attached-bottom.shepherd-element-attached-right.shepherd-target-attached-middle .shepherd-content { margin-bottom: 16px; } .shepherd-element.shepherd-theme-arrows.shepherd-element-attached-bottom.shepherd-element-attached-right.shepherd-target-attached-middle .shepherd-content:before { top: 100%; right: 16px; border-top-color: #fff; } .shepherd-element.shepherd-theme-arrows.shepherd-element-attached-top.shepherd-element-attached-left.shepherd-target-attached-bottom .shepherd-content { margin-top: 16px; } .shepherd-element.shepherd-theme-arrows.shepherd-element-attached-top.shepherd-element-attached-left.shepherd-target-attached-bottom .shepherd-content:before { bottom: 100%; left: 16px; border-bottom-color: #fff; } .shepherd-element.shepherd-theme-arrows.shepherd-element-attached-top.shepherd-element-attached-right.shepherd-target-attached-bottom .shepherd-content { margin-top: 16px; } .shepherd-element.shepherd-theme-arrows.shepherd-element-attached-top.shepherd-element-attached-right.shepherd-target-attached-bottom .shepherd-content:before { bottom: 100%; right: 16px; border-bottom-color: #fff; } .shepherd-element.shepherd-theme-arrows.shepherd-element-attached-bottom.shepherd-element-attached-left.shepherd-target-attached-top .shepherd-content { margin-bottom: 16px; } .shepherd-element.shepherd-theme-arrows.shepherd-element-attached-bottom.shepherd-element-attached-left.shepherd-target-attached-top .shepherd-content:before { top: 100%; left: 16px; border-top-color: #fff; } .shepherd-element.shepherd-theme-arrows.shepherd-element-attached-bottom.shepherd-element-attached-right.shepherd-target-attached-top .shepherd-content { margin-bottom: 16px; } .shepherd-element.shepherd-theme-arrows.shepherd-element-attached-bottom.shepherd-element-attached-right.shepherd-target-attached-top .shepherd-content:before { top: 100%; right: 16px; border-top-color: #fff; } .shepherd-element.shepherd-theme-arrows.shepherd-element-attached-top.shepherd-element-attached-right.shepherd-target-attached-left .shepherd-content { margin-right: 16px; } .shepherd-element.shepherd-theme-arrows.shepherd-element-attached-top.shepherd-element-attached-right.shepherd-target-attached-left .shepherd-content:before { top: 16px; left: 100%; border-left-color: #fff; } .shepherd-element.shepherd-theme-arrows.shepherd-element-attached-top.shepherd-element-attached-left.shepherd-target-attached-right .shepherd-content { margin-left: 16px; } .shepherd-element.shepherd-theme-arrows.shepherd-element-attached-top.shepherd-element-attached-left.shepherd-target-attached-right .shepherd-content:before { top: 16px; right: 100%; border-right-color: #fff; } .shepherd-element.shepherd-theme-arrows.shepherd-element-attached-bottom.shepherd-element-attached-right.shepherd-target-attached-left .shepherd-content { margin-right: 16px; } .shepherd-element.shepherd-theme-arrows.shepherd-element-attached-bottom.shepherd-element-attached-right.shepherd-target-attached-left .shepherd-content:before { bottom: 16px; left: 100%; border-left-color: #fff; } .shepherd-element.shepherd-theme-arrows.shepherd-element-attached-bottom.shepherd-element-attached-left.shepherd-target-attached-right .shepherd-content { margin-left: 16px; } .shepherd-element.shepherd-theme-arrows.shepherd-element-attached-bottom.shepherd-element-attached-left.shepherd-target-attached-right .shepherd-content:before { bottom: 16px; right: 100%; border-right-color: #fff; } .shepherd-element.shepherd-theme-arrows.shepherd-element-attached-top.shepherd-element-attached-center.shepherd-has-title .shepherd-content:before, .shepherd-element.shepherd-theme-arrows.shepherd-element-attached-top.shepherd-element-attached-right.shepherd-target-attached-bottom.shepherd-has-title .shepherd-content:before, .shepherd-element.shepherd-theme-arrows.shepherd-element-attached-top.shepherd-element-attached-left.shepherd-target-attached-bottom.shepherd-has-title .shepherd-content:before { border-bottom-color: #eee; } .shepherd-element.shepherd-theme-arrows.shepherd-has-title .shepherd-content header { background: #eee; padding: 1em; } .shepherd-element.shepherd-theme-arrows.shepherd-has-title .shepherd-content header a.shepherd-cancel-link { padding: 0; margin-bottom: 0; } .shepherd-element.shepherd-theme-arrows.shepherd-has-cancel-link .shepherd-content header h3 { float: left; } .shepherd-element.shepherd-theme-arrows .shepherd-content { padding: 0; } .shepherd-element.shepherd-theme-arrows .shepherd-content * { font-size: inherit; } .shepherd-element.shepherd-theme-arrows .shepherd-content header { *zoom: 1; border-radius: 5px 5px 0 0; } .shepherd-element.shepherd-theme-arrows .shepherd-content header:after { content: ""; display: table; clear: both; } .shepherd-element.shepherd-theme-arrows .shepherd-content header h3 { margin: 0; line-height: 1; font-weight: normal; } .shepherd-element.shepherd-theme-arrows .shepherd-content header a.shepherd-cancel-link { float: right; text-decoration: none; font-size: 1.25em; line-height: .8em; font-weight: normal; color: rgba(0, 0, 0, 0.5); opacity: 0.25; position: relative; top: .1em; padding: .8em; margin-bottom: -.8em; } .shepherd-element.shepherd-theme-arrows .shepherd-content header a.shepherd-cancel-link:hover { opacity: 1; } .shepherd-element.shepherd-theme-arrows .shepherd-content .shepherd-text { padding: 1em; } .shepherd-element.shepherd-theme-arrows .shepherd-content .shepherd-text p { margin: 0 0 .5em 0; line-height: 1.3em; } .shepherd-element.shepherd-theme-arrows .shepherd-content .shepherd-text p:last-child { margin-bottom: 0; } .shepherd-element.shepherd-theme-arrows .shepherd-content footer { padding: 0 1em 1em; } .shepherd-element.shepherd-theme-arrows .shepherd-content footer .shepherd-buttons { text-align: right; list-style: none; padding: 0; margin: 0; } .shepherd-element.shepherd-theme-arrows .shepherd-content footer .shepherd-buttons li { display: inline; padding: 0; margin: 0; } .shepherd-element.shepherd-theme-arrows .shepherd-content footer .shepherd-buttons li .shepherd-button { display: inline-block; vertical-align: middle; *vertical-align: auto; *zoom: 1; *display: inline; border-radius: 3px; cursor: pointer; border: 0; margin: 0 .5em 0 0; font-family: inherit; text-transform: uppercase; letter-spacing: .1em; font-size: .8em; line-height: 1em; padding: .75em 2em; background: #3288e6; color: #fff; } .shepherd-element.shepherd-theme-arrows .shepherd-content footer .shepherd-buttons li .shepherd-button.shepherd-button-secondary { background: #eee; color: #888; } .shepherd-element.shepherd-theme-arrows .shepherd-content footer .shepherd-buttons li:last-child .shepherd-button { margin-right: 0; } css/tether-shepherd/shepherd-theme-arrows.min.css000064400000024517152214270100016143 0ustar00.shepherd-element-attached-bottom.shepherd-element-attached-right.shepherd-target-attached-top.shepherd-target-attached-left .shepherd-content:before,.shepherd-element-attached-bottom.shepherd-element-attached-left.shepherd-target-attached-top.shepherd-target-attached-right .shepherd-content:before,.shepherd-element-attached-top.shepherd-element-attached-right.shepherd-target-attached-bottom.shepherd-target-attached-left .shepherd-content:before,.shepherd-element-attached-top.shepherd-element-attached-left.shepherd-target-attached-bottom.shepherd-target-attached-right .shepherd-content:before{display:none}.shepherd-element,.shepherd-element:after,.shepherd-element:before,.shepherd-element *,.shepherd-element *:after,.shepherd-element *:before{box-sizing:border-box}.shepherd-element{position:absolute;display:none}.shepherd-element.shepherd-open{display:block}.shepherd-element.shepherd-theme-arrows{max-width:100%;max-height:100%}.shepherd-element.shepherd-theme-arrows .shepherd-content{border-radius:5px;position:relative;font-family:inherit;background:#fff;color:#444;padding:1em;font-size:1.1em;line-height:1.5em;-webkit-transform:translateZ(0);transform:translateZ(0);-webkit-filter:drop-shadow(0 1px 4px rgba(0,0,0,0.2));filter:drop-shadow(0 1px 4px rgba(0,0,0,0.2))}.shepherd-element.shepherd-theme-arrows .shepherd-content:before{content:"";display:block;position:absolute;width:0;height:0;border-color:transparent;border-width:16px;border-style:solid;pointer-events:none}.shepherd-element.shepherd-theme-arrows.shepherd-element-attached-bottom.shepherd-element-attached-center .shepherd-content{margin-bottom:16px}.shepherd-element.shepherd-theme-arrows.shepherd-element-attached-bottom.shepherd-element-attached-center .shepherd-content:before{top:100%;left:50%;margin-left:-16px;border-top-color:#fff}.shepherd-element.shepherd-theme-arrows.shepherd-element-attached-top.shepherd-element-attached-center .shepherd-content{margin-top:16px}.shepherd-element.shepherd-theme-arrows.shepherd-element-attached-top.shepherd-element-attached-center .shepherd-content:before{bottom:100%;left:50%;margin-left:-16px;border-bottom-color:#fff}.shepherd-element.shepherd-theme-arrows.shepherd-element-attached-right.shepherd-element-attached-middle .shepherd-content{margin-right:16px}.shepherd-element.shepherd-theme-arrows.shepherd-element-attached-right.shepherd-element-attached-middle .shepherd-content:before{left:100%;top:50%;margin-top:-16px;border-left-color:#fff}.shepherd-element.shepherd-theme-arrows.shepherd-element-attached-left.shepherd-element-attached-middle .shepherd-content{margin-left:16px}.shepherd-element.shepherd-theme-arrows.shepherd-element-attached-left.shepherd-element-attached-middle .shepherd-content:before{right:100%;top:50%;margin-top:-16px;border-right-color:#fff}.shepherd-element.shepherd-theme-arrows.shepherd-element-attached-left.shepherd-target-attached-center .shepherd-content{left:-32px}.shepherd-element.shepherd-theme-arrows.shepherd-element-attached-right.shepherd-target-attached-center .shepherd-content{left:32px}.shepherd-element.shepherd-theme-arrows.shepherd-element-attached-top.shepherd-element-attached-left.shepherd-target-attached-middle .shepherd-content{margin-top:16px}.shepherd-element.shepherd-theme-arrows.shepherd-element-attached-top.shepherd-element-attached-left.shepherd-target-attached-middle .shepherd-content:before{bottom:100%;left:16px;border-bottom-color:#fff}.shepherd-element.shepherd-theme-arrows.shepherd-element-attached-top.shepherd-element-attached-right.shepherd-target-attached-middle .shepherd-content{margin-top:16px}.shepherd-element.shepherd-theme-arrows.shepherd-element-attached-top.shepherd-element-attached-right.shepherd-target-attached-middle .shepherd-content:before{bottom:100%;right:16px;border-bottom-color:#fff}.shepherd-element.shepherd-theme-arrows.shepherd-element-attached-bottom.shepherd-element-attached-left.shepherd-target-attached-middle .shepherd-content{margin-bottom:16px}.shepherd-element.shepherd-theme-arrows.shepherd-element-attached-bottom.shepherd-element-attached-left.shepherd-target-attached-middle .shepherd-content:before{top:100%;left:16px;border-top-color:#fff}.shepherd-element.shepherd-theme-arrows.shepherd-element-attached-bottom.shepherd-element-attached-right.shepherd-target-attached-middle .shepherd-content{margin-bottom:16px}.shepherd-element.shepherd-theme-arrows.shepherd-element-attached-bottom.shepherd-element-attached-right.shepherd-target-attached-middle .shepherd-content:before{top:100%;right:16px;border-top-color:#fff}.shepherd-element.shepherd-theme-arrows.shepherd-element-attached-top.shepherd-element-attached-left.shepherd-target-attached-bottom .shepherd-content{margin-top:16px}.shepherd-element.shepherd-theme-arrows.shepherd-element-attached-top.shepherd-element-attached-left.shepherd-target-attached-bottom .shepherd-content:before{bottom:100%;left:16px;border-bottom-color:#fff}.shepherd-element.shepherd-theme-arrows.shepherd-element-attached-top.shepherd-element-attached-right.shepherd-target-attached-bottom .shepherd-content{margin-top:16px}.shepherd-element.shepherd-theme-arrows.shepherd-element-attached-top.shepherd-element-attached-right.shepherd-target-attached-bottom .shepherd-content:before{bottom:100%;right:16px;border-bottom-color:#fff}.shepherd-element.shepherd-theme-arrows.shepherd-element-attached-bottom.shepherd-element-attached-left.shepherd-target-attached-top .shepherd-content{margin-bottom:16px}.shepherd-element.shepherd-theme-arrows.shepherd-element-attached-bottom.shepherd-element-attached-left.shepherd-target-attached-top .shepherd-content:before{top:100%;left:16px;border-top-color:#fff}.shepherd-element.shepherd-theme-arrows.shepherd-element-attached-bottom.shepherd-element-attached-right.shepherd-target-attached-top .shepherd-content{margin-bottom:16px}.shepherd-element.shepherd-theme-arrows.shepherd-element-attached-bottom.shepherd-element-attached-right.shepherd-target-attached-top .shepherd-content:before{top:100%;right:16px;border-top-color:#fff}.shepherd-element.shepherd-theme-arrows.shepherd-element-attached-top.shepherd-element-attached-right.shepherd-target-attached-left .shepherd-content{margin-right:16px}.shepherd-element.shepherd-theme-arrows.shepherd-element-attached-top.shepherd-element-attached-right.shepherd-target-attached-left .shepherd-content:before{top:16px;left:100%;border-left-color:#fff}.shepherd-element.shepherd-theme-arrows.shepherd-element-attached-top.shepherd-element-attached-left.shepherd-target-attached-right .shepherd-content{margin-left:16px}.shepherd-element.shepherd-theme-arrows.shepherd-element-attached-top.shepherd-element-attached-left.shepherd-target-attached-right .shepherd-content:before{top:16px;right:100%;border-right-color:#fff}.shepherd-element.shepherd-theme-arrows.shepherd-element-attached-bottom.shepherd-element-attached-right.shepherd-target-attached-left .shepherd-content{margin-right:16px}.shepherd-element.shepherd-theme-arrows.shepherd-element-attached-bottom.shepherd-element-attached-right.shepherd-target-attached-left .shepherd-content:before{bottom:16px;left:100%;border-left-color:#fff}.shepherd-element.shepherd-theme-arrows.shepherd-element-attached-bottom.shepherd-element-attached-left.shepherd-target-attached-right .shepherd-content{margin-left:16px}.shepherd-element.shepherd-theme-arrows.shepherd-element-attached-bottom.shepherd-element-attached-left.shepherd-target-attached-right .shepherd-content:before{bottom:16px;right:100%;border-right-color:#fff}.shepherd-element.shepherd-theme-arrows.shepherd-element-attached-top.shepherd-element-attached-center.shepherd-has-title .shepherd-content:before,.shepherd-element.shepherd-theme-arrows.shepherd-element-attached-top.shepherd-element-attached-right.shepherd-target-attached-bottom.shepherd-has-title .shepherd-content:before,.shepherd-element.shepherd-theme-arrows.shepherd-element-attached-top.shepherd-element-attached-left.shepherd-target-attached-bottom.shepherd-has-title .shepherd-content:before{border-bottom-color:#eee}.shepherd-element.shepherd-theme-arrows.shepherd-has-title .shepherd-content header{background:#eee;padding:1em}.shepherd-element.shepherd-theme-arrows.shepherd-has-title .shepherd-content header a.shepherd-cancel-link{padding:0;margin-bottom:0}.shepherd-element.shepherd-theme-arrows.shepherd-has-cancel-link .shepherd-content header h3{float:left}.shepherd-element.shepherd-theme-arrows .shepherd-content{padding:0}.shepherd-element.shepherd-theme-arrows .shepherd-content *{font-size:inherit}.shepherd-element.shepherd-theme-arrows .shepherd-content header{*zoom:1;border-radius:5px 5px 0 0}.shepherd-element.shepherd-theme-arrows .shepherd-content header:after{content:"";display:table;clear:both}.shepherd-element.shepherd-theme-arrows .shepherd-content header h3{margin:0;line-height:1;font-weight:normal}.shepherd-element.shepherd-theme-arrows .shepherd-content header a.shepherd-cancel-link{float:right;text-decoration:none;font-size:1.25em;line-height:.8em;font-weight:normal;color:rgba(0,0,0,0.5);opacity:.25;position:relative;top:.1em;padding:.8em;margin-bottom:-.8em}.shepherd-element.shepherd-theme-arrows .shepherd-content header a.shepherd-cancel-link:hover{opacity:1}.shepherd-element.shepherd-theme-arrows .shepherd-content .shepherd-text{padding:1em}.shepherd-element.shepherd-theme-arrows .shepherd-content .shepherd-text p{margin:0 0 .5em 0;line-height:1.3em}.shepherd-element.shepherd-theme-arrows .shepherd-content .shepherd-text p:last-child{margin-bottom:0}.shepherd-element.shepherd-theme-arrows .shepherd-content footer{padding:0 1em 1em}.shepherd-element.shepherd-theme-arrows .shepherd-content footer .shepherd-buttons{text-align:right;list-style:none;padding:0;margin:0}.shepherd-element.shepherd-theme-arrows .shepherd-content footer .shepherd-buttons li{display:inline;padding:0;margin:0}.shepherd-element.shepherd-theme-arrows .shepherd-content footer .shepherd-buttons li .shepherd-button{display:inline-block;vertical-align:middle;*vertical-align:auto;*zoom:1;*display:inline;border-radius:3px;cursor:pointer;border:0;margin:0 .5em 0 0;font-family:inherit;text-transform:uppercase;letter-spacing:.1em;font-size:.8em;line-height:1em;padding:.75em 2em;background:#3288e6;color:#fff}.shepherd-element.shepherd-theme-arrows .shepherd-content footer .shepherd-buttons li .shepherd-button.shepherd-button-secondary{background:#eee;color:#888}.shepherd-element.shepherd-theme-arrows .shepherd-content footer .shepherd-buttons li:last-child .shepherd-button{margin-right:0}css/tether-shepherd/shepherd-theme-arrows-fix.min.css000064400000001145152214270100016717 0ustar00.shepherd-element-attached-bottom.shepherd-element-attached-right.shepherd-target-attached-top.shepherd-target-attached-left .shepherd-content:before,.shepherd-element-attached-bottom.shepherd-element-attached-left.shepherd-target-attached-top.shepherd-target-attached-right .shepherd-content:before,.shepherd-element-attached-top.shepherd-element-attached-right.shepherd-target-attached-bottom.shepherd-target-attached-left .shepherd-content:before,.shepherd-element-attached-top.shepherd-element-attached-left.shepherd-target-attached-bottom.shepherd-target-attached-right .shepherd-content:before{display:none}css/tether-shepherd/shepherd-theme-arrows-plain-buttons.min.css000064400000025355152214270100020741 0ustar00.shepherd-element-attached-bottom.shepherd-element-attached-right.shepherd-target-attached-top.shepherd-target-attached-left .shepherd-content:before,.shepherd-element-attached-bottom.shepherd-element-attached-left.shepherd-target-attached-top.shepherd-target-attached-right .shepherd-content:before,.shepherd-element-attached-top.shepherd-element-attached-right.shepherd-target-attached-bottom.shepherd-target-attached-left .shepherd-content:before,.shepherd-element-attached-top.shepherd-element-attached-left.shepherd-target-attached-bottom.shepherd-target-attached-right .shepherd-content:before{display:none}.shepherd-element,.shepherd-element:after,.shepherd-element:before,.shepherd-element *,.shepherd-element *:after,.shepherd-element *:before{box-sizing:border-box}.shepherd-element{position:absolute;display:none}.shepherd-element.shepherd-open{display:block}.shepherd-element.shepherd-theme-arrows-plain-buttons{max-width:100%;max-height:100%}.shepherd-element.shepherd-theme-arrows-plain-buttons .shepherd-content{border-radius:5px;position:relative;font-family:inherit;background:#fff;color:#444;padding:1em;font-size:1.1em;line-height:1.5em;-webkit-transform:translateZ(0);transform:translateZ(0);-webkit-filter:drop-shadow(0 1px 4px rgba(0,0,0,0.2));filter:drop-shadow(0 1px 4px rgba(0,0,0,0.2))}.shepherd-element.shepherd-theme-arrows-plain-buttons .shepherd-content:before{content:"";display:block;position:absolute;width:0;height:0;border-color:transparent;border-width:16px;border-style:solid;pointer-events:none}.shepherd-element.shepherd-theme-arrows-plain-buttons.shepherd-element-attached-bottom.shepherd-element-attached-center .shepherd-content{margin-bottom:16px}.shepherd-element.shepherd-theme-arrows-plain-buttons.shepherd-element-attached-bottom.shepherd-element-attached-center .shepherd-content:before{top:100%;left:50%;margin-left:-16px;border-top-color:#fff}.shepherd-element.shepherd-theme-arrows-plain-buttons.shepherd-element-attached-top.shepherd-element-attached-center .shepherd-content{margin-top:16px}.shepherd-element.shepherd-theme-arrows-plain-buttons.shepherd-element-attached-top.shepherd-element-attached-center .shepherd-content:before{bottom:100%;left:50%;margin-left:-16px;border-bottom-color:#fff}.shepherd-element.shepherd-theme-arrows-plain-buttons.shepherd-element-attached-right.shepherd-element-attached-middle .shepherd-content{margin-right:16px}.shepherd-element.shepherd-theme-arrows-plain-buttons.shepherd-element-attached-right.shepherd-element-attached-middle .shepherd-content:before{left:100%;top:50%;margin-top:-16px;border-left-color:#fff}.shepherd-element.shepherd-theme-arrows-plain-buttons.shepherd-element-attached-left.shepherd-element-attached-middle .shepherd-content{margin-left:16px}.shepherd-element.shepherd-theme-arrows-plain-buttons.shepherd-element-attached-left.shepherd-element-attached-middle .shepherd-content:before{right:100%;top:50%;margin-top:-16px;border-right-color:#fff}.shepherd-element.shepherd-theme-arrows-plain-buttons.shepherd-element-attached-left.shepherd-target-attached-center .shepherd-content{left:-32px}.shepherd-element.shepherd-theme-arrows-plain-buttons.shepherd-element-attached-right.shepherd-target-attached-center .shepherd-content{left:32px}.shepherd-element.shepherd-theme-arrows-plain-buttons.shepherd-element-attached-top.shepherd-element-attached-left.shepherd-target-attached-middle .shepherd-content{margin-top:16px}.shepherd-element.shepherd-theme-arrows-plain-buttons.shepherd-element-attached-top.shepherd-element-attached-left.shepherd-target-attached-middle .shepherd-content:before{bottom:100%;left:16px;border-bottom-color:#fff}.shepherd-element.shepherd-theme-arrows-plain-buttons.shepherd-element-attached-top.shepherd-element-attached-right.shepherd-target-attached-middle .shepherd-content{margin-top:16px}.shepherd-element.shepherd-theme-arrows-plain-buttons.shepherd-element-attached-top.shepherd-element-attached-right.shepherd-target-attached-middle .shepherd-content:before{bottom:100%;right:16px;border-bottom-color:#fff}.shepherd-element.shepherd-theme-arrows-plain-buttons.shepherd-element-attached-bottom.shepherd-element-attached-left.shepherd-target-attached-middle .shepherd-content{margin-bottom:16px}.shepherd-element.shepherd-theme-arrows-plain-buttons.shepherd-element-attached-bottom.shepherd-element-attached-left.shepherd-target-attached-middle .shepherd-content:before{top:100%;left:16px;border-top-color:#fff}.shepherd-element.shepherd-theme-arrows-plain-buttons.shepherd-element-attached-bottom.shepherd-element-attached-right.shepherd-target-attached-middle .shepherd-content{margin-bottom:16px}.shepherd-element.shepherd-theme-arrows-plain-buttons.shepherd-element-attached-bottom.shepherd-element-attached-right.shepherd-target-attached-middle .shepherd-content:before{top:100%;right:16px;border-top-color:#fff}.shepherd-element.shepherd-theme-arrows-plain-buttons.shepherd-element-attached-top.shepherd-element-attached-left.shepherd-target-attached-bottom .shepherd-content{margin-top:16px}.shepherd-element.shepherd-theme-arrows-plain-buttons.shepherd-element-attached-top.shepherd-element-attached-left.shepherd-target-attached-bottom .shepherd-content:before{bottom:100%;left:16px;border-bottom-color:#fff}.shepherd-element.shepherd-theme-arrows-plain-buttons.shepherd-element-attached-top.shepherd-element-attached-right.shepherd-target-attached-bottom .shepherd-content{margin-top:16px}.shepherd-element.shepherd-theme-arrows-plain-buttons.shepherd-element-attached-top.shepherd-element-attached-right.shepherd-target-attached-bottom .shepherd-content:before{bottom:100%;right:16px;border-bottom-color:#fff}.shepherd-element.shepherd-theme-arrows-plain-buttons.shepherd-element-attached-bottom.shepherd-element-attached-left.shepherd-target-attached-top .shepherd-content{margin-bottom:16px}.shepherd-element.shepherd-theme-arrows-plain-buttons.shepherd-element-attached-bottom.shepherd-element-attached-left.shepherd-target-attached-top .shepherd-content:before{top:100%;left:16px;border-top-color:#fff}.shepherd-element.shepherd-theme-arrows-plain-buttons.shepherd-element-attached-bottom.shepherd-element-attached-right.shepherd-target-attached-top .shepherd-content{margin-bottom:16px}.shepherd-element.shepherd-theme-arrows-plain-buttons.shepherd-element-attached-bottom.shepherd-element-attached-right.shepherd-target-attached-top .shepherd-content:before{top:100%;right:16px;border-top-color:#fff}.shepherd-element.shepherd-theme-arrows-plain-buttons.shepherd-element-attached-top.shepherd-element-attached-right.shepherd-target-attached-left .shepherd-content{margin-right:16px}.shepherd-element.shepherd-theme-arrows-plain-buttons.shepherd-element-attached-top.shepherd-element-attached-right.shepherd-target-attached-left .shepherd-content:before{top:16px;left:100%;border-left-color:#fff}.shepherd-element.shepherd-theme-arrows-plain-buttons.shepherd-element-attached-top.shepherd-element-attached-left.shepherd-target-attached-right .shepherd-content{margin-left:16px}.shepherd-element.shepherd-theme-arrows-plain-buttons.shepherd-element-attached-top.shepherd-element-attached-left.shepherd-target-attached-right .shepherd-content:before{top:16px;right:100%;border-right-color:#fff}.shepherd-element.shepherd-theme-arrows-plain-buttons.shepherd-element-attached-bottom.shepherd-element-attached-right.shepherd-target-attached-left .shepherd-content{margin-right:16px}.shepherd-element.shepherd-theme-arrows-plain-buttons.shepherd-element-attached-bottom.shepherd-element-attached-right.shepherd-target-attached-left .shepherd-content:before{bottom:16px;left:100%;border-left-color:#fff}.shepherd-element.shepherd-theme-arrows-plain-buttons.shepherd-element-attached-bottom.shepherd-element-attached-left.shepherd-target-attached-right .shepherd-content{margin-left:16px}.shepherd-element.shepherd-theme-arrows-plain-buttons.shepherd-element-attached-bottom.shepherd-element-attached-left.shepherd-target-attached-right .shepherd-content:before{bottom:16px;right:100%;border-right-color:#fff}.shepherd-element.shepherd-theme-arrows-plain-buttons.shepherd-element-attached-top.shepherd-element-attached-center.shepherd-has-title .shepherd-content:before,.shepherd-element.shepherd-theme-arrows-plain-buttons.shepherd-element-attached-top.shepherd-element-attached-right.shepherd-target-attached-bottom.shepherd-has-title .shepherd-content:before,.shepherd-element.shepherd-theme-arrows-plain-buttons.shepherd-element-attached-top.shepherd-element-attached-left.shepherd-target-attached-bottom.shepherd-has-title .shepherd-content:before{border-bottom-color:#eee}.shepherd-element.shepherd-theme-arrows-plain-buttons.shepherd-has-title .shepherd-content header{background:#eee;padding:1em}.shepherd-element.shepherd-theme-arrows-plain-buttons.shepherd-has-title .shepherd-content header a.shepherd-cancel-link{padding:0;margin-bottom:0}.shepherd-element.shepherd-theme-arrows-plain-buttons.shepherd-has-cancel-link .shepherd-content header h3{float:left}.shepherd-element.shepherd-theme-arrows-plain-buttons .shepherd-content{padding:0}.shepherd-element.shepherd-theme-arrows-plain-buttons .shepherd-content header{*zoom:1;border-radius:5px 5px 0 0}.shepherd-element.shepherd-theme-arrows-plain-buttons .shepherd-content header:after{content:"";display:table;clear:both}.shepherd-element.shepherd-theme-arrows-plain-buttons .shepherd-content header h3{margin:0;line-height:1;font-weight:normal}.shepherd-element.shepherd-theme-arrows-plain-buttons .shepherd-content header a.shepherd-cancel-link{float:right;text-decoration:none;font-size:1.25em;line-height:.8em;font-weight:normal;color:rgba(0,0,0,0.5);opacity:.25;position:relative;top:.1em;padding:.8em;margin-bottom:-.8em}.shepherd-element.shepherd-theme-arrows-plain-buttons .shepherd-content header a.shepherd-cancel-link:hover{opacity:1}.shepherd-element.shepherd-theme-arrows-plain-buttons .shepherd-content .shepherd-text{padding:1em}.shepherd-element.shepherd-theme-arrows-plain-buttons .shepherd-content .shepherd-text p{margin:0 0 .5em 0;line-height:1.3em}.shepherd-element.shepherd-theme-arrows-plain-buttons .shepherd-content .shepherd-text p:last-child{margin-bottom:0}.shepherd-element.shepherd-theme-arrows-plain-buttons .shepherd-content footer{padding:0 1em 1em}.shepherd-element.shepherd-theme-arrows-plain-buttons .shepherd-content footer .shepherd-buttons{text-align:right;list-style:none;padding:0;margin:0}.shepherd-element.shepherd-theme-arrows-plain-buttons .shepherd-content footer .shepherd-buttons li{display:inline;padding:0;margin:0}.shepherd-element.shepherd-theme-arrows-plain-buttons .shepherd-content footer .shepherd-buttons li .shepherd-button{display:inline-block;vertical-align:middle;*vertical-align:auto;*zoom:1;*display:inline;cursor:pointer;margin:0 .5em 0 0;text-decoration:none}.shepherd-element.shepherd-theme-arrows-plain-buttons .shepherd-content footer .shepherd-buttons li:last-child .shepherd-button{margin-right:0}css/tether-shepherd/shepherd-theme-dark.min.css000064400000025075152214270100015547 0ustar00.shepherd-element-attached-bottom.shepherd-element-attached-right.shepherd-target-attached-top.shepherd-target-attached-left .shepherd-content:before,.shepherd-element-attached-bottom.shepherd-element-attached-left.shepherd-target-attached-top.shepherd-target-attached-right .shepherd-content:before,.shepherd-element-attached-top.shepherd-element-attached-right.shepherd-target-attached-bottom.shepherd-target-attached-left .shepherd-content:before,.shepherd-element-attached-top.shepherd-element-attached-left.shepherd-target-attached-bottom.shepherd-target-attached-right .shepherd-content:before{display:none}.shepherd-element,.shepherd-element:after,.shepherd-element:before,.shepherd-element *,.shepherd-element *:after,.shepherd-element *:before{box-sizing:border-box}.shepherd-element{position:absolute;display:none}.shepherd-element.shepherd-open{display:block}.shepherd-element.shepherd-theme-dark{max-width:100%;max-height:100%}.shepherd-element.shepherd-theme-dark .shepherd-content{border-radius:5px;position:relative;font-family:inherit;background:#232323;color:#eee;padding:1em;font-size:1.1em;line-height:1.5em}.shepherd-element.shepherd-theme-dark .shepherd-content:before{content:"";display:block;position:absolute;width:0;height:0;border-color:transparent;border-width:16px;border-style:solid;pointer-events:none}.shepherd-element.shepherd-theme-dark.shepherd-element-attached-bottom.shepherd-element-attached-center .shepherd-content{margin-bottom:16px}.shepherd-element.shepherd-theme-dark.shepherd-element-attached-bottom.shepherd-element-attached-center .shepherd-content:before{top:100%;left:50%;margin-left:-16px;border-top-color:#232323}.shepherd-element.shepherd-theme-dark.shepherd-element-attached-top.shepherd-element-attached-center .shepherd-content{margin-top:16px}.shepherd-element.shepherd-theme-dark.shepherd-element-attached-top.shepherd-element-attached-center .shepherd-content:before{bottom:100%;left:50%;margin-left:-16px;border-bottom-color:#232323}.shepherd-element.shepherd-theme-dark.shepherd-element-attached-right.shepherd-element-attached-middle .shepherd-content{margin-right:16px}.shepherd-element.shepherd-theme-dark.shepherd-element-attached-right.shepherd-element-attached-middle .shepherd-content:before{left:100%;top:50%;margin-top:-16px;border-left-color:#232323}.shepherd-element.shepherd-theme-dark.shepherd-element-attached-left.shepherd-element-attached-middle .shepherd-content{margin-left:16px}.shepherd-element.shepherd-theme-dark.shepherd-element-attached-left.shepherd-element-attached-middle .shepherd-content:before{right:100%;top:50%;margin-top:-16px;border-right-color:#232323}.shepherd-element.shepherd-theme-dark.shepherd-element-attached-left.shepherd-target-attached-center .shepherd-content{left:-32px}.shepherd-element.shepherd-theme-dark.shepherd-element-attached-right.shepherd-target-attached-center .shepherd-content{left:32px}.shepherd-element.shepherd-theme-dark.shepherd-element-attached-top.shepherd-element-attached-left.shepherd-target-attached-middle .shepherd-content{margin-top:16px}.shepherd-element.shepherd-theme-dark.shepherd-element-attached-top.shepherd-element-attached-left.shepherd-target-attached-middle .shepherd-content:before{bottom:100%;left:16px;border-bottom-color:#232323}.shepherd-element.shepherd-theme-dark.shepherd-element-attached-top.shepherd-element-attached-right.shepherd-target-attached-middle .shepherd-content{margin-top:16px}.shepherd-element.shepherd-theme-dark.shepherd-element-attached-top.shepherd-element-attached-right.shepherd-target-attached-middle .shepherd-content:before{bottom:100%;right:16px;border-bottom-color:#232323}.shepherd-element.shepherd-theme-dark.shepherd-element-attached-bottom.shepherd-element-attached-left.shepherd-target-attached-middle .shepherd-content{margin-bottom:16px}.shepherd-element.shepherd-theme-dark.shepherd-element-attached-bottom.shepherd-element-attached-left.shepherd-target-attached-middle .shepherd-content:before{top:100%;left:16px;border-top-color:#232323}.shepherd-element.shepherd-theme-dark.shepherd-element-attached-bottom.shepherd-element-attached-right.shepherd-target-attached-middle .shepherd-content{margin-bottom:16px}.shepherd-element.shepherd-theme-dark.shepherd-element-attached-bottom.shepherd-element-attached-right.shepherd-target-attached-middle .shepherd-content:before{top:100%;right:16px;border-top-color:#232323}.shepherd-element.shepherd-theme-dark.shepherd-element-attached-top.shepherd-element-attached-left.shepherd-target-attached-bottom .shepherd-content{margin-top:16px}.shepherd-element.shepherd-theme-dark.shepherd-element-attached-top.shepherd-element-attached-left.shepherd-target-attached-bottom .shepherd-content:before{bottom:100%;left:16px;border-bottom-color:#232323}.shepherd-element.shepherd-theme-dark.shepherd-element-attached-top.shepherd-element-attached-right.shepherd-target-attached-bottom .shepherd-content{margin-top:16px}.shepherd-element.shepherd-theme-dark.shepherd-element-attached-top.shepherd-element-attached-right.shepherd-target-attached-bottom .shepherd-content:before{bottom:100%;right:16px;border-bottom-color:#232323}.shepherd-element.shepherd-theme-dark.shepherd-element-attached-bottom.shepherd-element-attached-left.shepherd-target-attached-top .shepherd-content{margin-bottom:16px}.shepherd-element.shepherd-theme-dark.shepherd-element-attached-bottom.shepherd-element-attached-left.shepherd-target-attached-top .shepherd-content:before{top:100%;left:16px;border-top-color:#232323}.shepherd-element.shepherd-theme-dark.shepherd-element-attached-bottom.shepherd-element-attached-right.shepherd-target-attached-top .shepherd-content{margin-bottom:16px}.shepherd-element.shepherd-theme-dark.shepherd-element-attached-bottom.shepherd-element-attached-right.shepherd-target-attached-top .shepherd-content:before{top:100%;right:16px;border-top-color:#232323}.shepherd-element.shepherd-theme-dark.shepherd-element-attached-top.shepherd-element-attached-right.shepherd-target-attached-left .shepherd-content{margin-right:16px}.shepherd-element.shepherd-theme-dark.shepherd-element-attached-top.shepherd-element-attached-right.shepherd-target-attached-left .shepherd-content:before{top:16px;left:100%;border-left-color:#232323}.shepherd-element.shepherd-theme-dark.shepherd-element-attached-top.shepherd-element-attached-left.shepherd-target-attached-right .shepherd-content{margin-left:16px}.shepherd-element.shepherd-theme-dark.shepherd-element-attached-top.shepherd-element-attached-left.shepherd-target-attached-right .shepherd-content:before{top:16px;right:100%;border-right-color:#232323}.shepherd-element.shepherd-theme-dark.shepherd-element-attached-bottom.shepherd-element-attached-right.shepherd-target-attached-left .shepherd-content{margin-right:16px}.shepherd-element.shepherd-theme-dark.shepherd-element-attached-bottom.shepherd-element-attached-right.shepherd-target-attached-left .shepherd-content:before{bottom:16px;left:100%;border-left-color:#232323}.shepherd-element.shepherd-theme-dark.shepherd-element-attached-bottom.shepherd-element-attached-left.shepherd-target-attached-right .shepherd-content{margin-left:16px}.shepherd-element.shepherd-theme-dark.shepherd-element-attached-bottom.shepherd-element-attached-left.shepherd-target-attached-right .shepherd-content:before{bottom:16px;right:100%;border-right-color:#232323}.shepherd-element.shepherd-theme-dark{z-index:9999;max-width:24em;font-size:1em}.shepherd-element.shepherd-theme-dark.shepherd-element-attached-top.shepherd-element-attached-center.shepherd-has-title .shepherd-content:before,.shepherd-element.shepherd-theme-dark.shepherd-element-attached-top.shepherd-element-attached-right.shepherd-target-attached-bottom.shepherd-has-title .shepherd-content:before,.shepherd-element.shepherd-theme-dark.shepherd-element-attached-top.shepherd-element-attached-left.shepherd-target-attached-bottom.shepherd-has-title .shepherd-content:before{border-bottom-color:#303030}.shepherd-element.shepherd-theme-dark.shepherd-has-title .shepherd-content header{background:#303030;padding:1em}.shepherd-element.shepherd-theme-dark.shepherd-has-title .shepherd-content header a.shepherd-cancel-link{padding:0;margin-bottom:0}.shepherd-element.shepherd-theme-dark.shepherd-has-cancel-link .shepherd-content header h3{float:left}.shepherd-element.shepherd-theme-dark .shepherd-content{box-shadow:0 0 1em rgba(0,0,0,0.2);padding:0}.shepherd-element.shepherd-theme-dark .shepherd-content *{font-size:inherit}.shepherd-element.shepherd-theme-dark .shepherd-content header{*zoom:1;border-radius:5px 5px 0 0}.shepherd-element.shepherd-theme-dark .shepherd-content header:after{content:"";display:table;clear:both}.shepherd-element.shepherd-theme-dark .shepherd-content header h3{margin:0;line-height:1;font-weight:normal}.shepherd-element.shepherd-theme-dark .shepherd-content header a.shepherd-cancel-link{float:right;text-decoration:none;font-size:1.25em;line-height:.8em;font-weight:normal;color:rgba(0,0,0,0.5);opacity:.25;position:relative;top:.1em;padding:.8em;margin-bottom:-.8em}.shepherd-element.shepherd-theme-dark .shepherd-content header a.shepherd-cancel-link:hover{opacity:1}.shepherd-element.shepherd-theme-dark .shepherd-content .shepherd-text{padding:1em}.shepherd-element.shepherd-theme-dark .shepherd-content .shepherd-text p{margin:0 0 .5em 0;line-height:1.3em}.shepherd-element.shepherd-theme-dark .shepherd-content .shepherd-text p:last-child{margin-bottom:0}.shepherd-element.shepherd-theme-dark .shepherd-content footer{padding:0 1em 1em}.shepherd-element.shepherd-theme-dark .shepherd-content footer .shepherd-buttons{text-align:right;list-style:none;padding:0;margin:0}.shepherd-element.shepherd-theme-dark .shepherd-content footer .shepherd-buttons li{display:inline;padding:0;margin:0}.shepherd-element.shepherd-theme-dark .shepherd-content footer .shepherd-buttons li .shepherd-button{display:inline-block;vertical-align:middle;*vertical-align:auto;*zoom:1;*display:inline;border-radius:3px;cursor:pointer;border:0;margin:0 .5em 0 0;font-family:inherit;text-transform:uppercase;letter-spacing:.1em;font-size:.8em;line-height:1em;padding:.75em 2em;background:#3288e6;color:#fff}.shepherd-element.shepherd-theme-dark .shepherd-content footer .shepherd-buttons li .shepherd-button.shepherd-button-secondary{background:#eee;color:#888}.shepherd-element.shepherd-theme-dark .shepherd-content footer .shepherd-buttons li:last-child .shepherd-button{margin-right:0}.shepherd-start-tour-button.shepherd-theme-dark{display:inline-block;vertical-align:middle;*vertical-align:auto;*zoom:1;*display:inline;border-radius:3px;cursor:pointer;border:0;margin:0 .5em 0 0;font-family:inherit;text-transform:uppercase;letter-spacing:.1em;font-size:.8em;line-height:1em;padding:.75em 2em;background:#3288e6;color:#fff}css/tether-shepherd/shepherd-theme-dark.css000064400000030671152214270100014763 0ustar00.shepherd-element-attached-bottom.shepherd-element-attached-right.shepherd-target-attached-top.shepherd-target-attached-left .shepherd-content:before, .shepherd-element-attached-bottom.shepherd-element-attached-left.shepherd-target-attached-top.shepherd-target-attached-right .shepherd-content:before, .shepherd-element-attached-top.shepherd-element-attached-right.shepherd-target-attached-bottom.shepherd-target-attached-left .shepherd-content:before, .shepherd-element-attached-top.shepherd-element-attached-left.shepherd-target-attached-bottom.shepherd-target-attached-right .shepherd-content:before { display: none; } .shepherd-element, .shepherd-element:after, .shepherd-element:before, .shepherd-element *, .shepherd-element *:after, .shepherd-element *:before { box-sizing: border-box; } .shepherd-element { position: absolute; display: none; } .shepherd-element.shepherd-open { display: block; } .shepherd-element.shepherd-theme-dark { max-width: 100%; max-height: 100%; } .shepherd-element.shepherd-theme-dark .shepherd-content { border-radius: 5px; position: relative; font-family: inherit; background: #232323; color: #eee; padding: 1em; font-size: 1.1em; line-height: 1.5em; } .shepherd-element.shepherd-theme-dark .shepherd-content:before { content: ""; display: block; position: absolute; width: 0; height: 0; border-color: transparent; border-width: 16px; border-style: solid; pointer-events: none; } .shepherd-element.shepherd-theme-dark.shepherd-element-attached-bottom.shepherd-element-attached-center .shepherd-content { margin-bottom: 16px; } .shepherd-element.shepherd-theme-dark.shepherd-element-attached-bottom.shepherd-element-attached-center .shepherd-content:before { top: 100%; left: 50%; margin-left: -16px; border-top-color: #232323; } .shepherd-element.shepherd-theme-dark.shepherd-element-attached-top.shepherd-element-attached-center .shepherd-content { margin-top: 16px; } .shepherd-element.shepherd-theme-dark.shepherd-element-attached-top.shepherd-element-attached-center .shepherd-content:before { bottom: 100%; left: 50%; margin-left: -16px; border-bottom-color: #232323; } .shepherd-element.shepherd-theme-dark.shepherd-element-attached-right.shepherd-element-attached-middle .shepherd-content { margin-right: 16px; } .shepherd-element.shepherd-theme-dark.shepherd-element-attached-right.shepherd-element-attached-middle .shepherd-content:before { left: 100%; top: 50%; margin-top: -16px; border-left-color: #232323; } .shepherd-element.shepherd-theme-dark.shepherd-element-attached-left.shepherd-element-attached-middle .shepherd-content { margin-left: 16px; } .shepherd-element.shepherd-theme-dark.shepherd-element-attached-left.shepherd-element-attached-middle .shepherd-content:before { right: 100%; top: 50%; margin-top: -16px; border-right-color: #232323; } .shepherd-element.shepherd-theme-dark.shepherd-element-attached-left.shepherd-target-attached-center .shepherd-content { left: -32px; } .shepherd-element.shepherd-theme-dark.shepherd-element-attached-right.shepherd-target-attached-center .shepherd-content { left: 32px; } .shepherd-element.shepherd-theme-dark.shepherd-element-attached-top.shepherd-element-attached-left.shepherd-target-attached-middle .shepherd-content { margin-top: 16px; } .shepherd-element.shepherd-theme-dark.shepherd-element-attached-top.shepherd-element-attached-left.shepherd-target-attached-middle .shepherd-content:before { bottom: 100%; left: 16px; border-bottom-color: #232323; } .shepherd-element.shepherd-theme-dark.shepherd-element-attached-top.shepherd-element-attached-right.shepherd-target-attached-middle .shepherd-content { margin-top: 16px; } .shepherd-element.shepherd-theme-dark.shepherd-element-attached-top.shepherd-element-attached-right.shepherd-target-attached-middle .shepherd-content:before { bottom: 100%; right: 16px; border-bottom-color: #232323; } .shepherd-element.shepherd-theme-dark.shepherd-element-attached-bottom.shepherd-element-attached-left.shepherd-target-attached-middle .shepherd-content { margin-bottom: 16px; } .shepherd-element.shepherd-theme-dark.shepherd-element-attached-bottom.shepherd-element-attached-left.shepherd-target-attached-middle .shepherd-content:before { top: 100%; left: 16px; border-top-color: #232323; } .shepherd-element.shepherd-theme-dark.shepherd-element-attached-bottom.shepherd-element-attached-right.shepherd-target-attached-middle .shepherd-content { margin-bottom: 16px; } .shepherd-element.shepherd-theme-dark.shepherd-element-attached-bottom.shepherd-element-attached-right.shepherd-target-attached-middle .shepherd-content:before { top: 100%; right: 16px; border-top-color: #232323; } .shepherd-element.shepherd-theme-dark.shepherd-element-attached-top.shepherd-element-attached-left.shepherd-target-attached-bottom .shepherd-content { margin-top: 16px; } .shepherd-element.shepherd-theme-dark.shepherd-element-attached-top.shepherd-element-attached-left.shepherd-target-attached-bottom .shepherd-content:before { bottom: 100%; left: 16px; border-bottom-color: #232323; } .shepherd-element.shepherd-theme-dark.shepherd-element-attached-top.shepherd-element-attached-right.shepherd-target-attached-bottom .shepherd-content { margin-top: 16px; } .shepherd-element.shepherd-theme-dark.shepherd-element-attached-top.shepherd-element-attached-right.shepherd-target-attached-bottom .shepherd-content:before { bottom: 100%; right: 16px; border-bottom-color: #232323; } .shepherd-element.shepherd-theme-dark.shepherd-element-attached-bottom.shepherd-element-attached-left.shepherd-target-attached-top .shepherd-content { margin-bottom: 16px; } .shepherd-element.shepherd-theme-dark.shepherd-element-attached-bottom.shepherd-element-attached-left.shepherd-target-attached-top .shepherd-content:before { top: 100%; left: 16px; border-top-color: #232323; } .shepherd-element.shepherd-theme-dark.shepherd-element-attached-bottom.shepherd-element-attached-right.shepherd-target-attached-top .shepherd-content { margin-bottom: 16px; } .shepherd-element.shepherd-theme-dark.shepherd-element-attached-bottom.shepherd-element-attached-right.shepherd-target-attached-top .shepherd-content:before { top: 100%; right: 16px; border-top-color: #232323; } .shepherd-element.shepherd-theme-dark.shepherd-element-attached-top.shepherd-element-attached-right.shepherd-target-attached-left .shepherd-content { margin-right: 16px; } .shepherd-element.shepherd-theme-dark.shepherd-element-attached-top.shepherd-element-attached-right.shepherd-target-attached-left .shepherd-content:before { top: 16px; left: 100%; border-left-color: #232323; } .shepherd-element.shepherd-theme-dark.shepherd-element-attached-top.shepherd-element-attached-left.shepherd-target-attached-right .shepherd-content { margin-left: 16px; } .shepherd-element.shepherd-theme-dark.shepherd-element-attached-top.shepherd-element-attached-left.shepherd-target-attached-right .shepherd-content:before { top: 16px; right: 100%; border-right-color: #232323; } .shepherd-element.shepherd-theme-dark.shepherd-element-attached-bottom.shepherd-element-attached-right.shepherd-target-attached-left .shepherd-content { margin-right: 16px; } .shepherd-element.shepherd-theme-dark.shepherd-element-attached-bottom.shepherd-element-attached-right.shepherd-target-attached-left .shepherd-content:before { bottom: 16px; left: 100%; border-left-color: #232323; } .shepherd-element.shepherd-theme-dark.shepherd-element-attached-bottom.shepherd-element-attached-left.shepherd-target-attached-right .shepherd-content { margin-left: 16px; } .shepherd-element.shepherd-theme-dark.shepherd-element-attached-bottom.shepherd-element-attached-left.shepherd-target-attached-right .shepherd-content:before { bottom: 16px; right: 100%; border-right-color: #232323; } .shepherd-element.shepherd-theme-dark { z-index: 9999; max-width: 24em; font-size: 1em; } .shepherd-element.shepherd-theme-dark.shepherd-element-attached-top.shepherd-element-attached-center.shepherd-has-title .shepherd-content:before, .shepherd-element.shepherd-theme-dark.shepherd-element-attached-top.shepherd-element-attached-right.shepherd-target-attached-bottom.shepherd-has-title .shepherd-content:before, .shepherd-element.shepherd-theme-dark.shepherd-element-attached-top.shepherd-element-attached-left.shepherd-target-attached-bottom.shepherd-has-title .shepherd-content:before { border-bottom-color: #303030; } .shepherd-element.shepherd-theme-dark.shepherd-has-title .shepherd-content header { background: #303030; padding: 1em; } .shepherd-element.shepherd-theme-dark.shepherd-has-title .shepherd-content header a.shepherd-cancel-link { padding: 0; margin-bottom: 0; } .shepherd-element.shepherd-theme-dark.shepherd-has-cancel-link .shepherd-content header h3 { float: left; } .shepherd-element.shepherd-theme-dark .shepherd-content { box-shadow: 0 0 1em rgba(0, 0, 0, 0.2); padding: 0; } .shepherd-element.shepherd-theme-dark .shepherd-content * { font-size: inherit; } .shepherd-element.shepherd-theme-dark .shepherd-content header { *zoom: 1; border-radius: 5px 5px 0 0; } .shepherd-element.shepherd-theme-dark .shepherd-content header:after { content: ""; display: table; clear: both; } .shepherd-element.shepherd-theme-dark .shepherd-content header h3 { margin: 0; line-height: 1; font-weight: normal; } .shepherd-element.shepherd-theme-dark .shepherd-content header a.shepherd-cancel-link { float: right; text-decoration: none; font-size: 1.25em; line-height: .8em; font-weight: normal; color: rgba(0, 0, 0, 0.5); opacity: 0.25; position: relative; top: .1em; padding: .8em; margin-bottom: -.8em; } .shepherd-element.shepherd-theme-dark .shepherd-content header a.shepherd-cancel-link:hover { opacity: 1; } .shepherd-element.shepherd-theme-dark .shepherd-content .shepherd-text { padding: 1em; } .shepherd-element.shepherd-theme-dark .shepherd-content .shepherd-text p { margin: 0 0 .5em 0; line-height: 1.3em; } .shepherd-element.shepherd-theme-dark .shepherd-content .shepherd-text p:last-child { margin-bottom: 0; } .shepherd-element.shepherd-theme-dark .shepherd-content footer { padding: 0 1em 1em; } .shepherd-element.shepherd-theme-dark .shepherd-content footer .shepherd-buttons { text-align: right; list-style: none; padding: 0; margin: 0; } .shepherd-element.shepherd-theme-dark .shepherd-content footer .shepherd-buttons li { display: inline; padding: 0; margin: 0; } .shepherd-element.shepherd-theme-dark .shepherd-content footer .shepherd-buttons li .shepherd-button { display: inline-block; vertical-align: middle; *vertical-align: auto; *zoom: 1; *display: inline; border-radius: 3px; cursor: pointer; border: 0; margin: 0 .5em 0 0; font-family: inherit; text-transform: uppercase; letter-spacing: .1em; font-size: .8em; line-height: 1em; padding: .75em 2em; background: #3288e6; color: #fff; } .shepherd-element.shepherd-theme-dark .shepherd-content footer .shepherd-buttons li .shepherd-button.shepherd-button-secondary { background: #eee; color: #888; } .shepherd-element.shepherd-theme-dark .shepherd-content footer .shepherd-buttons li:last-child .shepherd-button { margin-right: 0; } .shepherd-start-tour-button.shepherd-theme-dark { display: inline-block; vertical-align: middle; *vertical-align: auto; *zoom: 1; *display: inline; border-radius: 3px; cursor: pointer; border: 0; margin: 0 .5em 0 0; font-family: inherit; text-transform: uppercase; letter-spacing: .1em; font-size: .8em; line-height: 1em; padding: .75em 2em; background: #3288e6; color: #fff; } css/updraftplus-admin.css000064400000232030152214270100011477 0ustar00@-webkit-keyframes udp_blink { from { opacity: 1; -webkit-transform: scale(1); transform: scale(1); } to { opacity: 0.4; -webkit-transform: scale(0.85); transform: scale(0.85); } } @keyframes udp_blink { from { opacity: 1; -webkit-transform: scale(1); transform: scale(1); } to { opacity: 0.4; -webkit-transform: scale(0.85); transform: scale(0.85); } } @-webkit-keyframes udp_rotate { from { -webkit-transform: rotate(0); transform: rotate(0); } to { -webkit-transform: rotate(360deg); transform: rotate(360deg); } } @keyframes udp_rotate { from { -webkit-transform: rotate(0); transform: rotate(0); } to { -webkit-transform: rotate(360deg); transform: rotate(360deg); } } /* Widths and sizing */ .max-width-600 { max-width: 600px; } .max-width-700 { max-width: 700px; } .width-900 { max-width: 900px; } .width-80 { width: 80%; } .updraft--flex { display: -webkit-box; display: -ms-flexbox; display: flex; -ms-flex-wrap: wrap; flex-wrap: wrap; } .updraft--flex > * { -webkit-box-flex: 1; -ms-flex: 1; flex: 1; -webkit-box-sizing: border-box; box-sizing: border-box; } .updraft--flex > .updraft--one-half { width: 50%; -webkit-box-flex: 1; -ms-flex: auto; flex: auto; } .updraft--flex > .updraft--two-halves { width: 100%; -webkit-box-flex: 1; -ms-flex: auto; flex: auto; } .updraft-color--very-light-grey { background: #F8F8F8; } /* End widths and sizing */ /* Font styling */ .no-decoration { text-decoration: none; } .bold { font-weight: bold; } /* End font styling */ /* Alignment */ .center-align-td { text-align: center; } /* End of Alignment */ /* Padding */ .remove-padding { padding: 0 !important; } /* End of padding */ .updraft-text-center { text-align: center; } .autobackup { padding: 6px; margin: 8px 0px; } ul .disc { list-style: disc inside; } .dashicons-log-fix { display: inherit; } .udpdraft__lifted { -webkit-box-shadow: 0 1px 1px 0 rgba(0,0,0,.1); box-shadow: 0 1px 1px 0 rgba(0,0,0,.1); } #updraft-wrap a .dashicons { text-decoration: none; } .updraft-field-description, table.form-table td p.updraft-field-description { font-size: 90%; line-height: 1.2; font-style: italic; margin-bottom: 5px; } /* Input boxes */ label.updraft_checkbox { display: block; margin-bottom: 4px; margin-left: 26px; } label.updraft_checkbox > input[type=checkbox] { margin-left: -25px; } div[id*="updraft_include_"] { margin-bottom: 9px; } /* Input boxes */ .settings_page_updraftplus input[type="file"] { border: none; } .settings_page_updraftplus .wipe_settings { padding-bottom: 10px; } .settings_page_updraftplus input[type="text"] { font-size: 14px; } .settings_page_updraftplus select { border-radius: 4px; max-width: 100%; } input.updraft_input--wide, textarea.updraft_input--wide { max-width: 442px; width: 100%; } #updraft-wrap .button-large { font-size: 1.3em; } /* End input boxes */ /* Main Buttons */ .main-dashboard-buttons { border-width: 4px; border-radius: 12px; letter-spacing: 0px; font-size: 17px; font-weight: bold; padding-left: 0.7em; padding-right: 2em; padding: 0.3em 1em; line-height: 1.7em; background: transparent; position: relative; border: 2px solid; -webkit-transition: all 0.2s; transition: all 0.2s; vertical-align: baseline; -webkit-box-sizing: border-box; box-sizing: border-box; text-align: center; line-height: 1.3em; margin-left: .3em; text-transform: none; line-height: 1; text-decoration: none; } .button-restore { border-color: rgb(98, 158, 192); color: rgb(98, 158, 192); } .button-ud-google { text-decoration: none !important; -webkit-transition: background-color .3s, -webkit-box-shadow .3s; transition: background-color .3s, -webkit-box-shadow .3s; transition: background-color .3s, box-shadow .3s; transition: background-color .3s, box-shadow .3s, -webkit-box-shadow .3s; padding: 12px 16px 12px 42px !important; border: none; border-radius: 3px; -webkit-box-shadow: 0 -1px 0 rgba(0, 0, 0, .04), 0 1px 1px rgba(0, 0, 0, .25); box-shadow: 0 -1px 0 rgba(0, 0, 0, .04), 0 1px 1px rgba(0, 0, 0, .25); color: #757575; font-size: 14px; font-weight: 500; font-family: "Roboto"; background-image: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTgiIGhlaWdodD0iMTgiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGcgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIj48cGF0aCBkPSJNMTcuNiA5LjJsLS4xLTEuOEg5djMuNGg0LjhDMTMuNiAxMiAxMyAxMyAxMiAxMy42djIuMmgzYTguOCA4LjggMCAwIDAgMi42LTYuNnoiIGZpbGw9IiM0Mjg1RjQiIGZpbGwtcnVsZT0ibm9uemVybyIvPjxwYXRoIGQ9Ik05IDE4YzIuNCAwIDQuNS0uOCA2LTIuMmwtMy0yLjJhNS40IDUuNCAwIDAgMS04LTIuOUgxVjEzYTkgOSAwIDAgMCA4IDV6IiBmaWxsPSIjMzRBODUzIiBmaWxsLXJ1bGU9Im5vbnplcm8iLz48cGF0aCBkPSJNNCAxMC43YTUuNCA1LjQgMCAwIDEgMC0zLjRWNUgxYTkgOSAwIDAgMCAwIDhsMy0yLjN6IiBmaWxsPSIjRkJCQzA1IiBmaWxsLXJ1bGU9Im5vbnplcm8iLz48cGF0aCBkPSJNOSAzLjZjMS4zIDAgMi41LjQgMy40IDEuM0wxNSAyLjNBOSA5IDAgMCAwIDEgNWwzIDIuNGE1LjQgNS40IDAgMCAxIDUtMy43eiIgZmlsbD0iI0VBNDMzNSIgZmlsbC1ydWxlPSJub256ZXJvIi8+PHBhdGggZD0iTTAgMGgxOHYxOEgweiIvPjwvZz48L3N2Zz4=); background-color: #FFF; background-repeat: no-repeat; background-position: 12px 11px; } .button-ud-google:hover { -webkit-box-shadow: 0 -1px 0 rgba(0, 0, 0, .04), 0 2px 4px rgba(0, 0, 0, .25); box-shadow: 0 -1px 0 rgba(0, 0, 0, .04), 0 2px 4px rgba(0, 0, 0, .25); } .button-ud-google:active { background-color: #EEE; } .button-ud-google:focus { outline: none; -webkit-box-shadow: 0 -1px 0 rgba(0, 0, 0, .04), 0 2px 4px rgba(0, 0, 0, .25), 0 0 0 3px #C8DAFC; box-shadow: 0 -1px 0 rgba(0, 0, 0, .04), 0 2px 4px rgba(0, 0, 0, .25), 0 0 0 3px #C8DAFC; } .button-ud-google:disabled { -webkit-filter: grayscale(100%); filter: grayscale(100%); background-color: #EBEBEB; -webkit-box-shadow: 0 -1px 0 rgba(0, 0, 0, .04), 0 1px 1px rgba(0, 0, 0, .25); box-shadow: 0 -1px 0 rgba(0, 0, 0, .04), 0 1px 1px rgba(0, 0, 0, .25); cursor: not-allowed; } .dashboard-main-sizing { border-width: 4px; width: 190px; line-height: 1.7em; } p.updraftplus-option { margin-top: 0; margin-bottom: 5px; } p.updraftplus-option-inline { display: inline-block; padding-right: 20px; } span.updraftplus-option-label { display: block; } /* * MIGRATE - CLONE */ #updraft-navtab-migrate-content .postbox { padding: 18px; } /* Clone Rows */ .updraftclone-main-row { display: -webkit-box; display: -ms-flexbox; display: flex; } .updraftclone-tokens { background: #F5F5F5; padding: 20px; border-radius: 10px; margin-right: 20px; max-width: 300px; } .updraftclone-tokens p { margin: 0; } .updraftclone_action_box { background: #F5F5F5; padding: 20px; border-radius: 10px; -webkit-box-flex: 1; -ms-flex: 1; flex: 1; } .updraftclone_action_box p:first-child { margin-top: 0; } .updraftclone_action_box p:last-child { margin-bottom: 0; } .updraftclone_action_box #ud_downloadstatus3 { margin-top: 10px; } span.tokens-number { font-size: 46px; display: block; } /* Clone header button */ .button.updraft_migrate_widget_temporary_clone_show_stage0 { display: none; position: absolute; right: 0; top: 0; height: 100%; border-left: 1px solid #CCC; padding-left: 10px; padding-right: 10px; } .updraft_migrate_widget_temporary_clone_stage0_container { display: -webkit-box; display: -ms-flexbox; display: flex; -webkit-box-orient: vertical; -webkit-box-direction: normal; -ms-flex-direction: column; flex-direction: column; } .updraft_migrate_widget_temporary_clone_stage0_box { margin-right: 20px; width: 100%; -ms-flex-preferred-size: 100%; flex-basis: 100%; } .updraft_migrate_widget_temporary_clone_stage0_box iframe, .updraft_migrate_widget_temporary_clone_stage0_box a.udp-replace-with-iframe--js { float: none; } @media (min-width: 1024px) { .updraft_migrate_widget_temporary_clone_stage0_container { -webkit-box-orient: horizontal; -webkit-box-direction: normal; -ms-flex-direction: row; flex-direction: row; -ms-flex-wrap: wrap; flex-wrap: wrap; } .updraft_migrate_widget_temporary_clone_stage0_box { -ms-flex-preferred-size: 45%; flex-basis: 45%; } .updraft_migrate_widget_temporary_clone_stage0_box iframe, .updraft_migrate_widget_temporary_clone_stage0_box a.udp-replace-with-iframe--js { float: right; } } .updraft_migrate_widget_temporary_clone_show_stage0 .dashicons { text-decoration: none; font-size: 20px; } .opened .button.updraft_migrate_widget_temporary_clone_show_stage0 { display: inline-block; } .opened .updraft_migrate_widget_temporary_clone_stage0 { background: #F5F5F5; padding: 20px; border-radius: 8px; margin-bottom: 21px; } /* Clone list table */ .clone-list { clear: both; width: 100%; margin-top: 40px; } .clone-list table { width: 100%; text-align: left; } .clone-list table tr th { background: #E4E4E4; } .clone-list table tr td { background: #F5F5F5; word-break: break-word; } .clone-list table tr:nth-child(odd) td { background: #FAFAFA; } .clone-list table td, .clone-list table th { padding: 6px; } /* Clone Progress */ .updraftplus-clone .updraft_row { padding-left: 0; padding-right: 0; } button#updraft_migrate_createclone + .updraftplus_spinner { margin-top: 13px; } /* Clone - Show step 1 info button */ .button.button-hero.updraftclone_show_step_1 { white-space: normal; height: auto; line-height: 14px; padding-top: 10px; padding-bottom: 10px; } .button.button-hero.updraftclone_show_step_1 span.dashicons { height: auto; } .updraftplus_clone_status { color: red; } /* MIGRATE */ a.updraft_migrate_add_site--trigger span.dashicons { text-decoration: none; } .button-restore:hover, .button-migrate:hover, .button-backup:hover, .button-view-log:hover, .button-mass-selectors:hover, .button-delete:hover, .button-entity-backup:hover, .udp-button-primary:hover { border-color: #DF6926; color: #DF6926; } .button-migrate { color: rgb(238, 169, 32); border-color: rgb(238, 169, 32); } #updraft_migrate_tab_main { padding: 8px; } .updraft_migrate_widget_module_content { background: #FFF; border-radius: 0; position: relative; } body.js #updraft_migrate .updraft_migrate_widget_module_content { display: none; } .updraft_migrate_widget_module_content > h3, div[class*="updraft_migrate_widget_temporary_clone_stage"] > h3 { margin-top: 0; } /* Migrate / Clone headers */ .updraft_migrate_widget_module_content header, #updraft_migrate_tab_alt header { position: relative; display: -webkit-box; display: -ms-flexbox; display: flex; -ms-flex-line-pack: center; align-content: center; justify-items: center; margin-top: -18px; margin-left: -18px; margin-right: -18px; margin-bottom: 15px; border-bottom: 1px solid #CCC; } .updraft_migrate_widget_module_content header h3, .updraft_migrate_widget_module_content header button.button.close, #updraft_migrate_tab_alt header h3, #updraft_migrate_tab_alt header button.button.close { padding: 10px; line-height: 20px; height: auto; margin: 0; } .updraft_migrate_widget_module_content button.button.close, #updraft_migrate_tab_alt button.button.close { text-decoration: none; padding-left: 5px; border-right: 1px solid #CCC; } .updraft_migrate_widget_module_content button.button.close .dashicons, #updraft_migrate_tab_alt button.button.close .dashicons { margin-top: 1px; } .updraft_migrate_widget_module_content header h3, #updraft_migrate_tab_alt header h3 { margin: 0; } .updraft_migrate_intro button.button.button-primary.button-hero { max-width: 235px; word-wrap: normal; white-space: normal; line-height: 1; height: auto; padding-top: 13px; padding-bottom: 13px; text-align: left; position: relative; margin-right: 10px; margin-bottom: 10px; } .updraft_migrate_intro button.button.button-primary.button-hero .dashicons { position: absolute; left: 10px; top: calc(50% - 8px); } #updraft_migrate_tab_alt #updraft_migrate_send_existing_button { margin-right: 6px; } /* jquery UI Accordion module */ #updraft_migrate .ui-widget-content a { color: #1C94C4; } #updraft-wrap .ui-accordion .ui-accordion-header { background: #F6F6F6; margin: 0; border-radius: 0; padding-left: 0.5em; padding-right: 0.7em; } #updraft-wrap .ui-widget { font-family: inherit; } .ui-accordion-header .ui-accordion-header-icon.ui-icon-caret-1-w { background-position: -96px 0px; } .ui-accordion-header .ui-accordion-header-icon.ui-icon-caret-1-s { background-position: -64px 0; } #updraft-wrap .ui-accordion .ui-accordion-header .ui-accordion-header-icon { left: auto; right: 5px; } #updraft-wrap .ui-accordion .ui-accordion-header:focus { outline: none; -webkit-box-shadow: 0 0 0 1px rgba(91, 157, 217, 0.22), 0 0 2px 1px rgba(30, 140, 190, 0.3); box-shadow: 0 0 0 1px rgba(91, 157, 217, 0.22), 0 0 2px 1px rgba(30, 140, 190, 0.3); background: #FFF; } #updraft-wrap .ui-accordion .ui-accordion-header:focus .dashicons { color: #0572AA; opacity: 1; } #updraft-wrap .ui-accordion .ui-accordion-header.ui-state-active { background: #F6F6F6; border-bottom: 2px solid #0572AA; -webkit-box-shadow: 1px 6px 12px -5px rgba(0, 0, 0, 0.3); box-shadow: 1px 6px 12px -5px rgba(0, 0, 0, 0.3); } #updraft-wrap .ui-accordion .ui-accordion-header.ui-state-active:focus { -webkit-box-shadow: 1px 6px 12px -5px rgba(0, 0, 0, 0.3), 0 0 0 1px #5B9DD9, 0 0 2px 1px rgba(30, 140, 190, .8); box-shadow: 1px 6px 12px -5px rgba(0, 0, 0, 0.3), 0 0 0 1px #5B9DD9, 0 0 2px 1px rgba(30, 140, 190, .8); } #updraft-wrap .ui-accordion .ui-accordion-header:not(:first-child) { border-top: none; } #updraft-wrap .ui-accordion .ui-accordion-header .dashicons { opacity: 0.4; margin-right: 10px; } #updraft-wrap .ui-accordion .ui-accordion-header:focus { outline: none; -webkit-box-shadow: 0 0 0 1px #5B9DD9, 0 0 2px 1px rgba(30, 140, 190, .8); box-shadow: 0 0 0 1px #5B9DD9, 0 0 2px 1px rgba(30, 140, 190, .8); z-index: 1; } button.ui-dialog-titlebar-close:before { content: none!important; } .updraft_next_scheduled_backups_wrapper { display: -webkit-box; display: -ms-flexbox; display: flex; background: #FFF; justify-items: center; -ms-flex-wrap: wrap; flex-wrap: wrap; } .updraft_next_scheduled_backups_wrapper > div { width: 50%; background: #FFF; height: auto; /* padding: 18px 33px; */ padding: 33px; -webkit-box-sizing: border-box; box-sizing: border-box; } .updraft_backup_btn_wrapper { text-align: center; border-left: 1px solid #F1F1F1; -webkit-box-pack: center; -ms-flex-pack: center; justify-content: center; -webkit-box-align: center; -ms-flex-align: center; align-items: center; } .incremental-backups-only { display: none; } .incremental-free-only { display: none; } .incremental-free-only p { padding: 5px; background: rgba(255, 0, 0, 0.06); border: 1px solid #BFBFBF; } #updraft-delete-waitwarning span.spinner { visibility: visible; float: none; margin: 0; margin-right: 10px; } button#updraft-backupnow-button .spinner, button#updraft-backupnow-button .dashicons-yes { display: none; } button#updraft-backupnow-button.loading .spinner { display: inline-block; visibility: visible; margin-top: 13px; margin-right: 0; } button#updraft-backupnow-button.loading { background-color: #EFEFEF; border-color: #CCC; text-shadow: 0 -1px 1px #BBC3C7, 1px 0 1px #BBC3C7, 0 1px 1px #BBC3C7, -1px 0 1px #BBC3C7; -webkit-box-shadow: none; box-shadow: none; } button#updraft-backupnow-button.finished .dashicons-yes { display: inline-block; visibility: visible; font-size: 42px; margin-right: 0; margin-top: 2px; } .updraft_next_scheduled_entity { width: 50%; display: inline-block; float: left; /* padding: 20px 20px 10px 20px; */ } .updraft_next_scheduled_entity .dashicons { color: #CCC; font-size: 20px; } .updraft_next_scheduled_entity strong { font-size: 20px; } .updraft_next_scheduled_heading { margin-bottom: 10px; } .updraft_next_scheduled_date_time { color: #46A84B; } .updraft_time_now_wrapper { margin-top: 68px; width: 100%; } .updraft_time_now_label, .updraft_time_now { display: inline-block; padding: 7px; } .updraft_time_now_label { background: #B7B7B7; border-top-left-radius: 4px; border-bottom-left-radius: 4px; color: #FFF; margin-right: 0; text-shadow: 0 1px 2px rgba(0, 0, 0, 0.4); } .updraft_time_now { background: #F1F1F1; border-top-right-radius: 4px; border-bottom-right-radius: 4px; margin-left: -3px; } #updraft_lastlogmessagerow { margin: 6px 0; } #updraft_lastlogmessagerow { clear: both; padding: 0.25px 0; } #updraft_lastlogmessagerow .updraft-log-link { float: right; margin-top: -2.5em; margin-right: 2px; } #updraft_lastlogmessagerow > div { clear: both; background: #FFF; padding: 18px; } #updraft_activejobs_table { overflow: hidden; width: 100%; background: #FAFAFA; padding: 0; } .updraft_requeststart { padding: 15px 33px; text-align: center; } .updraft_requeststart .spinner { visibility: visible; float: none; vertical-align: middle; margin-top: -2px; } a.updraft_jobinfo_delete.disabled { opacity: 0.4; color: inherit; text-decoration: none; } .updraft_row { clear: both; -webkit-transition: 0.3s all; transition: 0.3s all; padding: 15px 33px; } .updraft_row.deleting { opacity: 0.4; } .updraft_progress_container { /* width: 83%; */ } .updraft_existing_backups_count { padding: 2px 8px; font-size: 12px; background: #CA4A1E; color: #FFF; font-weight: bold; border-radius: 10px; } .form-table .existing-backups-table input[type="checkbox"] { border-radius: 0; } .form-table .existing-backups-table .check-column { width: 40px; padding: 0; padding-top: 8px; } .existing-backups-buttons { font-size: 11px; line-height: 1.4em; border-width: 3px; } .existing-backups-restore-buttons { font-size: 11px; line-height: 1.4em; border-width: 3px; } .button-delete { color: #E23900; border-color: #E23900; font-size: 14px; line-height: 1.4em; border-width: 2px; margin-right: 10px; } .button-view-log, .button-mass-selectors { color: darkgrey; border-color: darkgrey; font-size: 14px; line-height: 1.4em; border-width: 2px; margin-top: -1px; } .button-view-log { width: 120px; } .button-existing-restore { font-size: 14px; line-height: 1.4em; border-width: 2px; width: 110px; } .main-restore { margin-right: 3%; margin-left: 3%; } .button-entity-backup { color: #555; border-color: #555; font-size: 11px; line-height: 1.4em; border-width: 2px; margin-right: 5px; } .button-select-all { width: 122px; } .button-deselect { width: 92px; } #ud_massactions > .display-flex > .mass-selectors-margins, #updraft-delete-waitwarning > .display-flex > .mass-selectors-margins { margin-right: -4px; } .udp-button-primary { border-width: 4px; color: #0073AA; border-color: #0073AA; font-size: 14px; height: 40px; } #ud_massactions .button-delete { margin-right: 0px; } .stored_local { border-radius: 5px; background-color: #007FE7; padding: 3px 5px 5px 5px; color: #FFF; font-size: 75%; } span#updraft_lastlogcontainer { word-break: break-all; } .stored_icon { height: 1.3em; position: relative; top: 0.2em; } .backup_date_label > * { vertical-align: middle; } .backup_date_label .dashicons { font-size: 18px; } .backup_date_label .clear-right { clear: right; } .existing-backups-table .backup_date_label > div, .existing-backups-table .backup_date_label span > div { font-weight: bold; } /* End Main Buttons */ /* End of common elements */ .udp-logo-70 { width: 70px; height: 70px; float: left; padding-right: 25px; } h3 .thank-you { margin-top: 0px; } .ws_advert { max-width: 800px; font-size: 140%; line-height: 140%; padding: 14px; clear: left; } .dismiss-dash-notice { float: right; position: relative; top: -20px; } .updraft_exclude_container, .updraft_include_container { margin-left: 24px; margin-top: 5px; margin-bottom: 10px; padding: 15px; border: 1px solid #DDD; } label.updraft-exclude-label { font-weight: 500; margin-bottom: 5px; display: inline-block; } .updraft_add_exclude_item, #updraft_include_more_paths_another { display: inline-block; margin-top: 10px; } input.updraft_exclude_entity_field, .form-table td input.updraft_exclude_entity_field, .updraftplus-morefiles-row input[type=text] { width: calc(100% - 70px); max-width: 400px; } .updraft-fs-italic { font-style: italic; } @media screen and (max-width: 782px) { .form-table td input.updraft_exclude_entity_field, .form-table td .updraftplus-morefiles-row input[type=text] { display: inline-block; } } .updraft_exclude_entity_delete.dashicons, .updraft_exclude_entity_edit.dashicons, .updraft_exclude_entity_update.dashicons, .updraftplus-morefiles-row a.dashicons { margin-top: 2px; font-size: 20px; -webkit-box-shadow: none; box-shadow: none; line-height: 1; padding: 3px; margin-right: 4px; } .updraft_exclude_entity_delete, .updraft_exclude_entity_delete:hover, .updraftplus-morefiles-row-delete { color: #FF6347; } .updraft_exclude_entity_update.dashicons, .updraft_exclude_entity_update.dashicons:hover { color: #008000; font-weight: bold; font-size: 22px; margin-left: 4px; } .updraft_exclude_entity_edit { margin-left: 4px; } .updraft_exclude_entity_update.is-active ~ .updraft_exclude_entity_delete { display: none; } .updraft-exclude-panel-heading { margin-bottom: 8px; } .updraft-exclude-panel-heading h3 { margin: 0.5em 0 0.5em 0; } .updraft-exclude-submit.button-primary { margin-top: 5px; } .updraft_exclude_actions_list { font-weight: bold; } .updraft-exclude-link { cursor: pointer; } #updraft_include_more_options { padding-left: 25px; } #updraft_report_cell .updraft_reportbox, .updraft_small_box { padding: 12px; margin: 8px 0; border: 1px solid #CCC; position: relative; } #updraft_report_cell button.updraft_reportbox_delete, .updraft_box_delete_button, .updraft_small_box .updraft_box_delete_button { padding: 4px; padding-top: 6px; border: none; background: transparent; position: absolute; top: 4px; right: 4px; cursor: pointer; } #updraft_report_cell button.updraft_reportbox_delete:hover { color: #DE3C3C; } a.updraft_report_another .dashicons { text-decoration: none; margin-top: 2px; } .updraft_report_dbbackup.updraft_report_disabled { color: #CCC; } #updraft-navtab-settings-content .updraft-test-button { font-size: 18px !important; } #updraft_report_cell .updraft_report_email { display: block; width: calc(100% - 50px); margin-bottom: 9px; } #updraft_report_cell .updraft_report_another_p { clear: left; } /* Taken straight from admin.php */ #updraft-navtab-settings-content table.form-table p { max-width: 700px; } #updraft-navtab-settings-content table.form-table .notice p { max-width: none; } #updraft-navtab-backups-content .updraft_existing_backups .updraft_existing_backups_row.backuprowselected, #updraft-navtab-backups-content .updraft_existing_backups .updraft_existing_backups_row.backuprowselected td { background-color: #EFEFEF; } #updraft-navtab-backups-content .updraft_existing_backups .updraft_existing_backups_row.backuprowselected:nth-child(even) td { background-color: #E8E8E8; } .updraft_settings_sectionheading { display: none; } .updraft-backupentitybutton-disabled { background-color: transparent; border: none; color: #0074A2; text-decoration: underline; cursor: pointer; clear: none; float: left; } .updraft-backupentitybutton { margin-left: 8px; } .updraft-bigbutton { padding: 2px 0px !important; margin-right: 14px !important; font-size: 22px !important; min-height: 32px; min-width: 180px; } tr[class*="_updraft_remote_storage_border"] { border-top: 1px solid #CCC; } .updraft_multi_storage_options { float: right; clear: right; margin-bottom: 5px !important; } .updraft_toggle_instance_label { vertical-align: top !important; } .updraft_debugrow th { float: right; text-align: right; font-weight: bold; padding-right: 8px; min-width: 140px; } .updraft_debugrow td { min-width: 300px; vertical-align: bottom; } .updraft_webdav_host_error, .onedrive_folder_error { color: red; } label[for=updraft_servicecheckbox_updraftvault] { position: relative; } #updraft-wrap .udp-info { position: absolute; right: 10px; top: calc(50% - 10px); } #updraft-wrap span.info-trigger { display: inline-block; width: 20px; height: 20px; background: #FFF; color: #72777C; border-radius: 30px; text-align: center; line-height: 20px; -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.15); box-shadow: 0 1px 3px rgba(0, 0, 0, 0.15); } #updraft-wrap .info-content-wrapper { display: none; position: absolute; bottom: 20px; -webkit-transform: translatex(calc(-50% + 10px)); transform: translatex(calc(-50% + 10px)); width: 330px; padding-bottom: 10px; } #updraft-wrap .info-content-wrapper::before { content: ''; position: absolute; bottom: -10px; border: 10px solid transparent; border-top-color: #FFF; left: calc(50% - 10px); } #updraft-wrap .info-content { padding: 20px; background: #FFF; border-radius: 4px; -webkit-box-shadow: 0 3px 10px rgba(0, 0, 0, 0.1); box-shadow: 0 3px 10px rgba(0, 0, 0, 0.1); color: #72777C; } #updraft-wrap .info-content h3 { margin-top: 0; } #updraft-wrap .info-content p { margin-top: 10px; } #updraft-wrap .udp-info:hover .info-content-wrapper { display: block; } div.conditional_remote_backup select.logic_type { vertical-align: inherit !important; } div.conditional_remote_backup label.updraft_toggle_instance_label.radio_group { display: block; margin-top: 7px; } div.conditional_remote_backup div.logic ul.rules input.rule_value { vertical-align: middle; } div.conditional_remote_backup p { margin-bottom: 10px; } div.conditional_remote_backup div.logic ul.rules span svg { width: 20px; vertical-align: middle; cursor: pointer; } div.conditional_remote_backup div.logic ul.rules span svg { margin-left: 3px; } div.conditional_remote_backup div.logic select.logic_type { vertical-align: unset; } /* jstree styles */ /* these styles hide the dots from the parent but keep the arrows */ .updraft_jstree .jstree-container-ul > .jstree-node, div[id^="updraft_more_files_jstree_"] .jstree-container-ul > .jstree-node { background: transparent; } .updraft_jstree .jstree-container-ul > .jstree-open > .jstree-ocl, div[id^="updraft_more_files_jstree_"] .jstree-container-ul > .jstree-open > .jstree-ocl { background-position: -36px -4px; } .updraft_jstree .jstree-container-ul > .jstree-closed> .jstree-ocl, div[id^="updraft_more_files_jstree_"] .jstree-container-ul > .jstree-closed> .jstree-ocl { background-position: -4px -4px; } .updraft_jstree .jstree-container-ul > .jstree-leaf> .jstree-ocl, div[id^="updraft_more_files_jstree_"] .jstree-container-ul > .jstree-leaf> .jstree-ocl { background: transparent; } /* zip browser jstree styles */ #updraft_zip_files_container { position: relative; height: 450px; overflow: none; } .updraft_jstree_info_container { position: relative; height: auto; width: 100%; border: 1px dotted; margin-bottom: 5px; } .updraft_jstree_info_container p { margin: 1px; padding-left: 10px; font-size: 14px; } #updraft_zip_download_item { display: none; color: #0073AA; padding-left: 10px; } #updraft_zip_download_notice { padding-left: 10px; } #updraft_exclude_files_folders_jstree, #updraft_exclude_files_folders_wildcards_jstree { max-height: 200px; overflow-y: scroll; } .updraft_jstree { position: relative; border: 1px dotted; height: 80%; width: 100%; overflow: auto; } /* More files jstree styles */ div[id^="updraft_more_files_container_"] { position: relative; display: none; width: 100%; border: 1px solid #CCC; background: #FAFAFA; margin-bottom: 5px; margin-top: 4px; -webkit-box-shadow: 0 5px 8px rgba(0, 0, 0, 0.1); box-shadow: 0 5px 8px rgba(0, 0, 0, 0.1); } div[id^="updraft_more_files_container_"]::before { content: ' '; width: 11px; height: 11px; display: block; background: #FAFAFA; position: absolute; top: 0; left: 20px; border-top: 1px solid #CCC; border-left: 1px solid #CCC; -webkit-transform: translatey(-7px) rotate(45deg); transform: translatey(-7px) rotate(45deg); } input.updraft_more_path_editing { border-color: #0285BA; } input.updraft_more_path_editing ~ a.dashicons { display: none; } div[id^="updraft_jstree_buttons_"] { padding: 10px; background: #E6E6E6; } div[id^="updraft_jstree_container_"] { height: 300px; width: 100%; overflow: auto; } div[id^="updraft_more_files_container_"] button { line-height: 20px; } button[id^="updraft_parent_directory_"] { margin: 10px 10px 4px 10px; padding-left: 3px; } button[id^="updraft_jstree_confirm_"], button[id^="updraft_jstree_cancel_"] { display: none; } input[id^="updraft_include_more_path_restore_"] { text-align: right; } .updraftplus-morefiles-row-delete, .updraftplus-morefiles-row-edit { cursor: pointer; } #updraft_include_more_paths_error { color: #DE3C3C; } p[id^="updraftplus_manual_authentication_error_"] { color: #DE3C3C; } #updraft-wrap .form-table th { width: 230px; } #updraft-wrap .form-table .existing-backups-table th { width: auto; } .updraft-viewlogdiv form { margin: 0; padding: 0; } .updraft-viewlogdiv { display: inline-block; } .updraft-viewlogdiv input, .updraft-viewlogdiv a { border: none; background-color: transparent; color: #000; margin: 0px; padding: 3px 4px; font-size: 16px; line-height: 26px; } .updraft-viewlogdiv input:hover, .updraft-viewlogdiv a:hover { color: #FFF; cursor: pointer; } .button.button-remove { color: white; background-color: #DE3C3C; border-color: #C00000; -webkit-box-shadow: 0 1px 0 #C10100; box-shadow: 0 1px 0 #C10100; } .button.button-remove:hover, .button.button-remove:focus { border-color: #C00; color: #FFF; background: #C00; } /* button-remove colors for midnight admin theme */ body.admin-color-midnight .button.button-remove { color: #DE3C3C; background-color: #F7F7F7; border-color: #CCC; -webkit-box-shadow: 0 1px 0 #CCC; box-shadow: 0 1px 0 #CCC; } body.admin-color-midnight .button.button-remove:hover, body.admin-color-midnight .button.button-remove:focus { border-color: #BA281F; } body.admin-color-midnight .button.button-remove:focus { -webkit-box-shadow: inherit; box-shadow: inherit; -webkit-box-shadow: 0 0 3px rgba(0, 115, 170, 0.8); box-shadow: 0 0 3px rgba(0, 115, 170, 0.8); } .drag-drop #drag-drop-area2 { border: 4px dashed #DDD; height: 200px; } #drag-drop-area2 .drag-drop-inside { margin: 36px auto 0; width: 350px; } #filelist, #filelist2 { margin-top: 30px; width: 100%; } #filelist .file, #filelist2 .file, .ud_downloadstatus .file, #ud_downloadstatus2 .file, #ud_downloadstatus3 .file { padding: 1px; background: #ECECEC; border: solid 1px #CCC; margin: 4px 0; } .updraft_premium section { margin-bottom: 20px; } /* Call to action Premium */ .updraft_premium_cta { background: #FFF; margin-top: 30px; padding: 0; border-left: 4px solid #DB6A03; } .updraft_premium_cta a { font-weight: normal; } .updraft_premium_cta__action { position: relative; text-align: center; } .updraft_premium_cta a.button.button-primary.button-hero { font-size: 1.3em; letter-spacing: 0.03rem; text-transform: uppercase; margin-bottom: 7px; } .updraft_premium_cta a.button.button-primary.button-hero + small { display: block; max-width: 100%; text-align: center; color: #AFAFAF; } .updraft_premium_cta a.button.button-primary.button-hero + small .dashicons { width: 12px; height: 12px; } .updraft_premium_cta__top { display: -webkit-box; display: -ms-flexbox; display: flex; -webkit-box-align: center; -ms-flex-align: center; align-items: center; -webkit-box-pack: justify; -ms-flex-pack: justify; justify-content: space-between; padding: 18px 30px; } .updraft_premium_cta__bottom { background: #F9F9F9; padding: 5px 30px; } .updraft_premium_cta__summary { margin-right: 60px; } .updraft_premium_cta h2 { font-size: 28px; font-weight: 200; line-height: 1; margin: 0; margin-bottom: 5px; letter-spacing: 0.05rem; color: #DB6A03; } .updraft_premium_cta ul li::after { color: #CCC; } @media only screen and (max-width: 768px) { .updraft_premium_cta__top { -webkit-box-orient: vertical; -webkit-box-direction: normal; -ms-flex-direction: column; flex-direction: column; text-align: center; -webkit-box-align: center; -ms-flex-align: center; align-items: center; } .updraft_premium_cta__summary { margin-right: 0; margin-bottom: 30px; } } /* Box */ .udp-box { background: #FFF; padding: 20px; -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1); text-align: center; } .udp-box h3 { margin: 0; } .udp-box__heading { -ms-flex-item-align: center; align-self: center; background: none; -webkit-box-shadow: none; box-shadow: none; } /* Other Plugins */ .updraft-more-plugins { display: -webkit-box; display: -ms-flexbox; display: flex; -webkit-box-orient: horizontal; -webkit-box-direction: normal; -ms-flex-direction: row; flex-direction: row; -ms-flex-wrap: wrap; flex-wrap: wrap; -webkit-box-pack: justify; -ms-flex-pack: justify; justify-content: space-between; flex-wrap: wrap; } .updraft-more-plugins img { max-width: 80%; max-height: 30%; display: inline-block; } .updraft-more-plugins .udp-box { -webkit-box-sizing: border-box; box-sizing: border-box; width: 24%; } .updraft-more-plugins .udp-box p:last-child { margin-bottom: 0; padding-bottom: 0; } /* links list */ .updraft_premium_description_list { text-align: left; margin: 0; font-size: 12px; } ul.updraft_premium_description_list, ul#updraft_restore_warnings { list-style: disc inside; } ul.updraft_premium_description_list li { display: inline; } ul.updraft_premium_description_list li::after { content: " | "; } ul.updraft_premium_description_list li:last-child::after { content: ""; } .updraft_feature_cell { background-color: #F7D9C9 !important; padding: 5px 10px; } .updraftplus_com_login_status, .updraftplus_com_key_status { display: none; background: #FFF; border-left: 4px solid #FFF; border-left-color: #DC3232; -webkit-box-shadow: 0 1px 1px 0 rgba(0,0,0,.1); box-shadow: 0 1px 1px 0 rgba(0,0,0,.1); margin: 5px 0 15px 0; padding: 5px 12px; } .updraftplus_com_login_status.success { border-left-color: green; } #updraft-wrap strong.success { color: green; } .updraft_feat_table { border: none; border-collapse: collapse; font-size: 120%; background-color: white; text-align: center; } .updraft_feat_th, .updraft_feat_table td { border: 1px solid #F1F1F1; border-collapse: collapse; font-size: 120%; background-color: white; text-align: center; padding: 15px; } .updraft_feat_table td { border-bottom-width: 4px; } .updraft_feat_table td:first-child { border-left: none; } .updraft_feat_table td:last-child { border-right: none; } .updraft_feat_table tr:last-child td { border-bottom: none; } .updraft_feat_table td:nth-child(2), .updraft_feat_table td:nth-child(3) { background-color: rgba(241, 241, 241, 0.38); width: 190px; } .updraft_feat_table__header td img { display: block; margin: 0 auto; } .updraft_feat_table__header td { text-align: center; } .updraft_feat_table .installed { font-size: 14px; } .updraft_feat_table p { padding: 0px 10px; margin: 5px 0px; font-size: 13px; } .updraft_feat_table h4 { margin: 5px 0px; } .updraft_feat_table .dashicons { width: 25px; height: 25px; font-size: 25px; line-height: 1; } .updraft_feat_table .dashicons-yes, .updraft_feat_table .updraft-yes { color: green; } .updraft_feat_table .dashicons-no-alt, .updraft_feat_table .updraft-no { color: red; } .updraft_tick_cell { text-align: center; } .updraft_tick_cell img { margin: 4px 0; height: 24px; } .ud_downloadstatus__close { border: none; background: transparent; width: auto; font-size: 20px; padding: 0; cursor: pointer; } #filelist .fileprogress, #filelist2 .fileprogress, .ud_downloadstatus .dlfileprogress, #ud_downloadstatus2 .dlfileprogress, #ud_downloadstatus3 .dlfileprogress { width: 0%; background: #0572AA; height: 8px; -webkit-transition: width .3s; transition: width .3s; } .ud_downloadstatus .raw, #ud_downloadstatus2 .raw, #ud_downloadstatus3 .raw { margin-top: 8px; clear: left; } .ud_downloadstatus .file, #ud_downloadstatus2 .file, #ud_downloadstatus3 .file { margin-top: 8px; } div[class^="updraftplus_downloader_container_"] { padding: 10px; } tr.updraftplusmethod h3 { margin: 0px; } tr.updraftplusmethod img { max-width: 100%; } #updraft_retain_db_rules .updraft_retain_rules_delete, #updraft_retain_files_rules .updraft_retain_rules_delete { cursor: pointer; color: red; font-size: 120%; font-weight: bold; border: 0px; border-radius: 3px; padding: 2px; margin: 0 6px; text-decoration: none; display: inline-block; } #updraft_retain_db_rules .updraft_retain_rules_delete:hover, #updraft_retain_files_rules .updraft_retain_rules_delete:hover { cursor: pointer; color: white; background: red; } #updraft_backup_started { max-width: 800px; font-size: 140%; line-height: 140%; padding: 14px; clear: left; } /* backup finished */ .blockUI.blockOverlay.ui-widget-overlay { background: #000; } .updraft_success_popup { text-align: center; padding-bottom: 30px; } .updraft_success_popup > .dashicons { font-size: 100px; width: 100px; height: 100px; line-height: 100px; padding: 0px; border-radius: 50%; margin-top: 30px; display: block; margin-left: auto; margin-right: auto; background: #E2E6E5; } .updraft_success_popup > .dashicons.dashicons-yes { text-indent: -5px; } .updraft_success_popup.success > .dashicons { color: green; } .updraft_success_popup.warning > .dashicons { color: #888; } .updraft_success_popup--message { padding: 20px; } .button.updraft-close-overlay .dashicons { text-decoration: none; font-size: 20px; margin-left: -5px; padding: 0; -webkit-transform: translatey(3px); transform: translatey(3px); } .updraft_saving_popup img { -webkit-animation-name: udp_blink; animation-name: udp_blink; -webkit-animation-duration: 610ms; animation-duration: 610ms; -webkit-animation-iteration-count: infinite; animation-iteration-count: infinite; -webkit-animation-direction: alternate; animation-direction: alternate; -webkit-animation-timing-function: ease-out; animation-timing-function: ease-out; } .udp-premium-image { display: none; } @media screen and (min-width: 720px) { .udp-premium-image { display: block; float: left; padding-right: 5px; } } /* End stuff already in admin.php */ #plupload-upload-ui2 { width: 80%; } .backup-restored { padding: 8px; } .updated.backup-restored { padding-top: 15px; padding-bottom: 15px; } .backup-restored span { font-size: 120%; } .memory-limit { padding: 8px; } .updraft_list_errors { padding: 8px; } /*.nav-tab { border-radius: 20px 20px 0 0; border-color: grey; border-width: 2px; margin-top: 34px; } .nav-tab:hover { border-bottom: 0; } .nav-tab-active, .nav-tab-active:active { color: #df6926; border-color: #D3D3D3; border-width: 1px; border-bottom: 0; } .nav-tab-active:focus { color: #df6926; }*/ .nav-tab-wrapper { margin: 14px 0px; } #updraft-poplog-content { white-space: pre-wrap; } .next-backup { border: 0px; padding: 0px; margin: 0 10px 0 0; } .not-scheduled { vertical-align: top !important; margin: 0px !important; padding: 0px !important; } .next-backup .updraft_scheduled { /* width: 124px;*/ margin: 0px; padding: 2px 4px 2px 0px; } #next-backup-table-inner td { vertical-align: top; } .updraft_all-files { color: blue; } .multisite-advert-width { width: 800px; } .updraft_settings_sectionheading { margin-top: 6px; } .premium-upgrade-prompt { /* font-size: 115%; */ } section.premium-upgrade-purchase-success { padding: 2em; background: #FAFAFA; text-align: center; -webkit-box-shadow: 0px 14px 40px rgba(0, 0, 0, 0.1); box-shadow: 0px 14px 40px rgba(0, 0, 0, 0.1); } section.premium-upgrade-purchase-success h3 { font-size: 2em; color: green; } section.premium-upgrade-purchase-success h3 .dashicons { display: block; margin: 0 auto; font-size: 60px; width: 60px; height: 60px; border-radius: 50%; background: green; color: #FFF; margin-bottom: 20px; } section.premium-upgrade-purchase-success h3 .dashicons::before { display: inline-block; margin-left: -4px; margin-top: 2px; } section.premium-upgrade-purchase-success p { font-size: 120%; } .show_admin_restore_in_progress_notice { padding: 8px; } .show_admin_restore_in_progress_notice .unfinished-restoration { font-size: 120%; } #backupnow_includefiles_moreoptions, #backupnow_database_moreoptions, #backupnow_includecloud_moreoptions { margin: 4px 16px 6px 16px; border: 1px dotted; padding: 6px 10px; } #backupnow_database_moreoptions { max-height: 250px; overflow: auto; } #backupnow_database_moreoptions div.backupnow-db-tables { margin-bottom: 5px; } #backupnow_database_moreoptions div.backupnow-db-tables > a { color: #0073AA; } .form-table #updraft_activejobsrow .minimum-height { min-height: 100px; } #updraft_activejobsrow th { max-width: 112px; margin: 0; padding: 13px 0 0 0; } #updraft_lastlogmessagerow .last-message { padding-top: 20px; display: block; } .updraft_simplepie { vertical-align: top; } .download-backups { margin-top: 8px; } .download-backups .updraft_download_button { margin-right: 6px; } .download-backups .ud-whitespace-warning, .download-backups .ud-bom-warning { background-color: pink; padding: 8px; margin: 4px; border: 1px dotted; } .download-backups .ul { list-style: none inside; max-width: 800px; margin-top: 6px; margin-bottom: 12px; } #updraft-plupload-modal { margin: 16px 0; } .download-backups .upload { max-width: 610px; } .download-backups #plupload-upload-ui { width: 100%; } .ud_downloadstatus { padding: 10px 0; } #ud_massactions, #updraft-delete-waitwarning { padding: 14px; background: rgb(241, 241, 241); position: absolute; left: 0; top: 100%; } #ud_massactions > *, #updraft-delete-waitwarning > * { vertical-align: middle; } #ud_massactions .updraftplus-remove { display: inline-block; margin-right: 0; } #ud_massactions .updraftplus-remove a { text-decoration: none; } #ud_massactions .updraft-viewlogdiv a { text-decoration: none; position: relative; } small.ud_massactions-tip { display: inline-block; opacity: 0.5; font-style: italic; margin-left: 20px; } #updraft-navtab-backups-content .updraft_existing_backups { margin-bottom: 35px; position: relative; } #updraft-message-modal-innards { padding: 4px; } #updraft-authenticate-modal { text-align: center; font-size: 16px !important; } #updraft-authenticate-modal p { font-size: 16px; } div.ui-dialog.ui-widget.ui-widget-content { z-index: 99999 !important; } #updraft_delete_form p { margin-top: 3px; padding-top: 0; } #updraft_restore_form .cannot-restore { margin: 8px 0; } .notice.updraft-restore-option { padding: 12px; margin: 8px 0 4px 0; border-left-color: #CCC; } /* updraft_restore_crypteddb */ #updraft_restorer_dboptions h4 { margin: 0px 0px 6px 0px; padding: 0px; } .updraftplus_restore_tables_options_container { max-height: 250px; overflow: auto; } .updraft_debugrow th { vertical-align: top; padding-top: 6px; max-width: 140px; } .expertmode p { font-size: 125%; } .expertmode .call-wp-action { width: 300px; height: 22px; } .updraftplus-lock-advert { clear: left; max-width: 600px; } .uncompressed-data { clear: left; max-width: 600px; } .delete-old-directories { padding: 8px; padding-bottom: 12px; } .active-jobs { width: 100%; text-align: center; padding: 33px; } .job-id { margin-top: 0; margin-bottom: 8px; } .next-resumption { font-weight: bold; } .updraft_percentage { z-index: -1; position: absolute; left: 0px; top: 0px; text-align: center; background-color: #1D8EC2; -webkit-transition: width 0.3s; transition: width 0.3s; } .curstage { z-index: 1; border-radius: 2px; margin-top: 8px; width: 100%; height: 26px; line-height: 26px; position: relative; text-align: center; font-style: italic; color: #FFF; background-color: #B7B7B7; text-shadow: 0 1px 2px rgba(0, 0, 0, 0.3); } .curstage-info { display: inline-block; z-index: 2; } .retain-files { width: 48px; } .backup-interval-description tr td div { max-width: 670px; } #updraft-manualdecrypt-modal { width: 85%; margin: 6px; margin-left: 100px; } .directory-permissions { font-size: 110%; font-weight: bold; } .double-warning { border: 1px solid; padding: 6px; } .raw-backup-info { font-style: italic; font-weight: bold; font-size: 120%; } .updraft_existingbackup_date { width: 22%; max-width: 140px; } .updraft_existing_backups_wrapper { margin-top: 20px; border-top: 1px solid #DDD; } .updraft-no-backups-msg { padding: 10px 40px; text-align: center; font-style: italic; } .tr-bottom-4 { margin-bottom: 4px; } .existing-backups-table th { padding: 8px 10px; } .form-table .backup-date { width: 172px; } .form-table .backup-data { width: 426px; } .form-table .updraft_backup_actions { width: 272px; } .existing-date { -webkit-box-sizing: border-box; box-sizing: border-box; max-width: 140px; width: 25%; } .line-break-tr { height: 2px; padding: 1px; margin: 0px; } .line-break-td { margin: 0; padding: 0; } .td-line-color { height: 2px; background-color: #888; } .raw-backup { max-width: 140px; } .existing-backups-actions { padding: 1px; margin: 0px; } .existing-backups-border { height: 2px; padding: 1px; margin: 0px; } .existing-backups-border > td { margin: 0; padding: 0; } .existing-backups-border > div { height: 2px; background-color: #AAA; } .updraft_existing_backup_date { max-width: 140px; } .updraftplus-upload { margin-right: 6px; float: left; clear: none; } .before-restore-button { padding: 1px; margin: 0px; } .before-restore-button div { float: none; display: inline-block; } .table-separator-tr { height: 2px; padding: 1px; margin: 0px; } .table-separator-td { margin: 0px; padding: 0px; } .end-of-table-div { height: 2px; background-color: #AAA; } .last-backup-job { padding-top: 3% !important; } .line-height-03 { line-height: 0.3 !important; } .line-height-13 { line-height: 1.3 !important; } .line-height-23 { line-height: 2.3 !important; } #updraft_diskspaceused { color: #DF6926; } #updraft_delete_old_dirs_pagediv { padding-bottom: 10px; } /*#updraft_lastlogmessagerow > td, #updraft_last_backup > td { padding: 0; }*/ /* Time + scheduling add-on*/ .fix-time { width: 70px; } .retain-files { width: 70px; } .number-input { min-width: 50px; max-width: 70px; } .additional-rule-width { min-width: 60px; max-width: 70px; } /* Add-ons */ /* Want to fix the WordPress icons so that they fit inline with the text, and don't push everything out of place. */ #updraft-wrap .dashicons.dashicons-adapt-size { line-height: inherit; font-size: inherit; } #updraft-wrap .button span.dashicons:not(.dashicons-adapt-size) { vertical-align: middle; margin-top: -3px; } .addon-logo-150 { margin-left: 30px; margin-top: 33px; height: 125px; width: 150px; } .margin-bottom-50 { margin-bottom: 50px; } .premium-container { width: 80%; } /* Main Header */ .main-header { background-color: #DF6926; height: 200px; width: 100%; } .button-add-to-cart { color: white; border-color: white; float: none; margin-right: 17px; } .button-add-to-cart:hover, .button-add-to-cart:focus, .button-add-to-cart:active { border-color: #A0A5AA; color: #A0A5AA; } .addon-title { margin-top: 25px; } .addon-text { margin-top: 75px; } .image-main-div { width: 25%; float: left; } .text-main-div { width: 60%; float: left; text-align: center; color: white; margin-top: 16px; } .text-main-div-title { font-weight: bold !important; color: white; text-align: center; } .text-main-div-paragraph { color: white; } /* End main header */ /* Vault icons */ .updraftplus-vault-cta { width: 100%; text-align: center; margin-bottom: 50px; } .updraftplus-vault-cta h1 { font-weight: bold; } .updraftvault-buy { width: 225px; height: 225px; border: 2px solid #777; display: inline-table; margin: 0 auto; margin-right: 50px; position: relative; } .updraftplus-vault-cta > .vault-options > .center-vault { width: 275px; height: 275px; } .updraftplus-vault-cta > .vault-options > .center-vault > a { right: 21%; font-size: 16px; border-width: 4px !important; } .updraftplus-vault-cta > .vault-options > .center-vault > p { font-size: 16px; } .updraftvault-buy .button-purchase { right: 24%; margin-left: 0; line-height: 1.7em; } .updraftvault-buy hr { height: 2px; background-color: #777; margin-top: 18px; } .right { margin-right: 0px; } .updraftvault-buy .addon-logo-100 { height: 100px; width: 125px; margin-top: 7px; } .updraftvault-buy .addon-logo-large { margin-top: 7px; } .updraftvault-buy .button-buy-vault { font-size: 12px; color: #DF6926; border-color: #DF6926; border-width: 2px !important; position: absolute; right: 29%; bottom: 2%; } .premium-addon-div .button-purchase { line-height: 1.7em; } .updraftvault-buy .button-buy-vault:hover { border-color: darkgrey; color: darkgrey; } /* End Vault icons */ /* Premium addons */ .premium-addons { margin-top: 80px; width: 100%; margin: 0 auto; display: table; } .addon-list { /* margin-left: 32px; */ display: table; text-align: center; } .premium-addons h1 { text-align: center; font-weight: bold; } .premium-addons p { text-align: center; } .premium-addons .premium-addon-div { width: 200px; height: 250px; border: 2px solid #777; display: inline-table; margin: 0 auto; margin-right: 25px; margin-top: 25px; text-align: center; position: relative; } .premium-addons .premium-addon-div p { margin-left: 2px; margin-right: 2px; } .premium-addons .premium-addon-div img { width: auto; height: 50px; margin-top: 7px; } .premium-addons .premium-addon-div .hr-alignment { margin-top: 44px; } .premium-addons .premium-addon-div .dropbox-logo { height: 39px; width: 150px; } .premium-addons .premium-addon-div .azure-logo, .premium-addons .premium-addon-div .onedrive-logo { width: 75%; height: 24px; } .button-purchase { font-size: 12px; color: #DF6926; border-color: #DF6926; border-width: 2px !important; position: absolute; right: 25%; bottom: 2%; } .button-purchase:hover { color: darkgrey; border-color: darkgrey; } .premium-addons .premium-addon-div hr { height: 2px; background-color: #777; margin-top: 18px; } .premium-addon-div p { font-style: italic; } .addon-list > .premium-addon-div > .onedrive-fix, .addon-list > .premium-addon-div > .azure-logo { margin-top: 33px; } .addon-list > .premium-addon-div > .dropbox-fix { margin-top: 18px; } /* End premium addons */ /* Forgotton something (that is the name of the div rather than a mental note!) */ .premium-forgotton-something { margin-top: 5%; } .premium-forgotton-something h1 { text-align: center; font-weight: bold; } .premium-forgotton-something p { text-align: center; font-weight: normal; } .premium-forgotton-something .button-faq { color: #DF6926; border-color: #DF6926; margin: 0 auto; display: table; } .premium-forgotton-something .button-faq:hover { color: #777; border-color: #777; } /* End of forgotton something */ .updraftplusmethod.updraftvault #vaultlogo { padding-left: 40px; } .updraftplusmethod.updraftvault .vault_primary_option { float: left; width: 50%; text-align: center; padding-bottom: 20px; } .updraftplusmethod.updraftvault .vault_primary_option div { clear: right; padding-top: 20px; } .updraftplusmethod.updraftvault .clear-left { clear: left; } .updraftplusmethod.updraftvault .padding-top-20px { padding-top: 20px; } .updraftplusmethod.updraftvault .padding-top-14px { padding-top: 14px; } .updraftplusmethod.updraftvault #updraftvault_settings_default .button-primary, .updraftplusmethod.updraftvault #updraftvault_settings_showoptions .button-primary { font-size: 18px !important; } .updraftplusmethod.updraftvault #updraftvault_showoptions, .updraftplusmethod.updraftvault #updraftvault_connect { margin-top: 8px; } .updraftplusmethod.updraftvault #updraftvault_settings_connect input { margin-right: 10px; } .updraftplusmethod.updraftvault #updraftvault_email { width: 280px; } .updraftplusmethod.updraftvault #updraftvault_pass { width: 200px; } .updraftplusmethod.updraftvault #vault-is-connected { margin: 0; padding: 0; } .updraftplusmethod.updraftvault #updraftvault_settings_default p { clear: left; } .updraftplusmethod.updraftvault .vault-purchase-option-container { text-align: center; } .updraftplusmethod.updraftvault .vault-purchase-option { width: 40%; text-align: center; padding-top: 20px; display: inline-block; } .updraftplusmethod.updraftvault .vault-purchase-option-size { font-size: 200%; font-weight: bold; } .updraftplusmethod.updraftvault .vault-purchase-option-link { clear: both; font-size: 150%; } .updraftplusmethod.updraftvault .vault-purchase-option-or { clear: both; font-size: 115%; font-style: italic; } /* Automation Backup Advert by B */ .autobackup-image { /* display: inline-block; */ /* min-width: 10%; max-width:25%;*/ /* float: left;*/ clear: left; float: left; width: 110px; height: 110px; } .autobackup-description { width: 100%; } .advert-description { float: left; clear: right; padding: 4px 10px 8px 10px; width: 70%; clear: right; vertical-align: top; } .advert-btn { display: inline-block; min-width: 10%; vertical-align: top; margin-bottom: 8px; } .advert-btn:first-of-type { margin-top: 25px; } .advert-btn a { display: block; cursor: pointer; } a.btn-get-started { background: #FFF; border: 2px solid #DF6926; border-radius: 4px; color: #DF6926; display: inline-block; margin-left: 10px !important; margin-bottom: 7px !important; font-size: 18px !important; line-height: 20px; min-height: 28px; padding: 11px 10px 5px 10px; text-transform: uppercase; text-decoration: none; } .circle-dblarrow { border: 1px solid #DF6926; border-radius: 100%; display: inline-block; font-size: 17px; line-height: 17px; margin-left: 5px; width: 20px; height: 20px; text-align: center; } /* End Automation Backup Advert by B */ /* New Responsive Pretty Advanced Settings */ .expertmode .advanced_settings_container { height: auto; overflow: hidden; } .expertmode .advanced_settings_container .advanced_settings_menu { float: none; border-bottom: 1px solid rgb(204, 204, 204); } .expertmode .advanced_settings_container .advanced_settings_content { padding-top: 5px; float: none; width: auto; overflow: auto; } .expertmode .advanced_settings_container .advanced_settings_content h3:first-child { margin-top: 5px !important; } .expertmode .advanced_settings_container .advanced_settings_content .advanced_tools { display: none; } .expertmode .advanced_settings_container .advanced_settings_content .site_info { display: block; } .expertmode .advanced_settings_container .advanced_settings_menu .advanced_tools_button { display: inline-block; cursor: pointer; padding: 5px; color: #000; } .expertmode .advanced_settings_container .advanced_settings_menu .advanced_tools_text { font-size: 16px; } .expertmode .advanced_settings_container .advanced_settings_menu .advanced_tools_button:hover { background-color: #EAEAEA; } .expertmode .advanced_settings_container .advanced_settings_menu .active { background-color: #3498DB; color: #FFF; } .expertmode .advanced_settings_container .advanced_settings_menu .active:hover { background-color: #72C5FD; color: #FFF; } .expertmode .advanced_settings_container .advanced_settings_content input#import_settings { height: auto !important; } div#updraft-wrap a { cursor: pointer !important; } .updraftcentral_wizard_option { width: 45%; float: left; text-align: center; } .updraftcentral_wizard_option label { margin-bottom: 8px; } #updraftcentral_keys_table { display: none; } .create_key_container { border: 1px solid; border-radius: 4px; padding: 0 0 6px 6px; margin-bottom: 8px; } .updraftcentral_cloud_connect { border-radius: 4px; border: 1px solid #000; padding: 0 20px; margin-top: 30px; background-color: #FFF; } .updraftcentral_cloud_error { border: 1px solid #000; padding: 3px 10px; border-left: 3px solid #F00; background-color: #FFF; margin-bottom: 10px; } .updraftcentral_cloud_info { border: 1px solid #000; padding: 3px 10px; border-left: 3px solid #EF8F31; background-color: #FFF; margin-bottom: 10px; } .updraftplus_spinner.spinner { padding-left: 25px; float: none; } .updraftplus_spinner.spinner.visible { visibility: visible; width: auto; } .updraftcentral_cloud_notices .updraftplus_spinner { margin-top: -5px; } .updraftcentral-subheading { font-size: 14px; margin-top: -10px; margin-bottom: 20px; } #updraftcentral_cloud_form input#email, #updraftcentral_cloud_form input#password { min-width: 250px; } .updraftcentral-data-consent { font-size: 13px; margin-bottom: 10px; } .updraftcentral_cloud_wizard_image { float: left; min-width: 100px; margin-right: 25px; } .updraftcentral_cloud_wizard { float: left; } .updraftcentral_cloud_clear { clear: both; } .updraftplus-settings-footer { margin-top: 30px; } .updraftplus-top-menu { padding: 0.5em; } #updraft_inpage_backup #updraft_activejobs_table { background: transparent; } #updraft_inpage_backup #updraft_lastlogmessagerow .updraft-log-link { float: none; } #updraft_inpage_backup #updraft_activejobsrow .updraft_row { -webkit-box-orient: vertical; -webkit-box-direction: normal; -ms-flex-direction: column; flex-direction: column; padding-left: 20px; padding-right: 20px; } #updraft_inpage_backup #updraft_activejobsrow .updraft_progress_container { width: 100%; } #updraft_inpage_backup #updraft_activejobs_table { overflow: inherit; } #updraft_inpage_backup span#updraft_lastlogcontainer { padding: 18px; background: #FAFAFA; display: block; font-size: 90%; -webkit-box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.1); box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.1); } #updraft_inpage_backup div#updraft_activejobsrow { background: #FAFAFA; -webkit-box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.1); box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.1); } #updraft_inpage_backup #updraft_lastlogmessagerow > div { background: transparent; padding: 0; } #updraft_inpage_backup .last-message > strong { display: block; margin-top: 13px; } body.update-core-php #updraft_inpage_backup h2:nth-child(1) { margin-top: 1em !important; } /* Restoration page */ .updraft_restore_container { display: block; position: fixed; top: 0; left: 0; right: 0; bottom: 0; z-index: 99999; padding-top: 30px; background: #F1F1F1; overflow: auto; } .updraft-modal-is-opened .select2-container { z-index: 99999; } body.updraft-modal-is-opened { overflow: hidden; } .updraft_restore_container h2 { margin: 0; } .updraft_restore_container .updraftmessage { -webkit-box-sizing: border-box; box-sizing: border-box; max-width: 860px; margin-left: auto; margin-right: auto; } .updraft_restore_main { max-width: 860px; margin: 0 auto; margin-top: 20px; background: #FFF; -webkit-box-shadow: 0 3px 3px rgba(0, 0, 0, 0.1); box-shadow: 0 3px 3px rgba(0, 0, 0, 0.1); position: relative; display: -webkit-box; display: -ms-flexbox; display: flex; -ms-flex-wrap: wrap; flex-wrap: wrap; -webkit-box-sizing: border-box; box-sizing: border-box; } .updraft_restore_main--header { font-size: 20px; font-weight: bold; text-align: center; padding-top: 16px; line-height: 20px; width: 100%; max-width: 100%; padding-right: 30px; padding-left: 30px; -webkit-box-sizing: border-box; box-sizing: border-box; } .updraft_restore_main--activity { position: relative; width: calc(100% - 350px); -webkit-box-sizing: border-box; box-sizing: border-box; } .updraft_restore_main--activity-title { padding: 20px; margin: 0; } .show-credentials-form.updraft_restore_main .updraft_restore_main--activity-title { display: none; } .updraft_restore_main--components { width: 350px; padding: 20px; -webkit-box-sizing: border-box; box-sizing: border-box; background: #F8F8F8; min-height: 350px; } .updraft_restore_main:not(.show-credentials-form) div#updraftplus_ajax_restore_output { background: #23282D; color: #E3E3E3; font-family: monospace; padding: 19px; overflow: auto; position: absolute; top: 60px; bottom: 0; right: 0; left: 0; } #updraftplus_ajax_restore_output form { white-space: normal; font-family: -apple-system, blinkmacsystemfont, "Segoe UI", roboto, oxygen-sans, ubuntu, cantarell, "Helvetica Neue", sans-serif; } #updraftplus_ajax_restore_output .updraft_restore_errors { border: 1px solid #DC3232; padding: 10px 20px; white-space: normal; } .updraft_restore_main:not(.show-credentials-form) div#updraftplus_ajax_restore_output h2 { color: #00A0D2; padding-top: 10px; padding-bottom: 5px; } .updraft_restore_main.show-credentials-form div#updraftplus_ajax_restore_output { padding: 20px; border-left: 1px solid #EEE; } .updraft_restore_main.show-credentials-form div#updraftplus_ajax_restore_output #message { margin-left: 0; margin-right: 0; } .updraft_restore_main.show-credentials-form div#updraftplus_ajax_restore_output .form-table td, .updraft_restore_main.show-credentials-form div#updraftplus_ajax_restore_output .form-table th { padding-bottom: 0; } .updraft_restore_main.show-credentials-form .updraft_restore_main--components { opacity: 0.2; } .updraft_restore_main.show-credentials-form div.error .restore-credential-errors--list p { margin: 0; list-style-type: disc; display: list-item; list-style-position: inside; } .restore-credential-errors > :first-child { margin-top: 0; } .restore-credential-errors > :last-child { margin-bottom: 0; } ul.updraft_restore_components_list li { color: #BABABA; font-size: 1.2em; margin-bottom: 1em; } ul.updraft_restore_components_list li::before { content: '\f469'; font-family: dashicons; font-size: 20px; vertical-align: middle; display: inline-block; margin-right: 7px; } ul.updraft_restore_components_list li span { vertical-align: middle; } ul.updraft_restore_components_list li.done { color: green; } ul.updraft_restore_components_list li.done::before { content: "\f147"; } ul.updraft_restore_components_list li.active { color: inherit; } ul.updraft_restore_components_list li.active::before { content: "\f463"; -webkit-animation: udp_rotate 1s linear infinite; animation: udp_rotate 1s linear infinite; } ul.updraft_restore_components_list li.error { color: #DC3232; } ul.updraft_restore_components_list li.error::before { content: "\f335"; } .updraft_restore_result { padding: 10px 0; font-size: 1.3em; margin-bottom: 1em; vertical-align: middle; display: none; } .updraft_restore_result.restore-error { color: #DC3232; } .updraft_restore_result.restore-success { color: green; } .updraft_restore_result .dashicons { font-size: 35px; height: 35px; line-height: 33px; width: 35px; } .updraft_restore_result span { vertical-align: middle; } /* Restore modal */ #updraft-restore-modal { width: 100%; } div#updraft-restore-modal .notice { background: #F8F8F8; } .updraft-restore-modal--stage .updraft--two-halves, .updraft-restore-modal--stage .updraft--one-half { padding: 20px 30px; } .updraft-restore-modal--header { padding: 20px; padding-bottom: 0px; text-align: center; border-bottom: 1px solid #EEE; } .updraft-restore-modal--header h3 { margin: 0; padding: 0; } .updraft-restore-item { padding-bottom: 4px; } .updraft-restore-buttons { padding-top: 10px; } ul.updraft-restore--stages { display: inline-block; margin: 0; height: 28px; } ul.updraft-restore--stages li { display: inline-block; position: relative; width: 12px; height: 12px; background: #D2D2D2; border-radius: 20px; line-height: 1; margin: 0 4px; vertical-align: middle; } ul.updraft-restore--stages li.active { background: #444; } .updraft-restore--footer { border-top: 1px solid #EEE; padding: 20px; text-align: center; position: sticky; bottom: 0; background: #FFF; width: 100%; -webkit-box-sizing: border-box; box-sizing: border-box; } .updraft-restore--footer .updraft-restore--cancel { position: absolute; left: 20px; top: auto; } .updraft-restore--footer .updraft-restore--next-step { position: absolute; right: 20px; top: auto; } ul.updraft-restore--stages li span { position: absolute; width: 120px; bottom: calc(100% + 14px); left: -55px; background: rgba(0,0,0,0.85882); padding: 5px; -webkit-box-sizing: border-box; box-sizing: border-box; border-radius: 4px; color: #FFF; text-align: center; display: none; } ul.updraft-restore--stages li:hover span { display: inline-block; } .updraft-restore-item input[type=checkbox] { margin-bottom: -5px; } .updraft-restore-item input[type=checkbox]:checked + label { font-weight: bold; } /* Hide close button on download window */ div#updraft-restore-modal .ud_downloadstatus__close { display: none; } #ud_downloadstatus2:not(:empty) { margin-top: 15px; } .dashicons.rotate { -webkit-animation: udp_rotate 1s linear infinite; animation: udp_rotate 1s linear infinite; } /* Activity stalled */ span#updraftplus_ajax_restore_last_activity { font-size: .8rem; font-weight: normal; float: right; } .updraft_restore_main--components .updated.show_admin_restore_in_progress_notice { margin: -20px -20px 20px; padding: 19px; } .updraft_restore_main--components .updated.show_admin_restore_in_progress_notice button { margin-right: 5px; } #updraft_migrate_receivingsites .updraftplus-remote-sites-selector .button-primary, .updraft_migrate_add_site .input-field input, .updraft_migrate_add_site button { vertical-align: middle; } #updraft_migrate_receivingsites .text-link-menu a:not(:last-child) { padding-right: 10px; } #updraft_migrate_receivingsites a.updraft_migrate_clear_sites span.dashicons-trash:before { font-size: 17px; } #updraft_migrate_receivingsites .updraft_migrate_add_site { clear: both; } /* RTL Support */ .rtl .advanced_tools.total_size table td { direction: ltr; text-align: right; } .rtl #plupload-upload-ui2.drag-drop #drag-drop-area2 { margin-bottom: 20px; } .rtl #updraft_lastlogmessagerow .updraft-log-link { float: left; } .rtl label.updraft_checkbox > input[type=checkbox] { margin-right: -25px; margin-left: inherit; } .rtl .ud_downloadstatus__close { float: left !important; } .rtl #updraft_backupextradbs_another_container { float: right; } .rtl input.labelauty + label { direction: ltr; position: relative; min-height: 29px; } .rtl input.labelauty + label > span.labelauty-checked-image, .rtl input.labelauty + label > span.labelauty-unchecked-image { right: 8px; top: 11px; position: absolute; } .rtl .button.updraft-close-overlay .dashicons { margin-right: -5px; margin-left: inherit; } .rtl label.updraft_checkbox { margin-right: 26px; margin-left: inherit; } .rtl #updraft-wrap .udp-info { left: 10px; right: inherit; } .rtl input.labelauty + label > span.labelauty-unchecked-image + span.labelauty-unchecked, .rtl input.labelauty + label > span.labelauty-checked-image + span.labelauty-checked { margin-right: 7px; margin-left: inherit; padding: 7px 7px 7px 26px; width: 141px; text-align: right; } .rtl #updraft_report_cell button.updraft_reportbox_delete, .rtl .updraft_box_delete_button, .rtl .updraft_small_box .updraft_box_delete_button { left: 4px; right: inherit; } #updraft_exclude_modal .clause-input-container { overflow: auto; } #updraft_exclude_modal .clause-input-container select, #updraft_exclude_modal .clause-input-container input { float: left; } #updraft_exclude_modal .clause-input-container .wildcards-input { margin: 7px 7px 0 0; } #updraft_exclude_modal .updraft-exclude-panel .contain-clause-sub-label { margin-top: 10px; display: block; } @media only screen and (min-width: 1024px) { #updraft_activejobsrow .updraft_row { display: -webkit-box; display: -ms-flexbox; display: flex; -webkit-box-align: baseline; -ms-flex-align: baseline; align-items: baseline; } #updraft_activejobsrow .updraft_row .updraft_col { -webkit-box-flex: 1; -ms-flex: auto; flex: auto; } #updraft_activejobsrow .updraft_progress_container { width: calc(100% - 230px); } } @media only screen and (min-width: 782px) { .settings_page_updraftplus input[type=text], .settings_page_updraftplus input[type=password], .settings_page_updraftplus input[type=number] { /* border-radius: 4px; */ line-height: 1.42; /* border: 1px solid #CCC; */ height: 27px; padding: 2px 6px; color: #555; } .settings_page_updraftplus input[type="number"] { height: 31px; } #ud_massactions.active, #updraft-delete-waitwarning.active { position: fixed; bottom: 0; left: 160px; right: 0; top: auto; background: #FFF; z-index: 3; -webkit-box-shadow: 0 0 10px rgba(0, 0, 0, 0.2); box-shadow: 0 0 10px rgba(0, 0, 0, 0.2); } .rtl #ud_massactions.active, .rtl #updraft-delete-waitwarning.active { left: 0px; right: 160px; } body.folded #ud_massactions.active, body.folded #updraft-delete-waitwarning.active { left: 36px; } .updraft-after-form-table { margin-left: 250px; } #updraft-navtab-backups-content .updraft_existing_backups .updraft_existing_backups_row.range-selection:not(.backuprowselected) .updraft_existingbackup_date .backup_date_label { color: #FFF; } } @media only screen and (min-width: 782px) and (max-width: 960px) { body.auto-fold #ud_massactions.active, body.auto-fold #updraft-delete-waitwarning.active { left: 36px; } } @media only screen and (max-width: 782px) { #updraft-wrap { margin-right: 0; } #updraft-wrap .form-table td { padding-right: 0; } label.updraft_checkbox { margin-bottom: 8px; margin-top: 8px; margin-left: 36px; } .updraft_retain_rules { position: relative; margin-right: 0; border: 1px solid #CCC; padding: 5px; margin-bottom: -1px; } .updraft_retain_rules_delete { position: absolute; right: 0; top: 5px; } a[id*=updraft_retain_] { display: block; padding: 15px 15px 15px 0; } label.updraft_checkbox > input[type=checkbox] { margin-left: -33px; } #updraft-backupnow-button { margin: 0; display: block; width: 100%; } .updraft_next_scheduled_backups_wrapper > .updraft_backup_btn_wrapper { padding-top: 0; } #ud_massactions, #updraft-delete-waitwarning { width: 100%; -webkit-box-sizing: border-box; box-sizing: border-box; text-align: center; } #ud_massactions.active { position: fixed; top: auto; bottom: 0; width: 100%; -webkit-box-sizing: border-box; box-sizing: border-box; text-align: center; -webkit-box-shadow: 0 -3px 15px rgba(0, 0, 0, 0.08); box-shadow: 0 -3px 15px rgba(0, 0, 0, 0.08); background: #FFF; z-index: 3; } #ud_massactions strong { display: block; margin-bottom: 5px; } small.ud_massactions-tip { display: block; } /* .advert-description { min-width: 75%; margin-bottom: 5px; } .advert-btn { margin-top: 15px; margin-left:86px; min-width: 100%; }*/ .existing-backups-table .backup_date_label > div, .existing-backups-table .backup_date_label span > div { font-weight: normal; } .existing-backups-table .backup_date_label .clear-right { display: inline-block; } table.widefat.existing-backups-table { border: 0; -webkit-box-shadow: none; box-shadow: none; background: transparent; } .existing-backups-table thead { border: none; clip: rect(0 0 0 0); height: 1px; margin: -1px; overflow: hidden; padding: 0; position: absolute; width: 1px; padding: 0; margin: 0; } .existing-backups-table tr { display: block; margin-bottom: .625em; padding-bottom: 16.625px; width: 100%; padding: 0; margin: 0; margin-bottom: 10px; background: #FFF; -webkit-box-shadow: 0 2px 3px rgba(0, 0, 0, 0.1); box-shadow: 0 2px 3px rgba(0, 0, 0, 0.1); } .existing-backups-table td { border-bottom: 1px solid #DDD; display: block; font-size: .9em; text-align: left; width: 100%; padding: 10px; margin: 0; } .wp-list-table.existing-backups-table tr:not(.inline-edit-row):not(.no-items) td:not(.column-primary)::before { /* * aria-label has no advantage, it won't be read inside a table content: attr(aria-label); */ content: attr(data-label); font-weight: bold; display: block; position: relative; left: auto; padding-bottom: 10px; width: auto; text-align: left; } .existing-backups-table td:last-child { border-bottom: 0; } .form-table td.updraft_existingbackup_date { width: inherit; max-width: 100%; } .existing-backups-table td.before-restore-button { min-height: 36px; } .updraft_next_scheduled_backups_wrapper { -webkit-box-orient: vertical; -webkit-box-direction: normal; -ms-flex-direction: column; flex-direction: column; } .updraft_next_scheduled_backups_wrapper > div { width: 100%; } .updraft_progress_container { /* width: 77%; */ } #updraft-navtab-backups-content .updraft_existing_backups .updraft_existing_backups_row { position: relative; } #updraft-navtab-backups-content .updraft_existing_backups .updraft_existing_backups_row.backuprowselected { background-color: #FFF; border-left: 4px solid #0572AA; } #updraft-navtab-backups-content .updraft_existing_backups .updraft_existing_backups_row td:not(.backup-select) { margin-left: 50px; } #updraft-navtab-backups-content .updraft_existing_backups .updraft_existing_backups_row td.backup-select { width: 50px !important; position: absolute; left: 0; top: 0; -webkit-box-sizing: border-box; box-sizing: border-box; height: 100%; z-index: 1; border: none; border-right: 1px solid rgba(0, 0, 0, 0.05); } #updraft-navtab-backups-content .updraft_existing_backups input[type="checkbox"] { height: 25px; } .updraft_migrate_intro button.button.button-primary.button-hero { display: block; margin-right: 0; width: 100%; max-width: 100%; } .updraftclone-main-row { -webkit-box-orient: vertical; -webkit-box-direction: normal; -ms-flex-direction: column; flex-direction: column; } .updraftclone-main-row > div { width: auto; max-width: none; margin-right: 0; margin-bottom: 10px; } .form-table th { padding-bottom: 10px; } .updraft--flex { -webkit-box-orient: vertical; -webkit-box-direction: normal; -ms-flex-direction: column; flex-direction: column; } .updraft_restore_main { -ms-flex-wrap: wrap; flex-wrap: wrap; -webkit-box-orient: vertical; -webkit-box-direction: normal; -ms-flex-direction: column; flex-direction: column; } .updraft_restore_main--components { width: 100%; min-height: 0; } .updraft_restore_main--activity { width: 100%; } div#updraftplus_ajax_restore_output, .updraft_restore_main:not(.show-credentials-form) div#updraftplus_ajax_restore_output { position: relative; top: 0; bottom: auto; } .updraft--flex > .updraft--two-halves, .updraft--flex > .updraft--one-half { width: 100%; } .updraft-restore-item { padding-bottom: 10px; padding-top: 10px; } } @media screen and (max-width: 600px) { .updraft_next_scheduled_backups_wrapper > div { } .updraft_next_scheduled_entity { float: none; width: 100%; margin-bottom: 2em; } .updraft_time_now_wrapper { margin-top: 0; } #updraft_lastlogmessagerow h3 { margin-bottom: 5px; } #updraft_lastlogmessagerow .updraft-log-link { display: block; float: none; margin: 0; margin-bottom: 10px; } } @media screen and (max-width: 520px) { } @media only screen and (min-width: 768px) { .addon-activation-notice { left: 20em; } .existing-backups-table tbody tr.range-selection:hover, .existing-backups-table tbody tr.range-selection { background: #0572AA; /* #2b7fd9 */ } .existing-backups-table tbody tr:hover { background: #F1F1F1; } .existing-backups-table tbody tr td.before-restore-button { position: relative; } .form-table .existing-backups-table thead th.check-column { padding-left: 6px; } .existing-backups-table tr td:first-child { border-left: 4px solid transparent; } .existing-backups-table tr.backuprowselected td:first-child { border-left-color: #0572AA; } } @media screen and (min-width: 670px) { .expertmode .advanced_settings_container .advanced_settings_menu { float: left; width: 215px; border-right: 1px solid rgb(204, 204, 204); border-bottom: none; } .expertmode .advanced_settings_container .advanced_settings_content { padding-left: 10px; padding-top: 0px; } .expertmode .advanced_settings_container .advanced_settings_menu .advanced_tools_button { display: block; } } @media only screen and (max-width: 1068px) { .updraft-more-plugins .udp-box { width: calc(50% - 10px); margin-bottom: 20px; } .updraft_feat_table td:nth-child(2), .updraft_feat_table td:nth-child(3) { width: 100px; } } @media only screen and (max-width: 600px) { .updraft-more-plugins .udp-box { width: 100%; margin-bottom: 20px; } .updraft_feat_table td:nth-child(2), .updraft_feat_table td:nth-child(3) { width: auto; } table.updraft_feat_table { display: block; } table.updraft_feat_table tr { display: -webkit-box; display: -ms-flexbox; display: flex; -ms-flex-wrap: wrap; flex-wrap: wrap; } table.updraft_feat_table td { display: block; } table.updraft_feat_table td:first-child { width: 100%; border-bottom: none; } table.updraft_feat_table td:not(:first-child) { width: 50%; -webkit-box-sizing: border-box; box-sizing: border-box; } table.updraft_feat_table td:first-child:empty { display: none; } td[data-colname]::before { content: attr(data-colname); font-size: 0.8rem; color: #CCC; line-height: 1; } } css/updraftplus-notices-2-23-7.min.css.map000064400000004443152214270100014143 0ustar00{"version":3,"sources":["css/updraftplus-notices.css"],"names":[],"mappings":"AAAA,oBAAoB;;AAEpB;CACC,YAAY;CACZ,gBAAgB;AACjB;;AAEA;CACC,aAAa;CACb,oBAAa;CAAb,oBAAa;CAAb,aAAa;AACd;;AAEA;CACC,mBAAmB;CACnB,oBAAa;CAAb,oBAAa;CAAb,aAAa;CACb,yBAAmB;KAAnB,sBAAmB;SAAnB,mBAAmB;AACpB;;AAEA;CACC,iBAAiB;AAClB;;AAEA;CACC,WAAW;CACX,WAAW;AACZ;;AAEA;CACC,WAAW;CACX,YAAY;CACZ,mBAAmB;CACnB,oBAAa;CAAb,oBAAa;CAAb,aAAa;CACb,yBAAmB;KAAnB,sBAAmB;SAAnB,mBAAmB;AACpB;;AAEA;CACC,WAAW;CACX,WAAW;CACX,gBAAgB;AACjB;;AAEA;CACC,cAAc;CACd,aAAa;CACb,eAAe;CACf,uBAAuB;CACvB,qBAAqB;CACrB,iBAAiB;CACjB,kBAAkB;AACnB;;AAEA;CACC,YAAY;CACZ,eAAe;CACf,mBAAmB;AACpB;;AAEA;CACC,0BAA0B;CAC1B,6BAA6B;AAC9B;;AAEA;CACC,0BAA0B;CAC1B,6BAA6B;AAC9B;;AAEA;CACC,kBAAkB;CAClB,kBAAkB;AACnB;;AAEA;CACC,iBAAiB;AAClB;;AAEA;CACC,kBAAkB;AACnB;;AAEA;;CAEC;EACC,WAAW;CACZ;;AAED","file":"updraftplus-notices-2-23-7.min.css","sourcesContent":["/* CSS for adverts */\n\n.updraft_notice_container {\n\theight: auto;\n\toverflow: hidden;\n}\n\n.updraft_review_notice_container {\n\tpadding: 12px;\n\tdisplay: flex;\n}\n\n.updraft_advert_button_container {\n\tmargin-bottom: 10px;\n\tdisplay: flex;\n\talign-items: center;\n}\n\n.updraft_advert_button_container .dashicons {\n\tmargin-left: 10px;\n}\n\n.updraft_advert_content_left {\n\tfloat: none;\n\twidth: 65px;\n}\n\n.updraft_advert_content_left_extra {\n\tfloat: none;\n\twidth: 100px;\n\tpadding-right: 15px;\n\tdisplay: flex;\n\talign-items: center;\n}\n\n.updraft_advert_content_right {\n\tfloat: none;\n\twidth: auto;\n\toverflow: hidden;\n}\n\n.updraft_advert_bottom {\n\tmargin: 10px 0;\n\tpadding: 10px;\n\tfont-size: 140%;\n\tbackground-color: white;\n\tborder-color: #E6DB55;\n\tborder: 1px solid;\n\tborder-radius: 4px;\n}\n\n.updraft-advert-dismiss {\n\tfloat: right;\n\tfont-size: 13px;\n\tfont-weight: normal;\n}\n\nh3.updraft_advert_heading {\n\tmargin-top: 5px !important;\n\tmargin-bottom: 5px !important;\n}\n\nh4.updraft_advert_heading {\n\tmargin-top: 2px !important;\n\tmargin-bottom: 3px !important;\n}\n\n.updraft_center_content {\n\ttext-align: center;\n\tmargin-bottom: 5px;\n}\n\n.updraft_notice_link {\n\tpadding-left: 5px;\n}\n\n.updraft_text_center {\n\ttext-align: center;\n}\n\n@media screen and (min-width: 560px) {\n\n\t.updraft_advert_content_left, .updraft_advert_content_left_extra {\n\t\tfloat: left;\n\t}\n\n}\n"]}css/updraftplus-tour.css000064400000014352152214270100011405 0ustar00.shepherd-theme-arrows-plain-buttons { z-index: 9999; max-width: 390px!important; } .shepherd-theme-arrows-plain-buttons.super-index { z-index: 999999; } .shepherd-element.shepherd-theme-arrows-plain-buttons .shepherd-content { border-radius: 3px; -webkit-filter: none; filter: none; -webkit-box-shadow: 0px 1px 3px rgba(0, 0, 0, 0.15), 0px 10px 40px rgba(0, 0, 0, 0.15); box-shadow: 0px 1px 3px rgba(0, 0, 0, 0.15), 0px 10px 40px rgba(0, 0, 0, 0.15); } .shepherd-element-attached-bottom.shepherd-element-attached-right.shepherd-target-attached-top.shepherd-target-attached-left .shepherd-content:before, .shepherd-element-attached-bottom.shepherd-element-attached-left.shepherd-target-attached-top.shepherd-target-attached-right .shepherd-content:before, .shepherd-element-attached-top.shepherd-element-attached-right.shepherd-target-attached-bottom.shepherd-target-attached-left .shepherd-content:before, .shepherd-element-attached-top.shepherd-element-attached-left.shepherd-target-attached-bottom.shepherd-target-attached-right .shepherd-content:before { display: none; } .shepherd-element.shepherd-theme-arrows-plain-buttons.shepherd-element-attached-top.shepherd-element-attached-center.shepherd-has-title .shepherd-content:before, .shepherd-element.shepherd-theme-arrows-plain-buttons.shepherd-element-attached-top.shepherd-element-attached-right.shepherd-target-attached-bottom.shepherd-has-title .shepherd-content:before, .shepherd-element.shepherd-theme-arrows-plain-buttons.shepherd-element-attached-top.shepherd-element-attached-left.shepherd-target-attached-bottom.shepherd-has-title .shepherd-content:before { border-bottom-color: #DD6823; } .shepherd-element.shepherd-theme-arrows-plain-buttons.shepherd-has-title .shepherd-content header { background-color: #DD6823; border-radius: 3px 3px 0 0; padding-right: 90px; } .shepherd-element.shepherd-theme-arrows-plain-buttons .shepherd-content header h3 { color: #FFF; font-size: 1.2em; float: none; } .shepherd-element.shepherd-theme-arrows-plain-buttons.shepherd-has-title .shepherd-content header a.shepherd-cancel-link { opacity: 0.7; color: rgba(255, 255, 255, 0); font-size: 0.8em; border: 1px solid #FFF; border-radius: 50%; width: 22px; height: 22px; line-height: 20px; padding: 0; text-align: center; float: none; position: absolute; right: 11px; top: 12px } .shepherd-element.shepherd-theme-arrows-plain-buttons.shepherd-has-title .shepherd-content header a.shepherd-cancel-link::before { color: #FFF; content: attr(data-btntext); position: absolute; right: 20px; padding-right: 10px; } .shepherd-element.shepherd-theme-arrows-plain-buttons.shepherd-has-title .shepherd-content header a.shepherd-cancel-link::after { content: "\f335"; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; font-family: dashicons; color: #FFF; position: absolute; left: 2px; line-height: 21px; font-size: 16px; } .shepherd-element.shepherd-theme-arrows-plain-buttons.shepherd-has-title .shepherd-content header a.shepherd-cancel-link:hover, .shepherd-element.shepherd-theme-arrows-plain-buttons.shepherd-has-title .shepherd-content header a.shepherd-cancel-link:focus { border: 1px solid #A04E00; opacity: 1 } .shepherd-element.shepherd-theme-arrows-plain-buttons.shepherd-has-title .shepherd-content header a.shepherd-cancel-link:hover::before, .shepherd-element.shepherd-theme-arrows-plain-buttons.shepherd-has-title .shepherd-content header a.shepherd-cancel-link:focus::before { color: #A04E00; } .shepherd-element.shepherd-theme-arrows-plain-buttons.shepherd-has-title .shepherd-content header a.shepherd-cancel-link:hover::after, .shepherd-element.shepherd-theme-arrows-plain-buttons.shepherd-has-title .shepherd-content header a.shepherd-cancel-link:focus::after { color: #A04E00; } .shepherd-element.shepherd-theme-arrows-plain-buttons.shepherd-element-attached-top.shepherd-element-attached-left.shepherd-target-attached-right .shepherd-content:before { top: 44px; } .shepherd-content .ud-notice { background: #F0F0F0; padding: 14px; border-radius: 4px; font-size: 90% !important; line-height: 1.5; } .shepherd-content .ud-notice h3 { margin-top: 0; padding-top: 0; margin-bottom: .5em; } .shepherd-element.shepherd-theme-arrows-plain-buttons .shepherd-content .shepherd-text p { margin-top: 0.5em; margin-bottom: 1.3em; } .ud-notice span.ud-special-offer { font-weight: bold; display: inline-block; padding: 1px 6px; border-radius: 3px; background: rgba(217, 105, 0, 0.09); } label[for=updraft_servicecheckbox_updraftvault] { border: 1px solid rgba(204, 204, 204, 0.4); -webkit-transition: border .5s; transition: border .5s } label[for=updraft_servicecheckbox_updraftvault].emphasize { border-color: #DD6823; } .shepherd-element.shepherd-theme-arrows-plain-buttons .shepherd-content footer .shepherd-buttons li .shepherd-button.udp-tour-back, .shepherd-element.shepherd-theme-arrows-plain-buttons .shepherd-content footer .shepherd-buttons li .shepherd-button.udp-tour-end { float: left; position: relative; padding-left: 10px; } .shepherd-element.shepherd-theme-arrows-plain-buttons .shepherd-content footer .shepherd-buttons li .shepherd-button.udp-tour-end { padding-left: 0; color: #B7B7B7; } .shepherd-element.shepherd-theme-arrows-plain-buttons .shepherd-content footer .shepherd-buttons li .shepherd-button.udp-tour-back::before { content: ' '; width: 6px; height: 6px; display: block; border-left: 1px solid; border-bottom: 1px solid; position: absolute; left: 0px; top: 8px; -webkit-transform: rotate(45deg); transform: rotate(45deg); } a.shepherd-button.udp-tour-end::before { display: inline-block; position: relative; content: "\f335"; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; font-family: dashicons; font-size: 20px; line-height: 20px; vertical-align: middle; margin-top: -2px; } .updraftplus-welcome-logo { display: block; width: 70px; float: left; margin-top: -11px; margin-right: 12px; } .updraftplus-welcome-logo img { display: block; width: auto; max-width: 100%; } .highlight-udp .plugins #the-list tr:not([data-slug="updraftplus"]) { opacity: 0.3; } @media(max-width: 790px) { .shepherd-element.shepherd-theme-arrows-plain-buttons { display: none; } } css/updraftplus-admin-2-23-7.min.css000064400000177062152214270100013023 0ustar00@-webkit-keyframes udp_blink{from{opacity:1;-webkit-transform:scale(1);transform:scale(1)}to{opacity:.4;-webkit-transform:scale(0.85);transform:scale(0.85)}}@keyframes udp_blink{from{opacity:1;-webkit-transform:scale(1);transform:scale(1)}to{opacity:.4;-webkit-transform:scale(0.85);transform:scale(0.85)}}@-webkit-keyframes udp_rotate{from{-webkit-transform:rotate(0);transform:rotate(0)}to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes udp_rotate{from{-webkit-transform:rotate(0);transform:rotate(0)}to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}.max-width-600{max-width:600px}.max-width-700{max-width:700px}.width-900{max-width:900px}.width-80{width:80%}.updraft--flex{display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap}.updraft--flex>*{-webkit-box-flex:1;-ms-flex:1;flex:1;-webkit-box-sizing:border-box;box-sizing:border-box}.updraft--flex>.updraft--one-half{width:50%;-webkit-box-flex:1;-ms-flex:auto;flex:auto}.updraft--flex>.updraft--two-halves{width:100%;-webkit-box-flex:1;-ms-flex:auto;flex:auto}.updraft-color--very-light-grey{background:#f8f8f8}.no-decoration{text-decoration:none}.bold{font-weight:bold}.center-align-td{text-align:center}.remove-padding{padding:0 !important}.updraft-text-center{text-align:center}.autobackup{padding:6px;margin:8px 0}ul .disc{list-style:disc inside}.dashicons-log-fix{display:inherit}.udpdraft__lifted{-webkit-box-shadow:0 1px 1px 0 rgba(0,0,0,.1);box-shadow:0 1px 1px 0 rgba(0,0,0,.1)}#updraft-wrap a .dashicons{text-decoration:none}.updraft-field-description,table.form-table td p.updraft-field-description{font-size:90%;line-height:1.2;font-style:italic;margin-bottom:5px}label.updraft_checkbox{display:block;margin-bottom:4px;margin-left:26px}label.updraft_checkbox>input[type=checkbox]{margin-left:-25px}div[id*="updraft_include_"]{margin-bottom:9px}.settings_page_updraftplus input[type="file"]{border:0}.settings_page_updraftplus .wipe_settings{padding-bottom:10px}.settings_page_updraftplus input[type="text"]{font-size:14px}.settings_page_updraftplus select{border-radius:4px;max-width:100%}input.updraft_input--wide,textarea.updraft_input--wide{max-width:442px;width:100%}#updraft-wrap .button-large{font-size:1.3em}.main-dashboard-buttons{border-width:4px;border-radius:12px;letter-spacing:0;font-size:17px;font-weight:bold;padding-left:.7em;padding-right:2em;padding:.3em 1em;line-height:1.7em;background:transparent;position:relative;border:2px solid;-webkit-transition:all .2s;transition:all .2s;vertical-align:baseline;-webkit-box-sizing:border-box;box-sizing:border-box;text-align:center;line-height:1.3em;margin-left:.3em;text-transform:none;line-height:1;text-decoration:none}.button-restore{border-color:#629ec0;color:#629ec0}.button-ud-google{text-decoration:none !important;-webkit-transition:background-color .3s,-webkit-box-shadow .3s;transition:background-color .3s,-webkit-box-shadow .3s;transition:background-color .3s,box-shadow .3s;transition:background-color .3s,box-shadow .3s,-webkit-box-shadow .3s;padding:12px 16px 12px 42px !important;border:0;border-radius:3px;-webkit-box-shadow:0 -1px 0 rgba(0,0,0,.04),0 1px 1px rgba(0,0,0,.25);box-shadow:0 -1px 0 rgba(0,0,0,.04),0 1px 1px rgba(0,0,0,.25);color:#757575;font-size:14px;font-weight:500;font-family:"Roboto";background-image:url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTgiIGhlaWdodD0iMTgiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGcgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIj48cGF0aCBkPSJNMTcuNiA5LjJsLS4xLTEuOEg5djMuNGg0LjhDMTMuNiAxMiAxMyAxMyAxMiAxMy42djIuMmgzYTguOCA4LjggMCAwIDAgMi42LTYuNnoiIGZpbGw9IiM0Mjg1RjQiIGZpbGwtcnVsZT0ibm9uemVybyIvPjxwYXRoIGQ9Ik05IDE4YzIuNCAwIDQuNS0uOCA2LTIuMmwtMy0yLjJhNS40IDUuNCAwIDAgMS04LTIuOUgxVjEzYTkgOSAwIDAgMCA4IDV6IiBmaWxsPSIjMzRBODUzIiBmaWxsLXJ1bGU9Im5vbnplcm8iLz48cGF0aCBkPSJNNCAxMC43YTUuNCA1LjQgMCAwIDEgMC0zLjRWNUgxYTkgOSAwIDAgMCAwIDhsMy0yLjN6IiBmaWxsPSIjRkJCQzA1IiBmaWxsLXJ1bGU9Im5vbnplcm8iLz48cGF0aCBkPSJNOSAzLjZjMS4zIDAgMi41LjQgMy40IDEuM0wxNSAyLjNBOSA5IDAgMCAwIDEgNWwzIDIuNGE1LjQgNS40IDAgMCAxIDUtMy43eiIgZmlsbD0iI0VBNDMzNSIgZmlsbC1ydWxlPSJub256ZXJvIi8+PHBhdGggZD0iTTAgMGgxOHYxOEgweiIvPjwvZz48L3N2Zz4=);background-color:#FFF;background-repeat:no-repeat;background-position:12px 11px}.button-ud-google:hover{-webkit-box-shadow:0 -1px 0 rgba(0,0,0,.04),0 2px 4px rgba(0,0,0,.25);box-shadow:0 -1px 0 rgba(0,0,0,.04),0 2px 4px rgba(0,0,0,.25)}.button-ud-google:active{background-color:#EEE}.button-ud-google:focus{outline:0;-webkit-box-shadow:0 -1px 0 rgba(0,0,0,.04),0 2px 4px rgba(0,0,0,.25),0 0 0 3px #c8dafc;box-shadow:0 -1px 0 rgba(0,0,0,.04),0 2px 4px rgba(0,0,0,.25),0 0 0 3px #c8dafc}.button-ud-google:disabled{-webkit-filter:grayscale(100%);filter:grayscale(100%);background-color:#ebebeb;-webkit-box-shadow:0 -1px 0 rgba(0,0,0,.04),0 1px 1px rgba(0,0,0,.25);box-shadow:0 -1px 0 rgba(0,0,0,.04),0 1px 1px rgba(0,0,0,.25);cursor:not-allowed}.dashboard-main-sizing{border-width:4px;width:190px;line-height:1.7em}p.updraftplus-option{margin-top:0;margin-bottom:5px}p.updraftplus-option-inline{display:inline-block;padding-right:20px}span.updraftplus-option-label{display:block}#updraft-navtab-migrate-content .postbox{padding:18px}.updraftclone-main-row{display:-webkit-box;display:-ms-flexbox;display:flex}.updraftclone-tokens{background:#f5f5f5;padding:20px;border-radius:10px;margin-right:20px;max-width:300px}.updraftclone-tokens p{margin:0}.updraftclone_action_box{background:#f5f5f5;padding:20px;border-radius:10px;-webkit-box-flex:1;-ms-flex:1;flex:1}.updraftclone_action_box p:first-child{margin-top:0}.updraftclone_action_box p:last-child{margin-bottom:0}.updraftclone_action_box #ud_downloadstatus3{margin-top:10px}span.tokens-number{font-size:46px;display:block}.button.updraft_migrate_widget_temporary_clone_show_stage0{display:none;position:absolute;right:0;top:0;height:100%;border-left:1px solid #CCC;padding-left:10px;padding-right:10px}.updraft_migrate_widget_temporary_clone_stage0_container{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}.updraft_migrate_widget_temporary_clone_stage0_box{margin-right:20px;width:100%;-ms-flex-preferred-size:100%;flex-basis:100%}.updraft_migrate_widget_temporary_clone_stage0_box iframe,.updraft_migrate_widget_temporary_clone_stage0_box a.udp-replace-with-iframe--js{float:none}@media(min-width:1024px){.updraft_migrate_widget_temporary_clone_stage0_container{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row;-ms-flex-wrap:wrap;flex-wrap:wrap}.updraft_migrate_widget_temporary_clone_stage0_box{-ms-flex-preferred-size:45%;flex-basis:45%}.updraft_migrate_widget_temporary_clone_stage0_box iframe,.updraft_migrate_widget_temporary_clone_stage0_box a.udp-replace-with-iframe--js{float:right}}.updraft_migrate_widget_temporary_clone_show_stage0 .dashicons{text-decoration:none;font-size:20px}.opened .button.updraft_migrate_widget_temporary_clone_show_stage0{display:inline-block}.opened .updraft_migrate_widget_temporary_clone_stage0{background:#f5f5f5;padding:20px;border-radius:8px;margin-bottom:21px}.clone-list{clear:both;width:100%;margin-top:40px}.clone-list table{width:100%;text-align:left}.clone-list table tr th{background:#e4e4e4}.clone-list table tr td{background:#f5f5f5;word-break:break-word}.clone-list table tr:nth-child(odd) td{background:#fafafa}.clone-list table td,.clone-list table th{padding:6px}.updraftplus-clone .updraft_row{padding-left:0;padding-right:0}button#updraft_migrate_createclone+.updraftplus_spinner{margin-top:13px}.button.button-hero.updraftclone_show_step_1{white-space:normal;height:auto;line-height:14px;padding-top:10px;padding-bottom:10px}.button.button-hero.updraftclone_show_step_1 span.dashicons{height:auto}.updraftplus_clone_status{color:red}a.updraft_migrate_add_site--trigger span.dashicons{text-decoration:none}.button-restore:hover,.button-migrate:hover,.button-backup:hover,.button-view-log:hover,.button-mass-selectors:hover,.button-delete:hover,.button-entity-backup:hover,.udp-button-primary:hover{border-color:#df6926;color:#df6926}.button-migrate{color:#eea920;border-color:#eea920}#updraft_migrate_tab_main{padding:8px}.updraft_migrate_widget_module_content{background:#FFF;border-radius:0;position:relative}body.js #updraft_migrate .updraft_migrate_widget_module_content{display:none}.updraft_migrate_widget_module_content>h3,div[class*="updraft_migrate_widget_temporary_clone_stage"]>h3{margin-top:0}.updraft_migrate_widget_module_content header,#updraft_migrate_tab_alt header{position:relative;display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-line-pack:center;align-content:center;justify-items:center;margin-top:-18px;margin-left:-18px;margin-right:-18px;margin-bottom:15px;border-bottom:1px solid #CCC}.updraft_migrate_widget_module_content header h3,.updraft_migrate_widget_module_content header button.button.close,#updraft_migrate_tab_alt header h3,#updraft_migrate_tab_alt header button.button.close{padding:10px;line-height:20px;height:auto;margin:0}.updraft_migrate_widget_module_content button.button.close,#updraft_migrate_tab_alt button.button.close{text-decoration:none;padding-left:5px;border-right:1px solid #CCC}.updraft_migrate_widget_module_content button.button.close .dashicons,#updraft_migrate_tab_alt button.button.close .dashicons{margin-top:1px}.updraft_migrate_widget_module_content header h3,#updraft_migrate_tab_alt header h3{margin:0}.updraft_migrate_intro button.button.button-primary.button-hero{max-width:235px;word-wrap:normal;white-space:normal;line-height:1;height:auto;padding-top:13px;padding-bottom:13px;text-align:left;position:relative;margin-right:10px;margin-bottom:10px}.updraft_migrate_intro button.button.button-primary.button-hero .dashicons{position:absolute;left:10px;top:calc(50% - 8px)}#updraft_migrate_tab_alt #updraft_migrate_send_existing_button{margin-right:6px}#updraft_migrate .ui-widget-content a{color:#1c94c4}#updraft-wrap .ui-accordion .ui-accordion-header{background:#f6f6f6;margin:0;border-radius:0;padding-left:.5em;padding-right:.7em}#updraft-wrap .ui-widget{font-family:inherit}.ui-accordion-header .ui-accordion-header-icon.ui-icon-caret-1-w{background-position:-96px 0}.ui-accordion-header .ui-accordion-header-icon.ui-icon-caret-1-s{background-position:-64px 0}#updraft-wrap .ui-accordion .ui-accordion-header .ui-accordion-header-icon{left:auto;right:5px}#updraft-wrap .ui-accordion .ui-accordion-header:focus{outline:0;-webkit-box-shadow:0 0 0 1px rgba(91,157,217,0.22),0 0 2px 1px rgba(30,140,190,0.3);box-shadow:0 0 0 1px rgba(91,157,217,0.22),0 0 2px 1px rgba(30,140,190,0.3);background:#FFF}#updraft-wrap .ui-accordion .ui-accordion-header:focus .dashicons{color:#0572aa;opacity:1}#updraft-wrap .ui-accordion .ui-accordion-header.ui-state-active{background:#f6f6f6;border-bottom:2px solid #0572aa;-webkit-box-shadow:1px 6px 12px -5px rgba(0,0,0,0.3);box-shadow:1px 6px 12px -5px rgba(0,0,0,0.3)}#updraft-wrap .ui-accordion .ui-accordion-header.ui-state-active:focus{-webkit-box-shadow:1px 6px 12px -5px rgba(0,0,0,0.3),0 0 0 1px #5b9dd9,0 0 2px 1px rgba(30,140,190,.8);box-shadow:1px 6px 12px -5px rgba(0,0,0,0.3),0 0 0 1px #5b9dd9,0 0 2px 1px rgba(30,140,190,.8)}#updraft-wrap .ui-accordion .ui-accordion-header:not(:first-child){border-top:0}#updraft-wrap .ui-accordion .ui-accordion-header .dashicons{opacity:.4;margin-right:10px}#updraft-wrap .ui-accordion .ui-accordion-header:focus{outline:0;-webkit-box-shadow:0 0 0 1px #5b9dd9,0 0 2px 1px rgba(30,140,190,.8);box-shadow:0 0 0 1px #5b9dd9,0 0 2px 1px rgba(30,140,190,.8);z-index:1}button.ui-dialog-titlebar-close:before{content:none !important}.updraft_next_scheduled_backups_wrapper{display:-webkit-box;display:-ms-flexbox;display:flex;background:#FFF;justify-items:center;-ms-flex-wrap:wrap;flex-wrap:wrap}.updraft_next_scheduled_backups_wrapper>div{width:50%;background:#FFF;height:auto;padding:33px;-webkit-box-sizing:border-box;box-sizing:border-box}.updraft_backup_btn_wrapper{text-align:center;border-left:1px solid #f1f1f1;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.incremental-backups-only{display:none}.incremental-free-only{display:none}.incremental-free-only p{padding:5px;background:rgba(255,0,0,0.06);border:1px solid #bfbfbf}#updraft-delete-waitwarning span.spinner{visibility:visible;float:none;margin:0;margin-right:10px}button#updraft-backupnow-button .spinner,button#updraft-backupnow-button .dashicons-yes{display:none}button#updraft-backupnow-button.loading .spinner{display:inline-block;visibility:visible;margin-top:13px;margin-right:0}button#updraft-backupnow-button.loading{background-color:#efefef;border-color:#CCC;text-shadow:0 -1px 1px #bbc3c7,1px 0 1px #bbc3c7,0 1px 1px #bbc3c7,-1px 0 1px #bbc3c7;-webkit-box-shadow:none;box-shadow:none}button#updraft-backupnow-button.finished .dashicons-yes{display:inline-block;visibility:visible;font-size:42px;margin-right:0;margin-top:2px}.updraft_next_scheduled_entity{width:50%;display:inline-block;float:left}.updraft_next_scheduled_entity .dashicons{color:#CCC;font-size:20px}.updraft_next_scheduled_entity strong{font-size:20px}.updraft_next_scheduled_heading{margin-bottom:10px}.updraft_next_scheduled_date_time{color:#46a84b}.updraft_time_now_wrapper{margin-top:68px;width:100%}.updraft_time_now_label,.updraft_time_now{display:inline-block;padding:7px}.updraft_time_now_label{background:#b7b7b7;border-top-left-radius:4px;border-bottom-left-radius:4px;color:#FFF;margin-right:0;text-shadow:0 1px 2px rgba(0,0,0,0.4)}.updraft_time_now{background:#f1f1f1;border-top-right-radius:4px;border-bottom-right-radius:4px;margin-left:-3px}#updraft_lastlogmessagerow{margin:6px 0}#updraft_lastlogmessagerow{clear:both;padding:.25px 0}#updraft_lastlogmessagerow .updraft-log-link{float:right;margin-top:-2.5em;margin-right:2px}#updraft_lastlogmessagerow>div{clear:both;background:#FFF;padding:18px}#updraft_activejobs_table{overflow:hidden;width:100%;background:#fafafa;padding:0}.updraft_requeststart{padding:15px 33px;text-align:center}.updraft_requeststart .spinner{visibility:visible;float:none;vertical-align:middle;margin-top:-2px}a.updraft_jobinfo_delete.disabled{opacity:.4;color:inherit;text-decoration:none}.updraft_row{clear:both;-webkit-transition:.3s all;transition:.3s all;padding:15px 33px}.updraft_row.deleting{opacity:.4}.updraft_existing_backups_count{padding:2px 8px;font-size:12px;background:#ca4a1e;color:#FFF;font-weight:bold;border-radius:10px}.form-table .existing-backups-table input[type="checkbox"]{border-radius:0}.form-table .existing-backups-table .check-column{width:40px;padding:0;padding-top:8px}.existing-backups-buttons{font-size:11px;line-height:1.4em;border-width:3px}.existing-backups-restore-buttons{font-size:11px;line-height:1.4em;border-width:3px}.button-delete{color:#e23900;border-color:#e23900;font-size:14px;line-height:1.4em;border-width:2px;margin-right:10px}.button-view-log,.button-mass-selectors{color:darkgrey;border-color:darkgrey;font-size:14px;line-height:1.4em;border-width:2px;margin-top:-1px}.button-view-log{width:120px}.button-existing-restore{font-size:14px;line-height:1.4em;border-width:2px;width:110px}.main-restore{margin-right:3%;margin-left:3%}.button-entity-backup{color:#555;border-color:#555;font-size:11px;line-height:1.4em;border-width:2px;margin-right:5px}.button-select-all{width:122px}.button-deselect{width:92px}#ud_massactions>.display-flex>.mass-selectors-margins,#updraft-delete-waitwarning>.display-flex>.mass-selectors-margins{margin-right:-4px}.udp-button-primary{border-width:4px;color:#0073aa;border-color:#0073aa;font-size:14px;height:40px}#ud_massactions .button-delete{margin-right:0}.stored_local{border-radius:5px;background-color:#007fe7;padding:3px 5px 5px 5px;color:#FFF;font-size:75%}span#updraft_lastlogcontainer{word-break:break-all}.stored_icon{height:1.3em;position:relative;top:.2em}.backup_date_label>*{vertical-align:middle}.backup_date_label .dashicons{font-size:18px}.backup_date_label .clear-right{clear:right}.existing-backups-table .backup_date_label>div,.existing-backups-table .backup_date_label span>div{font-weight:bold}.udp-logo-70{width:70px;height:70px;float:left;padding-right:25px}h3 .thank-you{margin-top:0}.ws_advert{max-width:800px;font-size:140%;line-height:140%;padding:14px;clear:left}.dismiss-dash-notice{float:right;position:relative;top:-20px}.updraft_exclude_container,.updraft_include_container{margin-left:24px;margin-top:5px;margin-bottom:10px;padding:15px;border:1px solid #DDD}label.updraft-exclude-label{font-weight:500;margin-bottom:5px;display:inline-block}.updraft_add_exclude_item,#updraft_include_more_paths_another{display:inline-block;margin-top:10px}input.updraft_exclude_entity_field,.form-table td input.updraft_exclude_entity_field,.updraftplus-morefiles-row input[type=text]{width:calc(100% - 70px);max-width:400px}.updraft-fs-italic{font-style:italic}@media screen and (max-width:782px){.form-table td input.updraft_exclude_entity_field,.form-table td .updraftplus-morefiles-row input[type=text]{display:inline-block}}.updraft_exclude_entity_delete.dashicons,.updraft_exclude_entity_edit.dashicons,.updraft_exclude_entity_update.dashicons,.updraftplus-morefiles-row a.dashicons{margin-top:2px;font-size:20px;-webkit-box-shadow:none;box-shadow:none;line-height:1;padding:3px;margin-right:4px}.updraft_exclude_entity_delete,.updraft_exclude_entity_delete:hover,.updraftplus-morefiles-row-delete{color:#ff6347}.updraft_exclude_entity_update.dashicons,.updraft_exclude_entity_update.dashicons:hover{color:#008000;font-weight:bold;font-size:22px;margin-left:4px}.updraft_exclude_entity_edit{margin-left:4px}.updraft_exclude_entity_update.is-active ~ .updraft_exclude_entity_delete{display:none}.updraft-exclude-panel-heading{margin-bottom:8px}.updraft-exclude-panel-heading h3{margin:.5em 0 .5em 0}.updraft-exclude-submit.button-primary{margin-top:5px}.updraft_exclude_actions_list{font-weight:bold}.updraft-exclude-link{cursor:pointer}#updraft_include_more_options{padding-left:25px}#updraft_report_cell .updraft_reportbox,.updraft_small_box{padding:12px;margin:8px 0;border:1px solid #CCC;position:relative}#updraft_report_cell button.updraft_reportbox_delete,.updraft_box_delete_button,.updraft_small_box .updraft_box_delete_button{padding:4px;padding-top:6px;border:0;background:transparent;position:absolute;top:4px;right:4px;cursor:pointer}#updraft_report_cell button.updraft_reportbox_delete:hover{color:#de3c3c}a.updraft_report_another .dashicons{text-decoration:none;margin-top:2px}.updraft_report_dbbackup.updraft_report_disabled{color:#CCC}#updraft-navtab-settings-content .updraft-test-button{font-size:18px !important}#updraft_report_cell .updraft_report_email{display:block;width:calc(100% - 50px);margin-bottom:9px}#updraft_report_cell .updraft_report_another_p{clear:left}#updraft-navtab-settings-content table.form-table p{max-width:700px}#updraft-navtab-settings-content table.form-table .notice p{max-width:none}#updraft-navtab-backups-content .updraft_existing_backups .updraft_existing_backups_row.backuprowselected,#updraft-navtab-backups-content .updraft_existing_backups .updraft_existing_backups_row.backuprowselected td{background-color:#efefef}#updraft-navtab-backups-content .updraft_existing_backups .updraft_existing_backups_row.backuprowselected:nth-child(even) td{background-color:#e8e8e8}.updraft_settings_sectionheading{display:none}.updraft-backupentitybutton-disabled{background-color:transparent;border:0;color:#0074a2;text-decoration:underline;cursor:pointer;clear:none;float:left}.updraft-backupentitybutton{margin-left:8px}.updraft-bigbutton{padding:2px 0 !important;margin-right:14px !important;font-size:22px !important;min-height:32px;min-width:180px}tr[class*="_updraft_remote_storage_border"]{border-top:1px solid #CCC}.updraft_multi_storage_options{float:right;clear:right;margin-bottom:5px !important}.updraft_toggle_instance_label{vertical-align:top !important}.updraft_debugrow th{float:right;text-align:right;font-weight:bold;padding-right:8px;min-width:140px}.updraft_debugrow td{min-width:300px;vertical-align:bottom}.updraft_webdav_host_error,.onedrive_folder_error{color:red}label[for=updraft_servicecheckbox_updraftvault]{position:relative}#updraft-wrap .udp-info{position:absolute;right:10px;top:calc(50% - 10px)}#updraft-wrap span.info-trigger{display:inline-block;width:20px;height:20px;background:#FFF;color:#72777c;border-radius:30px;text-align:center;line-height:20px;-webkit-box-shadow:0 1px 3px rgba(0,0,0,0.15);box-shadow:0 1px 3px rgba(0,0,0,0.15)}#updraft-wrap .info-content-wrapper{display:none;position:absolute;bottom:20px;-webkit-transform:translatex(calc(-50% + 10px));transform:translatex(calc(-50% + 10px));width:330px;padding-bottom:10px}#updraft-wrap .info-content-wrapper::before{content:'';position:absolute;bottom:-10px;border:10px solid transparent;border-top-color:#FFF;left:calc(50% - 10px)}#updraft-wrap .info-content{padding:20px;background:#FFF;border-radius:4px;-webkit-box-shadow:0 3px 10px rgba(0,0,0,0.1);box-shadow:0 3px 10px rgba(0,0,0,0.1);color:#72777c}#updraft-wrap .info-content h3{margin-top:0}#updraft-wrap .info-content p{margin-top:10px}#updraft-wrap .udp-info:hover .info-content-wrapper{display:block}div.conditional_remote_backup select.logic_type{vertical-align:inherit !important}div.conditional_remote_backup label.updraft_toggle_instance_label.radio_group{display:block;margin-top:7px}div.conditional_remote_backup div.logic ul.rules input.rule_value{vertical-align:middle}div.conditional_remote_backup p{margin-bottom:10px}div.conditional_remote_backup div.logic ul.rules span svg{width:20px;vertical-align:middle;cursor:pointer}div.conditional_remote_backup div.logic ul.rules span svg{margin-left:3px}div.conditional_remote_backup div.logic select.logic_type{vertical-align:unset}.updraft_jstree .jstree-container-ul>.jstree-node,div[id^="updraft_more_files_jstree_"] .jstree-container-ul>.jstree-node{background:transparent}.updraft_jstree .jstree-container-ul>.jstree-open>.jstree-ocl,div[id^="updraft_more_files_jstree_"] .jstree-container-ul>.jstree-open>.jstree-ocl{background-position:-36px -4px}.updraft_jstree .jstree-container-ul>.jstree-closed>.jstree-ocl,div[id^="updraft_more_files_jstree_"] .jstree-container-ul>.jstree-closed>.jstree-ocl{background-position:-4px -4px}.updraft_jstree .jstree-container-ul>.jstree-leaf>.jstree-ocl,div[id^="updraft_more_files_jstree_"] .jstree-container-ul>.jstree-leaf>.jstree-ocl{background:transparent}#updraft_zip_files_container{position:relative;height:450px;overflow:none}.updraft_jstree_info_container{position:relative;height:auto;width:100%;border:1px dotted;margin-bottom:5px}.updraft_jstree_info_container p{margin:1px;padding-left:10px;font-size:14px}#updraft_zip_download_item{display:none;color:#0073aa;padding-left:10px}#updraft_zip_download_notice{padding-left:10px}#updraft_exclude_files_folders_jstree,#updraft_exclude_files_folders_wildcards_jstree{max-height:200px;overflow-y:scroll}.updraft_jstree{position:relative;border:1px dotted;height:80%;width:100%;overflow:auto}div[id^="updraft_more_files_container_"]{position:relative;display:none;width:100%;border:1px solid #CCC;background:#fafafa;margin-bottom:5px;margin-top:4px;-webkit-box-shadow:0 5px 8px rgba(0,0,0,0.1);box-shadow:0 5px 8px rgba(0,0,0,0.1)}div[id^="updraft_more_files_container_"]::before{content:' ';width:11px;height:11px;display:block;background:#fafafa;position:absolute;top:0;left:20px;border-top:1px solid #CCC;border-left:1px solid #CCC;-webkit-transform:translatey(-7px) rotate(45deg);transform:translatey(-7px) rotate(45deg)}input.updraft_more_path_editing{border-color:#0285ba}input.updraft_more_path_editing ~ a.dashicons{display:none}div[id^="updraft_jstree_buttons_"]{padding:10px;background:#e6e6e6}div[id^="updraft_jstree_container_"]{height:300px;width:100%;overflow:auto}div[id^="updraft_more_files_container_"] button{line-height:20px}button[id^="updraft_parent_directory_"]{margin:10px 10px 4px 10px;padding-left:3px}button[id^="updraft_jstree_confirm_"],button[id^="updraft_jstree_cancel_"]{display:none}input[id^="updraft_include_more_path_restore_"]{text-align:right}.updraftplus-morefiles-row-delete,.updraftplus-morefiles-row-edit{cursor:pointer}#updraft_include_more_paths_error{color:#de3c3c}p[id^="updraftplus_manual_authentication_error_"]{color:#de3c3c}#updraft-wrap .form-table th{width:230px}#updraft-wrap .form-table .existing-backups-table th{width:auto}.updraft-viewlogdiv form{margin:0;padding:0}.updraft-viewlogdiv{display:inline-block}.updraft-viewlogdiv input,.updraft-viewlogdiv a{border:0;background-color:transparent;color:#000;margin:0;padding:3px 4px;font-size:16px;line-height:26px}.updraft-viewlogdiv input:hover,.updraft-viewlogdiv a:hover{color:#FFF;cursor:pointer}.button.button-remove{color:white;background-color:#de3c3c;border-color:#c00000;-webkit-box-shadow:0 1px 0 #c10100;box-shadow:0 1px 0 #c10100}.button.button-remove:hover,.button.button-remove:focus{border-color:#C00;color:#FFF;background:#C00}body.admin-color-midnight .button.button-remove{color:#de3c3c;background-color:#f7f7f7;border-color:#CCC;-webkit-box-shadow:0 1px 0 #CCC;box-shadow:0 1px 0 #CCC}body.admin-color-midnight .button.button-remove:hover,body.admin-color-midnight .button.button-remove:focus{border-color:#ba281f}body.admin-color-midnight .button.button-remove:focus{-webkit-box-shadow:inherit;box-shadow:inherit;-webkit-box-shadow:0 0 3px rgba(0,115,170,0.8);box-shadow:0 0 3px rgba(0,115,170,0.8)}.drag-drop #drag-drop-area2{border:4px dashed #DDD;height:200px}#drag-drop-area2 .drag-drop-inside{margin:36px auto 0;width:350px}#filelist,#filelist2{margin-top:30px;width:100%}#filelist .file,#filelist2 .file,.ud_downloadstatus .file,#ud_downloadstatus2 .file,#ud_downloadstatus3 .file{padding:1px;background:#ececec;border:solid 1px #CCC;margin:4px 0}.updraft_premium section{margin-bottom:20px}.updraft_premium_cta{background:#FFF;margin-top:30px;padding:0;border-left:4px solid #db6a03}.updraft_premium_cta a{font-weight:normal}.updraft_premium_cta__action{position:relative;text-align:center}.updraft_premium_cta a.button.button-primary.button-hero{font-size:1.3em;letter-spacing:.03rem;text-transform:uppercase;margin-bottom:7px}.updraft_premium_cta a.button.button-primary.button-hero+small{display:block;max-width:100%;text-align:center;color:#afafaf}.updraft_premium_cta a.button.button-primary.button-hero+small .dashicons{width:12px;height:12px}.updraft_premium_cta__top{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between;padding:18px 30px}.updraft_premium_cta__bottom{background:#f9f9f9;padding:5px 30px}.updraft_premium_cta__summary{margin-right:60px}.updraft_premium_cta h2{font-size:28px;font-weight:200;line-height:1;margin:0;margin-bottom:5px;letter-spacing:.05rem;color:#db6a03}.updraft_premium_cta ul li::after{color:#CCC}@media only screen and (max-width:768px){.updraft_premium_cta__top{-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;text-align:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.updraft_premium_cta__summary{margin-right:0;margin-bottom:30px}}.udp-box{background:#FFF;padding:20px;-webkit-box-shadow:0 1px 2px rgba(0,0,0,0.1);box-shadow:0 1px 2px rgba(0,0,0,0.1);text-align:center}.udp-box h3{margin:0}.udp-box__heading{-ms-flex-item-align:center;align-self:center;background:0;-webkit-box-shadow:none;box-shadow:none}.updraft-more-plugins{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row;-ms-flex-wrap:wrap;flex-wrap:wrap;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between;flex-wrap:wrap}.updraft-more-plugins img{max-width:80%;max-height:30%;display:inline-block}.updraft-more-plugins .udp-box{-webkit-box-sizing:border-box;box-sizing:border-box;width:24%}.updraft-more-plugins .udp-box p:last-child{margin-bottom:0;padding-bottom:0}.updraft_premium_description_list{text-align:left;margin:0;font-size:12px}ul.updraft_premium_description_list,ul#updraft_restore_warnings{list-style:disc inside}ul.updraft_premium_description_list li{display:inline}ul.updraft_premium_description_list li::after{content:" | "}ul.updraft_premium_description_list li:last-child::after{content:""}.updraft_feature_cell{background-color:#f7d9c9 !important;padding:5px 10px}.updraftplus_com_login_status,.updraftplus_com_key_status{display:none;background:#FFF;border-left:4px solid #FFF;border-left-color:#dc3232;-webkit-box-shadow:0 1px 1px 0 rgba(0,0,0,.1);box-shadow:0 1px 1px 0 rgba(0,0,0,.1);margin:5px 0 15px 0;padding:5px 12px}.updraftplus_com_login_status.success{border-left-color:green}#updraft-wrap strong.success{color:green}.updraft_feat_table{border:0;border-collapse:collapse;font-size:120%;background-color:white;text-align:center}.updraft_feat_th,.updraft_feat_table td{border:1px solid #f1f1f1;border-collapse:collapse;font-size:120%;background-color:white;text-align:center;padding:15px}.updraft_feat_table td{border-bottom-width:4px}.updraft_feat_table td:first-child{border-left:0}.updraft_feat_table td:last-child{border-right:0}.updraft_feat_table tr:last-child td{border-bottom:0}.updraft_feat_table td:nth-child(2),.updraft_feat_table td:nth-child(3){background-color:rgba(241,241,241,0.38);width:190px}.updraft_feat_table__header td img{display:block;margin:0 auto}.updraft_feat_table__header td{text-align:center}.updraft_feat_table .installed{font-size:14px}.updraft_feat_table p{padding:0 10px;margin:5px 0;font-size:13px}.updraft_feat_table h4{margin:5px 0}.updraft_feat_table .dashicons{width:25px;height:25px;font-size:25px;line-height:1}.updraft_feat_table .dashicons-yes,.updraft_feat_table .updraft-yes{color:green}.updraft_feat_table .dashicons-no-alt,.updraft_feat_table .updraft-no{color:red}.updraft_tick_cell{text-align:center}.updraft_tick_cell img{margin:4px 0;height:24px}.ud_downloadstatus__close{border:0;background:transparent;width:auto;font-size:20px;padding:0;cursor:pointer}#filelist .fileprogress,#filelist2 .fileprogress,.ud_downloadstatus .dlfileprogress,#ud_downloadstatus2 .dlfileprogress,#ud_downloadstatus3 .dlfileprogress{width:0;background:#0572aa;height:8px;-webkit-transition:width .3s;transition:width .3s}.ud_downloadstatus .raw,#ud_downloadstatus2 .raw,#ud_downloadstatus3 .raw{margin-top:8px;clear:left}.ud_downloadstatus .file,#ud_downloadstatus2 .file,#ud_downloadstatus3 .file{margin-top:8px}div[class^="updraftplus_downloader_container_"]{padding:10px}tr.updraftplusmethod h3{margin:0}tr.updraftplusmethod img{max-width:100%}#updraft_retain_db_rules .updraft_retain_rules_delete,#updraft_retain_files_rules .updraft_retain_rules_delete{cursor:pointer;color:red;font-size:120%;font-weight:bold;border:0;border-radius:3px;padding:2px;margin:0 6px;text-decoration:none;display:inline-block}#updraft_retain_db_rules .updraft_retain_rules_delete:hover,#updraft_retain_files_rules .updraft_retain_rules_delete:hover{cursor:pointer;color:white;background:red}#updraft_backup_started{max-width:800px;font-size:140%;line-height:140%;padding:14px;clear:left}.blockUI.blockOverlay.ui-widget-overlay{background:#000}.updraft_success_popup{text-align:center;padding-bottom:30px}.updraft_success_popup>.dashicons{font-size:100px;width:100px;height:100px;line-height:100px;padding:0;border-radius:50%;margin-top:30px;display:block;margin-left:auto;margin-right:auto;background:#e2e6e5}.updraft_success_popup>.dashicons.dashicons-yes{text-indent:-5px}.updraft_success_popup.success>.dashicons{color:green}.updraft_success_popup.warning>.dashicons{color:#888}.updraft_success_popup--message{padding:20px}.button.updraft-close-overlay .dashicons{text-decoration:none;font-size:20px;margin-left:-5px;padding:0;-webkit-transform:translatey(3px);transform:translatey(3px)}.updraft_saving_popup img{-webkit-animation-name:udp_blink;animation-name:udp_blink;-webkit-animation-duration:610ms;animation-duration:610ms;-webkit-animation-iteration-count:infinite;animation-iteration-count:infinite;-webkit-animation-direction:alternate;animation-direction:alternate;-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}.udp-premium-image{display:none}@media screen and (min-width:720px){.udp-premium-image{display:block;float:left;padding-right:5px}}#plupload-upload-ui2{width:80%}.backup-restored{padding:8px}.updated.backup-restored{padding-top:15px;padding-bottom:15px}.backup-restored span{font-size:120%}.memory-limit{padding:8px}.updraft_list_errors{padding:8px}.nav-tab-wrapper{margin:14px 0}#updraft-poplog-content{white-space:pre-wrap}.next-backup{border:0;padding:0;margin:0 10px 0 0}.not-scheduled{vertical-align:top !important;margin:0 !important;padding:0 !important}.next-backup .updraft_scheduled{margin:0;padding:2px 4px 2px 0}#next-backup-table-inner td{vertical-align:top}.updraft_all-files{color:blue}.multisite-advert-width{width:800px}.updraft_settings_sectionheading{margin-top:6px}section.premium-upgrade-purchase-success{padding:2em;background:#fafafa;text-align:center;-webkit-box-shadow:0 14px 40px rgba(0,0,0,0.1);box-shadow:0 14px 40px rgba(0,0,0,0.1)}section.premium-upgrade-purchase-success h3{font-size:2em;color:green}section.premium-upgrade-purchase-success h3 .dashicons{display:block;margin:0 auto;font-size:60px;width:60px;height:60px;border-radius:50%;background:green;color:#FFF;margin-bottom:20px}section.premium-upgrade-purchase-success h3 .dashicons::before{display:inline-block;margin-left:-4px;margin-top:2px}section.premium-upgrade-purchase-success p{font-size:120%}.show_admin_restore_in_progress_notice{padding:8px}.show_admin_restore_in_progress_notice .unfinished-restoration{font-size:120%}#backupnow_includefiles_moreoptions,#backupnow_database_moreoptions,#backupnow_includecloud_moreoptions{margin:4px 16px 6px 16px;border:1px dotted;padding:6px 10px}#backupnow_database_moreoptions{max-height:250px;overflow:auto}#backupnow_database_moreoptions div.backupnow-db-tables{margin-bottom:5px}#backupnow_database_moreoptions div.backupnow-db-tables>a{color:#0073aa}.form-table #updraft_activejobsrow .minimum-height{min-height:100px}#updraft_activejobsrow th{max-width:112px;margin:0;padding:13px 0 0 0}#updraft_lastlogmessagerow .last-message{padding-top:20px;display:block}.updraft_simplepie{vertical-align:top}.download-backups{margin-top:8px}.download-backups .updraft_download_button{margin-right:6px}.download-backups .ud-whitespace-warning,.download-backups .ud-bom-warning{background-color:pink;padding:8px;margin:4px;border:1px dotted}.download-backups .ul{list-style:none inside;max-width:800px;margin-top:6px;margin-bottom:12px}#updraft-plupload-modal{margin:16px 0}.download-backups .upload{max-width:610px}.download-backups #plupload-upload-ui{width:100%}.ud_downloadstatus{padding:10px 0}#ud_massactions,#updraft-delete-waitwarning{padding:14px;background:#f1f1f1;position:absolute;left:0;top:100%}#ud_massactions>*,#updraft-delete-waitwarning>*{vertical-align:middle}#ud_massactions .updraftplus-remove{display:inline-block;margin-right:0}#ud_massactions .updraftplus-remove a{text-decoration:none}#ud_massactions .updraft-viewlogdiv a{text-decoration:none;position:relative}small.ud_massactions-tip{display:inline-block;opacity:.5;font-style:italic;margin-left:20px}#updraft-navtab-backups-content .updraft_existing_backups{margin-bottom:35px;position:relative}#updraft-message-modal-innards{padding:4px}#updraft-authenticate-modal{text-align:center;font-size:16px !important}#updraft-authenticate-modal p{font-size:16px}div.ui-dialog.ui-widget.ui-widget-content{z-index:99999 !important}#updraft_delete_form p{margin-top:3px;padding-top:0}#updraft_restore_form .cannot-restore{margin:8px 0}.notice.updraft-restore-option{padding:12px;margin:8px 0 4px 0;border-left-color:#CCC}#updraft_restorer_dboptions h4{margin:0 0 6px 0;padding:0}.updraftplus_restore_tables_options_container{max-height:250px;overflow:auto}.updraft_debugrow th{vertical-align:top;padding-top:6px;max-width:140px}.expertmode p{font-size:125%}.expertmode .call-wp-action{width:300px;height:22px}.updraftplus-lock-advert{clear:left;max-width:600px}.uncompressed-data{clear:left;max-width:600px}.delete-old-directories{padding:8px;padding-bottom:12px}.active-jobs{width:100%;text-align:center;padding:33px}.job-id{margin-top:0;margin-bottom:8px}.next-resumption{font-weight:bold}.updraft_percentage{z-index:-1;position:absolute;left:0;top:0;text-align:center;background-color:#1d8ec2;-webkit-transition:width .3s;transition:width .3s}.curstage{z-index:1;border-radius:2px;margin-top:8px;width:100%;height:26px;line-height:26px;position:relative;text-align:center;font-style:italic;color:#FFF;background-color:#b7b7b7;text-shadow:0 1px 2px rgba(0,0,0,0.3)}.curstage-info{display:inline-block;z-index:2}.retain-files{width:48px}.backup-interval-description tr td div{max-width:670px}#updraft-manualdecrypt-modal{width:85%;margin:6px;margin-left:100px}.directory-permissions{font-size:110%;font-weight:bold}.double-warning{border:1px solid;padding:6px}.raw-backup-info{font-style:italic;font-weight:bold;font-size:120%}.updraft_existingbackup_date{width:22%;max-width:140px}.updraft_existing_backups_wrapper{margin-top:20px;border-top:1px solid #DDD}.updraft-no-backups-msg{padding:10px 40px;text-align:center;font-style:italic}.tr-bottom-4{margin-bottom:4px}.existing-backups-table th{padding:8px 10px}.form-table .backup-date{width:172px}.form-table .backup-data{width:426px}.form-table .updraft_backup_actions{width:272px}.existing-date{-webkit-box-sizing:border-box;box-sizing:border-box;max-width:140px;width:25%}.line-break-tr{height:2px;padding:1px;margin:0}.line-break-td{margin:0;padding:0}.td-line-color{height:2px;background-color:#888}.raw-backup{max-width:140px}.existing-backups-actions{padding:1px;margin:0}.existing-backups-border{height:2px;padding:1px;margin:0}.existing-backups-border>td{margin:0;padding:0}.existing-backups-border>div{height:2px;background-color:#AAA}.updraft_existing_backup_date{max-width:140px}.updraftplus-upload{margin-right:6px;float:left;clear:none}.before-restore-button{padding:1px;margin:0}.before-restore-button div{float:none;display:inline-block}.table-separator-tr{height:2px;padding:1px;margin:0}.table-separator-td{margin:0;padding:0}.end-of-table-div{height:2px;background-color:#AAA}.last-backup-job{padding-top:3% !important}.line-height-03{line-height:.3 !important}.line-height-13{line-height:1.3 !important}.line-height-23{line-height:2.3 !important}#updraft_diskspaceused{color:#df6926}#updraft_delete_old_dirs_pagediv{padding-bottom:10px}.fix-time{width:70px}.retain-files{width:70px}.number-input{min-width:50px;max-width:70px}.additional-rule-width{min-width:60px;max-width:70px}#updraft-wrap .dashicons.dashicons-adapt-size{line-height:inherit;font-size:inherit}#updraft-wrap .button span.dashicons:not(.dashicons-adapt-size){vertical-align:middle;margin-top:-3px}.addon-logo-150{margin-left:30px;margin-top:33px;height:125px;width:150px}.margin-bottom-50{margin-bottom:50px}.premium-container{width:80%}.main-header{background-color:#df6926;height:200px;width:100%}.button-add-to-cart{color:white;border-color:white;float:none;margin-right:17px}.button-add-to-cart:hover,.button-add-to-cart:focus,.button-add-to-cart:active{border-color:#a0a5aa;color:#a0a5aa}.addon-title{margin-top:25px}.addon-text{margin-top:75px}.image-main-div{width:25%;float:left}.text-main-div{width:60%;float:left;text-align:center;color:white;margin-top:16px}.text-main-div-title{font-weight:bold !important;color:white;text-align:center}.text-main-div-paragraph{color:white}.updraftplus-vault-cta{width:100%;text-align:center;margin-bottom:50px}.updraftplus-vault-cta h1{font-weight:bold}.updraftvault-buy{width:225px;height:225px;border:2px solid #777;display:inline-table;margin:0 auto;margin-right:50px;position:relative}.updraftplus-vault-cta>.vault-options>.center-vault{width:275px;height:275px}.updraftplus-vault-cta>.vault-options>.center-vault>a{right:21%;font-size:16px;border-width:4px !important}.updraftplus-vault-cta>.vault-options>.center-vault>p{font-size:16px}.updraftvault-buy .button-purchase{right:24%;margin-left:0;line-height:1.7em}.updraftvault-buy hr{height:2px;background-color:#777;margin-top:18px}.right{margin-right:0}.updraftvault-buy .addon-logo-100{height:100px;width:125px;margin-top:7px}.updraftvault-buy .addon-logo-large{margin-top:7px}.updraftvault-buy .button-buy-vault{font-size:12px;color:#df6926;border-color:#df6926;border-width:2px !important;position:absolute;right:29%;bottom:2%}.premium-addon-div .button-purchase{line-height:1.7em}.updraftvault-buy .button-buy-vault:hover{border-color:darkgrey;color:darkgrey}.premium-addons{margin-top:80px;width:100%;margin:0 auto;display:table}.addon-list{display:table;text-align:center}.premium-addons h1{text-align:center;font-weight:bold}.premium-addons p{text-align:center}.premium-addons .premium-addon-div{width:200px;height:250px;border:2px solid #777;display:inline-table;margin:0 auto;margin-right:25px;margin-top:25px;text-align:center;position:relative}.premium-addons .premium-addon-div p{margin-left:2px;margin-right:2px}.premium-addons .premium-addon-div img{width:auto;height:50px;margin-top:7px}.premium-addons .premium-addon-div .hr-alignment{margin-top:44px}.premium-addons .premium-addon-div .dropbox-logo{height:39px;width:150px}.premium-addons .premium-addon-div .azure-logo,.premium-addons .premium-addon-div .onedrive-logo{width:75%;height:24px}.button-purchase{font-size:12px;color:#df6926;border-color:#df6926;border-width:2px !important;position:absolute;right:25%;bottom:2%}.button-purchase:hover{color:darkgrey;border-color:darkgrey}.premium-addons .premium-addon-div hr{height:2px;background-color:#777;margin-top:18px}.premium-addon-div p{font-style:italic}.addon-list>.premium-addon-div>.onedrive-fix,.addon-list>.premium-addon-div>.azure-logo{margin-top:33px}.addon-list>.premium-addon-div>.dropbox-fix{margin-top:18px}.premium-forgotton-something{margin-top:5%}.premium-forgotton-something h1{text-align:center;font-weight:bold}.premium-forgotton-something p{text-align:center;font-weight:normal}.premium-forgotton-something .button-faq{color:#df6926;border-color:#df6926;margin:0 auto;display:table}.premium-forgotton-something .button-faq:hover{color:#777;border-color:#777}.updraftplusmethod.updraftvault #vaultlogo{padding-left:40px}.updraftplusmethod.updraftvault .vault_primary_option{float:left;width:50%;text-align:center;padding-bottom:20px}.updraftplusmethod.updraftvault .vault_primary_option div{clear:right;padding-top:20px}.updraftplusmethod.updraftvault .clear-left{clear:left}.updraftplusmethod.updraftvault .padding-top-20px{padding-top:20px}.updraftplusmethod.updraftvault .padding-top-14px{padding-top:14px}.updraftplusmethod.updraftvault #updraftvault_settings_default .button-primary,.updraftplusmethod.updraftvault #updraftvault_settings_showoptions .button-primary{font-size:18px !important}.updraftplusmethod.updraftvault #updraftvault_showoptions,.updraftplusmethod.updraftvault #updraftvault_connect{margin-top:8px}.updraftplusmethod.updraftvault #updraftvault_settings_connect input{margin-right:10px}.updraftplusmethod.updraftvault #updraftvault_email{width:280px}.updraftplusmethod.updraftvault #updraftvault_pass{width:200px}.updraftplusmethod.updraftvault #vault-is-connected{margin:0;padding:0}.updraftplusmethod.updraftvault #updraftvault_settings_default p{clear:left}.updraftplusmethod.updraftvault .vault-purchase-option-container{text-align:center}.updraftplusmethod.updraftvault .vault-purchase-option{width:40%;text-align:center;padding-top:20px;display:inline-block}.updraftplusmethod.updraftvault .vault-purchase-option-size{font-size:200%;font-weight:bold}.updraftplusmethod.updraftvault .vault-purchase-option-link{clear:both;font-size:150%}.updraftplusmethod.updraftvault .vault-purchase-option-or{clear:both;font-size:115%;font-style:italic}.autobackup-image{clear:left;float:left;width:110px;height:110px}.autobackup-description{width:100%}.advert-description{float:left;clear:right;padding:4px 10px 8px 10px;width:70%;clear:right;vertical-align:top}.advert-btn{display:inline-block;min-width:10%;vertical-align:top;margin-bottom:8px}.advert-btn:first-of-type{margin-top:25px}.advert-btn a{display:block;cursor:pointer}a.btn-get-started{background:#FFF;border:2px solid #df6926;border-radius:4px;color:#df6926;display:inline-block;margin-left:10px !important;margin-bottom:7px !important;font-size:18px !important;line-height:20px;min-height:28px;padding:11px 10px 5px 10px;text-transform:uppercase;text-decoration:none}.circle-dblarrow{border:1px solid #df6926;border-radius:100%;display:inline-block;font-size:17px;line-height:17px;margin-left:5px;width:20px;height:20px;text-align:center}.expertmode .advanced_settings_container{height:auto;overflow:hidden}.expertmode .advanced_settings_container .advanced_settings_menu{float:none;border-bottom:1px solid #ccc}.expertmode .advanced_settings_container .advanced_settings_content{padding-top:5px;float:none;width:auto;overflow:auto}.expertmode .advanced_settings_container .advanced_settings_content h3:first-child{margin-top:5px !important}.expertmode .advanced_settings_container .advanced_settings_content .advanced_tools{display:none}.expertmode .advanced_settings_container .advanced_settings_content .site_info{display:block}.expertmode .advanced_settings_container .advanced_settings_menu .advanced_tools_button{display:inline-block;cursor:pointer;padding:5px;color:#000}.expertmode .advanced_settings_container .advanced_settings_menu .advanced_tools_text{font-size:16px}.expertmode .advanced_settings_container .advanced_settings_menu .advanced_tools_button:hover{background-color:#eaeaea}.expertmode .advanced_settings_container .advanced_settings_menu .active{background-color:#3498db;color:#FFF}.expertmode .advanced_settings_container .advanced_settings_menu .active:hover{background-color:#72c5fd;color:#FFF}.expertmode .advanced_settings_container .advanced_settings_content input#import_settings{height:auto !important}div#updraft-wrap a{cursor:pointer !important}.updraftcentral_wizard_option{width:45%;float:left;text-align:center}.updraftcentral_wizard_option label{margin-bottom:8px}#updraftcentral_keys_table{display:none}.create_key_container{border:1px solid;border-radius:4px;padding:0 0 6px 6px;margin-bottom:8px}.updraftcentral_cloud_connect{border-radius:4px;border:1px solid #000;padding:0 20px;margin-top:30px;background-color:#FFF}.updraftcentral_cloud_error{border:1px solid #000;padding:3px 10px;border-left:3px solid #F00;background-color:#FFF;margin-bottom:10px}.updraftcentral_cloud_info{border:1px solid #000;padding:3px 10px;border-left:3px solid #ef8f31;background-color:#FFF;margin-bottom:10px}.updraftplus_spinner.spinner{padding-left:25px;float:none}.updraftplus_spinner.spinner.visible{visibility:visible;width:auto}.updraftcentral_cloud_notices .updraftplus_spinner{margin-top:-5px}.updraftcentral-subheading{font-size:14px;margin-top:-10px;margin-bottom:20px}#updraftcentral_cloud_form input#email,#updraftcentral_cloud_form input#password{min-width:250px}.updraftcentral-data-consent{font-size:13px;margin-bottom:10px}.updraftcentral_cloud_wizard_image{float:left;min-width:100px;margin-right:25px}.updraftcentral_cloud_wizard{float:left}.updraftcentral_cloud_clear{clear:both}.updraftplus-settings-footer{margin-top:30px}.updraftplus-top-menu{padding:.5em}#updraft_inpage_backup #updraft_activejobs_table{background:transparent}#updraft_inpage_backup #updraft_lastlogmessagerow .updraft-log-link{float:none}#updraft_inpage_backup #updraft_activejobsrow .updraft_row{-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;padding-left:20px;padding-right:20px}#updraft_inpage_backup #updraft_activejobsrow .updraft_progress_container{width:100%}#updraft_inpage_backup #updraft_activejobs_table{overflow:inherit}#updraft_inpage_backup span#updraft_lastlogcontainer{padding:18px;background:#fafafa;display:block;font-size:90%;-webkit-box-shadow:0 1px 2px rgba(0,0,0,0.1);box-shadow:0 1px 2px rgba(0,0,0,0.1)}#updraft_inpage_backup div#updraft_activejobsrow{background:#fafafa;-webkit-box-shadow:0 1px 2px rgba(0,0,0,0.1);box-shadow:0 1px 2px rgba(0,0,0,0.1)}#updraft_inpage_backup #updraft_lastlogmessagerow>div{background:transparent;padding:0}#updraft_inpage_backup .last-message>strong{display:block;margin-top:13px}body.update-core-php #updraft_inpage_backup h2:nth-child(1){margin-top:1em !important}.updraft_restore_container{display:block;position:fixed;top:0;left:0;right:0;bottom:0;z-index:99999;padding-top:30px;background:#f1f1f1;overflow:auto}.updraft-modal-is-opened .select2-container{z-index:99999}body.updraft-modal-is-opened{overflow:hidden}.updraft_restore_container h2{margin:0}.updraft_restore_container .updraftmessage{-webkit-box-sizing:border-box;box-sizing:border-box;max-width:860px;margin-left:auto;margin-right:auto}.updraft_restore_main{max-width:860px;margin:0 auto;margin-top:20px;background:#FFF;-webkit-box-shadow:0 3px 3px rgba(0,0,0,0.1);box-shadow:0 3px 3px rgba(0,0,0,0.1);position:relative;display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-webkit-box-sizing:border-box;box-sizing:border-box}.updraft_restore_main--header{font-size:20px;font-weight:bold;text-align:center;padding-top:16px;line-height:20px;width:100%;max-width:100%;padding-right:30px;padding-left:30px;-webkit-box-sizing:border-box;box-sizing:border-box}.updraft_restore_main--activity{position:relative;width:calc(100% - 350px);-webkit-box-sizing:border-box;box-sizing:border-box}.updraft_restore_main--activity-title{padding:20px;margin:0}.show-credentials-form.updraft_restore_main .updraft_restore_main--activity-title{display:none}.updraft_restore_main--components{width:350px;padding:20px;-webkit-box-sizing:border-box;box-sizing:border-box;background:#f8f8f8;min-height:350px}.updraft_restore_main:not(.show-credentials-form) div#updraftplus_ajax_restore_output{background:#23282d;color:#e3e3e3;font-family:monospace;padding:19px;overflow:auto;position:absolute;top:60px;bottom:0;right:0;left:0}#updraftplus_ajax_restore_output form{white-space:normal;font-family:-apple-system,blinkmacsystemfont,"Segoe UI",roboto,oxygen-sans,ubuntu,cantarell,"Helvetica Neue",sans-serif}#updraftplus_ajax_restore_output .updraft_restore_errors{border:1px solid #dc3232;padding:10px 20px;white-space:normal}.updraft_restore_main:not(.show-credentials-form) div#updraftplus_ajax_restore_output h2{color:#00a0d2;padding-top:10px;padding-bottom:5px}.updraft_restore_main.show-credentials-form div#updraftplus_ajax_restore_output{padding:20px;border-left:1px solid #EEE}.updraft_restore_main.show-credentials-form div#updraftplus_ajax_restore_output #message{margin-left:0;margin-right:0}.updraft_restore_main.show-credentials-form div#updraftplus_ajax_restore_output .form-table td,.updraft_restore_main.show-credentials-form div#updraftplus_ajax_restore_output .form-table th{padding-bottom:0}.updraft_restore_main.show-credentials-form .updraft_restore_main--components{opacity:.2}.updraft_restore_main.show-credentials-form div.error .restore-credential-errors--list p{margin:0;list-style-type:disc;display:list-item;list-style-position:inside}.restore-credential-errors>:first-child{margin-top:0}.restore-credential-errors>:last-child{margin-bottom:0}ul.updraft_restore_components_list li{color:#bababa;font-size:1.2em;margin-bottom:1em}ul.updraft_restore_components_list li::before{content:'\f469';font-family:dashicons;font-size:20px;vertical-align:middle;display:inline-block;margin-right:7px}ul.updraft_restore_components_list li span{vertical-align:middle}ul.updraft_restore_components_list li.done{color:green}ul.updraft_restore_components_list li.done::before{content:"\f147"}ul.updraft_restore_components_list li.active{color:inherit}ul.updraft_restore_components_list li.active::before{content:"\f463";-webkit-animation:udp_rotate 1s linear infinite;animation:udp_rotate 1s linear infinite}ul.updraft_restore_components_list li.error{color:#dc3232}ul.updraft_restore_components_list li.error::before{content:"\f335"}.updraft_restore_result{padding:10px 0;font-size:1.3em;margin-bottom:1em;vertical-align:middle;display:none}.updraft_restore_result.restore-error{color:#dc3232}.updraft_restore_result.restore-success{color:green}.updraft_restore_result .dashicons{font-size:35px;height:35px;line-height:33px;width:35px}.updraft_restore_result span{vertical-align:middle}#updraft-restore-modal{width:100%}div#updraft-restore-modal .notice{background:#f8f8f8}.updraft-restore-modal--stage .updraft--two-halves,.updraft-restore-modal--stage .updraft--one-half{padding:20px 30px}.updraft-restore-modal--header{padding:20px;padding-bottom:0;text-align:center;border-bottom:1px solid #EEE}.updraft-restore-modal--header h3{margin:0;padding:0}.updraft-restore-item{padding-bottom:4px}.updraft-restore-buttons{padding-top:10px}ul.updraft-restore--stages{display:inline-block;margin:0;height:28px}ul.updraft-restore--stages li{display:inline-block;position:relative;width:12px;height:12px;background:#d2d2d2;border-radius:20px;line-height:1;margin:0 4px;vertical-align:middle}ul.updraft-restore--stages li.active{background:#444}.updraft-restore--footer{border-top:1px solid #EEE;padding:20px;text-align:center;position:sticky;bottom:0;background:#FFF;width:100%;-webkit-box-sizing:border-box;box-sizing:border-box}.updraft-restore--footer .updraft-restore--cancel{position:absolute;left:20px;top:auto}.updraft-restore--footer .updraft-restore--next-step{position:absolute;right:20px;top:auto}ul.updraft-restore--stages li span{position:absolute;width:120px;bottom:calc(100% + 14px);left:-55px;background:rgba(0,0,0,0.85882);padding:5px;-webkit-box-sizing:border-box;box-sizing:border-box;border-radius:4px;color:#FFF;text-align:center;display:none}ul.updraft-restore--stages li:hover span{display:inline-block}.updraft-restore-item input[type=checkbox]{margin-bottom:-5px}.updraft-restore-item input[type=checkbox]:checked+label{font-weight:bold}div#updraft-restore-modal .ud_downloadstatus__close{display:none}#ud_downloadstatus2:not(:empty){margin-top:15px}.dashicons.rotate{-webkit-animation:udp_rotate 1s linear infinite;animation:udp_rotate 1s linear infinite}span#updraftplus_ajax_restore_last_activity{font-size:.8rem;font-weight:normal;float:right}.updraft_restore_main--components .updated.show_admin_restore_in_progress_notice{margin:-20px -20px 20px;padding:19px}.updraft_restore_main--components .updated.show_admin_restore_in_progress_notice button{margin-right:5px}#updraft_migrate_receivingsites .updraftplus-remote-sites-selector .button-primary,.updraft_migrate_add_site .input-field input,.updraft_migrate_add_site button{vertical-align:middle}#updraft_migrate_receivingsites .text-link-menu a:not(:last-child){padding-right:10px}#updraft_migrate_receivingsites a.updraft_migrate_clear_sites span.dashicons-trash:before{font-size:17px}#updraft_migrate_receivingsites .updraft_migrate_add_site{clear:both}.rtl .advanced_tools.total_size table td{direction:ltr;text-align:right}.rtl #plupload-upload-ui2.drag-drop #drag-drop-area2{margin-bottom:20px}.rtl #updraft_lastlogmessagerow .updraft-log-link{float:left}.rtl label.updraft_checkbox>input[type=checkbox]{margin-right:-25px;margin-left:inherit}.rtl .ud_downloadstatus__close{float:left !important}.rtl #updraft_backupextradbs_another_container{float:right}.rtl input.labelauty+label{direction:ltr;position:relative;min-height:29px}.rtl input.labelauty+label>span.labelauty-checked-image,.rtl input.labelauty+label>span.labelauty-unchecked-image{right:8px;top:11px;position:absolute}.rtl .button.updraft-close-overlay .dashicons{margin-right:-5px;margin-left:inherit}.rtl label.updraft_checkbox{margin-right:26px;margin-left:inherit}.rtl #updraft-wrap .udp-info{left:10px;right:inherit}.rtl input.labelauty+label>span.labelauty-unchecked-image+span.labelauty-unchecked,.rtl input.labelauty+label>span.labelauty-checked-image+span.labelauty-checked{margin-right:7px;margin-left:inherit;padding:7px 7px 7px 26px;width:141px;text-align:right}.rtl #updraft_report_cell button.updraft_reportbox_delete,.rtl .updraft_box_delete_button,.rtl .updraft_small_box .updraft_box_delete_button{left:4px;right:inherit}#updraft_exclude_modal .clause-input-container{overflow:auto}#updraft_exclude_modal .clause-input-container select,#updraft_exclude_modal .clause-input-container input{float:left}#updraft_exclude_modal .clause-input-container .wildcards-input{margin:7px 7px 0 0}#updraft_exclude_modal .updraft-exclude-panel .contain-clause-sub-label{margin-top:10px;display:block}@media only screen and (min-width:1024px){#updraft_activejobsrow .updraft_row{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:baseline;-ms-flex-align:baseline;align-items:baseline}#updraft_activejobsrow .updraft_row .updraft_col{-webkit-box-flex:1;-ms-flex:auto;flex:auto}#updraft_activejobsrow .updraft_progress_container{width:calc(100% - 230px)}}@media only screen and (min-width:782px){.settings_page_updraftplus input[type=text],.settings_page_updraftplus input[type=password],.settings_page_updraftplus input[type=number]{line-height:1.42;height:27px;padding:2px 6px;color:#555}.settings_page_updraftplus input[type="number"]{height:31px}#ud_massactions.active,#updraft-delete-waitwarning.active{position:fixed;bottom:0;left:160px;right:0;top:auto;background:#FFF;z-index:3;-webkit-box-shadow:0 0 10px rgba(0,0,0,0.2);box-shadow:0 0 10px rgba(0,0,0,0.2)}.rtl #ud_massactions.active,.rtl #updraft-delete-waitwarning.active{left:0;right:160px}body.folded #ud_massactions.active,body.folded #updraft-delete-waitwarning.active{left:36px}.updraft-after-form-table{margin-left:250px}#updraft-navtab-backups-content .updraft_existing_backups .updraft_existing_backups_row.range-selection:not(.backuprowselected) .updraft_existingbackup_date .backup_date_label{color:#FFF}}@media only screen and (min-width:782px) and (max-width:960px){body.auto-fold #ud_massactions.active,body.auto-fold #updraft-delete-waitwarning.active{left:36px}}@media only screen and (max-width:782px){#updraft-wrap{margin-right:0}#updraft-wrap .form-table td{padding-right:0}label.updraft_checkbox{margin-bottom:8px;margin-top:8px;margin-left:36px}.updraft_retain_rules{position:relative;margin-right:0;border:1px solid #CCC;padding:5px;margin-bottom:-1px}.updraft_retain_rules_delete{position:absolute;right:0;top:5px}a[id*=updraft_retain_]{display:block;padding:15px 15px 15px 0}label.updraft_checkbox>input[type=checkbox]{margin-left:-33px}#updraft-backupnow-button{margin:0;display:block;width:100%}.updraft_next_scheduled_backups_wrapper>.updraft_backup_btn_wrapper{padding-top:0}#ud_massactions,#updraft-delete-waitwarning{width:100%;-webkit-box-sizing:border-box;box-sizing:border-box;text-align:center}#ud_massactions.active{position:fixed;top:auto;bottom:0;width:100%;-webkit-box-sizing:border-box;box-sizing:border-box;text-align:center;-webkit-box-shadow:0 -3px 15px rgba(0,0,0,0.08);box-shadow:0 -3px 15px rgba(0,0,0,0.08);background:#FFF;z-index:3}#ud_massactions strong{display:block;margin-bottom:5px}small.ud_massactions-tip{display:block}.existing-backups-table .backup_date_label>div,.existing-backups-table .backup_date_label span>div{font-weight:normal}.existing-backups-table .backup_date_label .clear-right{display:inline-block}table.widefat.existing-backups-table{border:0;-webkit-box-shadow:none;box-shadow:none;background:transparent}.existing-backups-table thead{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px;padding:0;margin:0}.existing-backups-table tr{display:block;margin-bottom:.625em;padding-bottom:16.625px;width:100%;padding:0;margin:0;margin-bottom:10px;background:#FFF;-webkit-box-shadow:0 2px 3px rgba(0,0,0,0.1);box-shadow:0 2px 3px rgba(0,0,0,0.1)}.existing-backups-table td{border-bottom:1px solid #DDD;display:block;font-size:.9em;text-align:left;width:100%;padding:10px;margin:0}.wp-list-table.existing-backups-table tr:not(.inline-edit-row):not(.no-items) td:not(.column-primary)::before{content:attr(data-label);font-weight:bold;display:block;position:relative;left:auto;padding-bottom:10px;width:auto;text-align:left}.existing-backups-table td:last-child{border-bottom:0}.form-table td.updraft_existingbackup_date{width:inherit;max-width:100%}.existing-backups-table td.before-restore-button{min-height:36px}.updraft_next_scheduled_backups_wrapper{-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}.updraft_next_scheduled_backups_wrapper>div{width:100%}#updraft-navtab-backups-content .updraft_existing_backups .updraft_existing_backups_row{position:relative}#updraft-navtab-backups-content .updraft_existing_backups .updraft_existing_backups_row.backuprowselected{background-color:#FFF;border-left:4px solid #0572aa}#updraft-navtab-backups-content .updraft_existing_backups .updraft_existing_backups_row td:not(.backup-select){margin-left:50px}#updraft-navtab-backups-content .updraft_existing_backups .updraft_existing_backups_row td.backup-select{width:50px !important;position:absolute;left:0;top:0;-webkit-box-sizing:border-box;box-sizing:border-box;height:100%;z-index:1;border:0;border-right:1px solid rgba(0,0,0,0.05)}#updraft-navtab-backups-content .updraft_existing_backups input[type="checkbox"]{height:25px}.updraft_migrate_intro button.button.button-primary.button-hero{display:block;margin-right:0;width:100%;max-width:100%}.updraftclone-main-row{-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}.updraftclone-main-row>div{width:auto;max-width:none;margin-right:0;margin-bottom:10px}.form-table th{padding-bottom:10px}.updraft--flex{-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}.updraft_restore_main{-ms-flex-wrap:wrap;flex-wrap:wrap;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}.updraft_restore_main--components{width:100%;min-height:0}.updraft_restore_main--activity{width:100%}div#updraftplus_ajax_restore_output,.updraft_restore_main:not(.show-credentials-form) div#updraftplus_ajax_restore_output{position:relative;top:0;bottom:auto}.updraft--flex>.updraft--two-halves,.updraft--flex>.updraft--one-half{width:100%}.updraft-restore-item{padding-bottom:10px;padding-top:10px}}@media screen and (max-width:600px){.updraft_next_scheduled_entity{float:none;width:100%;margin-bottom:2em}.updraft_time_now_wrapper{margin-top:0}#updraft_lastlogmessagerow h3{margin-bottom:5px}#updraft_lastlogmessagerow .updraft-log-link{display:block;float:none;margin:0;margin-bottom:10px}}@media only screen and (min-width:768px){.addon-activation-notice{left:20em}.existing-backups-table tbody tr.range-selection:hover,.existing-backups-table tbody tr.range-selection{background:#0572aa}.existing-backups-table tbody tr:hover{background:#f1f1f1}.existing-backups-table tbody tr td.before-restore-button{position:relative}.form-table .existing-backups-table thead th.check-column{padding-left:6px}.existing-backups-table tr td:first-child{border-left:4px solid transparent}.existing-backups-table tr.backuprowselected td:first-child{border-left-color:#0572aa}}@media screen and (min-width:670px){.expertmode .advanced_settings_container .advanced_settings_menu{float:left;width:215px;border-right:1px solid #ccc;border-bottom:0}.expertmode .advanced_settings_container .advanced_settings_content{padding-left:10px;padding-top:0}.expertmode .advanced_settings_container .advanced_settings_menu .advanced_tools_button{display:block}}@media only screen and (max-width:1068px){.updraft-more-plugins .udp-box{width:calc(50% - 10px);margin-bottom:20px}.updraft_feat_table td:nth-child(2),.updraft_feat_table td:nth-child(3){width:100px}}@media only screen and (max-width:600px){.updraft-more-plugins .udp-box{width:100%;margin-bottom:20px}.updraft_feat_table td:nth-child(2),.updraft_feat_table td:nth-child(3){width:auto}table.updraft_feat_table{display:block}table.updraft_feat_table tr{display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap}table.updraft_feat_table td{display:block}table.updraft_feat_table td:first-child{width:100%;border-bottom:0}table.updraft_feat_table td:not(:first-child){width:50%;-webkit-box-sizing:border-box;box-sizing:border-box}table.updraft_feat_table td:first-child:empty{display:none}td[data-colname]::before{content:attr(data-colname);font-size:.8rem;color:#CCC;line-height:1}} /*# sourceMappingURL=updraftplus-admin-2-23-7.min.css.map */ css/updraftplus-tour-2-23-7.min.css000064400000013373152214270100012716 0ustar00.shepherd-theme-arrows-plain-buttons{z-index:9999;max-width:390px !important}.shepherd-theme-arrows-plain-buttons.super-index{z-index:999999}.shepherd-element.shepherd-theme-arrows-plain-buttons .shepherd-content{border-radius:3px;-webkit-filter:none;filter:none;-webkit-box-shadow:0 1px 3px rgba(0,0,0,0.15),0 10px 40px rgba(0,0,0,0.15);box-shadow:0 1px 3px rgba(0,0,0,0.15),0 10px 40px rgba(0,0,0,0.15)}.shepherd-element-attached-bottom.shepherd-element-attached-right.shepherd-target-attached-top.shepherd-target-attached-left .shepherd-content:before,.shepherd-element-attached-bottom.shepherd-element-attached-left.shepherd-target-attached-top.shepherd-target-attached-right .shepherd-content:before,.shepherd-element-attached-top.shepherd-element-attached-right.shepherd-target-attached-bottom.shepherd-target-attached-left .shepherd-content:before,.shepherd-element-attached-top.shepherd-element-attached-left.shepherd-target-attached-bottom.shepherd-target-attached-right .shepherd-content:before{display:none}.shepherd-element.shepherd-theme-arrows-plain-buttons.shepherd-element-attached-top.shepherd-element-attached-center.shepherd-has-title .shepherd-content:before,.shepherd-element.shepherd-theme-arrows-plain-buttons.shepherd-element-attached-top.shepherd-element-attached-right.shepherd-target-attached-bottom.shepherd-has-title .shepherd-content:before,.shepherd-element.shepherd-theme-arrows-plain-buttons.shepherd-element-attached-top.shepherd-element-attached-left.shepherd-target-attached-bottom.shepherd-has-title .shepherd-content:before{border-bottom-color:#dd6823}.shepherd-element.shepherd-theme-arrows-plain-buttons.shepherd-has-title .shepherd-content header{background-color:#dd6823;border-radius:3px 3px 0 0;padding-right:90px}.shepherd-element.shepherd-theme-arrows-plain-buttons .shepherd-content header h3{color:#FFF;font-size:1.2em;float:none}.shepherd-element.shepherd-theme-arrows-plain-buttons.shepherd-has-title .shepherd-content header a.shepherd-cancel-link{opacity:.7;color:rgba(255,255,255,0);font-size:.8em;border:1px solid #FFF;border-radius:50%;width:22px;height:22px;line-height:20px;padding:0;text-align:center;float:none;position:absolute;right:11px;top:12px}.shepherd-element.shepherd-theme-arrows-plain-buttons.shepherd-has-title .shepherd-content header a.shepherd-cancel-link::before{color:#FFF;content:attr(data-btntext);position:absolute;right:20px;padding-right:10px}.shepherd-element.shepherd-theme-arrows-plain-buttons.shepherd-has-title .shepherd-content header a.shepherd-cancel-link::after{content:"\f335";-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-family:dashicons;color:#FFF;position:absolute;left:2px;line-height:21px;font-size:16px}.shepherd-element.shepherd-theme-arrows-plain-buttons.shepherd-has-title .shepherd-content header a.shepherd-cancel-link:hover,.shepherd-element.shepherd-theme-arrows-plain-buttons.shepherd-has-title .shepherd-content header a.shepherd-cancel-link:focus{border:1px solid #a04e00;opacity:1}.shepherd-element.shepherd-theme-arrows-plain-buttons.shepherd-has-title .shepherd-content header a.shepherd-cancel-link:hover::before,.shepherd-element.shepherd-theme-arrows-plain-buttons.shepherd-has-title .shepherd-content header a.shepherd-cancel-link:focus::before{color:#a04e00}.shepherd-element.shepherd-theme-arrows-plain-buttons.shepherd-has-title .shepherd-content header a.shepherd-cancel-link:hover::after,.shepherd-element.shepherd-theme-arrows-plain-buttons.shepherd-has-title .shepherd-content header a.shepherd-cancel-link:focus::after{color:#a04e00}.shepherd-element.shepherd-theme-arrows-plain-buttons.shepherd-element-attached-top.shepherd-element-attached-left.shepherd-target-attached-right .shepherd-content:before{top:44px}.shepherd-content .ud-notice{background:#f0f0f0;padding:14px;border-radius:4px;font-size:90% !important;line-height:1.5}.shepherd-content .ud-notice h3{margin-top:0;padding-top:0;margin-bottom:.5em}.shepherd-element.shepherd-theme-arrows-plain-buttons .shepherd-content .shepherd-text p{margin-top:.5em;margin-bottom:1.3em}.ud-notice span.ud-special-offer{font-weight:bold;display:inline-block;padding:1px 6px;border-radius:3px;background:rgba(217,105,0,0.09)}label[for=updraft_servicecheckbox_updraftvault]{border:1px solid rgba(204,204,204,0.4);-webkit-transition:border .5s;transition:border .5s}label[for=updraft_servicecheckbox_updraftvault].emphasize{border-color:#dd6823}.shepherd-element.shepherd-theme-arrows-plain-buttons .shepherd-content footer .shepherd-buttons li .shepherd-button.udp-tour-back,.shepherd-element.shepherd-theme-arrows-plain-buttons .shepherd-content footer .shepherd-buttons li .shepherd-button.udp-tour-end{float:left;position:relative;padding-left:10px}.shepherd-element.shepherd-theme-arrows-plain-buttons .shepherd-content footer .shepherd-buttons li .shepherd-button.udp-tour-end{padding-left:0;color:#b7b7b7}.shepherd-element.shepherd-theme-arrows-plain-buttons .shepherd-content footer .shepherd-buttons li .shepherd-button.udp-tour-back::before{content:' ';width:6px;height:6px;display:block;border-left:1px solid;border-bottom:1px solid;position:absolute;left:0;top:8px;-webkit-transform:rotate(45deg);transform:rotate(45deg)}a.shepherd-button.udp-tour-end::before{display:inline-block;position:relative;content:"\f335";-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-family:dashicons;font-size:20px;line-height:20px;vertical-align:middle;margin-top:-2px}.updraftplus-welcome-logo{display:block;width:70px;float:left;margin-top:-11px;margin-right:12px}.updraftplus-welcome-logo img{display:block;width:auto;max-width:100%}.highlight-udp .plugins #the-list tr:not([data-slug="updraftplus"]){opacity:.3}@media(max-width:790px){.shepherd-element.shepherd-theme-arrows-plain-buttons{display:none}} /*# sourceMappingURL=updraftplus-tour-2-23-7.min.css.map */ css/updraftplus-notices-2-23-7.min.css000064400000002555152214270100013371 0ustar00.updraft_notice_container{height:auto;overflow:hidden}.updraft_review_notice_container{padding:12px;display:-webkit-box;display:-ms-flexbox;display:flex}.updraft_advert_button_container{margin-bottom:10px;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.updraft_advert_button_container .dashicons{margin-left:10px}.updraft_advert_content_left{float:none;width:65px}.updraft_advert_content_left_extra{float:none;width:100px;padding-right:15px;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.updraft_advert_content_right{float:none;width:auto;overflow:hidden}.updraft_advert_bottom{margin:10px 0;padding:10px;font-size:140%;background-color:white;border-color:#e6db55;border:1px solid;border-radius:4px}.updraft-advert-dismiss{float:right;font-size:13px;font-weight:normal}h3.updraft_advert_heading{margin-top:5px !important;margin-bottom:5px !important}h4.updraft_advert_heading{margin-top:2px !important;margin-bottom:3px !important}.updraft_center_content{text-align:center;margin-bottom:5px}.updraft_notice_link{padding-left:5px}.updraft_text_center{text-align:center}@media screen and (min-width:560px){.updraft_advert_content_left,.updraft_advert_content_left_extra{float:left}} /*# sourceMappingURL=updraftplus-notices-2-23-7.min.css.map */ css/updraftplus-tour.scss000064400000012431152214270100011564 0ustar00$udp_primary: #DD6823; $wp_blue: #0073AA; .shepherd-theme-arrows-plain-buttons { z-index: 9999; max-width: 390px!important; } .shepherd-theme-arrows-plain-buttons.super-index { z-index: 999999; } .shepherd-element.shepherd-theme-arrows-plain-buttons .shepherd-content { border-radius: 3px; filter: none; box-shadow: 0px 1px 3px rgba(0, 0, 0, 0.15), 0px 10px 40px rgba(0, 0, 0, 0.15); } .shepherd-element-attached-bottom.shepherd-element-attached-right.shepherd-target-attached-top.shepherd-target-attached-left .shepherd-content:before, .shepherd-element-attached-bottom.shepherd-element-attached-left.shepherd-target-attached-top.shepherd-target-attached-right .shepherd-content:before, .shepherd-element-attached-top.shepherd-element-attached-right.shepherd-target-attached-bottom.shepherd-target-attached-left .shepherd-content:before, .shepherd-element-attached-top.shepherd-element-attached-left.shepherd-target-attached-bottom.shepherd-target-attached-right .shepherd-content:before { display: none; } .shepherd-element.shepherd-theme-arrows-plain-buttons.shepherd-element-attached-top.shepherd-element-attached-center.shepherd-has-title .shepherd-content:before, .shepherd-element.shepherd-theme-arrows-plain-buttons.shepherd-element-attached-top.shepherd-element-attached-right.shepherd-target-attached-bottom.shepherd-has-title .shepherd-content:before, .shepherd-element.shepherd-theme-arrows-plain-buttons.shepherd-element-attached-top.shepherd-element-attached-left.shepherd-target-attached-bottom.shepherd-has-title .shepherd-content:before { border-bottom-color: $udp_primary; } .shepherd-element.shepherd-theme-arrows-plain-buttons.shepherd-has-title .shepherd-content header { background-color: $udp_primary; border-radius: 3px 3px 0 0; padding-right: 90px; } .shepherd-element.shepherd-theme-arrows-plain-buttons .shepherd-content header h3 { color: #FFF; font-size: 1.2em; float: none; } .shepherd-element.shepherd-theme-arrows-plain-buttons.shepherd-has-title .shepherd-content header a.shepherd-cancel-link { opacity: 0.7; color: rgba(255, 255, 255, 0); font-size: 0.8em; border: 1px solid #FFF; border-radius: 50%; width: 22px; height: 22px; line-height: 20px; padding: 0; text-align: center; float: none; position: absolute; right: 11px; top: 12px; &::before { color: #FFF; content: attr(data-btntext); position: absolute; right: 20px; padding-right: 10px; } &::after { content: "\f335"; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; font-family: dashicons; color: #FFF; position: absolute; left: 2px; line-height: 21px; font-size: 16px; } } .shepherd-element.shepherd-theme-arrows-plain-buttons.shepherd-has-title .shepherd-content header a.shepherd-cancel-link:hover, .shepherd-element.shepherd-theme-arrows-plain-buttons.shepherd-has-title .shepherd-content header a.shepherd-cancel-link:focus { border: 1px solid #A04E00; opacity: 1; &::before { color: #A04E00; } &::after { color: #A04E00; } } .shepherd-element.shepherd-theme-arrows-plain-buttons.shepherd-element-attached-top.shepherd-element-attached-left.shepherd-target-attached-right .shepherd-content:before { top: 44px; } .shepherd-content .ud-notice { background: #F0F0F0; padding: 14px; border-radius: 4px; font-size: 90% !important; line-height: 1.5; h3 { margin-top: 0; padding-top: 0; margin-bottom: .5em; } } .shepherd-element.shepherd-theme-arrows-plain-buttons .shepherd-content .shepherd-text p { margin-top: 0.5em; margin-bottom: 1.3em; } .ud-notice span.ud-special-offer { font-weight: bold; display: inline-block; padding: 1px 6px; border-radius: 3px; background: rgba(217, 105, 0, 0.09); } label[for=updraft_servicecheckbox_updraftvault] { border: 1px solid rgba(204, 204, 204, 0.4); transition: border .5s; &.emphasize { border-color: $udp_primary; } } .shepherd-element.shepherd-theme-arrows-plain-buttons .shepherd-content footer .shepherd-buttons li .shepherd-button.udp-tour-back, .shepherd-element.shepherd-theme-arrows-plain-buttons .shepherd-content footer .shepherd-buttons li .shepherd-button.udp-tour-end { float: left; position: relative; padding-left: 10px; } .shepherd-element.shepherd-theme-arrows-plain-buttons .shepherd-content footer .shepherd-buttons li .shepherd-button.udp-tour-end { padding-left: 0; color: #B7B7B7; } .shepherd-element.shepherd-theme-arrows-plain-buttons .shepherd-content footer .shepherd-buttons li .shepherd-button.udp-tour-back::before { content: ' '; width: 6px; height: 6px; display: block; border-left: 1px solid; border-bottom: 1px solid; position: absolute; left: 0px; top: 8px; transform: rotate(45deg); } a.shepherd-button.udp-tour-end::before { display: inline-block; position: relative; content: "\f335"; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; font-family: dashicons; font-size: 20px; line-height: 20px; vertical-align: middle; margin-top: -2px; } .updraftplus-welcome-logo { display: block; width: 70px; float: left; margin-top: -11px; margin-right: 12px; } .updraftplus-welcome-logo img { display: block; width: auto; max-width: 100%; } .highlight-udp .plugins #the-list tr:not([data-slug="updraftplus"]) { opacity: 0.3; } @media(max-width: 790px) { .shepherd-element.shepherd-theme-arrows-plain-buttons { display: none; } } css/updraftplus-tour-2-23-7.min.css.map000064400000016371152214270100013473 0ustar00{"version":3,"sources":["css/updraftplus-tour.scss"],"names":[],"mappings":"AAEA;CACC,aAAa;CACb,0BAA0B;AAC3B;;AAEA;CACC,eAAe;AAChB;;AAEA;CACC,kBAAkB;CAClB,oBAAY;SAAZ,YAAY;CACZ,sFAA8E;SAA9E,8EAA8E;AAC/E;;AAEA;;;;CAIC,aAAa;AACd;;AAEA;;;CAGC,4BAAiC;AAClC;;AAEA;CACC,yBAA8B;CAC9B,0BAA0B;CAC1B,mBAAmB;AACpB;;AAEA;CACC,WAAW;CACX,gBAAgB;CAChB,WAAW;AACZ;;AAEA;CACC,YAAY;CACZ,6BAA6B;CAC7B,gBAAgB;CAChB,sBAAsB;CACtB,kBAAkB;CAClB,WAAW;CACX,YAAY;CACZ,iBAAiB;CACjB,UAAU;CACV,kBAAkB;CAClB,WAAW;CACX,kBAAkB;CAClB,WAAW;CACX;AAoBD;;AAlBC;EACC,WAAW;EACX,2BAA2B;EAC3B,kBAAkB;EAClB,WAAW;EACX,mBAAmB;CACpB;;AACA;EACC,gBAAgB;EAChB,mCAAmC;EACnC,kCAAkC;EAClC,sBAAsB;EACtB,WAAW;EACX,kBAAkB;EAClB,SAAS;EACT,iBAAiB;EACjB,eAAe;CAChB;;AAGD;;CAEC,yBAAyB;CACzB;AAOD;;AANC;EACC,cAAc;CACf;;AACA;EACC,cAAc;CACf;;AAGD;CACC,SAAS;AACV;;AAEA;;CAEC,mBAAmB;CACnB,aAAa;CACb,kBAAkB;CAClB,yBAAyB;CACzB,gBAAgB;;AAOjB;;AANC;EACC,aAAa;EACb,cAAc;EACd,mBAAmB;CACpB;;AAID;CACC,iBAAiB;CACjB,oBAAoB;AACrB;;AAEA;CACC,iBAAiB;CACjB,qBAAqB;CACrB,gBAAgB;CAChB,kBAAkB;CAClB,mCAAmC;AACpC;;AAEA;;CAEC,0CAA0C;CAC1C,8BAAsB;CAAtB;;AAKD;;AAJC;EACC,qBAA0B;CAC3B;;AAID;;CAEC,WAAW;CACX,kBAAkB;CAClB,kBAAkB;AACnB;;AAEA;CACC,eAAe;CACf,cAAc;AACf;;AAEA;CACC,YAAY;CACZ,UAAU;CACV,WAAW;CACX,cAAc;CACd,sBAAsB;CACtB,wBAAwB;CACxB,kBAAkB;CAClB,SAAS;CACT,QAAQ;CACR,gCAAwB;SAAxB,wBAAwB;AACzB;;AAEA;CACC,qBAAqB;CACrB,kBAAkB;CAClB,gBAAgB;CAChB,mCAAmC;CACnC,kCAAkC;CAClC,sBAAsB;CACtB,eAAe;CACf,iBAAiB;CACjB,sBAAsB;CACtB,gBAAgB;AACjB;;AAEA;CACC,cAAc;CACd,WAAW;CACX,WAAW;CACX,iBAAiB;CACjB,kBAAkB;AACnB;;AAEA;CACC,cAAc;CACd,WAAW;CACX,eAAe;AAChB;;AAEA;CACC,YAAY;AACb;;AAEA;;CAEC;EACC,aAAa;CACd;;AAED","file":"updraftplus-tour-2-23-7.min.css","sourcesContent":["$udp_primary: #DD6823;\n$wp_blue: #0073AA;\n.shepherd-theme-arrows-plain-buttons {\n\tz-index: 9999;\n\tmax-width: 390px!important;\n}\n\n.shepherd-theme-arrows-plain-buttons.super-index {\n\tz-index: 999999;\n}\n\n.shepherd-element.shepherd-theme-arrows-plain-buttons .shepherd-content {\n\tborder-radius: 3px;\n\tfilter: none;\n\tbox-shadow: 0px 1px 3px rgba(0, 0, 0, 0.15), 0px 10px 40px rgba(0, 0, 0, 0.15);\n}\n\n.shepherd-element-attached-bottom.shepherd-element-attached-right.shepherd-target-attached-top.shepherd-target-attached-left .shepherd-content:before,\n.shepherd-element-attached-bottom.shepherd-element-attached-left.shepherd-target-attached-top.shepherd-target-attached-right .shepherd-content:before,\n.shepherd-element-attached-top.shepherd-element-attached-right.shepherd-target-attached-bottom.shepherd-target-attached-left .shepherd-content:before,\n.shepherd-element-attached-top.shepherd-element-attached-left.shepherd-target-attached-bottom.shepherd-target-attached-right .shepherd-content:before {\n\tdisplay: none;\n}\n\n.shepherd-element.shepherd-theme-arrows-plain-buttons.shepherd-element-attached-top.shepherd-element-attached-center.shepherd-has-title .shepherd-content:before,\n.shepherd-element.shepherd-theme-arrows-plain-buttons.shepherd-element-attached-top.shepherd-element-attached-right.shepherd-target-attached-bottom.shepherd-has-title .shepherd-content:before,\n.shepherd-element.shepherd-theme-arrows-plain-buttons.shepherd-element-attached-top.shepherd-element-attached-left.shepherd-target-attached-bottom.shepherd-has-title .shepherd-content:before {\n\tborder-bottom-color: $udp_primary;\n}\n\n.shepherd-element.shepherd-theme-arrows-plain-buttons.shepherd-has-title .shepherd-content header {\n\tbackground-color: $udp_primary;\n\tborder-radius: 3px 3px 0 0;\n\tpadding-right: 90px;\n}\n\n.shepherd-element.shepherd-theme-arrows-plain-buttons .shepherd-content header h3 {\n\tcolor: #FFF;\n\tfont-size: 1.2em;\n\tfloat: none;\n}\n\n.shepherd-element.shepherd-theme-arrows-plain-buttons.shepherd-has-title .shepherd-content header a.shepherd-cancel-link {\n\topacity: 0.7;\n\tcolor: rgba(255, 255, 255, 0);\n\tfont-size: 0.8em;\n\tborder: 1px solid #FFF;\n\tborder-radius: 50%;\n\twidth: 22px;\n\theight: 22px;\n\tline-height: 20px;\n\tpadding: 0;\n\ttext-align: center;\n\tfloat: none;\n\tposition: absolute;\n\tright: 11px;\n\ttop: 12px;\n\n\t&::before {\n\t\tcolor: #FFF;\n\t\tcontent: attr(data-btntext);\n\t\tposition: absolute;\n\t\tright: 20px;\n\t\tpadding-right: 10px;\n\t}\n\t&::after {\n\t\tcontent: \"\\f335\";\n\t\t-webkit-font-smoothing: antialiased;\n\t\t-moz-osx-font-smoothing: grayscale;\n\t\tfont-family: dashicons;\n\t\tcolor: #FFF;\n\t\tposition: absolute;\n\t\tleft: 2px;\n\t\tline-height: 21px;\n\t\tfont-size: 16px;\n\t}\n}\n\n.shepherd-element.shepherd-theme-arrows-plain-buttons.shepherd-has-title .shepherd-content header a.shepherd-cancel-link:hover,\n.shepherd-element.shepherd-theme-arrows-plain-buttons.shepherd-has-title .shepherd-content header a.shepherd-cancel-link:focus {\n\tborder: 1px solid #A04E00;\n\topacity: 1;\n\t&::before {\n\t\tcolor: #A04E00;\n\t}\n\t&::after {\n\t\tcolor: #A04E00;\n\t}\n}\n\n.shepherd-element.shepherd-theme-arrows-plain-buttons.shepherd-element-attached-top.shepherd-element-attached-left.shepherd-target-attached-right .shepherd-content:before {\n\ttop: 44px;\n}\n\n.shepherd-content .ud-notice {\n\n\tbackground: #F0F0F0;\n\tpadding: 14px;\n\tborder-radius: 4px;\n\tfont-size: 90% !important;\n\tline-height: 1.5;\n\th3 {\n\t\tmargin-top: 0;\n\t\tpadding-top: 0;\n\t\tmargin-bottom: .5em;\n\t}\n\n}\n\n.shepherd-element.shepherd-theme-arrows-plain-buttons .shepherd-content .shepherd-text p {\n\tmargin-top: 0.5em;\n\tmargin-bottom: 1.3em;\n}\n\n.ud-notice span.ud-special-offer {\n\tfont-weight: bold;\n\tdisplay: inline-block;\n\tpadding: 1px 6px;\n\tborder-radius: 3px;\n\tbackground: rgba(217, 105, 0, 0.09);\n}\n\nlabel[for=updraft_servicecheckbox_updraftvault] {\n\n\tborder: 1px solid rgba(204, 204, 204, 0.4);\n\ttransition: border .5s;\n\t&.emphasize {\n\t\tborder-color: $udp_primary;\n\t}\n\n}\n\n.shepherd-element.shepherd-theme-arrows-plain-buttons .shepherd-content footer .shepherd-buttons li .shepherd-button.udp-tour-back,\n.shepherd-element.shepherd-theme-arrows-plain-buttons .shepherd-content footer .shepherd-buttons li .shepherd-button.udp-tour-end {\n\tfloat: left;\n\tposition: relative;\n\tpadding-left: 10px;\n}\n\n.shepherd-element.shepherd-theme-arrows-plain-buttons .shepherd-content footer .shepherd-buttons li .shepherd-button.udp-tour-end {\n\tpadding-left: 0;\n\tcolor: #B7B7B7;\n}\n\n.shepherd-element.shepherd-theme-arrows-plain-buttons .shepherd-content footer .shepherd-buttons li .shepherd-button.udp-tour-back::before {\n\tcontent: ' ';\n\twidth: 6px;\n\theight: 6px;\n\tdisplay: block;\n\tborder-left: 1px solid;\n\tborder-bottom: 1px solid;\n\tposition: absolute;\n\tleft: 0px;\n\ttop: 8px;\n\ttransform: rotate(45deg);\n}\n\na.shepherd-button.udp-tour-end::before {\n\tdisplay: inline-block;\n\tposition: relative;\n\tcontent: \"\\f335\";\n\t-webkit-font-smoothing: antialiased;\n\t-moz-osx-font-smoothing: grayscale;\n\tfont-family: dashicons;\n\tfont-size: 20px;\n\tline-height: 20px;\n\tvertical-align: middle;\n\tmargin-top: -2px;\n}\n\n.updraftplus-welcome-logo {\n\tdisplay: block;\n\twidth: 70px;\n\tfloat: left;\n\tmargin-top: -11px;\n\tmargin-right: 12px;\n}\n\n.updraftplus-welcome-logo img {\n\tdisplay: block;\n\twidth: auto;\n\tmax-width: 100%;\n}\n\n.highlight-udp .plugins #the-list tr:not([data-slug=\"updraftplus\"]) {\n\topacity: 0.3;\n}\n\n@media(max-width: 790px) {\n\n\t.shepherd-element.shepherd-theme-arrows-plain-buttons {\n\t\tdisplay: none;\n\t}\n\n}\n"]}css/updraftplus-notices.css000064400000003075152214270100012060 0ustar00/* CSS for adverts */ .updraft_notice_container { height: auto; overflow: hidden; } .updraft_review_notice_container { padding: 12px; display: -webkit-box; display: -ms-flexbox; display: flex; } .updraft_advert_button_container { margin-bottom: 10px; display: -webkit-box; display: -ms-flexbox; display: flex; -webkit-box-align: center; -ms-flex-align: center; align-items: center; } .updraft_advert_button_container .dashicons { margin-left: 10px; } .updraft_advert_content_left { float: none; width: 65px; } .updraft_advert_content_left_extra { float: none; width: 100px; padding-right: 15px; display: -webkit-box; display: -ms-flexbox; display: flex; -webkit-box-align: center; -ms-flex-align: center; align-items: center; } .updraft_advert_content_right { float: none; width: auto; overflow: hidden; } .updraft_advert_bottom { margin: 10px 0; padding: 10px; font-size: 140%; background-color: white; border-color: #E6DB55; border: 1px solid; border-radius: 4px; } .updraft-advert-dismiss { float: right; font-size: 13px; font-weight: normal; } h3.updraft_advert_heading { margin-top: 5px !important; margin-bottom: 5px !important; } h4.updraft_advert_heading { margin-top: 2px !important; margin-bottom: 3px !important; } .updraft_center_content { text-align: center; margin-bottom: 5px; } .updraft_notice_link { padding-left: 5px; } .updraft_text_center { text-align: center; } @media screen and (min-width: 560px) { .updraft_advert_content_left, .updraft_advert_content_left_extra { float: left; } } css/updraftplus-admin-2-23-7.min.css.map000064400000325426152214270100013576 0ustar00{"version":3,"sources":["css/updraftplus-admin.css"],"names":[],"mappings":"AAAA;;CAEC;EACC,UAAU;EACV,2BAAmB;UAAnB,mBAAmB;CACpB;;CAEA;EACC,YAAY;EACZ,8BAAsB;UAAtB,sBAAsB;CACvB;;AAED;;AAZA;;CAEC;EACC,UAAU;EACV,2BAAmB;UAAnB,mBAAmB;CACpB;;CAEA;EACC,YAAY;EACZ,8BAAsB;UAAtB,sBAAsB;CACvB;;AAED;;AAEA;;CAEC;EACC,4BAAoB;UAApB,oBAAoB;CACrB;;CAEA;EACC,iCAAyB;UAAzB,yBAAyB;CAC1B;;AAED;;AAVA;;CAEC;EACC,4BAAoB;UAApB,oBAAoB;CACrB;;CAEA;EACC,iCAAyB;UAAzB,yBAAyB;CAC1B;;AAED;;AAEA,sBAAsB;AACtB;CACC,gBAAgB;AACjB;;AAEA;CACC,gBAAgB;AACjB;;AAEA;CACC,gBAAgB;AACjB;;AAEA;CACC,UAAU;AACX;;AAEA;CACC,oBAAa;CAAb,oBAAa;CAAb,aAAa;CACb,mBAAe;KAAf,eAAe;AAChB;;AAEA;CACC,mBAAO;KAAP,WAAO;SAAP,OAAO;CACP,8BAAsB;SAAtB,sBAAsB;AACvB;;AAEA;CACC,UAAU;CACV,mBAAU;KAAV,cAAU;SAAV,UAAU;AACX;;AAEA;CACC,WAAW;CACX,mBAAU;KAAV,cAAU;SAAV,UAAU;AACX;;AAEA;CACC,mBAAmB;AACpB;;AAEA,0BAA0B;;AAE1B,iBAAiB;AACjB;CACC,qBAAqB;AACtB;;AAEA;CACC,iBAAiB;AAClB;;AAEA,qBAAqB;AACrB,cAAc;AACd;CACC,kBAAkB;AACnB;;AAEA,qBAAqB;AACrB,YAAY;AACZ;CACC,qBAAqB;AACtB;;AAEA,mBAAmB;;AAEnB;CACC,kBAAkB;AACnB;;AAEA;CACC,YAAY;CACZ,eAAe;AAChB;;AAEA;CACC,uBAAuB;AACxB;;AAEA;CACC,gBAAgB;AACjB;;AAEA;CACC,8CAAsC;SAAtC,sCAAsC;AACvC;;AAEA;CACC,qBAAqB;AACtB;;AAEA;;CAEC,cAAc;CACd,gBAAgB;CAChB,kBAAkB;CAClB,kBAAkB;AACnB;;AAEA,gBAAgB;AAChB;CACC,cAAc;CACd,kBAAkB;CAClB,iBAAiB;AAClB;;AAEA;CACC,kBAAkB;AACnB;;AAEA;CACC,kBAAkB;AACnB;;AAEA,gBAAgB;AAChB;CACC,YAAY;AACb;;AAEA;CACC,oBAAoB;AACrB;;AAEA;CACC,eAAe;AAChB;;AAEA;CACC,kBAAkB;CAClB,eAAe;AAChB;;AAEA;;CAEC,gBAAgB;CAChB,WAAW;AACZ;;AAEA;CACC,gBAAgB;AACjB;;AAEA,oBAAoB;;AAEpB,iBAAiB;AACjB;CACC,iBAAiB;CACjB,mBAAmB;CACnB,mBAAmB;CACnB,eAAe;CACf,iBAAiB;CACjB,mBAAmB;CACnB,kBAAkB;CAClB,kBAAkB;CAClB,kBAAkB;CAClB,uBAAuB;CACvB,kBAAkB;CAClB,iBAAiB;CACjB,4BAAoB;CAApB,oBAAoB;CACpB,wBAAwB;CACxB,8BAAsB;SAAtB,sBAAsB;CACtB,kBAAkB;CAClB,kBAAkB;CAClB,iBAAiB;CACjB,oBAAoB;CACpB,cAAc;CACd,qBAAqB;AACtB;;AAEA;CACC,+BAA+B;CAC/B,wBAAwB;AACzB;;AAEA;CACC,gCAAgC;CAChC,gEAAgD;CAAhD,wDAAgD;CAAhD,gDAAgD;CAAhD,wEAAgD;CAChD,uCAAuC;CACvC,YAAY;CACZ,kBAAkB;CAClB,6EAAqE;SAArE,qEAAqE;CACrE,cAAc;CACd,eAAe;CACf,gBAAgB;CAChB,qBAAqB;CACrB,60BAA60B;CAC70B,sBAAsB;CACtB,4BAA4B;CAC5B,8BAA8B;AAC/B;;AAEA;CACC,6EAAqE;SAArE,qEAAqE;AACtE;;AAEA;CACC,sBAAsB;AACvB;;AAEA;CACC,aAAa;CACb,gGAAwF;SAAxF,wFAAwF;AACzF;;AAEA;CACC,+BAAuB;SAAvB,uBAAuB;CACvB,yBAAyB;CACzB,6EAAqE;SAArE,qEAAqE;CACrE,mBAAmB;AACpB;;AAEA;CACC,iBAAiB;CACjB,YAAY;CACZ,kBAAkB;AACnB;;AAEA;CACC,aAAa;CACb,kBAAkB;AACnB;;AAEA;CACC,qBAAqB;CACrB,mBAAmB;AACpB;;AAEA;CACC,cAAc;AACf;;AAEA;;CAEC;;AAED;CACC,aAAa;AACd;;AAEA,eAAe;;AAEf;CACC,oBAAa;CAAb,oBAAa;CAAb,aAAa;AACd;;AAEA;CACC,mBAAmB;CACnB,aAAa;CACb,mBAAmB;CACnB,kBAAkB;CAClB,gBAAgB;AACjB;;AAEA;CACC,SAAS;AACV;;AAEA;CACC,mBAAmB;CACnB,aAAa;CACb,mBAAmB;CACnB,mBAAO;KAAP,WAAO;SAAP,OAAO;AACR;;AAEA;CACC,aAAa;AACd;;AAEA;CACC,gBAAgB;AACjB;;AAEA;CACC,gBAAgB;AACjB;;AAEA;CACC,eAAe;CACf,cAAc;AACf;;AAEA,wBAAwB;AACxB;CACC,aAAa;CACb,kBAAkB;CAClB,QAAQ;CACR,MAAM;CACN,YAAY;CACZ,2BAA2B;CAC3B,kBAAkB;CAClB,mBAAmB;AACpB;;AAEA;CACC,oBAAa;CAAb,oBAAa;CAAb,aAAa;CACb,4BAAsB;CAAtB,6BAAsB;KAAtB,0BAAsB;SAAtB,sBAAsB;AACvB;;AAEA;CACC,kBAAkB;CAClB,WAAW;CACX,6BAAgB;KAAhB,gBAAgB;AACjB;;AAEA;;CAEC,WAAW;AACZ;;AAEA;;CAEC;EACC,8BAAmB;EAAnB,6BAAmB;MAAnB,uBAAmB;UAAnB,mBAAmB;EACnB,mBAAe;MAAf,eAAe;CAChB;;CAEA;EACC,4BAAe;MAAf,eAAe;CAChB;;CAEA;;EAEC,YAAY;CACb;;AAED;;AAEA;CACC,qBAAqB;CACrB,eAAe;AAChB;;AAEA;CACC,qBAAqB;AACtB;;AAEA;CACC,mBAAmB;CACnB,aAAa;CACb,kBAAkB;CAClB,mBAAmB;AACpB;;AAEA,qBAAqB;AACrB;CACC,WAAW;CACX,WAAW;CACX,gBAAgB;AACjB;;AAEA;CACC,WAAW;CACX,gBAAgB;AACjB;;AAEA;CACC,mBAAmB;AACpB;;AAEA;CACC,mBAAmB;CACnB,sBAAsB;AACvB;;AAEA;CACC,mBAAmB;AACpB;;AAEA;;CAEC,YAAY;AACb;;AAEA,mBAAmB;AACnB;CACC,eAAe;CACf,gBAAgB;AACjB;;AAEA;CACC,gBAAgB;AACjB;;AAEA,oCAAoC;AACpC;CACC,mBAAmB;CACnB,YAAY;CACZ,iBAAiB;CACjB,iBAAiB;CACjB,oBAAoB;AACrB;;AAEA;CACC,YAAY;AACb;;AAEA;CACC,UAAU;AACX;;AAEA,YAAY;;AAEZ;CACC,qBAAqB;AACtB;;AAEA;;;CAGC,qBAAqB;CACrB,cAAc;AACf;;AAEA;CACC,wBAAwB;CACxB,+BAA+B;AAChC;;AAEA;CACC,YAAY;AACb;;AAEA;CACC,gBAAgB;CAChB,gBAAgB;CAChB,kBAAkB;AACnB;;AAEA;CACC,aAAa;AACd;;AAEA;;CAEC,aAAa;AACd;;AAEA,4BAA4B;AAC5B;;CAEC,kBAAkB;CAClB,oBAAa;CAAb,oBAAa;CAAb,aAAa;CACb,0BAAqB;KAArB,qBAAqB;CACrB,qBAAqB;CACrB,iBAAiB;CACjB,kBAAkB;CAClB,mBAAmB;CACnB,mBAAmB;CACnB,6BAA6B;AAC9B;;AAEA;;;;CAIC,aAAa;CACb,iBAAiB;CACjB,YAAY;CACZ,SAAS;AACV;;AAEA;;CAEC,qBAAqB;CACrB,iBAAiB;CACjB,4BAA4B;AAC7B;;AAEA;;CAEC,eAAe;AAChB;;AAEA;;CAEC,SAAS;AACV;;AAEA;CACC,gBAAgB;CAChB,iBAAiB;CACjB,mBAAmB;CACnB,cAAc;CACd,YAAY;CACZ,iBAAiB;CACjB,oBAAoB;CACpB,gBAAgB;CAChB,kBAAkB;CAClB,kBAAkB;CAClB,mBAAmB;AACpB;;AAEA;CACC,kBAAkB;CAClB,UAAU;CACV,oBAAoB;AACrB;;AAEA;CACC,iBAAiB;AAClB;;AAEA;;CAEC;AACD;CACC,cAAc;AACf;;AAEA;CACC,mBAAmB;CACnB,SAAS;CACT,gBAAgB;CAChB,mBAAmB;CACnB,oBAAoB;AACrB;;AAEA;CACC,oBAAoB;AACrB;;AAEA;CACC,8BAA8B;AAC/B;;AAEA;CACC,4BAA4B;AAC7B;;AAEA;CACC,UAAU;CACV,UAAU;AACX;;AAEA;CACC,aAAa;CACb,2FAAmF;SAAnF,mFAAmF;CACnF,gBAAgB;AACjB;;AAEA;CACC,cAAc;CACd,UAAU;AACX;;AAEA;CACC,mBAAmB;CACnB,gCAAgC;CAChC,wDAAgD;SAAhD,gDAAgD;AACjD;;AAEA;CACC,+GAAuG;SAAvG,uGAAuG;AACxG;;AAEA;CACC,gBAAgB;AACjB;;AAEA;CACC,YAAY;CACZ,kBAAkB;AACnB;;AAEA;CACC,aAAa;CACb,yEAAiE;SAAjE,iEAAiE;CACjE,UAAU;AACX;;AAEA;CACC,uBAAuB;AACxB;;AAEA;CACC,oBAAa;CAAb,oBAAa;CAAb,aAAa;CACb,gBAAgB;CAChB,qBAAqB;CACrB,mBAAe;KAAf,eAAe;AAChB;;AAEA;CACC,UAAU;CACV,gBAAgB;CAChB,YAAY;CACZ,wBAAwB;CACxB,aAAa;CACb,8BAAsB;SAAtB,sBAAsB;AACvB;;AAEA;CACC,kBAAkB;CAClB,8BAA8B;CAC9B,wBAAuB;KAAvB,qBAAuB;SAAvB,uBAAuB;CACvB,yBAAmB;KAAnB,sBAAmB;SAAnB,mBAAmB;AACpB;;AAEA;CACC,aAAa;AACd;;AAEA;CACC,aAAa;AACd;;AAEA;CACC,YAAY;CACZ,iCAAiC;CACjC,yBAAyB;AAC1B;;AAEA;CACC,mBAAmB;CACnB,WAAW;CACX,SAAS;CACT,kBAAkB;AACnB;;AAEA;;CAEC,aAAa;AACd;;AAEA;CACC,qBAAqB;CACrB,mBAAmB;CACnB,gBAAgB;CAChB,eAAe;AAChB;;AAEA;CACC,yBAAyB;CACzB,kBAAkB;CAClB,yFAAyF;CACzF,wBAAgB;SAAhB,gBAAgB;AACjB;;AAEA;CACC,qBAAqB;CACrB,mBAAmB;CACnB,eAAe;CACf,eAAe;CACf,eAAe;AAChB;;AAEA;CACC,UAAU;CACV,qBAAqB;CACrB,WAAW;CACX;;EAEC;AACF;;AAEA;CACC,WAAW;CACX,eAAe;AAChB;;AAEA;CACC,eAAe;AAChB;;AAEA;CACC,mBAAmB;AACpB;;AAEA;CACC,cAAc;AACf;;AAEA;CACC,gBAAgB;CAChB,WAAW;AACZ;;AAEA;CACC,qBAAqB;CACrB,YAAY;AACb;;AAEA;CACC,mBAAmB;CACnB,2BAA2B;CAC3B,8BAA8B;CAC9B,WAAW;CACX,eAAe;CACf,yCAAyC;AAC1C;;AAEA;CACC,mBAAmB;CACnB,4BAA4B;CAC5B,+BAA+B;CAC/B,iBAAiB;AAClB;;AAEA;CACC,aAAa;AACd;;AAEA;CACC,WAAW;CACX,iBAAiB;AAClB;;AAEA;CACC,YAAY;CACZ,kBAAkB;CAClB,iBAAiB;AAClB;;AAEA;CACC,WAAW;CACX,gBAAgB;CAChB,aAAa;AACd;;AAEA;CACC,gBAAgB;CAChB,WAAW;CACX,mBAAmB;CACnB,UAAU;AACX;;AAEA;CACC,kBAAkB;CAClB,kBAAkB;AACnB;;AAEA;CACC,mBAAmB;CACnB,WAAW;CACX,sBAAsB;CACtB,gBAAgB;AACjB;;AAEA;CACC,YAAY;CACZ,cAAc;CACd,qBAAqB;AACtB;;AAEA;CACC,WAAW;CACX,4BAAoB;CAApB,oBAAoB;CACpB,kBAAkB;AACnB;;AAEA;CACC,YAAY;AACb;;AAEA;CACC,gBAAgB;AACjB;;AAEA;CACC,gBAAgB;CAChB,eAAe;CACf,mBAAmB;CACnB,WAAW;CACX,iBAAiB;CACjB,mBAAmB;AACpB;;AAEA;CACC,gBAAgB;AACjB;;AAEA;CACC,WAAW;CACX,UAAU;CACV,gBAAgB;AACjB;;AAEA;CACC,eAAe;CACf,kBAAkB;CAClB,iBAAiB;AAClB;;AAEA;CACC,eAAe;CACf,kBAAkB;CAClB,iBAAiB;AAClB;;AAEA;CACC,cAAc;CACd,qBAAqB;CACrB,eAAe;CACf,kBAAkB;CAClB,iBAAiB;CACjB,kBAAkB;AACnB;;AAEA;CACC,eAAe;CACf,sBAAsB;CACtB,eAAe;CACf,kBAAkB;CAClB,iBAAiB;CACjB,gBAAgB;AACjB;;AAEA;CACC,YAAY;AACb;;AAEA;CACC,eAAe;CACf,kBAAkB;CAClB,iBAAiB;CACjB,YAAY;AACb;;AAEA;CACC,gBAAgB;CAChB,eAAe;AAChB;;AAEA;CACC,WAAW;CACX,kBAAkB;CAClB,eAAe;CACf,kBAAkB;CAClB,iBAAiB;CACjB,iBAAiB;AAClB;;AAEA;CACC,YAAY;AACb;;AAEA;CACC,WAAW;AACZ;;AAEA;CACC,kBAAkB;AACnB;;AAEA;CACC,iBAAiB;CACjB,cAAc;CACd,qBAAqB;CACrB,eAAe;CACf,YAAY;AACb;;AAEA;CACC,iBAAiB;AAClB;;AAEA;CACC,kBAAkB;CAClB,yBAAyB;CACzB,wBAAwB;CACxB,WAAW;CACX,cAAc;AACf;;AAEA;CACC,qBAAqB;AACtB;;AAEA;CACC,aAAa;CACb,kBAAkB;CAClB,UAAU;AACX;;AAEA;CACC,sBAAsB;AACvB;;AAEA;CACC,eAAe;AAChB;;AAEA;CACC,YAAY;AACb;;AAEA;CACC,iBAAiB;AAClB;;AAEA,qBAAqB;;AAErB,2BAA2B;;AAE3B;CACC,WAAW;CACX,YAAY;CACZ,WAAW;CACX,mBAAmB;AACpB;;AAEA;CACC,eAAe;AAChB;;AAEA;CACC,gBAAgB;CAChB,eAAe;CACf,iBAAiB;CACjB,aAAa;CACb,WAAW;AACZ;;AAEA;CACC,YAAY;CACZ,kBAAkB;CAClB,UAAU;AACX;;AAEA;;CAEC,iBAAiB;CACjB,eAAe;CACf,mBAAmB;CACnB,aAAa;CACb,sBAAsB;AACvB;;AAEA;CACC,gBAAgB;CAChB,kBAAkB;CAClB,qBAAqB;AACtB;;AAEA;;CAEC,qBAAqB;CACrB,gBAAgB;AACjB;;AAEA;;;CAGC,wBAAwB;CACxB,gBAAgB;AACjB;;AAEA;CACC,kBAAkB;AACnB;;AAEA;;CAEC;;EAEC,qBAAqB;CACtB;;AAED;;AAEA;CACC,eAAe;CACf,eAAe;CACf,wBAAgB;SAAhB,gBAAgB;CAChB,cAAc;CACd,YAAY;CACZ,iBAAiB;AAClB;;AAEA;;;CAGC,cAAc;AACf;;AAEA;CACC,cAAc;CACd,iBAAiB;CACjB,eAAe;CACf,gBAAgB;AACjB;;AAEA;CACC,gBAAgB;AACjB;;AAEA;CACC,aAAa;AACd;;AAEA;CACC,kBAAkB;AACnB;;AAEA;CACC,uBAAuB;AACxB;;AAEA;CACC,eAAe;AAChB;;AAEA;CACC,iBAAiB;AAClB;;AAEA;CACC,eAAe;AAChB;;AAEA;CACC,kBAAkB;AACnB;;AAEA;;CAEC,aAAa;CACb,aAAa;CACb,sBAAsB;CACtB,kBAAkB;AACnB;;AAEA;;;CAGC,YAAY;CACZ,gBAAgB;CAChB,YAAY;CACZ,uBAAuB;CACvB,kBAAkB;CAClB,QAAQ;CACR,UAAU;CACV,eAAe;AAChB;;AAEA;CACC,cAAc;AACf;;AAEA;CACC,qBAAqB;CACrB,eAAe;AAChB;;AAEA;CACC,WAAW;AACZ;;AAEA;CACC,0BAA0B;AAC3B;;AAEA;CACC,cAAc;CACd,wBAAwB;CACxB,kBAAkB;AACnB;;AAEA;CACC,WAAW;AACZ;;AAEA,kCAAkC;;AAElC;CACC,gBAAgB;AACjB;;AAEA;CACC,eAAe;AAChB;;AAEA;;CAEC,yBAAyB;AAC1B;;AAEA;CACC,yBAAyB;AAC1B;;AAEA;CACC,aAAa;AACd;;AAEA;CACC,6BAA6B;CAC7B,YAAY;CACZ,cAAc;CACd,0BAA0B;CAC1B,eAAe;CACf,WAAW;CACX,WAAW;AACZ;;AAEA;CACC,gBAAgB;AACjB;;AAEA;CACC,2BAA2B;CAC3B,6BAA6B;CAC7B,0BAA0B;CAC1B,gBAAgB;CAChB,gBAAgB;AACjB;;AAEA;CACC,0BAA0B;AAC3B;;AAEA;CACC,YAAY;CACZ,YAAY;CACZ,6BAA6B;AAC9B;;AAEA;CACC,8BAA8B;AAC/B;;AAEA;CACC,YAAY;CACZ,iBAAiB;CACjB,iBAAiB;CACjB,kBAAkB;CAClB,gBAAgB;AACjB;;AAEA;CACC,gBAAgB;CAChB,sBAAsB;AACvB;;AAEA;CACC,UAAU;AACX;;AAEA;CACC,kBAAkB;AACnB;;AAEA;CACC,kBAAkB;CAClB,WAAW;CACX,qBAAqB;AACtB;;AAEA;CACC,qBAAqB;CACrB,WAAW;CACX,YAAY;CACZ,gBAAgB;CAChB,cAAc;CACd,mBAAmB;CACnB,kBAAkB;CAClB,iBAAiB;CACjB,iDAAyC;SAAzC,yCAAyC;AAC1C;;AAEA;CACC,aAAa;CACb,kBAAkB;CAClB,YAAY;CACZ,gDAAwC;SAAxC,wCAAwC;CACxC,YAAY;CACZ,oBAAoB;AACrB;;AAEA;CACC,WAAW;CACX,kBAAkB;CAClB,aAAa;CACb,8BAA8B;CAC9B,sBAAsB;CACtB,sBAAsB;AACvB;;AAEA;CACC,aAAa;CACb,gBAAgB;CAChB,kBAAkB;CAClB,iDAAyC;SAAzC,yCAAyC;CACzC,cAAc;AACf;;AAEA;CACC,aAAa;AACd;;AAEA;CACC,gBAAgB;AACjB;;AAEA;CACC,cAAc;AACf;;AAEA;CACC,kCAAkC;AACnC;;AAEA;CACC,cAAc;CACd,eAAe;AAChB;;AAEA;CACC,sBAAsB;AACvB;;AAEA;CACC,mBAAmB;AACpB;;AAEA;CACC,WAAW;CACX,sBAAsB;CACtB,eAAe;AAChB;;AAEA;CACC,gBAAgB;AACjB;;AAEA;CACC,qBAAqB;AACtB;;AAEA,kBAAkB;;AAElB,mEAAmE;AACnE;;CAEC,uBAAuB;AACxB;;AAEA;;CAEC,+BAA+B;AAChC;;AAEA;;CAEC,8BAA8B;AAC/B;;AAEA;;CAEC,uBAAuB;AACxB;;AAEA,8BAA8B;AAC9B;CACC,kBAAkB;CAClB,aAAa;CACb,cAAc;AACf;;AAEA;CACC,kBAAkB;CAClB,YAAY;CACZ,WAAW;CACX,kBAAkB;CAClB,kBAAkB;AACnB;;AAEA;CACC,WAAW;CACX,kBAAkB;CAClB,eAAe;AAChB;;AAEA;CACC,aAAa;CACb,cAAc;CACd,kBAAkB;AACnB;;AAEA;CACC,kBAAkB;AACnB;;AAEA;CACC,iBAAiB;CACjB,kBAAkB;AACnB;;AAEA;CACC,kBAAkB;CAClB,kBAAkB;CAClB,WAAW;CACX,WAAW;CACX,cAAc;AACf;;AAEA,6BAA6B;AAC7B;CACC,kBAAkB;CAClB,aAAa;CACb,WAAW;CACX,sBAAsB;CACtB,mBAAmB;CACnB,kBAAkB;CAClB,eAAe;CACf,gDAAwC;SAAxC,wCAAwC;AACzC;;AAEA;CACC,YAAY;CACZ,WAAW;CACX,YAAY;CACZ,cAAc;CACd,mBAAmB;CACnB,kBAAkB;CAClB,MAAM;CACN,UAAU;CACV,0BAA0B;CAC1B,2BAA2B;CAC3B,iDAAyC;SAAzC,yCAAyC;AAC1C;;AAEA;CACC,qBAAqB;AACtB;;AAEA;CACC,aAAa;AACd;;AAEA;CACC,aAAa;CACb,mBAAmB;AACpB;;AAEA;CACC,aAAa;CACb,WAAW;CACX,cAAc;AACf;;AAEA;CACC,iBAAiB;AAClB;;AAEA;CACC,0BAA0B;CAC1B,iBAAiB;AAClB;;AAEA;CACC,aAAa;AACd;;AAEA;CACC,iBAAiB;AAClB;;AAEA;;CAEC,eAAe;AAChB;;AAEA;CACC,cAAc;AACf;;AAEA;CACC,cAAc;AACf;;AAEA;CACC,YAAY;AACb;;AAEA;CACC,WAAW;AACZ;;AAEA;CACC,SAAS;CACT,UAAU;AACX;;AAEA;CACC,qBAAqB;AACtB;;AAEA;CACC,YAAY;CACZ,6BAA6B;CAC7B,WAAW;CACX,WAAW;CACX,gBAAgB;CAChB,eAAe;CACf,iBAAiB;AAClB;;AAEA;CACC,WAAW;CACX,eAAe;AAChB;;AAEA;CACC,YAAY;CACZ,yBAAyB;CACzB,qBAAqB;CACrB,mCAA2B;SAA3B,2BAA2B;AAC5B;;AAEA;;CAEC,kBAAkB;CAClB,WAAW;CACX,gBAAgB;AACjB;;AAEA,kDAAkD;AAClD;CACC,cAAc;CACd,yBAAyB;CACzB,kBAAkB;CAClB,gCAAwB;SAAxB,wBAAwB;AACzB;;AAEA;CACC,qBAAqB;AACtB;;AAEA;CACC,2BAAmB;SAAnB,mBAAmB;CACnB,kDAA0C;SAA1C,0CAA0C;AAC3C;;AAEA;CACC,uBAAuB;CACvB,aAAa;AACd;;AAEA;CACC,mBAAmB;CACnB,YAAY;AACb;;AAEA;CACC,gBAAgB;CAChB,WAAW;AACZ;;AAEA;CACC,YAAY;CACZ,mBAAmB;CACnB,sBAAsB;CACtB,aAAa;AACd;;AAEA;CACC,mBAAmB;AACpB;;AAEA;;CAEC;AACD;CACC,gBAAgB;CAChB,gBAAgB;CAChB,UAAU;CACV,8BAA8B;AAC/B;;AAEA;CACC,mBAAmB;AACpB;;AAEA;CACC,kBAAkB;CAClB,kBAAkB;AACnB;;AAEA;CACC,gBAAgB;CAChB,uBAAuB;CACvB,yBAAyB;CACzB,kBAAkB;AACnB;;AAEA;CACC,cAAc;CACd,eAAe;CACf,kBAAkB;CAClB,cAAc;AACf;;AAEA;CACC,WAAW;CACX,YAAY;AACb;;AAEA;CACC,oBAAa;CAAb,oBAAa;CAAb,aAAa;CACb,yBAAmB;KAAnB,sBAAmB;SAAnB,mBAAmB;CACnB,yBAA8B;KAA9B,sBAA8B;SAA9B,8BAA8B;CAC9B,kBAAkB;AACnB;;AAEA;CACC,mBAAmB;CACnB,iBAAiB;AAClB;;AAEA;CACC,kBAAkB;AACnB;;AAEA;CACC,eAAe;CACf,gBAAgB;CAChB,cAAc;CACd,SAAS;CACT,kBAAkB;CAClB,uBAAuB;CACvB,cAAc;AACf;;AAEA;CACC,WAAW;AACZ;;AAEA;;CAEC;EACC,4BAAsB;EAAtB,6BAAsB;MAAtB,0BAAsB;UAAtB,sBAAsB;EACtB,kBAAkB;EAClB,yBAAmB;MAAnB,sBAAmB;UAAnB,mBAAmB;CACpB;;CAEA;EACC,eAAe;EACf,mBAAmB;CACpB;;AAED;;AAEA;;CAEC;AACD;CACC,gBAAgB;CAChB,aAAa;CACb,gDAAwC;SAAxC,wCAAwC;CACxC,kBAAkB;AACnB;;AAEA;CACC,SAAS;AACV;;AAEA;CACC,2BAAkB;KAAlB,kBAAkB;CAClB,gBAAgB;CAChB,wBAAgB;SAAhB,gBAAgB;AACjB;;AAEA;;CAEC;AACD;CACC,oBAAa;CAAb,oBAAa;CAAb,aAAa;CACb,8BAAmB;CAAnB,6BAAmB;KAAnB,uBAAmB;SAAnB,mBAAmB;CACnB,mBAAe;KAAf,eAAe;CACf,yBAA8B;KAA9B,sBAA8B;SAA9B,8BAA8B;CAC9B,eAAe;AAChB;;AAEA;CACC,cAAc;CACd,eAAe;CACf,qBAAqB;AACtB;;AAEA;CACC,8BAAsB;SAAtB,sBAAsB;CACtB,UAAU;AACX;;AAEA;CACC,gBAAgB;CAChB,iBAAiB;AAClB;;AAEA;;CAEC;AACD;CACC,gBAAgB;CAChB,SAAS;CACT,eAAe;AAChB;;AAEA;CACC,uBAAuB;AACxB;;AAEA;CACC,eAAe;AAChB;;AAEA;CACC,cAAc;AACf;;AAEA;CACC,WAAW;AACZ;;AAEA;CACC,oCAAoC;CACpC,iBAAiB;AAClB;;AAEA;CACC,aAAa;CACb,gBAAgB;CAChB,2BAA2B;CAC3B,0BAA0B;CAC1B,8CAAsC;SAAtC,sCAAsC;CACtC,oBAAoB;CACpB,iBAAiB;AAClB;;AAEA;CACC,wBAAwB;AACzB;;AAEA;CACC,YAAY;AACb;;AAEA;CACC,YAAY;CACZ,yBAAyB;CACzB,eAAe;CACf,uBAAuB;CACvB,kBAAkB;AACnB;;AAEA;CACC,yBAAyB;CACzB,yBAAyB;CACzB,eAAe;CACf,uBAAuB;CACvB,kBAAkB;CAClB,aAAa;AACd;;AAEA;CACC,wBAAwB;AACzB;;AAEA;CACC,iBAAiB;AAClB;;AAEA;CACC,kBAAkB;AACnB;;AAEA;CACC,mBAAmB;AACpB;;AAEA;;CAEC,2CAA2C;CAC3C,YAAY;AACb;;AAEA;CACC,cAAc;CACd,cAAc;AACf;;AAEA;CACC,kBAAkB;AACnB;;AAEA;CACC,eAAe;AAChB;;AAEA;CACC,iBAAiB;CACjB,eAAe;CACf,eAAe;AAChB;;AAEA;CACC,eAAe;AAChB;;AAEA;CACC,WAAW;CACX,YAAY;CACZ,eAAe;CACf,cAAc;AACf;;AAEA;CACC,YAAY;AACb;;AAEA;CACC,UAAU;AACX;;AAEA;CACC,kBAAkB;AACnB;;AAEA;CACC,aAAa;CACb,YAAY;AACb;;AAEA;CACC,YAAY;CACZ,uBAAuB;CACvB,WAAW;CACX,eAAe;CACf,UAAU;CACV,eAAe;AAChB;;AAEA;CACC,SAAS;CACT,mBAAmB;CACnB,WAAW;CACX,6BAAqB;CAArB,qBAAqB;AACtB;;AAEA;CACC,eAAe;CACf,WAAW;AACZ;;AAEA;CACC,eAAe;AAChB;;AAEA;CACC,aAAa;AACd;;AAEA;CACC,WAAW;AACZ;;AAEA;CACC,eAAe;AAChB;;AAEA;CACC,eAAe;CACf,UAAU;CACV,eAAe;CACf,iBAAiB;CACjB,WAAW;CACX,kBAAkB;CAClB,YAAY;CACZ,aAAa;CACb,qBAAqB;CACrB,qBAAqB;AACtB;;AAEA;CACC,eAAe;CACf,YAAY;CACZ,eAAe;AAChB;;AAEA;CACC,gBAAgB;CAChB,eAAe;CACf,iBAAiB;CACjB,aAAa;CACb,WAAW;AACZ;;AAEA,oBAAoB;AACpB;CACC,gBAAgB;AACjB;;AAEA;CACC,kBAAkB;CAClB,oBAAoB;AACrB;;AAEA;CACC,gBAAgB;CAChB,YAAY;CACZ,aAAa;CACb,kBAAkB;CAClB,YAAY;CACZ,kBAAkB;CAClB,gBAAgB;CAChB,cAAc;CACd,iBAAiB;CACjB,kBAAkB;CAClB,mBAAmB;AACpB;;AAEA;CACC,iBAAiB;AAClB;;AAEA;CACC,YAAY;AACb;;AAEA;CACC,WAAW;AACZ;;AAEA;CACC,aAAa;AACd;;AAEA;CACC,qBAAqB;CACrB,eAAe;CACf,iBAAiB;CACjB,UAAU;CACV,kCAA0B;SAA1B,0BAA0B;AAC3B;;AAEA;CACC,iCAAyB;SAAzB,yBAAyB;CACzB,iCAAyB;SAAzB,yBAAyB;CACzB,2CAAmC;SAAnC,mCAAmC;CACnC,sCAA8B;SAA9B,8BAA8B;CAC9B,2CAAmC;SAAnC,mCAAmC;AACpC;;AAEA;CACC,aAAa;AACd;;AAEA;;CAEC;EACC,cAAc;EACd,WAAW;EACX,kBAAkB;CACnB;;AAED;;AAEA,mCAAmC;AACnC;CACC,UAAU;AACX;;AAEA;CACC,YAAY;AACb;;AAEA;CACC,iBAAiB;CACjB,oBAAoB;AACrB;;AAEA;CACC,eAAe;AAChB;;AAEA;CACC,YAAY;AACb;;AAEA;CACC,YAAY;AACb;;AAEA;;;;;;;;;;;;;;;;;;;;EAoBE;;AAEF;CACC,gBAAgB;AACjB;;AAEA;CACC,qBAAqB;AACtB;;AAEA;CACC,WAAW;CACX,YAAY;CACZ,kBAAkB;AACnB;;AAEA;CACC,8BAA8B;CAC9B,sBAAsB;CACtB,uBAAuB;AACxB;;AAEA;CACC,iBAAiB;CACjB,WAAW;CACX,wBAAwB;AACzB;;AAEA;CACC,mBAAmB;AACpB;;AAEA;CACC,WAAW;AACZ;;AAEA;CACC,YAAY;AACb;;AAEA;CACC,eAAe;AAChB;;AAEA;CACC,qBAAqB;AACtB;;AAEA;CACC,YAAY;CACZ,mBAAmB;CACnB,kBAAkB;CAClB,oDAA4C;SAA5C,4CAA4C;AAC7C;;AAEA;CACC,cAAc;CACd,YAAY;AACb;;AAEA;CACC,cAAc;CACd,cAAc;CACd,eAAe;CACf,WAAW;CACX,YAAY;CACZ,kBAAkB;CAClB,iBAAiB;CACjB,WAAW;CACX,mBAAmB;AACpB;;AAEA;CACC,qBAAqB;CACrB,iBAAiB;CACjB,eAAe;AAChB;;AAEA;CACC,eAAe;AAChB;;AAEA;CACC,YAAY;AACb;;AAEA;CACC,eAAe;AAChB;;AAEA;CACC,yBAAyB;CACzB,kBAAkB;CAClB,iBAAiB;AAClB;;AAEA;CACC,iBAAiB;CACjB,cAAc;AACf;;AAEA;CACC,kBAAkB;AACnB;;AAEA;CACC,cAAc;AACf;;AAEA;CACC,iBAAiB;AAClB;;AAEA;CACC,gBAAgB;CAChB,SAAS;CACT,mBAAmB;AACpB;;AAEA;CACC,iBAAiB;CACjB,cAAc;AACf;;AAEA;CACC,mBAAmB;AACpB;;AAEA;CACC,eAAe;AAChB;;AAEA;CACC,iBAAiB;AAClB;;AAEA;CACC,sBAAsB;CACtB,YAAY;CACZ,WAAW;CACX,kBAAkB;AACnB;;AAEA;CACC,uBAAuB;CACvB,gBAAgB;CAChB,eAAe;CACf,mBAAmB;AACpB;;AAEA;CACC,cAAc;AACf;;AAEA;CACC,gBAAgB;AACjB;;AAEA;CACC,WAAW;AACZ;;AAEA;CACC,eAAe;AAChB;;AAEA;CACC,aAAa;CACb,8BAA8B;CAC9B,kBAAkB;CAClB,OAAO;CACP,SAAS;AACV;;AAEA;CACC,sBAAsB;AACvB;;AAEA;CACC,qBAAqB;CACrB,eAAe;AAChB;;AAEA;CACC,qBAAqB;AACtB;;AAEA;CACC,qBAAqB;CACrB,kBAAkB;AACnB;;AAEA;CACC,qBAAqB;CACrB,YAAY;CACZ,kBAAkB;CAClB,iBAAiB;AAClB;;AAEA;CACC,mBAAmB;CACnB,kBAAkB;AACnB;;AAEA;CACC,YAAY;AACb;;AAEA;CACC,kBAAkB;CAClB,0BAA0B;AAC3B;;AAEA;CACC,eAAe;AAChB;;AAEA;CACC,yBAAyB;AAC1B;;AAEA;CACC,eAAe;CACf,cAAc;AACf;;AAEA;CACC,aAAa;AACd;;AAEA;CACC,aAAa;CACb,mBAAmB;CACnB,uBAAuB;AACxB;;AAEA,8BAA8B;AAC9B;CACC,uBAAuB;CACvB,YAAY;AACb;;AAEA;CACC,iBAAiB;CACjB,cAAc;AACf;;AAEA;CACC,mBAAmB;CACnB,gBAAgB;CAChB,gBAAgB;AACjB;;AAEA;CACC,eAAe;AAChB;;AAEA;CACC,YAAY;CACZ,YAAY;AACb;;AAEA;CACC,WAAW;CACX,gBAAgB;AACjB;;AAEA;CACC,WAAW;CACX,gBAAgB;AACjB;;AAEA;CACC,YAAY;CACZ,oBAAoB;AACrB;;AAEA;CACC,WAAW;CACX,kBAAkB;CAClB,aAAa;AACd;;AAEA;CACC,aAAa;CACb,kBAAkB;AACnB;;AAEA;CACC,iBAAiB;AAClB;;AAEA;CACC,WAAW;CACX,kBAAkB;CAClB,SAAS;CACT,QAAQ;CACR,kBAAkB;CAClB,yBAAyB;CACzB,8BAAsB;CAAtB,sBAAsB;AACvB;;AAEA;CACC,UAAU;CACV,kBAAkB;CAClB,eAAe;CACf,WAAW;CACX,YAAY;CACZ,iBAAiB;CACjB,kBAAkB;CAClB,kBAAkB;CAClB,kBAAkB;CAClB,WAAW;CACX,yBAAyB;CACzB,yCAAyC;AAC1C;;AAEA;CACC,qBAAqB;CACrB,UAAU;AACX;;AAEA;CACC,WAAW;AACZ;;AAEA;CACC,gBAAgB;AACjB;;AAEA;CACC,UAAU;CACV,WAAW;CACX,kBAAkB;AACnB;;AAEA;CACC,eAAe;CACf,iBAAiB;AAClB;;AAEA;CACC,iBAAiB;CACjB,YAAY;AACb;;AAEA;CACC,kBAAkB;CAClB,iBAAiB;CACjB,eAAe;AAChB;;AAEA;CACC,UAAU;CACV,gBAAgB;AACjB;;AAEA;CACC,gBAAgB;CAChB,0BAA0B;AAC3B;;AAEA;CACC,kBAAkB;CAClB,kBAAkB;CAClB,kBAAkB;AACnB;;AAEA;CACC,kBAAkB;AACnB;;AAEA;CACC,iBAAiB;AAClB;;AAEA;CACC,YAAY;AACb;;AAEA;CACC,YAAY;AACb;;AAEA;CACC,YAAY;AACb;;AAEA;CACC,8BAA8B;CAE9B,sBAAsB;CACtB,gBAAgB;CAChB,UAAU;AACX;;AAEA;CACC,WAAW;CACX,YAAY;CACZ,WAAW;AACZ;;AAEA;CACC,SAAS;CACT,UAAU;AACX;;AAEA;CACC,WAAW;CACX,sBAAsB;AACvB;;AAEA;CACC,gBAAgB;AACjB;;AAEA;CACC,YAAY;CACZ,WAAW;AACZ;;AAEA;CACC,WAAW;CACX,YAAY;CACZ,WAAW;AACZ;;AAEA;CACC,SAAS;CACT,UAAU;AACX;;AAEA;CACC,WAAW;CACX,sBAAsB;AACvB;;AAEA;CACC,gBAAgB;AACjB;;AAEA;CACC,iBAAiB;CACjB,WAAW;CACX,WAAW;AACZ;;AAEA;CACC,YAAY;CACZ,WAAW;AACZ;;AAEA;CACC,WAAW;CACX,qBAAqB;AACtB;;AAEA;CACC,WAAW;CACX,YAAY;CACZ,WAAW;AACZ;;AAEA;CACC,WAAW;CACX,YAAY;AACb;;AAEA;CACC,WAAW;CACX,sBAAsB;AACvB;;AAEA;CACC,0BAA0B;AAC3B;;AAEA;CACC,2BAA2B;AAC5B;;AAEA;CACC,2BAA2B;AAC5B;;AAEA;CACC,2BAA2B;AAC5B;;AAEA;CACC,cAAc;AACf;;AAEA;CACC,oBAAoB;AACrB;;AAEA;;EAEE;;AAEF,4BAA4B;AAC5B;CACC,WAAW;AACZ;;AAEA;CACC,WAAW;AACZ;;AAEA;CACC,eAAe;CACf,eAAe;AAChB;;AAEA;CACC,eAAe;CACf,eAAe;AAChB;;AAEA,YAAY;AACZ,mHAAmH;;AAEnH;CACC,oBAAoB;CACpB,kBAAkB;AACnB;;AAEA;CACC,sBAAsB;CACtB,gBAAgB;AACjB;;AAEA;CACC,iBAAiB;CACjB,gBAAgB;CAChB,aAAa;CACb,YAAY;AACb;;AAEA;CACC,mBAAmB;AACpB;;AAEA;CACC,UAAU;AACX;;AAEA,gBAAgB;;AAEhB;CACC,yBAAyB;CACzB,aAAa;CACb,WAAW;AACZ;;AAEA;CACC,YAAY;CACZ,mBAAmB;CACnB,WAAW;CACX,kBAAkB;AACnB;;AAEA;CACC,qBAAqB;CACrB,cAAc;AACf;;AAEA;CACC,gBAAgB;AACjB;;AAEA;CACC,gBAAgB;AACjB;;AAEA;CACC,UAAU;CACV,WAAW;AACZ;;AAEA;CACC,UAAU;CACV,WAAW;CACX,kBAAkB;CAClB,YAAY;CACZ,gBAAgB;AACjB;;AAEA;CACC,4BAA4B;CAC5B,YAAY;CACZ,kBAAkB;AACnB;;AAEA;CACC,YAAY;AACb;;AAEA,oBAAoB;;AAEpB,gBAAgB;;AAEhB;CACC,WAAW;CACX,kBAAkB;CAClB,mBAAmB;AACpB;;AAEA;CACC,iBAAiB;AAClB;;AAEA;CACC,YAAY;CACZ,aAAa;CACb,sBAAsB;CACtB,qBAAqB;CACrB,cAAc;CACd,kBAAkB;CAClB,kBAAkB;AACnB;;AAEA;CACC,YAAY;CACZ,aAAa;AACd;;AAEA;CACC,UAAU;CACV,eAAe;CACf,4BAA4B;AAC7B;;AAEA;CACC,eAAe;AAChB;;AAEA;CACC,UAAU;CACV,cAAc;CACd,kBAAkB;AACnB;;AAEA;CACC,WAAW;CACX,sBAAsB;CACtB,gBAAgB;AACjB;;AAEA;CACC,iBAAiB;AAClB;;AAEA;CACC,aAAa;CACb,YAAY;CACZ,eAAe;AAChB;;AAEA;CACC,eAAe;AAChB;;AAEA;CACC,eAAe;CACf,cAAc;CACd,qBAAqB;CACrB,4BAA4B;CAC5B,kBAAkB;CAClB,UAAU;CACV,UAAU;AACX;;AAEA;CACC,kBAAkB;AACnB;;AAEA;CACC,sBAAsB;CACtB,eAAe;AAChB;;AAEA,oBAAoB;;AAEpB,mBAAmB;;AAEnB;CACC,gBAAgB;CAChB,WAAW;CACX,cAAc;CACd,cAAc;AACf;;AAEA;CACC,uBAAuB;CACvB,cAAc;CACd,kBAAkB;AACnB;;AAEA;CACC,kBAAkB;CAClB,iBAAiB;AAClB;;AAEA;CACC,kBAAkB;AACnB;;AAEA;CACC,YAAY;CACZ,aAAa;CACb,sBAAsB;CACtB,qBAAqB;CACrB,cAAc;CACd,kBAAkB;CAClB,gBAAgB;CAChB,kBAAkB;CAClB,kBAAkB;AACnB;;AAEA;CACC,gBAAgB;CAChB,iBAAiB;AAClB;;AAEA;CACC,WAAW;CACX,YAAY;CACZ,eAAe;AAChB;;AAEA;CACC,gBAAgB;AACjB;;AAEA;CACC,YAAY;CACZ,YAAY;AACb;;AAEA;CACC,UAAU;CACV,YAAY;AACb;;AAEA;CACC,eAAe;CACf,cAAc;CACd,qBAAqB;CACrB,4BAA4B;CAC5B,kBAAkB;CAClB,UAAU;CACV,UAAU;AACX;;AAEA;CACC,eAAe;CACf,sBAAsB;AACvB;;AAEA;CACC,WAAW;CACX,sBAAsB;CACtB,gBAAgB;AACjB;;AAEA;CACC,kBAAkB;AACnB;;AAEA;;CAEC,gBAAgB;AACjB;;AAEA;CACC,gBAAgB;AACjB;;AAEA,uBAAuB;;;AAGvB,kFAAkF;;AAElF;CACC,cAAc;AACf;;AAEA;CACC,kBAAkB;CAClB,iBAAiB;AAClB;;AAEA;CACC,kBAAkB;CAClB,mBAAmB;AACpB;;AAEA;CACC,cAAc;CACd,qBAAqB;CACrB,cAAc;CACd,cAAc;AACf;;AAEA;CACC,WAAW;CACX,kBAAkB;AACnB;;AAEA,+BAA+B;;AAE/B;CACC,kBAAkB;AACnB;;AAEA;CACC,WAAW;CACX,UAAU;CACV,kBAAkB;CAClB,oBAAoB;AACrB;;AAEA;CACC,YAAY;CACZ,iBAAiB;AAClB;;AAEA;CACC,WAAW;AACZ;;AAEA;CACC,iBAAiB;AAClB;;AAEA;CACC,iBAAiB;AAClB;;AAEA;CACC,0BAA0B;AAC3B;;AAEA;CACC,eAAe;AAChB;;AAEA;CACC,kBAAkB;AACnB;;AAEA;CACC,YAAY;AACb;;AAEA;CACC,YAAY;AACb;;AAEA;CACC,SAAS;CACT,UAAU;AACX;;AAEA;CACC,WAAW;AACZ;;AAEA;CACC,kBAAkB;AACnB;;AAEA;CACC,UAAU;CACV,kBAAkB;CAClB,iBAAiB;CACjB,qBAAqB;AACtB;;AAEA;CACC,eAAe;CACf,iBAAiB;AAClB;;AAEA;CACC,WAAW;CACX,eAAe;AAChB;;AAEA;CACC,WAAW;CACX,eAAe;CACf,kBAAkB;AACnB;;AAEA,kCAAkC;AAClC;AACA,4BAA4B;AAC5B;gBACgB;AAChB,gBAAgB;CACf,WAAW;CACX,WAAW;CACX,YAAY;CACZ,aAAa;AACd;;AAEA;CACC,WAAW;AACZ;;AAEA;CACC,WAAW;CACX,YAAY;CACZ,0BAA0B;CAC1B,UAAU;CACV,YAAY;CACZ,mBAAmB;AACpB;;AAEA;CACC,qBAAqB;CACrB,cAAc;CACd,mBAAmB;CACnB,kBAAkB;AACnB;;AAEA;CACC,gBAAgB;AACjB;;AAEA;CACC,cAAc;CACd,eAAe;AAChB;;AAEA;CACC,gBAAgB;CAChB,yBAAyB;CACzB,kBAAkB;CAClB,cAAc;CACd,qBAAqB;CACrB,4BAA4B;CAC5B,6BAA6B;CAC7B,0BAA0B;CAC1B,iBAAiB;CACjB,gBAAgB;CAChB,2BAA2B;CAC3B,yBAAyB;CACzB,qBAAqB;AACtB;;AAEA;CACC,yBAAyB;CACzB,mBAAmB;CACnB,qBAAqB;CACrB,eAAe;CACf,iBAAiB;CACjB,gBAAgB;CAChB,WAAW;CACX,YAAY;CACZ,kBAAkB;AACnB;;AAEA,sCAAsC;AACtC,4CAA4C;AAC5C;CACC,YAAY;CACZ,gBAAgB;AACjB;;AAEA;CACC,WAAW;CACX,2CAA2C;AAC5C;;AAEA;CACC,gBAAgB;CAChB,WAAW;CACX,WAAW;CACX,cAAc;AACf;;AAEA;CACC,0BAA0B;AAC3B;;AAEA;CACC,aAAa;AACd;;AAEA;CACC,cAAc;AACf;;AAEA;CACC,qBAAqB;CACrB,eAAe;CACf,YAAY;CACZ,WAAW;AACZ;;AAEA;CACC,eAAe;AAChB;;AAEA;CACC,yBAAyB;AAC1B;;AAEA;CACC,yBAAyB;CACzB,WAAW;AACZ;;AAEA;CACC,yBAAyB;CACzB,WAAW;AACZ;;AAEA;CACC,uBAAuB;AACxB;;AAEA;CACC,0BAA0B;AAC3B;;AAEA;CACC,UAAU;CACV,WAAW;CACX,kBAAkB;AACnB;;AAEA;CACC,kBAAkB;AACnB;;AAEA;CACC,aAAa;AACd;;AAEA;CACC,iBAAiB;CACjB,kBAAkB;CAClB,oBAAoB;CACpB,kBAAkB;AACnB;;AAEA;CACC,kBAAkB;CAClB,sBAAsB;CACtB,eAAe;CACf,gBAAgB;CAChB,sBAAsB;AACvB;;AAEA;CACC,sBAAsB;CACtB,iBAAiB;CACjB,2BAA2B;CAC3B,sBAAsB;CACtB,mBAAmB;AACpB;;AAEA;CACC,sBAAsB;CACtB,iBAAiB;CACjB,8BAA8B;CAC9B,sBAAsB;CACtB,mBAAmB;AACpB;;AAEA;CACC,kBAAkB;CAClB,WAAW;AACZ;;AAEA;CACC,mBAAmB;CACnB,WAAW;AACZ;;AAEA;CACC,gBAAgB;AACjB;;AAEA;CACC,eAAe;CACf,iBAAiB;CACjB,mBAAmB;AACpB;;AAEA;;CAEC,gBAAgB;AACjB;;AAEA;CACC,eAAe;CACf,mBAAmB;AACpB;;AAEA;CACC,WAAW;CACX,gBAAgB;CAChB,kBAAkB;AACnB;;AAEA;CACC,WAAW;AACZ;;AAEA;CACC,WAAW;AACZ;;AAEA;CACC,gBAAgB;AACjB;;AAEA;CACC,cAAc;AACf;;AAEA;CACC,uBAAuB;AACxB;;AAEA;CACC,WAAW;AACZ;;AAEA;CACC,4BAAsB;CAAtB,6BAAsB;KAAtB,0BAAsB;SAAtB,sBAAsB;CACtB,kBAAkB;CAClB,mBAAmB;AACpB;;AAEA;CACC,WAAW;AACZ;;AAEA;CACC,iBAAiB;AAClB;;AAEA;CACC,aAAa;CACb,mBAAmB;CACnB,cAAc;CACd,cAAc;CACd,kDAA0C;SAA1C,0CAA0C;AAC3C;;AAEA;CACC,mBAAmB;CACnB,kDAA0C;SAA1C,0CAA0C;AAC3C;;AAEA;CACC,uBAAuB;CACvB,UAAU;AACX;;AAEA;CACC,cAAc;CACd,gBAAgB;AACjB;;AAEA;CACC,0BAA0B;AAC3B;;AAEA,qBAAqB;;AAErB;CACC,cAAc;CACd,eAAe;CACf,MAAM;CACN,OAAO;CACP,QAAQ;CACR,SAAS;CACT,cAAc;CACd,iBAAiB;CACjB,mBAAmB;CACnB,cAAc;AACf;;AAEA;CACC,cAAc;AACf;;AAEA;CACC,gBAAgB;AACjB;;AAEA;CACC,SAAS;AACV;;AAEA;CACC,8BAAsB;SAAtB,sBAAsB;CACtB,gBAAgB;CAChB,iBAAiB;CACjB,kBAAkB;AACnB;;AAEA;CACC,gBAAgB;CAChB,cAAc;CACd,gBAAgB;CAChB,gBAAgB;CAChB,gDAAwC;SAAxC,wCAAwC;CACxC,kBAAkB;CAClB,oBAAa;CAAb,oBAAa;CAAb,aAAa;CACb,mBAAe;KAAf,eAAe;CACf,8BAAsB;SAAtB,sBAAsB;AACvB;;AAEA;CACC,eAAe;CACf,iBAAiB;CACjB,kBAAkB;CAClB,iBAAiB;CACjB,iBAAiB;CACjB,WAAW;CACX,eAAe;CACf,mBAAmB;CACnB,kBAAkB;CAClB,8BAAsB;SAAtB,sBAAsB;AACvB;;AAEA;CACC,kBAAkB;CAClB,yBAAyB;CACzB,8BAAsB;SAAtB,sBAAsB;AACvB;;AAEA;CACC,aAAa;CACb,SAAS;AACV;;AAEA;CACC,aAAa;AACd;;AAEA;CACC,YAAY;CACZ,aAAa;CACb,8BAAsB;SAAtB,sBAAsB;CACtB,mBAAmB;CACnB,iBAAiB;AAClB;;AAEA;CACC,mBAAmB;CACnB,cAAc;CACd,sBAAsB;CACtB,aAAa;CACb,cAAc;CACd,kBAAkB;CAClB,SAAS;CACT,SAAS;CACT,QAAQ;CACR,OAAO;AACR;;AAEA;CACC,mBAAmB;CACnB,gIAAgI;AACjI;;AAEA;CACC,yBAAyB;CACzB,kBAAkB;CAClB,mBAAmB;AACpB;;AAEA;CACC,cAAc;CACd,iBAAiB;CACjB,mBAAmB;AACpB;;AAEA;CACC,aAAa;CACb,2BAA2B;AAC5B;;AAEA;CACC,cAAc;CACd,eAAe;AAChB;;AAEA;;CAEC,iBAAiB;AAClB;;AAEA;CACC,YAAY;AACb;;AAEA;CACC,SAAS;CACT,qBAAqB;CACrB,kBAAkB;CAClB,2BAA2B;AAC5B;;AAEA;CACC,aAAa;AACd;;AAEA;CACC,gBAAgB;AACjB;;AAEA;CACC,cAAc;CACd,gBAAgB;CAChB,kBAAkB;AACnB;;AAEA;CACC,gBAAgB;CAChB,sBAAsB;CACtB,eAAe;CACf,sBAAsB;CACtB,qBAAqB;CACrB,iBAAiB;AAClB;;AAEA;CACC,sBAAsB;AACvB;;AAEA;CACC,YAAY;AACb;;AAEA;CACC,gBAAgB;AACjB;;AAEA;CACC,cAAc;AACf;;AAEA;CACC,gBAAgB;CAChB,gDAAwC;SAAxC,wCAAwC;AACzC;;AAEA;CACC,cAAc;AACf;;AAEA;CACC,gBAAgB;AACjB;;AAEA;CACC,eAAe;CACf,gBAAgB;CAChB,kBAAkB;CAClB,sBAAsB;CACtB,aAAa;AACd;;AAEA;CACC,cAAc;AACf;;AAEA;CACC,YAAY;AACb;;AAEA;CACC,eAAe;CACf,YAAY;CACZ,iBAAiB;CACjB,WAAW;AACZ;;AAEA;CACC,sBAAsB;AACvB;;AAEA,kBAAkB;;AAElB;CACC,WAAW;AACZ;;AAEA;CACC,mBAAmB;AACpB;;AAEA;;CAEC,kBAAkB;AACnB;;AAEA;CACC,aAAa;CACb,mBAAmB;CACnB,kBAAkB;CAClB,6BAA6B;AAC9B;;AAEA;CACC,SAAS;CACT,UAAU;AACX;;AAEA;CACC,mBAAmB;AACpB;;AAEA;CACC,iBAAiB;AAClB;;AAEA;CACC,qBAAqB;CACrB,SAAS;CACT,YAAY;AACb;;AAEA;CACC,qBAAqB;CACrB,kBAAkB;CAClB,WAAW;CACX,YAAY;CACZ,mBAAmB;CACnB,mBAAmB;CACnB,cAAc;CACd,aAAa;CACb,sBAAsB;AACvB;;AAEA;CACC,gBAAgB;AACjB;;AAEA;CACC,0BAA0B;CAC1B,aAAa;CACb,kBAAkB;CAClB,gBAAgB;CAChB,SAAS;CACT,gBAAgB;CAChB,WAAW;CACX,8BAAsB;SAAtB,sBAAsB;AACvB;;AAEA;CACC,kBAAkB;CAClB,UAAU;CACV,SAAS;AACV;;AAEA;CACC,kBAAkB;CAClB,WAAW;CACX,SAAS;AACV;;AAEA;CACC,kBAAkB;CAClB,YAAY;CACZ,yBAAyB;CACzB,WAAW;CACX,+BAAqB;CACrB,YAAY;CACZ,8BAAsB;SAAtB,sBAAsB;CACtB,kBAAkB;CAClB,WAAW;CACX,kBAAkB;CAClB,aAAa;AACd;;AAEA;CACC,qBAAqB;AACtB;;AAEA;CACC,mBAAmB;AACpB;;AAEA;CACC,iBAAiB;AAClB;;AAEA,yCAAyC;AACzC;CACC,aAAa;AACd;;AAEA;CACC,gBAAgB;AACjB;;AAEA;CACC,gDAAwC;SAAxC,wCAAwC;AACzC;;AAEA,qBAAqB;;AAErB;CACC,gBAAgB;CAChB,mBAAmB;CACnB,YAAY;AACb;;AAEA;CACC,wBAAwB;CACxB,aAAa;AACd;;AAEA;CACC,iBAAiB;AAClB;;AAEA;CACC,sBAAsB;AACvB;;AAEA;CACC,mBAAmB;AACpB;;AAEA;CACC,eAAe;AAChB;;AAEA;CACC,WAAW;AACZ;;AAEA,gBAAgB;;AAEhB;CACC,cAAc;CACd,iBAAiB;AAClB;;AAEA;CACC,mBAAmB;AACpB;;AAEA;CACC,WAAW;AACZ;;AAEA;CACC,mBAAmB;CACnB,oBAAoB;AACrB;;AAEA;CACC,sBAAsB;AACvB;;AAEA;CACC,YAAY;AACb;;AAEA;CACC,cAAc;CACd,kBAAkB;CAClB,gBAAgB;AACjB;;AAEA;CACC,UAAU;CACV,SAAS;CACT,kBAAkB;AACnB;;AAEA;CACC,kBAAkB;CAClB,oBAAoB;AACrB;;AAEA;CACC,kBAAkB;CAClB,oBAAoB;AACrB;;AAEA;CACC,UAAU;CACV,cAAc;AACf;;AAEA;;CAEC,iBAAiB;CACjB,oBAAoB;CACpB,yBAAyB;CACzB,YAAY;CACZ,iBAAiB;AAClB;;AAEA;;;CAGC,SAAS;CACT,cAAc;AACf;;AAEA;CACC,cAAc;AACf;;AAEA;CACC,WAAW;AACZ;;AAEA;CACC,mBAAmB;AACpB;;AAEA;CACC,gBAAgB;CAChB,cAAc;AACf;;AAEA;;CAEC;EACC,oBAAa;EAAb,oBAAa;EAAb,aAAa;EACb,2BAAqB;MAArB,wBAAqB;UAArB,qBAAqB;CACtB;;CAEA;EACC,mBAAU;MAAV,cAAU;UAAV,UAAU;CACX;;CAEA;EACC,yBAAyB;CAC1B;;AAED;;AAEA;;CAEC;;;EAGC,wBAAwB;EACxB,iBAAiB;EACjB,4BAA4B;EAC5B,YAAY;EACZ,gBAAgB;EAChB,WAAW;CACZ;;CAEA;EACC,YAAY;CACb;;CAEA;EACC,eAAe;EACf,SAAS;EACT,WAAW;EACX,QAAQ;EACR,SAAS;EACT,gBAAgB;EAChB,UAAU;EACV,+CAAuC;UAAvC,uCAAuC;CACxC;;CAEA;EACC,SAAS;EACT,YAAY;CACb;;CAEA;EACC,UAAU;CACX;;CAEA;EACC,kBAAkB;CACnB;;CAEA;EACC,WAAW;CACZ;;AAED;;AAEA;;CAEC;EACC,UAAU;CACX;;AAED;;AAEA;;CAEC;EACC,eAAe;CAChB;;CAEA;EACC,gBAAgB;CACjB;;CAEA;EACC,kBAAkB;EAClB,eAAe;EACf,iBAAiB;CAClB;;CAEA;EACC,kBAAkB;EAClB,eAAe;EACf,sBAAsB;EACtB,YAAY;EACZ,mBAAmB;CACpB;;CAEA;EACC,kBAAkB;EAClB,QAAQ;EACR,QAAQ;CACT;;CAEA;EACC,cAAc;EACd,yBAAyB;CAC1B;;CAEA;EACC,kBAAkB;CACnB;;CAEA;EACC,SAAS;EACT,cAAc;EACd,WAAW;CACZ;;CAEA;EACC,cAAc;CACf;;CAEA;EACC,WAAW;EACX,8BAAsB;UAAtB,sBAAsB;EACtB,kBAAkB;CACnB;;CAEA;EACC,eAAe;EACf,SAAS;EACT,SAAS;EACT,WAAW;EACX,8BAAsB;UAAtB,sBAAsB;EACtB,kBAAkB;EAClB,mDAA2C;UAA3C,2CAA2C;EAC3C,gBAAgB;EAChB,UAAU;CACX;;CAEA;EACC,cAAc;EACd,kBAAkB;CACnB;;CAEA;EACC,cAAc;CACf;;AAED;;;;;;;;;GASG;;CAEF;EACC,mBAAmB;CACpB;;CAEA;EACC,qBAAqB;CACtB;;CAEA;EACC,SAAS;EACT,wBAAgB;UAAhB,gBAAgB;EAChB,uBAAuB;CACxB;;CAEA;EACC,YAAY;EACZ,mBAAmB;EACnB,WAAW;EACX,YAAY;EACZ,gBAAgB;EAChB,UAAU;EACV,kBAAkB;EAClB,UAAU;EACV,UAAU;EACV,SAAS;CACV;;CAEA;EACC,cAAc;EACd,qBAAqB;EACrB,wBAAwB;EACxB,WAAW;EACX,UAAU;EACV,SAAS;EACT,mBAAmB;EACnB,gBAAgB;EAChB,gDAAwC;UAAxC,wCAAwC;CACzC;;CAEA;EACC,6BAA6B;EAC7B,cAAc;EACd,eAAe;EACf,gBAAgB;EAChB,WAAW;EACX,aAAa;EACb,SAAS;CACV;;CAEA;EACC;;;GAGC;EACD,yBAAyB;EACzB,iBAAiB;EACjB,cAAc;EACd,kBAAkB;EAClB,UAAU;EACV,oBAAoB;EACpB,WAAW;EACX,gBAAgB;CACjB;;CAEA;EACC,gBAAgB;CACjB;;CAEA;EACC,cAAc;EACd,eAAe;CAChB;;CAEA;EACC,gBAAgB;CACjB;;CAEA;EACC,4BAAsB;EAAtB,6BAAsB;MAAtB,0BAAsB;UAAtB,sBAAsB;CACvB;;CAEA;EACC,WAAW;CACZ;;CAEA;EACC,gBAAgB;CACjB;;CAEA;EACC,kBAAkB;CACnB;;CAEA;EACC,sBAAsB;EACtB,8BAA8B;CAC/B;;CAEA;EACC,iBAAiB;CAClB;;CAEA;EACC,sBAAsB;EACtB,kBAAkB;EAClB,OAAO;EACP,MAAM;EACN,8BAAsB;UAAtB,sBAAsB;EACtB,YAAY;EACZ,UAAU;EACV,YAAY;EACZ,2CAA2C;CAC5C;;CAEA;EACC,YAAY;CACb;;CAEA;EACC,cAAc;EACd,eAAe;EACf,WAAW;EACX,eAAe;CAChB;;CAEA;EACC,4BAAsB;EAAtB,6BAAsB;MAAtB,0BAAsB;UAAtB,sBAAsB;CACvB;;CAEA;EACC,WAAW;EACX,eAAe;EACf,eAAe;EACf,mBAAmB;CACpB;;CAEA;EACC,oBAAoB;CACrB;;CAEA;EACC,4BAAsB;EAAtB,6BAAsB;MAAtB,0BAAsB;UAAtB,sBAAsB;CACvB;;CAEA;EACC,mBAAe;MAAf,eAAe;EACf,4BAAsB;EAAtB,6BAAsB;MAAtB,0BAAsB;UAAtB,sBAAsB;CACvB;;CAEA;EACC,WAAW;EACX,aAAa;CACd;;CAEA;EACC,WAAW;CACZ;;CAEA;;EAEC,kBAAkB;EAClB,MAAM;EACN,YAAY;CACb;;CAEA;;EAEC,WAAW;CACZ;;CAEA;EACC,oBAAoB;EACpB,iBAAiB;CAClB;;AAED;;AAEA;;CAEC;CACA;;CAEA;EACC,WAAW;EACX,WAAW;EACX,kBAAkB;CACnB;;CAEA;EACC,aAAa;CACd;;CAEA;EACC,kBAAkB;CACnB;;CAEA;EACC,cAAc;EACd,WAAW;EACX,SAAS;EACT,mBAAmB;CACpB;;AAED;;AAEA;AACA;;AAEA;;CAEC;EACC,UAAU;CACX;;CAEA;EACC,mBAAmB,EAAE,YAAY;CAClC;;CAEA;EACC,mBAAmB;CACpB;;CAEA;EACC,kBAAkB;CACnB;;CAEA;EACC,iBAAiB;CAClB;;CAEA;EACC,kCAAkC;CACnC;;CAEA;EACC,0BAA0B;CAC3B;;AAED;;AAEA;;CAEC;EACC,WAAW;EACX,YAAY;EACZ,0CAA0C;EAC1C,mBAAmB;CACpB;;CAEA;EACC,kBAAkB;EAClB,gBAAgB;CACjB;;CAEA;EACC,cAAc;CACf;;AAED;;AAEA;;CAEC;EACC,uBAAuB;EACvB,mBAAmB;CACpB;;CAEA;EACC,YAAY;CACb;;AAED;;AAEA;;CAEC;EACC,WAAW;EACX,mBAAmB;CACpB;;CAEA;EACC,WAAW;CACZ;;CAEA;EACC,cAAc;CACf;;CAEA;EACC,oBAAa;EAAb,oBAAa;EAAb,aAAa;EACb,mBAAe;MAAf,eAAe;CAChB;;CAEA;EACC,cAAc;CACf;;CAEA;EACC,WAAW;EACX,mBAAmB;CACpB;;CAEA;EACC,UAAU;EACV,8BAAsB;UAAtB,sBAAsB;CACvB;;CAEA;EACC,aAAa;CACd;;CAEA;EACC,2BAA2B;EAC3B,iBAAiB;EACjB,WAAW;EACX,cAAc;CACf;;AAED","file":"updraftplus-admin-2-23-7.min.css","sourcesContent":["@keyframes udp_blink {\n\n\tfrom {\n\t\topacity: 1;\n\t\ttransform: scale(1);\n\t}\n\n\tto {\n\t\topacity: 0.4;\n\t\ttransform: scale(0.85);\n\t}\n\n}\n\n@keyframes udp_rotate {\n\n\tfrom {\n\t\ttransform: rotate(0);\n\t}\n\n\tto {\n\t\ttransform: rotate(360deg);\n\t}\n\n}\n\n/* Widths and sizing */\n.max-width-600 {\n\tmax-width: 600px;\n}\n\n.max-width-700 {\n\tmax-width: 700px;\n}\n\n.width-900 {\n\tmax-width: 900px;\n}\n\n.width-80 {\n\twidth: 80%;\n}\n\n.updraft--flex {\n\tdisplay: flex;\n\tflex-wrap: wrap;\n}\n\n.updraft--flex > * {\n\tflex: 1;\n\tbox-sizing: border-box;\n}\n\n.updraft--flex > .updraft--one-half {\n\twidth: 50%;\n\tflex: auto;\n}\n\n.updraft--flex > .updraft--two-halves {\n\twidth: 100%;\n\tflex: auto;\n}\n\n.updraft-color--very-light-grey {\n\tbackground: #F8F8F8;\n}\n\n/* End widths and sizing */\n\n/* Font styling */\n.no-decoration {\n\ttext-decoration: none;\n}\n\n.bold {\n\tfont-weight: bold;\n}\n\n/* End font styling */\n/* Alignment */\n.center-align-td {\n\ttext-align: center;\n}\n\n/* End of Alignment */\n/* Padding */\n.remove-padding {\n\tpadding: 0 !important;\n}\n\n/* End of padding */\n\n.updraft-text-center {\n\ttext-align: center;\n}\n\n.autobackup {\n\tpadding: 6px;\n\tmargin: 8px 0px;\n}\n\nul .disc {\n\tlist-style: disc inside;\n}\n\n.dashicons-log-fix {\n\tdisplay: inherit;\n}\n\n.udpdraft__lifted {\n\tbox-shadow: 0 1px 1px 0 rgba(0,0,0,.1);\n}\n\n#updraft-wrap a .dashicons {\n\ttext-decoration: none;\n}\n\n.updraft-field-description,\ntable.form-table td p.updraft-field-description {\n\tfont-size: 90%;\n\tline-height: 1.2;\n\tfont-style: italic;\n\tmargin-bottom: 5px;\n}\n\n/* Input boxes */\nlabel.updraft_checkbox {\n\tdisplay: block;\n\tmargin-bottom: 4px;\n\tmargin-left: 26px;\n}\n\nlabel.updraft_checkbox > input[type=checkbox] {\n\tmargin-left: -25px;\n}\n\ndiv[id*=\"updraft_include_\"] {\n\tmargin-bottom: 9px;\n}\n\n/* Input boxes */\n.settings_page_updraftplus input[type=\"file\"] {\n\tborder: none;\n}\n\n.settings_page_updraftplus .wipe_settings {\n\tpadding-bottom: 10px;\n}\n\n.settings_page_updraftplus input[type=\"text\"] {\n\tfont-size: 14px;\n}\n\n.settings_page_updraftplus select {\n\tborder-radius: 4px;\n\tmax-width: 100%;\n}\n\ninput.updraft_input--wide,\ntextarea.updraft_input--wide {\n\tmax-width: 442px;\n\twidth: 100%;\n}\n\n#updraft-wrap .button-large {\n\tfont-size: 1.3em;\n}\n\n/* End input boxes */\n\n/* Main Buttons */\n.main-dashboard-buttons {\n\tborder-width: 4px;\n\tborder-radius: 12px;\n\tletter-spacing: 0px;\n\tfont-size: 17px;\n\tfont-weight: bold;\n\tpadding-left: 0.7em;\n\tpadding-right: 2em;\n\tpadding: 0.3em 1em;\n\tline-height: 1.7em;\n\tbackground: transparent;\n\tposition: relative;\n\tborder: 2px solid;\n\ttransition: all 0.2s;\n\tvertical-align: baseline;\n\tbox-sizing: border-box;\n\ttext-align: center;\n\tline-height: 1.3em;\n\tmargin-left: .3em;\n\ttext-transform: none;\n\tline-height: 1;\n\ttext-decoration: none;\n}\n\n.button-restore {\n\tborder-color: rgb(98, 158, 192);\n\tcolor: rgb(98, 158, 192);\n}\n\n.button-ud-google {\n\ttext-decoration: none !important;\n\ttransition: background-color .3s, box-shadow .3s;\n\tpadding: 12px 16px 12px 42px !important;\n\tborder: none;\n\tborder-radius: 3px;\n\tbox-shadow: 0 -1px 0 rgba(0, 0, 0, .04), 0 1px 1px rgba(0, 0, 0, .25);\n\tcolor: #757575;\n\tfont-size: 14px;\n\tfont-weight: 500;\n\tfont-family: \"Roboto\";\n\tbackground-image: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTgiIGhlaWdodD0iMTgiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGcgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIj48cGF0aCBkPSJNMTcuNiA5LjJsLS4xLTEuOEg5djMuNGg0LjhDMTMuNiAxMiAxMyAxMyAxMiAxMy42djIuMmgzYTguOCA4LjggMCAwIDAgMi42LTYuNnoiIGZpbGw9IiM0Mjg1RjQiIGZpbGwtcnVsZT0ibm9uemVybyIvPjxwYXRoIGQ9Ik05IDE4YzIuNCAwIDQuNS0uOCA2LTIuMmwtMy0yLjJhNS40IDUuNCAwIDAgMS04LTIuOUgxVjEzYTkgOSAwIDAgMCA4IDV6IiBmaWxsPSIjMzRBODUzIiBmaWxsLXJ1bGU9Im5vbnplcm8iLz48cGF0aCBkPSJNNCAxMC43YTUuNCA1LjQgMCAwIDEgMC0zLjRWNUgxYTkgOSAwIDAgMCAwIDhsMy0yLjN6IiBmaWxsPSIjRkJCQzA1IiBmaWxsLXJ1bGU9Im5vbnplcm8iLz48cGF0aCBkPSJNOSAzLjZjMS4zIDAgMi41LjQgMy40IDEuM0wxNSAyLjNBOSA5IDAgMCAwIDEgNWwzIDIuNGE1LjQgNS40IDAgMCAxIDUtMy43eiIgZmlsbD0iI0VBNDMzNSIgZmlsbC1ydWxlPSJub256ZXJvIi8+PHBhdGggZD0iTTAgMGgxOHYxOEgweiIvPjwvZz48L3N2Zz4=);\n\tbackground-color: #FFF;\n\tbackground-repeat: no-repeat;\n\tbackground-position: 12px 11px;\n}\n\n.button-ud-google:hover {\n\tbox-shadow: 0 -1px 0 rgba(0, 0, 0, .04), 0 2px 4px rgba(0, 0, 0, .25);\n}\n\n.button-ud-google:active {\n\tbackground-color: #EEE;\n}\n\n.button-ud-google:focus {\n\toutline: none;\n\tbox-shadow: 0 -1px 0 rgba(0, 0, 0, .04), 0 2px 4px rgba(0, 0, 0, .25), 0 0 0 3px #C8DAFC;\n}\n\n.button-ud-google:disabled {\n\tfilter: grayscale(100%);\n\tbackground-color: #EBEBEB;\n\tbox-shadow: 0 -1px 0 rgba(0, 0, 0, .04), 0 1px 1px rgba(0, 0, 0, .25);\n\tcursor: not-allowed;\n}\n\n.dashboard-main-sizing {\n\tborder-width: 4px;\n\twidth: 190px;\n\tline-height: 1.7em;\n}\n\np.updraftplus-option {\n\tmargin-top: 0;\n\tmargin-bottom: 5px;\n}\n\np.updraftplus-option-inline {\n\tdisplay: inline-block;\n\tpadding-right: 20px;\n}\n\nspan.updraftplus-option-label {\n\tdisplay: block;\n}\n\n/*\n* MIGRATE - CLONE\n*/\n\n#updraft-navtab-migrate-content .postbox {\n\tpadding: 18px;\n}\n\n/* Clone Rows */\n\n.updraftclone-main-row {\n\tdisplay: flex;\n}\n\n.updraftclone-tokens {\n\tbackground: #F5F5F5;\n\tpadding: 20px;\n\tborder-radius: 10px;\n\tmargin-right: 20px;\n\tmax-width: 300px;\n}\n\n.updraftclone-tokens p {\n\tmargin: 0;\n}\n\n.updraftclone_action_box {\n\tbackground: #F5F5F5;\n\tpadding: 20px;\n\tborder-radius: 10px;\n\tflex: 1;\n}\n\n.updraftclone_action_box p:first-child {\n\tmargin-top: 0;\n}\n\n.updraftclone_action_box p:last-child {\n\tmargin-bottom: 0;\n}\n\n.updraftclone_action_box #ud_downloadstatus3 {\n\tmargin-top: 10px;\n}\n\nspan.tokens-number {\n\tfont-size: 46px;\n\tdisplay: block;\n}\n\n/* Clone header button */\n.button.updraft_migrate_widget_temporary_clone_show_stage0 {\n\tdisplay: none;\n\tposition: absolute;\n\tright: 0;\n\ttop: 0;\n\theight: 100%;\n\tborder-left: 1px solid #CCC;\n\tpadding-left: 10px;\n\tpadding-right: 10px;\n}\n\n.updraft_migrate_widget_temporary_clone_stage0_container {\n\tdisplay: flex;\n\tflex-direction: column;\n}\n\n.updraft_migrate_widget_temporary_clone_stage0_box {\n\tmargin-right: 20px;\n\twidth: 100%;\n\tflex-basis: 100%;\n}\n\n.updraft_migrate_widget_temporary_clone_stage0_box iframe,\n.updraft_migrate_widget_temporary_clone_stage0_box a.udp-replace-with-iframe--js {\n\tfloat: none;\n}\n\n@media (min-width: 1024px) {\n\n\t.updraft_migrate_widget_temporary_clone_stage0_container {\n\t\tflex-direction: row;\n\t\tflex-wrap: wrap;\n\t}\n\n\t.updraft_migrate_widget_temporary_clone_stage0_box {\n\t\tflex-basis: 45%;\n\t}\n\n\t.updraft_migrate_widget_temporary_clone_stage0_box iframe,\n\t.updraft_migrate_widget_temporary_clone_stage0_box a.udp-replace-with-iframe--js {\n\t\tfloat: right;\n\t}\n\n}\n\n.updraft_migrate_widget_temporary_clone_show_stage0 .dashicons {\n\ttext-decoration: none;\n\tfont-size: 20px;\n}\n\n.opened .button.updraft_migrate_widget_temporary_clone_show_stage0 {\n\tdisplay: inline-block;\n}\n\n.opened .updraft_migrate_widget_temporary_clone_stage0 {\n\tbackground: #F5F5F5;\n\tpadding: 20px;\n\tborder-radius: 8px;\n\tmargin-bottom: 21px;\n}\n\n/* Clone list table */\n.clone-list {\n\tclear: both;\n\twidth: 100%;\n\tmargin-top: 40px;\n}\n\n.clone-list table {\n\twidth: 100%;\n\ttext-align: left;\n}\n\n.clone-list table tr th {\n\tbackground: #E4E4E4;\n}\n\n.clone-list table tr td {\n\tbackground: #F5F5F5;\n\tword-break: break-word;\n}\n\n.clone-list table tr:nth-child(odd) td {\n\tbackground: #FAFAFA;\n}\n\n.clone-list table td,\n.clone-list table th {\n\tpadding: 6px;\n}\n\n/* Clone Progress */\n.updraftplus-clone .updraft_row {\n\tpadding-left: 0;\n\tpadding-right: 0;\n}\n\nbutton#updraft_migrate_createclone + .updraftplus_spinner {\n\tmargin-top: 13px;\n}\n\n/* Clone - Show step 1 info button */\n.button.button-hero.updraftclone_show_step_1 {\n\twhite-space: normal;\n\theight: auto;\n\tline-height: 14px;\n\tpadding-top: 10px;\n\tpadding-bottom: 10px;\n}\n\n.button.button-hero.updraftclone_show_step_1 span.dashicons {\n\theight: auto;\n}\n\n.updraftplus_clone_status {\n\tcolor: red;\n}\n\n/* MIGRATE */\n\na.updraft_migrate_add_site--trigger span.dashicons {\n\ttext-decoration: none;\n}\n\n.button-restore:hover, .button-migrate:hover, .button-backup:hover,\n.button-view-log:hover, .button-mass-selectors:hover,\n.button-delete:hover, .button-entity-backup:hover, .udp-button-primary:hover {\n\tborder-color: #DF6926;\n\tcolor: #DF6926;\n}\n\n.button-migrate {\n\tcolor: rgb(238, 169, 32);\n\tborder-color: rgb(238, 169, 32);\n}\n\n#updraft_migrate_tab_main {\n\tpadding: 8px;\n}\n\n.updraft_migrate_widget_module_content {\n\tbackground: #FFF;\n\tborder-radius: 0;\n\tposition: relative;\n}\n\nbody.js #updraft_migrate .updraft_migrate_widget_module_content {\n\tdisplay: none;\n}\n\n.updraft_migrate_widget_module_content > h3,\ndiv[class*=\"updraft_migrate_widget_temporary_clone_stage\"] > h3 {\n\tmargin-top: 0;\n}\n\n/* Migrate / Clone headers */\n.updraft_migrate_widget_module_content header,\n#updraft_migrate_tab_alt header {\n\tposition: relative;\n\tdisplay: flex;\n\talign-content: center;\n\tjustify-items: center;\n\tmargin-top: -18px;\n\tmargin-left: -18px;\n\tmargin-right: -18px;\n\tmargin-bottom: 15px;\n\tborder-bottom: 1px solid #CCC;\n}\n\n.updraft_migrate_widget_module_content header h3,\n.updraft_migrate_widget_module_content header button.button.close,\n#updraft_migrate_tab_alt header h3,\n#updraft_migrate_tab_alt header button.button.close {\n\tpadding: 10px;\n\tline-height: 20px;\n\theight: auto;\n\tmargin: 0;\n}\n\n.updraft_migrate_widget_module_content button.button.close,\n#updraft_migrate_tab_alt button.button.close {\n\ttext-decoration: none;\n\tpadding-left: 5px;\n\tborder-right: 1px solid #CCC;\n}\n\n.updraft_migrate_widget_module_content button.button.close .dashicons,\n#updraft_migrate_tab_alt button.button.close .dashicons {\n\tmargin-top: 1px;\n}\n\n.updraft_migrate_widget_module_content header h3,\n#updraft_migrate_tab_alt header h3 {\n\tmargin: 0;\n}\n\n.updraft_migrate_intro button.button.button-primary.button-hero {\n\tmax-width: 235px;\n\tword-wrap: normal;\n\twhite-space: normal;\n\tline-height: 1;\n\theight: auto;\n\tpadding-top: 13px;\n\tpadding-bottom: 13px;\n\ttext-align: left;\n\tposition: relative;\n\tmargin-right: 10px;\n\tmargin-bottom: 10px;\n}\n\n.updraft_migrate_intro button.button.button-primary.button-hero .dashicons {\n\tposition: absolute;\n\tleft: 10px;\n\ttop: calc(50% - 8px);\n}\n\n#updraft_migrate_tab_alt #updraft_migrate_send_existing_button {\n\tmargin-right: 6px;\n}\n\n/*\njquery UI Accordion module\n*/\n#updraft_migrate .ui-widget-content a {\n\tcolor: #1C94C4;\n}\n\n#updraft-wrap .ui-accordion .ui-accordion-header {\n\tbackground: #F6F6F6;\n\tmargin: 0;\n\tborder-radius: 0;\n\tpadding-left: 0.5em;\n\tpadding-right: 0.7em;\n}\n\n#updraft-wrap .ui-widget {\n\tfont-family: inherit;\n}\n\n.ui-accordion-header .ui-accordion-header-icon.ui-icon-caret-1-w {\n\tbackground-position: -96px 0px;\n}\n\n.ui-accordion-header .ui-accordion-header-icon.ui-icon-caret-1-s {\n\tbackground-position: -64px 0;\n}\n\n#updraft-wrap .ui-accordion .ui-accordion-header .ui-accordion-header-icon {\n\tleft: auto;\n\tright: 5px;\n}\n\n#updraft-wrap .ui-accordion .ui-accordion-header:focus {\n\toutline: none;\n\tbox-shadow: 0 0 0 1px rgba(91, 157, 217, 0.22), 0 0 2px 1px rgba(30, 140, 190, 0.3);\n\tbackground: #FFF;\n}\n\n#updraft-wrap .ui-accordion .ui-accordion-header:focus .dashicons {\n\tcolor: #0572AA;\n\topacity: 1;\n}\n\n#updraft-wrap .ui-accordion .ui-accordion-header.ui-state-active {\n\tbackground: #F6F6F6;\n\tborder-bottom: 2px solid #0572AA;\n\tbox-shadow: 1px 6px 12px -5px rgba(0, 0, 0, 0.3);\n}\n\n#updraft-wrap .ui-accordion .ui-accordion-header.ui-state-active:focus {\n\tbox-shadow: 1px 6px 12px -5px rgba(0, 0, 0, 0.3), 0 0 0 1px #5B9DD9, 0 0 2px 1px rgba(30, 140, 190, .8);\n}\n\n#updraft-wrap .ui-accordion .ui-accordion-header:not(:first-child) {\n\tborder-top: none;\n}\n\n#updraft-wrap .ui-accordion .ui-accordion-header .dashicons {\n\topacity: 0.4;\n\tmargin-right: 10px;\n}\n\n#updraft-wrap .ui-accordion .ui-accordion-header:focus {\n\toutline: none;\n\tbox-shadow: 0 0 0 1px #5B9DD9, 0 0 2px 1px rgba(30, 140, 190, .8);\n\tz-index: 1;\n}\n\nbutton.ui-dialog-titlebar-close:before {\n\tcontent: none!important;\n}\n\n.updraft_next_scheduled_backups_wrapper {\n\tdisplay: flex;\n\tbackground: #FFF;\n\tjustify-items: center;\n\tflex-wrap: wrap;\n}\n\n.updraft_next_scheduled_backups_wrapper > div {\n\twidth: 50%;\n\tbackground: #FFF;\n\theight: auto;\n\t/* padding: 18px 33px; */\n\tpadding: 33px;\n\tbox-sizing: border-box;\n}\n\n.updraft_backup_btn_wrapper {\n\ttext-align: center;\n\tborder-left: 1px solid #F1F1F1;\n\tjustify-content: center;\n\talign-items: center;\n}\n\n.incremental-backups-only {\n\tdisplay: none;\n}\n\n.incremental-free-only {\n\tdisplay: none;\n}\n\n.incremental-free-only p {\n\tpadding: 5px;\n\tbackground: rgba(255, 0, 0, 0.06);\n\tborder: 1px solid #BFBFBF;\n}\n\n#updraft-delete-waitwarning span.spinner {\n\tvisibility: visible;\n\tfloat: none;\n\tmargin: 0;\n\tmargin-right: 10px;\n}\n\nbutton#updraft-backupnow-button .spinner,\nbutton#updraft-backupnow-button .dashicons-yes {\n\tdisplay: none;\n}\n\nbutton#updraft-backupnow-button.loading .spinner {\n\tdisplay: inline-block;\n\tvisibility: visible;\n\tmargin-top: 13px;\n\tmargin-right: 0;\n}\n\nbutton#updraft-backupnow-button.loading {\n\tbackground-color: #EFEFEF;\n\tborder-color: #CCC;\n\ttext-shadow: 0 -1px 1px #BBC3C7, 1px 0 1px #BBC3C7, 0 1px 1px #BBC3C7, -1px 0 1px #BBC3C7;\n\tbox-shadow: none;\n}\n\nbutton#updraft-backupnow-button.finished .dashicons-yes {\n\tdisplay: inline-block;\n\tvisibility: visible;\n\tfont-size: 42px;\n\tmargin-right: 0;\n\tmargin-top: 2px;\n}\n\n.updraft_next_scheduled_entity {\n\twidth: 50%;\n\tdisplay: inline-block;\n\tfloat: left;\n\t/*\n\tpadding: 20px 20px 10px 20px;\n\t*/\n}\n\n.updraft_next_scheduled_entity .dashicons {\n\tcolor: #CCC;\n\tfont-size: 20px;\n}\n\n.updraft_next_scheduled_entity strong {\n\tfont-size: 20px;\n}\n\n.updraft_next_scheduled_heading {\n\tmargin-bottom: 10px;\n}\n\n.updraft_next_scheduled_date_time {\n\tcolor: #46A84B;\n}\n\n.updraft_time_now_wrapper {\n\tmargin-top: 68px;\n\twidth: 100%;\n}\n\n.updraft_time_now_label, .updraft_time_now {\n\tdisplay: inline-block;\n\tpadding: 7px;\n}\n\n.updraft_time_now_label {\n\tbackground: #B7B7B7;\n\tborder-top-left-radius: 4px;\n\tborder-bottom-left-radius: 4px;\n\tcolor: #FFF;\n\tmargin-right: 0;\n\ttext-shadow: 0 1px 2px rgba(0, 0, 0, 0.4);\n}\n\n.updraft_time_now {\n\tbackground: #F1F1F1;\n\tborder-top-right-radius: 4px;\n\tborder-bottom-right-radius: 4px;\n\tmargin-left: -3px;\n}\n\n#updraft_lastlogmessagerow {\n\tmargin: 6px 0;\n}\n\n#updraft_lastlogmessagerow {\n\tclear: both;\n\tpadding: 0.25px 0;\n}\n\n#updraft_lastlogmessagerow .updraft-log-link {\n\tfloat: right;\n\tmargin-top: -2.5em;\n\tmargin-right: 2px;\n}\n\n#updraft_lastlogmessagerow > div {\n\tclear: both;\n\tbackground: #FFF;\n\tpadding: 18px;\n}\n\n#updraft_activejobs_table {\n\toverflow: hidden;\n\twidth: 100%;\n\tbackground: #FAFAFA;\n\tpadding: 0;\n}\n\n.updraft_requeststart {\n\tpadding: 15px 33px;\n\ttext-align: center;\n}\n\n.updraft_requeststart .spinner {\n\tvisibility: visible;\n\tfloat: none;\n\tvertical-align: middle;\n\tmargin-top: -2px;\n}\n\na.updraft_jobinfo_delete.disabled {\n\topacity: 0.4;\n\tcolor: inherit;\n\ttext-decoration: none;\n}\n\n.updraft_row {\n\tclear: both;\n\ttransition: 0.3s all;\n\tpadding: 15px 33px;\n}\n\n.updraft_row.deleting {\n\topacity: 0.4;\n}\n\n.updraft_progress_container {\n\t/* width: 83%; */\n}\n\n.updraft_existing_backups_count {\n\tpadding: 2px 8px;\n\tfont-size: 12px;\n\tbackground: #CA4A1E;\n\tcolor: #FFF;\n\tfont-weight: bold;\n\tborder-radius: 10px;\n}\n\n.form-table .existing-backups-table input[type=\"checkbox\"] {\n\tborder-radius: 0;\n}\n\n.form-table .existing-backups-table .check-column {\n\twidth: 40px;\n\tpadding: 0;\n\tpadding-top: 8px;\n}\n\n.existing-backups-buttons {\n\tfont-size: 11px;\n\tline-height: 1.4em;\n\tborder-width: 3px;\n}\n\n.existing-backups-restore-buttons {\n\tfont-size: 11px;\n\tline-height: 1.4em;\n\tborder-width: 3px;\n}\n\n.button-delete {\n\tcolor: #E23900;\n\tborder-color: #E23900;\n\tfont-size: 14px;\n\tline-height: 1.4em;\n\tborder-width: 2px;\n\tmargin-right: 10px;\n}\n\n.button-view-log, .button-mass-selectors {\n\tcolor: darkgrey;\n\tborder-color: darkgrey;\n\tfont-size: 14px;\n\tline-height: 1.4em;\n\tborder-width: 2px;\n\tmargin-top: -1px;\n}\n\n.button-view-log {\n\twidth: 120px;\n}\n\n.button-existing-restore {\n\tfont-size: 14px;\n\tline-height: 1.4em;\n\tborder-width: 2px;\n\twidth: 110px;\n}\n\n.main-restore {\n\tmargin-right: 3%;\n\tmargin-left: 3%;\n}\n\n.button-entity-backup {\n\tcolor: #555;\n\tborder-color: #555;\n\tfont-size: 11px;\n\tline-height: 1.4em;\n\tborder-width: 2px;\n\tmargin-right: 5px;\n}\n\n.button-select-all {\n\twidth: 122px;\n}\n\n.button-deselect {\n\twidth: 92px;\n}\n\n#ud_massactions > .display-flex > .mass-selectors-margins, #updraft-delete-waitwarning > .display-flex > .mass-selectors-margins {\n\tmargin-right: -4px;\n}\n\n.udp-button-primary {\n\tborder-width: 4px;\n\tcolor: #0073AA;\n\tborder-color: #0073AA;\n\tfont-size: 14px;\n\theight: 40px;\n}\n\n#ud_massactions .button-delete {\n\tmargin-right: 0px;\n}\n\n.stored_local {\n\tborder-radius: 5px;\n\tbackground-color: #007FE7;\n\tpadding: 3px 5px 5px 5px;\n\tcolor: #FFF;\n\tfont-size: 75%;\n}\n\nspan#updraft_lastlogcontainer {\n\tword-break: break-all;\n}\n\n.stored_icon {\n\theight: 1.3em;\n\tposition: relative;\n\ttop: 0.2em;\n}\n\n.backup_date_label > * {\n\tvertical-align: middle;\n}\n\n.backup_date_label .dashicons {\n\tfont-size: 18px;\n}\n\n.backup_date_label .clear-right {\n\tclear: right;\n}\n\n.existing-backups-table .backup_date_label > div, .existing-backups-table .backup_date_label span > div {\n\tfont-weight: bold;\n}\n\n/* End Main Buttons */\n\n/* End of common elements */\n\n.udp-logo-70 {\n\twidth: 70px;\n\theight: 70px;\n\tfloat: left;\n\tpadding-right: 25px;\n}\n\nh3 .thank-you {\n\tmargin-top: 0px;\n}\n\n.ws_advert {\n\tmax-width: 800px;\n\tfont-size: 140%;\n\tline-height: 140%;\n\tpadding: 14px;\n\tclear: left;\n}\n\n.dismiss-dash-notice {\n\tfloat: right;\n\tposition: relative;\n\ttop: -20px;\n}\n\n.updraft_exclude_container,\n.updraft_include_container {\n\tmargin-left: 24px;\n\tmargin-top: 5px;\n\tmargin-bottom: 10px;\n\tpadding: 15px;\n\tborder: 1px solid #DDD;\n}\n\nlabel.updraft-exclude-label {\n\tfont-weight: 500;\n\tmargin-bottom: 5px;\n\tdisplay: inline-block;\n}\n\n.updraft_add_exclude_item,\n#updraft_include_more_paths_another {\n\tdisplay: inline-block;\n\tmargin-top: 10px;\n}\n\ninput.updraft_exclude_entity_field,\n.form-table td input.updraft_exclude_entity_field,\n.updraftplus-morefiles-row input[type=text] {\n\twidth: calc(100% - 70px);\n\tmax-width: 400px;\n}\n\n.updraft-fs-italic {\n\tfont-style: italic;\n}\n\n@media screen and (max-width: 782px) {\n\n\t.form-table td input.updraft_exclude_entity_field,\n\t.form-table td .updraftplus-morefiles-row input[type=text] {\n\t\tdisplay: inline-block;\n\t}\n\n}\n\n.updraft_exclude_entity_delete.dashicons, .updraft_exclude_entity_edit.dashicons, .updraft_exclude_entity_update.dashicons, .updraftplus-morefiles-row a.dashicons {\n\tmargin-top: 2px;\n\tfont-size: 20px;\n\tbox-shadow: none;\n\tline-height: 1;\n\tpadding: 3px;\n\tmargin-right: 4px;\n}\n\n.updraft_exclude_entity_delete,\n.updraft_exclude_entity_delete:hover,\n.updraftplus-morefiles-row-delete {\n\tcolor: #FF6347;\n}\n\n.updraft_exclude_entity_update.dashicons, .updraft_exclude_entity_update.dashicons:hover {\n\tcolor: #008000;\n\tfont-weight: bold;\n\tfont-size: 22px;\n\tmargin-left: 4px;\n}\n\n.updraft_exclude_entity_edit {\n\tmargin-left: 4px;\n}\n\n.updraft_exclude_entity_update.is-active ~ .updraft_exclude_entity_delete {\n\tdisplay: none;\n}\n\n.updraft-exclude-panel-heading {\n\tmargin-bottom: 8px;\n}\n\n.updraft-exclude-panel-heading h3 {\n\tmargin: 0.5em 0 0.5em 0;\n}\n\n.updraft-exclude-submit.button-primary {\n\tmargin-top: 5px;\n}\n\n.updraft_exclude_actions_list {\n\tfont-weight: bold;\n}\n\n.updraft-exclude-link {\n\tcursor: pointer;\n}\n\n#updraft_include_more_options {\n\tpadding-left: 25px;\n}\n\n#updraft_report_cell .updraft_reportbox,\n.updraft_small_box {\n\tpadding: 12px;\n\tmargin: 8px 0;\n\tborder: 1px solid #CCC;\n\tposition: relative;\n}\n\n#updraft_report_cell button.updraft_reportbox_delete,\n.updraft_box_delete_button,\n.updraft_small_box .updraft_box_delete_button {\n\tpadding: 4px;\n\tpadding-top: 6px;\n\tborder: none;\n\tbackground: transparent;\n\tposition: absolute;\n\ttop: 4px;\n\tright: 4px;\n\tcursor: pointer;\n}\n\n#updraft_report_cell button.updraft_reportbox_delete:hover {\n\tcolor: #DE3C3C;\n}\n\na.updraft_report_another .dashicons {\n\ttext-decoration: none;\n\tmargin-top: 2px;\n}\n\n.updraft_report_dbbackup.updraft_report_disabled {\n\tcolor: #CCC;\n}\n\n#updraft-navtab-settings-content .updraft-test-button {\n\tfont-size: 18px !important;\n}\n\n#updraft_report_cell .updraft_report_email {\n\tdisplay: block;\n\twidth: calc(100% - 50px);\n\tmargin-bottom: 9px;\n}\n\n#updraft_report_cell .updraft_report_another_p {\n\tclear: left;\n}\n\n/* Taken straight from admin.php */\n\n#updraft-navtab-settings-content table.form-table p {\n\tmax-width: 700px;\n}\n\n#updraft-navtab-settings-content table.form-table .notice p {\n\tmax-width: none;\n}\n\n#updraft-navtab-backups-content .updraft_existing_backups .updraft_existing_backups_row.backuprowselected,\n#updraft-navtab-backups-content .updraft_existing_backups .updraft_existing_backups_row.backuprowselected td {\n\tbackground-color: #EFEFEF;\n}\n\n#updraft-navtab-backups-content .updraft_existing_backups .updraft_existing_backups_row.backuprowselected:nth-child(even) td {\n\tbackground-color: #E8E8E8;\n}\n\n.updraft_settings_sectionheading {\n\tdisplay: none;\n}\n\n.updraft-backupentitybutton-disabled {\n\tbackground-color: transparent;\n\tborder: none;\n\tcolor: #0074A2;\n\ttext-decoration: underline;\n\tcursor: pointer;\n\tclear: none;\n\tfloat: left;\n}\n\n.updraft-backupentitybutton {\n\tmargin-left: 8px;\n}\n\n.updraft-bigbutton {\n\tpadding: 2px 0px !important;\n\tmargin-right: 14px !important;\n\tfont-size: 22px !important;\n\tmin-height: 32px;\n\tmin-width: 180px;\n}\n\ntr[class*=\"_updraft_remote_storage_border\"] {\n\tborder-top: 1px solid #CCC;\n}\n\n.updraft_multi_storage_options {\n\tfloat: right;\n\tclear: right;\n\tmargin-bottom: 5px !important;\n}\n\n.updraft_toggle_instance_label {\n\tvertical-align: top !important;\n}\n\n.updraft_debugrow th {\n\tfloat: right;\n\ttext-align: right;\n\tfont-weight: bold;\n\tpadding-right: 8px;\n\tmin-width: 140px;\n}\n\n.updraft_debugrow td {\n\tmin-width: 300px;\n\tvertical-align: bottom;\n}\n\n.updraft_webdav_host_error, .onedrive_folder_error {\n\tcolor: red;\n}\n\nlabel[for=updraft_servicecheckbox_updraftvault] {\n\tposition: relative;\n}\n\n#updraft-wrap .udp-info {\n\tposition: absolute;\n\tright: 10px;\n\ttop: calc(50% - 10px);\n}\n\n#updraft-wrap span.info-trigger {\n\tdisplay: inline-block;\n\twidth: 20px;\n\theight: 20px;\n\tbackground: #FFF;\n\tcolor: #72777C;\n\tborder-radius: 30px;\n\ttext-align: center;\n\tline-height: 20px;\n\tbox-shadow: 0 1px 3px rgba(0, 0, 0, 0.15);\n}\n\n#updraft-wrap .info-content-wrapper {\n\tdisplay: none;\n\tposition: absolute;\n\tbottom: 20px;\n\ttransform: translatex(calc(-50% + 10px));\n\twidth: 330px;\n\tpadding-bottom: 10px;\n}\n\n#updraft-wrap .info-content-wrapper::before {\n\tcontent: '';\n\tposition: absolute;\n\tbottom: -10px;\n\tborder: 10px solid transparent;\n\tborder-top-color: #FFF;\n\tleft: calc(50% - 10px);\n}\n\n#updraft-wrap .info-content {\n\tpadding: 20px;\n\tbackground: #FFF;\n\tborder-radius: 4px;\n\tbox-shadow: 0 3px 10px rgba(0, 0, 0, 0.1);\n\tcolor: #72777C;\n}\n\n#updraft-wrap .info-content h3 {\n\tmargin-top: 0;\n}\n\n#updraft-wrap .info-content p {\n\tmargin-top: 10px;\n}\n\n#updraft-wrap .udp-info:hover .info-content-wrapper {\n\tdisplay: block;\n}\n\ndiv.conditional_remote_backup select.logic_type {\n\tvertical-align: inherit !important;\n}\n\ndiv.conditional_remote_backup label.updraft_toggle_instance_label.radio_group {\n\tdisplay: block;\n\tmargin-top: 7px;\n}\n\ndiv.conditional_remote_backup div.logic ul.rules input.rule_value {\n\tvertical-align: middle;\n}\n\ndiv.conditional_remote_backup p {\n\tmargin-bottom: 10px;\n}\n\ndiv.conditional_remote_backup div.logic ul.rules span svg {\n\twidth: 20px;\n\tvertical-align: middle;\n\tcursor: pointer;\n}\n\ndiv.conditional_remote_backup div.logic ul.rules span svg {\n\tmargin-left: 3px;\n}\n\ndiv.conditional_remote_backup div.logic select.logic_type {\n\tvertical-align: unset;\n}\n\n/* jstree styles */\n\n/* these styles hide the dots from the parent but keep the arrows */\n.updraft_jstree .jstree-container-ul > .jstree-node,\ndiv[id^=\"updraft_more_files_jstree_\"] .jstree-container-ul > .jstree-node {\n\tbackground: transparent;\n}\n\n.updraft_jstree .jstree-container-ul > .jstree-open > .jstree-ocl,\ndiv[id^=\"updraft_more_files_jstree_\"] .jstree-container-ul > .jstree-open > .jstree-ocl {\n\tbackground-position: -36px -4px;\n}\n\n.updraft_jstree .jstree-container-ul > .jstree-closed> .jstree-ocl,\ndiv[id^=\"updraft_more_files_jstree_\"] .jstree-container-ul > .jstree-closed> .jstree-ocl {\n\tbackground-position: -4px -4px;\n}\n\n.updraft_jstree .jstree-container-ul > .jstree-leaf> .jstree-ocl,\ndiv[id^=\"updraft_more_files_jstree_\"] .jstree-container-ul > .jstree-leaf> .jstree-ocl {\n\tbackground: transparent;\n}\n\n/* zip browser jstree styles */\n#updraft_zip_files_container {\n\tposition: relative;\n\theight: 450px;\n\toverflow: none;\n}\n\n.updraft_jstree_info_container {\n\tposition: relative;\n\theight: auto;\n\twidth: 100%;\n\tborder: 1px dotted;\n\tmargin-bottom: 5px;\n}\n\n.updraft_jstree_info_container p {\n\tmargin: 1px;\n\tpadding-left: 10px;\n\tfont-size: 14px;\n}\n\n#updraft_zip_download_item {\n\tdisplay: none;\n\tcolor: #0073AA;\n\tpadding-left: 10px;\n}\n\n#updraft_zip_download_notice {\n\tpadding-left: 10px;\n}\n\n#updraft_exclude_files_folders_jstree, #updraft_exclude_files_folders_wildcards_jstree {\n\tmax-height: 200px;\n\toverflow-y: scroll;\n}\n\n.updraft_jstree {\n\tposition: relative;\n\tborder: 1px dotted;\n\theight: 80%;\n\twidth: 100%;\n\toverflow: auto;\n}\n\n/* More files jstree styles */\ndiv[id^=\"updraft_more_files_container_\"] {\n\tposition: relative;\n\tdisplay: none;\n\twidth: 100%;\n\tborder: 1px solid #CCC;\n\tbackground: #FAFAFA;\n\tmargin-bottom: 5px;\n\tmargin-top: 4px;\n\tbox-shadow: 0 5px 8px rgba(0, 0, 0, 0.1);\n}\n\ndiv[id^=\"updraft_more_files_container_\"]::before {\n\tcontent: ' ';\n\twidth: 11px;\n\theight: 11px;\n\tdisplay: block;\n\tbackground: #FAFAFA;\n\tposition: absolute;\n\ttop: 0;\n\tleft: 20px;\n\tborder-top: 1px solid #CCC;\n\tborder-left: 1px solid #CCC;\n\ttransform: translatey(-7px) rotate(45deg);\n}\n\ninput.updraft_more_path_editing {\n\tborder-color: #0285BA;\n}\n\ninput.updraft_more_path_editing ~ a.dashicons {\n\tdisplay: none;\n}\n\ndiv[id^=\"updraft_jstree_buttons_\"] {\n\tpadding: 10px;\n\tbackground: #E6E6E6;\n}\n\ndiv[id^=\"updraft_jstree_container_\"] {\n\theight: 300px;\n\twidth: 100%;\n\toverflow: auto;\n}\n\ndiv[id^=\"updraft_more_files_container_\"] button {\n\tline-height: 20px;\n}\n\nbutton[id^=\"updraft_parent_directory_\"] {\n\tmargin: 10px 10px 4px 10px;\n\tpadding-left: 3px;\n}\n\nbutton[id^=\"updraft_jstree_confirm_\"], button[id^=\"updraft_jstree_cancel_\"] {\n\tdisplay: none;\n}\n\ninput[id^=\"updraft_include_more_path_restore_\"] {\n\ttext-align: right;\n}\n\n.updraftplus-morefiles-row-delete,\n.updraftplus-morefiles-row-edit {\n\tcursor: pointer;\n}\n\n#updraft_include_more_paths_error {\n\tcolor: #DE3C3C;\n}\n\np[id^=\"updraftplus_manual_authentication_error_\"] {\n\tcolor: #DE3C3C;\n}\n\n#updraft-wrap .form-table th {\n\twidth: 230px;\n}\n\n#updraft-wrap .form-table .existing-backups-table th {\n\twidth: auto;\n}\n\n.updraft-viewlogdiv form {\n\tmargin: 0;\n\tpadding: 0;\n}\n\n.updraft-viewlogdiv {\n\tdisplay: inline-block;\n}\n\n.updraft-viewlogdiv input, .updraft-viewlogdiv a {\n\tborder: none;\n\tbackground-color: transparent;\n\tcolor: #000;\n\tmargin: 0px;\n\tpadding: 3px 4px;\n\tfont-size: 16px;\n\tline-height: 26px;\n}\n\n.updraft-viewlogdiv input:hover, .updraft-viewlogdiv a:hover {\n\tcolor: #FFF;\n\tcursor: pointer;\n}\n\n.button.button-remove {\n\tcolor: white;\n\tbackground-color: #DE3C3C;\n\tborder-color: #C00000;\n\tbox-shadow: 0 1px 0 #C10100;\n}\n\n.button.button-remove:hover,\n.button.button-remove:focus {\n\tborder-color: #C00;\n\tcolor: #FFF;\n\tbackground: #C00;\n}\n\n/* button-remove colors for midnight admin theme */\nbody.admin-color-midnight .button.button-remove {\n\tcolor: #DE3C3C;\n\tbackground-color: #F7F7F7;\n\tborder-color: #CCC;\n\tbox-shadow: 0 1px 0 #CCC;\n}\n\nbody.admin-color-midnight .button.button-remove:hover, body.admin-color-midnight .button.button-remove:focus {\n\tborder-color: #BA281F;\n}\n\nbody.admin-color-midnight .button.button-remove:focus {\n\tbox-shadow: inherit;\n\tbox-shadow: 0 0 3px rgba(0, 115, 170, 0.8);\n}\n\n.drag-drop #drag-drop-area2 {\n\tborder: 4px dashed #DDD;\n\theight: 200px;\n}\n\n#drag-drop-area2 .drag-drop-inside {\n\tmargin: 36px auto 0;\n\twidth: 350px;\n}\n\n#filelist, #filelist2 {\n\tmargin-top: 30px;\n\twidth: 100%;\n}\n\n#filelist .file, #filelist2 .file, .ud_downloadstatus .file, #ud_downloadstatus2 .file, #ud_downloadstatus3 .file {\n\tpadding: 1px;\n\tbackground: #ECECEC;\n\tborder: solid 1px #CCC;\n\tmargin: 4px 0;\n}\n\n.updraft_premium section {\n\tmargin-bottom: 20px;\n}\n\n/*\n\tCall to action Premium\n*/\n.updraft_premium_cta {\n\tbackground: #FFF;\n\tmargin-top: 30px;\n\tpadding: 0;\n\tborder-left: 4px solid #DB6A03;\n}\n\n.updraft_premium_cta a {\n\tfont-weight: normal;\n}\n\n.updraft_premium_cta__action {\n\tposition: relative;\n\ttext-align: center;\n}\n\n.updraft_premium_cta a.button.button-primary.button-hero {\n\tfont-size: 1.3em;\n\tletter-spacing: 0.03rem;\n\ttext-transform: uppercase;\n\tmargin-bottom: 7px;\n}\n\n.updraft_premium_cta a.button.button-primary.button-hero + small {\n\tdisplay: block;\n\tmax-width: 100%;\n\ttext-align: center;\n\tcolor: #AFAFAF;\n}\n\n.updraft_premium_cta a.button.button-primary.button-hero + small .dashicons {\n\twidth: 12px;\n\theight: 12px;\n}\n\n.updraft_premium_cta__top {\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: space-between;\n\tpadding: 18px 30px;\n}\n\n.updraft_premium_cta__bottom {\n\tbackground: #F9F9F9;\n\tpadding: 5px 30px;\n}\n\n.updraft_premium_cta__summary {\n\tmargin-right: 60px;\n}\n\n.updraft_premium_cta h2 {\n\tfont-size: 28px;\n\tfont-weight: 200;\n\tline-height: 1;\n\tmargin: 0;\n\tmargin-bottom: 5px;\n\tletter-spacing: 0.05rem;\n\tcolor: #DB6A03;\n}\n\n.updraft_premium_cta ul li::after {\n\tcolor: #CCC;\n}\n\n@media only screen and (max-width: 768px) {\n\n\t.updraft_premium_cta__top {\n\t\tflex-direction: column;\n\t\ttext-align: center;\n\t\talign-items: center;\n\t}\n\n\t.updraft_premium_cta__summary {\n\t\tmargin-right: 0;\n\t\tmargin-bottom: 30px;\n\t}\n\n}\n\n/*\n\tBox\n*/\n.udp-box {\n\tbackground: #FFF;\n\tpadding: 20px;\n\tbox-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);\n\ttext-align: center;\n}\n\n.udp-box h3 {\n\tmargin: 0;\n}\n\n.udp-box__heading {\n\talign-self: center;\n\tbackground: none;\n\tbox-shadow: none;\n}\n\n/*\n\tOther Plugins\n*/\n.updraft-more-plugins {\n\tdisplay: flex;\n\tflex-direction: row;\n\tflex-wrap: wrap;\n\tjustify-content: space-between;\n\tflex-wrap: wrap;\n}\n\n.updraft-more-plugins img {\n\tmax-width: 80%;\n\tmax-height: 30%;\n\tdisplay: inline-block;\n}\n\n.updraft-more-plugins .udp-box {\n\tbox-sizing: border-box;\n\twidth: 24%;\n}\n\n.updraft-more-plugins .udp-box p:last-child {\n\tmargin-bottom: 0;\n\tpadding-bottom: 0;\n}\n\n/*\n\tlinks list\n*/\n.updraft_premium_description_list {\n\ttext-align: left;\n\tmargin: 0;\n\tfont-size: 12px;\n}\n\nul.updraft_premium_description_list, ul#updraft_restore_warnings {\n\tlist-style: disc inside;\n}\n\nul.updraft_premium_description_list li {\n\tdisplay: inline;\n}\n\nul.updraft_premium_description_list li::after {\n\tcontent: \" | \";\n}\n\nul.updraft_premium_description_list li:last-child::after {\n\tcontent: \"\";\n}\n\n.updraft_feature_cell {\n\tbackground-color: #F7D9C9 !important;\n\tpadding: 5px 10px;\n}\n\n.updraftplus_com_login_status, .updraftplus_com_key_status {\n\tdisplay: none;\n\tbackground: #FFF;\n\tborder-left: 4px solid #FFF;\n\tborder-left-color: #DC3232;\n\tbox-shadow: 0 1px 1px 0 rgba(0,0,0,.1);\n\tmargin: 5px 0 15px 0;\n\tpadding: 5px 12px;\n}\n\n.updraftplus_com_login_status.success {\n\tborder-left-color: green;\n}\n\n#updraft-wrap strong.success {\n\tcolor: green;\n}\n\n.updraft_feat_table {\n\tborder: none;\n\tborder-collapse: collapse;\n\tfont-size: 120%;\n\tbackground-color: white;\n\ttext-align: center;\n}\n\n.updraft_feat_th, .updraft_feat_table td {\n\tborder: 1px solid #F1F1F1;\n\tborder-collapse: collapse;\n\tfont-size: 120%;\n\tbackground-color: white;\n\ttext-align: center;\n\tpadding: 15px;\n}\n\n.updraft_feat_table td {\n\tborder-bottom-width: 4px;\n}\n\n.updraft_feat_table td:first-child {\n\tborder-left: none;\n}\n\n.updraft_feat_table td:last-child {\n\tborder-right: none;\n}\n\n.updraft_feat_table tr:last-child td {\n\tborder-bottom: none;\n}\n\n.updraft_feat_table td:nth-child(2),\n.updraft_feat_table td:nth-child(3) {\n\tbackground-color: rgba(241, 241, 241, 0.38);\n\twidth: 190px;\n}\n\n.updraft_feat_table__header td img {\n\tdisplay: block;\n\tmargin: 0 auto;\n}\n\n.updraft_feat_table__header td {\n\ttext-align: center;\n}\n\n.updraft_feat_table .installed {\n\tfont-size: 14px;\n}\n\n.updraft_feat_table p {\n\tpadding: 0px 10px;\n\tmargin: 5px 0px;\n\tfont-size: 13px;\n}\n\n.updraft_feat_table h4 {\n\tmargin: 5px 0px;\n}\n\n.updraft_feat_table .dashicons {\n\twidth: 25px;\n\theight: 25px;\n\tfont-size: 25px;\n\tline-height: 1;\n}\n\n.updraft_feat_table .dashicons-yes, .updraft_feat_table .updraft-yes {\n\tcolor: green;\n}\n\n.updraft_feat_table .dashicons-no-alt, .updraft_feat_table .updraft-no {\n\tcolor: red;\n}\n\n.updraft_tick_cell {\n\ttext-align: center;\n}\n\n.updraft_tick_cell img {\n\tmargin: 4px 0;\n\theight: 24px;\n}\n\n.ud_downloadstatus__close {\n\tborder: none;\n\tbackground: transparent;\n\twidth: auto;\n\tfont-size: 20px;\n\tpadding: 0;\n\tcursor: pointer;\n}\n\n#filelist .fileprogress, #filelist2 .fileprogress, .ud_downloadstatus .dlfileprogress, #ud_downloadstatus2 .dlfileprogress, #ud_downloadstatus3 .dlfileprogress {\n\twidth: 0%;\n\tbackground: #0572AA;\n\theight: 8px;\n\ttransition: width .3s;\n}\n\n.ud_downloadstatus .raw, #ud_downloadstatus2 .raw, #ud_downloadstatus3 .raw {\n\tmargin-top: 8px;\n\tclear: left;\n}\n\n.ud_downloadstatus .file, #ud_downloadstatus2 .file, #ud_downloadstatus3 .file {\n\tmargin-top: 8px;\n}\n\ndiv[class^=\"updraftplus_downloader_container_\"] {\n\tpadding: 10px;\n}\n\ntr.updraftplusmethod h3 {\n\tmargin: 0px;\n}\n\ntr.updraftplusmethod img {\n\tmax-width: 100%;\n}\n\n#updraft_retain_db_rules .updraft_retain_rules_delete, #updraft_retain_files_rules .updraft_retain_rules_delete {\n\tcursor: pointer;\n\tcolor: red;\n\tfont-size: 120%;\n\tfont-weight: bold;\n\tborder: 0px;\n\tborder-radius: 3px;\n\tpadding: 2px;\n\tmargin: 0 6px;\n\ttext-decoration: none;\n\tdisplay: inline-block;\n}\n\n#updraft_retain_db_rules .updraft_retain_rules_delete:hover, #updraft_retain_files_rules .updraft_retain_rules_delete:hover {\n\tcursor: pointer;\n\tcolor: white;\n\tbackground: red;\n}\n\n#updraft_backup_started {\n\tmax-width: 800px;\n\tfont-size: 140%;\n\tline-height: 140%;\n\tpadding: 14px;\n\tclear: left;\n}\n\n/* backup finished */\n.blockUI.blockOverlay.ui-widget-overlay {\n\tbackground: #000;\n}\n\n.updraft_success_popup {\n\ttext-align: center;\n\tpadding-bottom: 30px;\n}\n\n.updraft_success_popup > .dashicons {\n\tfont-size: 100px;\n\twidth: 100px;\n\theight: 100px;\n\tline-height: 100px;\n\tpadding: 0px;\n\tborder-radius: 50%;\n\tmargin-top: 30px;\n\tdisplay: block;\n\tmargin-left: auto;\n\tmargin-right: auto;\n\tbackground: #E2E6E5;\n}\n\n.updraft_success_popup > .dashicons.dashicons-yes {\n\ttext-indent: -5px;\n}\n\n.updraft_success_popup.success > .dashicons {\n\tcolor: green;\n}\n\n.updraft_success_popup.warning > .dashicons {\n\tcolor: #888;\n}\n\n.updraft_success_popup--message {\n\tpadding: 20px;\n}\n\n.button.updraft-close-overlay .dashicons {\n\ttext-decoration: none;\n\tfont-size: 20px;\n\tmargin-left: -5px;\n\tpadding: 0;\n\ttransform: translatey(3px);\n}\n\n.updraft_saving_popup img {\n\tanimation-name: udp_blink;\n\tanimation-duration: 610ms;\n\tanimation-iteration-count: infinite;\n\tanimation-direction: alternate;\n\tanimation-timing-function: ease-out;\n}\n\n.udp-premium-image {\n\tdisplay: none;\n}\n\n@media screen and (min-width: 720px) {\n\n\t.udp-premium-image {\n\t\tdisplay: block;\n\t\tfloat: left;\n\t\tpadding-right: 5px;\n\t}\n\n}\n\n/* End stuff already in admin.php */\n#plupload-upload-ui2 {\n\twidth: 80%;\n}\n\n.backup-restored {\n\tpadding: 8px;\n}\n\n.updated.backup-restored {\n\tpadding-top: 15px;\n\tpadding-bottom: 15px;\n}\n\n.backup-restored span {\n\tfont-size: 120%;\n}\n\n.memory-limit {\n\tpadding: 8px;\n}\n\n.updraft_list_errors {\n\tpadding: 8px;\n}\n\n/*.nav-tab {\n\tborder-radius: 20px 20px 0 0;\n\tborder-color: grey;\n\tborder-width: 2px;\n\tmargin-top: 34px;\n}\n\n.nav-tab:hover {\n\tborder-bottom: 0;\n}\n\n.nav-tab-active, .nav-tab-active:active {\n\tcolor: #df6926;\n\tborder-color: #D3D3D3;\n\tborder-width: 1px;\n\tborder-bottom: 0;\n}\n\n.nav-tab-active:focus {\n\tcolor: #df6926;\n}*/\n\n.nav-tab-wrapper {\n\tmargin: 14px 0px;\n}\n\n#updraft-poplog-content {\n\twhite-space: pre-wrap;\n}\n\n.next-backup {\n\tborder: 0px;\n\tpadding: 0px;\n\tmargin: 0 10px 0 0;\n}\n\n.not-scheduled {\n\tvertical-align: top !important;\n\tmargin: 0px !important;\n\tpadding: 0px !important;\n}\n\n.next-backup .updraft_scheduled {\n\t/* width: 124px;*/\n\tmargin: 0px;\n\tpadding: 2px 4px 2px 0px;\n}\n\n#next-backup-table-inner td {\n\tvertical-align: top;\n}\n\n.updraft_all-files {\n\tcolor: blue;\n}\n\n.multisite-advert-width {\n\twidth: 800px;\n}\n\n.updraft_settings_sectionheading {\n\tmargin-top: 6px;\n}\n\n.premium-upgrade-prompt {\n\t/* font-size: 115%; */\n}\n\nsection.premium-upgrade-purchase-success {\n\tpadding: 2em;\n\tbackground: #FAFAFA;\n\ttext-align: center;\n\tbox-shadow: 0px 14px 40px rgba(0, 0, 0, 0.1);\n}\n\nsection.premium-upgrade-purchase-success h3 {\n\tfont-size: 2em;\n\tcolor: green;\n}\n\nsection.premium-upgrade-purchase-success h3 .dashicons {\n\tdisplay: block;\n\tmargin: 0 auto;\n\tfont-size: 60px;\n\twidth: 60px;\n\theight: 60px;\n\tborder-radius: 50%;\n\tbackground: green;\n\tcolor: #FFF;\n\tmargin-bottom: 20px;\n}\n\nsection.premium-upgrade-purchase-success h3 .dashicons::before {\n\tdisplay: inline-block;\n\tmargin-left: -4px;\n\tmargin-top: 2px;\n}\n\nsection.premium-upgrade-purchase-success p {\n\tfont-size: 120%;\n}\n\n.show_admin_restore_in_progress_notice {\n\tpadding: 8px;\n}\n\n.show_admin_restore_in_progress_notice .unfinished-restoration {\n\tfont-size: 120%;\n}\n\n#backupnow_includefiles_moreoptions, #backupnow_database_moreoptions, #backupnow_includecloud_moreoptions {\n\tmargin: 4px 16px 6px 16px;\n\tborder: 1px dotted;\n\tpadding: 6px 10px;\n}\n\n#backupnow_database_moreoptions {\n\tmax-height: 250px;\n\toverflow: auto;\n}\n\n#backupnow_database_moreoptions div.backupnow-db-tables {\n\tmargin-bottom: 5px;\n}\n\n#backupnow_database_moreoptions div.backupnow-db-tables > a {\n\tcolor: #0073AA;\n}\n\n.form-table #updraft_activejobsrow .minimum-height {\n\tmin-height: 100px;\n}\n\n#updraft_activejobsrow th {\n\tmax-width: 112px;\n\tmargin: 0;\n\tpadding: 13px 0 0 0;\n}\n\n#updraft_lastlogmessagerow .last-message {\n\tpadding-top: 20px;\n\tdisplay: block;\n}\n\n.updraft_simplepie {\n\tvertical-align: top;\n}\n\n.download-backups {\n\tmargin-top: 8px;\n}\n\n.download-backups .updraft_download_button {\n\tmargin-right: 6px;\n}\n\n.download-backups .ud-whitespace-warning, .download-backups .ud-bom-warning {\n\tbackground-color: pink;\n\tpadding: 8px;\n\tmargin: 4px;\n\tborder: 1px dotted;\n}\n\n.download-backups .ul {\n\tlist-style: none inside;\n\tmax-width: 800px;\n\tmargin-top: 6px;\n\tmargin-bottom: 12px;\n}\n\n#updraft-plupload-modal {\n\tmargin: 16px 0;\n}\n\n.download-backups .upload {\n\tmax-width: 610px;\n}\n\n.download-backups #plupload-upload-ui {\n\twidth: 100%;\n}\n\n.ud_downloadstatus {\n\tpadding: 10px 0;\n}\n\n#ud_massactions, #updraft-delete-waitwarning {\n\tpadding: 14px;\n\tbackground: rgb(241, 241, 241);\n\tposition: absolute;\n\tleft: 0;\n\ttop: 100%;\n}\n\n#ud_massactions > *, #updraft-delete-waitwarning > * {\n\tvertical-align: middle;\n}\n\n#ud_massactions .updraftplus-remove {\n\tdisplay: inline-block;\n\tmargin-right: 0;\n}\n\n#ud_massactions .updraftplus-remove a {\n\ttext-decoration: none;\n}\n\n#ud_massactions .updraft-viewlogdiv a {\n\ttext-decoration: none;\n\tposition: relative;\n}\n\nsmall.ud_massactions-tip {\n\tdisplay: inline-block;\n\topacity: 0.5;\n\tfont-style: italic;\n\tmargin-left: 20px;\n}\n\n#updraft-navtab-backups-content .updraft_existing_backups {\n\tmargin-bottom: 35px;\n\tposition: relative;\n}\n\n#updraft-message-modal-innards {\n\tpadding: 4px;\n}\n\n#updraft-authenticate-modal {\n\ttext-align: center;\n\tfont-size: 16px !important;\n}\n\n#updraft-authenticate-modal p {\n\tfont-size: 16px;\n}\n\ndiv.ui-dialog.ui-widget.ui-widget-content {\n\tz-index: 99999 !important;\n}\n\n#updraft_delete_form p {\n\tmargin-top: 3px;\n\tpadding-top: 0;\n}\n\n#updraft_restore_form .cannot-restore {\n\tmargin: 8px 0;\n}\n\n.notice.updraft-restore-option {\n\tpadding: 12px;\n\tmargin: 8px 0 4px 0;\n\tborder-left-color: #CCC;\n}\n\n/* updraft_restore_crypteddb */\n#updraft_restorer_dboptions h4 {\n\tmargin: 0px 0px 6px 0px;\n\tpadding: 0px;\n}\n\n.updraftplus_restore_tables_options_container {\n\tmax-height: 250px;\n\toverflow: auto;\n}\n\n.updraft_debugrow th {\n\tvertical-align: top;\n\tpadding-top: 6px;\n\tmax-width: 140px;\n}\n\n.expertmode p {\n\tfont-size: 125%;\n}\n\n.expertmode .call-wp-action {\n\twidth: 300px;\n\theight: 22px;\n}\n\n.updraftplus-lock-advert {\n\tclear: left;\n\tmax-width: 600px;\n}\n\n.uncompressed-data {\n\tclear: left;\n\tmax-width: 600px;\n}\n\n.delete-old-directories {\n\tpadding: 8px;\n\tpadding-bottom: 12px;\n}\n\n.active-jobs {\n\twidth: 100%;\n\ttext-align: center;\n\tpadding: 33px;\n}\n\n.job-id {\n\tmargin-top: 0;\n\tmargin-bottom: 8px;\n}\n\n.next-resumption {\n\tfont-weight: bold;\n}\n\n.updraft_percentage {\n\tz-index: -1;\n\tposition: absolute;\n\tleft: 0px;\n\ttop: 0px;\n\ttext-align: center;\n\tbackground-color: #1D8EC2;\n\ttransition: width 0.3s;\n}\n\n.curstage {\n\tz-index: 1;\n\tborder-radius: 2px;\n\tmargin-top: 8px;\n\twidth: 100%;\n\theight: 26px;\n\tline-height: 26px;\n\tposition: relative;\n\ttext-align: center;\n\tfont-style: italic;\n\tcolor: #FFF;\n\tbackground-color: #B7B7B7;\n\ttext-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);\n}\n\n.curstage-info {\n\tdisplay: inline-block;\n\tz-index: 2;\n}\n\n.retain-files {\n\twidth: 48px;\n}\n\n.backup-interval-description tr td div {\n\tmax-width: 670px;\n}\n\n#updraft-manualdecrypt-modal {\n\twidth: 85%;\n\tmargin: 6px;\n\tmargin-left: 100px;\n}\n\n.directory-permissions {\n\tfont-size: 110%;\n\tfont-weight: bold;\n}\n\n.double-warning {\n\tborder: 1px solid;\n\tpadding: 6px;\n}\n\n.raw-backup-info {\n\tfont-style: italic;\n\tfont-weight: bold;\n\tfont-size: 120%;\n}\n\n.updraft_existingbackup_date {\n\twidth: 22%;\n\tmax-width: 140px;\n}\n\n.updraft_existing_backups_wrapper {\n\tmargin-top: 20px;\n\tborder-top: 1px solid #DDD;\n}\n\n.updraft-no-backups-msg {\n\tpadding: 10px 40px;\n\ttext-align: center;\n\tfont-style: italic;\n}\n\n.tr-bottom-4 {\n\tmargin-bottom: 4px;\n}\n\n.existing-backups-table th {\n\tpadding: 8px 10px;\n}\n\n.form-table .backup-date {\n\twidth: 172px;\n}\n\n.form-table .backup-data {\n\twidth: 426px;\n}\n\n.form-table .updraft_backup_actions {\n\twidth: 272px;\n}\n\n.existing-date {\n\t-webkit-box-sizing: border-box;\n\t-moz-box-sizing: border-box;\n\tbox-sizing: border-box;\n\tmax-width: 140px;\n\twidth: 25%;\n}\n\n.line-break-tr {\n\theight: 2px;\n\tpadding: 1px;\n\tmargin: 0px;\n}\n\n.line-break-td {\n\tmargin: 0;\n\tpadding: 0;\n}\n\n.td-line-color {\n\theight: 2px;\n\tbackground-color: #888;\n}\n\n.raw-backup {\n\tmax-width: 140px;\n}\n\n.existing-backups-actions {\n\tpadding: 1px;\n\tmargin: 0px;\n}\n\n.existing-backups-border {\n\theight: 2px;\n\tpadding: 1px;\n\tmargin: 0px;\n}\n\n.existing-backups-border > td {\n\tmargin: 0;\n\tpadding: 0;\n}\n\n.existing-backups-border > div {\n\theight: 2px;\n\tbackground-color: #AAA;\n}\n\n.updraft_existing_backup_date {\n\tmax-width: 140px;\n}\n\n.updraftplus-upload {\n\tmargin-right: 6px;\n\tfloat: left;\n\tclear: none;\n}\n\n.before-restore-button {\n\tpadding: 1px;\n\tmargin: 0px;\n}\n\n.before-restore-button div {\n\tfloat: none;\n\tdisplay: inline-block;\n}\n\n.table-separator-tr {\n\theight: 2px;\n\tpadding: 1px;\n\tmargin: 0px;\n}\n\n.table-separator-td {\n\tmargin: 0px;\n\tpadding: 0px;\n}\n\n.end-of-table-div {\n\theight: 2px;\n\tbackground-color: #AAA;\n}\n\n.last-backup-job {\n\tpadding-top: 3% !important;\n}\n\n.line-height-03 {\n\tline-height: 0.3 !important;\n}\n\n.line-height-13 {\n\tline-height: 1.3 !important;\n}\n\n.line-height-23 {\n\tline-height: 2.3 !important;\n}\n\n#updraft_diskspaceused {\n\tcolor: #DF6926;\n}\n\n#updraft_delete_old_dirs_pagediv {\n\tpadding-bottom: 10px;\n}\n\n/*#updraft_lastlogmessagerow > td, #updraft_last_backup > td {\n\tpadding: 0;\n}*/\n\n/* Time + scheduling add-on*/\n.fix-time {\n\twidth: 70px;\n}\n\n.retain-files {\n\twidth: 70px;\n}\n\n.number-input {\n\tmin-width: 50px;\n\tmax-width: 70px;\n}\n\n.additional-rule-width {\n\tmin-width: 60px;\n\tmax-width: 70px;\n}\n\n/* Add-ons */\n/* Want to fix the WordPress icons so that they fit inline with the text, and don't push everything out of place. */\n\n#updraft-wrap .dashicons.dashicons-adapt-size {\n\tline-height: inherit;\n\tfont-size: inherit;\n}\n\n#updraft-wrap .button span.dashicons:not(.dashicons-adapt-size) {\n\tvertical-align: middle;\n\tmargin-top: -3px;\n}\n\n.addon-logo-150 {\n\tmargin-left: 30px;\n\tmargin-top: 33px;\n\theight: 125px;\n\twidth: 150px;\n}\n\n.margin-bottom-50 {\n\tmargin-bottom: 50px;\n}\n\n.premium-container {\n\twidth: 80%;\n}\n\n/* Main Header */\n\n.main-header {\n\tbackground-color: #DF6926;\n\theight: 200px;\n\twidth: 100%;\n}\n\n.button-add-to-cart {\n\tcolor: white;\n\tborder-color: white;\n\tfloat: none;\n\tmargin-right: 17px;\n}\n\n.button-add-to-cart:hover, .button-add-to-cart:focus, .button-add-to-cart:active {\n\tborder-color: #A0A5AA;\n\tcolor: #A0A5AA;\n}\n\n.addon-title {\n\tmargin-top: 25px;\n}\n\n.addon-text {\n\tmargin-top: 75px;\n}\n\n.image-main-div {\n\twidth: 25%;\n\tfloat: left;\n}\n\n.text-main-div {\n\twidth: 60%;\n\tfloat: left;\n\ttext-align: center;\n\tcolor: white;\n\tmargin-top: 16px;\n}\n\n.text-main-div-title {\n\tfont-weight: bold !important;\n\tcolor: white;\n\ttext-align: center;\n}\n\n.text-main-div-paragraph {\n\tcolor: white;\n}\n\n/* End main header */\n\n/* Vault icons */\n\n.updraftplus-vault-cta {\n\twidth: 100%;\n\ttext-align: center;\n\tmargin-bottom: 50px;\n}\n\n.updraftplus-vault-cta h1 {\n\tfont-weight: bold;\n}\n\n.updraftvault-buy {\n\twidth: 225px;\n\theight: 225px;\n\tborder: 2px solid #777;\n\tdisplay: inline-table;\n\tmargin: 0 auto;\n\tmargin-right: 50px;\n\tposition: relative;\n}\n\n.updraftplus-vault-cta > .vault-options > .center-vault {\n\twidth: 275px;\n\theight: 275px;\n}\n\n.updraftplus-vault-cta > .vault-options > .center-vault > a {\n\tright: 21%;\n\tfont-size: 16px;\n\tborder-width: 4px !important;\n}\n\n.updraftplus-vault-cta > .vault-options > .center-vault > p {\n\tfont-size: 16px;\n}\n\n.updraftvault-buy .button-purchase {\n\tright: 24%;\n\tmargin-left: 0;\n\tline-height: 1.7em;\n}\n\n.updraftvault-buy hr {\n\theight: 2px;\n\tbackground-color: #777;\n\tmargin-top: 18px;\n}\n\n.right {\n\tmargin-right: 0px;\n}\n\n.updraftvault-buy .addon-logo-100 {\n\theight: 100px;\n\twidth: 125px;\n\tmargin-top: 7px;\n}\n\n.updraftvault-buy .addon-logo-large {\n\tmargin-top: 7px;\n}\n\n.updraftvault-buy .button-buy-vault {\n\tfont-size: 12px;\n\tcolor: #DF6926;\n\tborder-color: #DF6926;\n\tborder-width: 2px !important;\n\tposition: absolute;\n\tright: 29%;\n\tbottom: 2%;\n}\n\n.premium-addon-div .button-purchase {\n\tline-height: 1.7em;\n}\n\n.updraftvault-buy .button-buy-vault:hover {\n\tborder-color: darkgrey;\n\tcolor: darkgrey;\n}\n\n/* End Vault icons */\n\n/* Premium addons */\n\n.premium-addons {\n\tmargin-top: 80px;\n\twidth: 100%;\n\tmargin: 0 auto;\n\tdisplay: table;\n}\n\n.addon-list {\n\t/* margin-left: 32px; */\n\tdisplay: table;\n\ttext-align: center;\n}\n\n.premium-addons h1 {\n\ttext-align: center;\n\tfont-weight: bold;\n}\n\n.premium-addons p {\n\ttext-align: center;\n}\n\n.premium-addons .premium-addon-div {\n\twidth: 200px;\n\theight: 250px;\n\tborder: 2px solid #777;\n\tdisplay: inline-table;\n\tmargin: 0 auto;\n\tmargin-right: 25px;\n\tmargin-top: 25px;\n\ttext-align: center;\n\tposition: relative;\n}\n\n.premium-addons .premium-addon-div p {\n\tmargin-left: 2px;\n\tmargin-right: 2px;\n}\n\n.premium-addons .premium-addon-div img {\n\twidth: auto;\n\theight: 50px;\n\tmargin-top: 7px;\n}\n\n.premium-addons .premium-addon-div .hr-alignment {\n\tmargin-top: 44px;\n}\n\n.premium-addons .premium-addon-div .dropbox-logo {\n\theight: 39px;\n\twidth: 150px;\n}\n\n.premium-addons .premium-addon-div .azure-logo, .premium-addons .premium-addon-div .onedrive-logo {\n\twidth: 75%;\n\theight: 24px;\n}\n\n.button-purchase {\n\tfont-size: 12px;\n\tcolor: #DF6926;\n\tborder-color: #DF6926;\n\tborder-width: 2px !important;\n\tposition: absolute;\n\tright: 25%;\n\tbottom: 2%;\n}\n\n.button-purchase:hover {\n\tcolor: darkgrey;\n\tborder-color: darkgrey;\n}\n\n.premium-addons .premium-addon-div hr {\n\theight: 2px;\n\tbackground-color: #777;\n\tmargin-top: 18px;\n}\n\n.premium-addon-div p {\n\tfont-style: italic;\n}\n\n.addon-list > .premium-addon-div > .onedrive-fix,\n.addon-list > .premium-addon-div > .azure-logo {\n\tmargin-top: 33px;\n}\n\n.addon-list > .premium-addon-div > .dropbox-fix {\n\tmargin-top: 18px;\n}\n\n/* End premium addons */\n\n\n/* Forgotton something (that is the name of the div rather than a mental note!) */\n\n.premium-forgotton-something {\n\tmargin-top: 5%;\n}\n\n.premium-forgotton-something h1 {\n\ttext-align: center;\n\tfont-weight: bold;\n}\n\n.premium-forgotton-something p {\n\ttext-align: center;\n\tfont-weight: normal;\n}\n\n.premium-forgotton-something .button-faq {\n\tcolor: #DF6926;\n\tborder-color: #DF6926;\n\tmargin: 0 auto;\n\tdisplay: table;\n}\n\n.premium-forgotton-something .button-faq:hover {\n\tcolor: #777;\n\tborder-color: #777;\n}\n\n/* End of forgotton something */\n\n.updraftplusmethod.updraftvault #vaultlogo {\n\tpadding-left: 40px;\n}\n\n.updraftplusmethod.updraftvault .vault_primary_option {\n\tfloat: left;\n\twidth: 50%;\n\ttext-align: center;\n\tpadding-bottom: 20px;\n}\n\n.updraftplusmethod.updraftvault .vault_primary_option div {\n\tclear: right;\n\tpadding-top: 20px;\n}\n\n.updraftplusmethod.updraftvault .clear-left {\n\tclear: left;\n}\n\n.updraftplusmethod.updraftvault .padding-top-20px {\n\tpadding-top: 20px;\n}\n\n.updraftplusmethod.updraftvault .padding-top-14px {\n\tpadding-top: 14px;\n}\n\n.updraftplusmethod.updraftvault #updraftvault_settings_default .button-primary, .updraftplusmethod.updraftvault #updraftvault_settings_showoptions .button-primary {\n\tfont-size: 18px !important;\n}\n\n.updraftplusmethod.updraftvault #updraftvault_showoptions, .updraftplusmethod.updraftvault #updraftvault_connect {\n\tmargin-top: 8px;\n}\n\n.updraftplusmethod.updraftvault #updraftvault_settings_connect input {\n\tmargin-right: 10px;\n}\n\n.updraftplusmethod.updraftvault #updraftvault_email {\n\twidth: 280px;\n}\n\n.updraftplusmethod.updraftvault #updraftvault_pass {\n\twidth: 200px;\n}\n\n.updraftplusmethod.updraftvault #vault-is-connected {\n\tmargin: 0;\n\tpadding: 0;\n}\n\n.updraftplusmethod.updraftvault #updraftvault_settings_default p {\n\tclear: left;\n}\n\n.updraftplusmethod.updraftvault .vault-purchase-option-container {\n\ttext-align: center;\n}\n\n.updraftplusmethod.updraftvault .vault-purchase-option {\n\twidth: 40%;\n\ttext-align: center;\n\tpadding-top: 20px;\n\tdisplay: inline-block;\n}\n\n.updraftplusmethod.updraftvault .vault-purchase-option-size {\n\tfont-size: 200%;\n\tfont-weight: bold;\n}\n\n.updraftplusmethod.updraftvault .vault-purchase-option-link {\n\tclear: both;\n\tfont-size: 150%;\n}\n\n.updraftplusmethod.updraftvault .vault-purchase-option-or {\n\tclear: both;\n\tfont-size: 115%;\n\tfont-style: italic;\n}\n\n/* Automation Backup Advert by B */\n.autobackup-image {\n/* \tdisplay: inline-block; */\n/*\tmin-width: 10%;\n\tmax-width:25%;*/\n/*\tfloat: left;*/\n\tclear: left;\n\tfloat: left;\n\twidth: 110px;\n\theight: 110px;\n}\n\n.autobackup-description {\n\twidth: 100%;\n}\n\n.advert-description {\n\tfloat: left;\n\tclear: right;\n\tpadding: 4px 10px 8px 10px;\n\twidth: 70%;\n\tclear: right;\n\tvertical-align: top;\n}\n\n.advert-btn {\n\tdisplay: inline-block;\n\tmin-width: 10%;\n\tvertical-align: top;\n\tmargin-bottom: 8px;\n}\n\n.advert-btn:first-of-type {\n\tmargin-top: 25px;\n}\n\n.advert-btn a {\n\tdisplay: block;\n\tcursor: pointer;\n}\n\na.btn-get-started {\n\tbackground: #FFF;\n\tborder: 2px solid #DF6926;\n\tborder-radius: 4px;\n\tcolor: #DF6926;\n\tdisplay: inline-block;\n\tmargin-left: 10px !important;\n\tmargin-bottom: 7px !important;\n\tfont-size: 18px !important;\n\tline-height: 20px;\n\tmin-height: 28px;\n\tpadding: 11px 10px 5px 10px;\n\ttext-transform: uppercase;\n\ttext-decoration: none;\n}\n\n.circle-dblarrow {\n\tborder: 1px solid #DF6926;\n\tborder-radius: 100%;\n\tdisplay: inline-block;\n\tfont-size: 17px;\n\tline-height: 17px;\n\tmargin-left: 5px;\n\twidth: 20px;\n\theight: 20px;\n\ttext-align: center;\n}\n\n/* End Automation Backup Advert by B */\n/* New Responsive Pretty Advanced Settings */\n.expertmode .advanced_settings_container {\n\theight: auto;\n\toverflow: hidden;\n}\n\n.expertmode .advanced_settings_container .advanced_settings_menu {\n\tfloat: none;\n\tborder-bottom: 1px solid rgb(204, 204, 204);\n}\n\n.expertmode .advanced_settings_container .advanced_settings_content {\n\tpadding-top: 5px;\n\tfloat: none;\n\twidth: auto;\n\toverflow: auto;\n}\n\n.expertmode .advanced_settings_container .advanced_settings_content h3:first-child {\n\tmargin-top: 5px !important;\n}\n\n.expertmode .advanced_settings_container .advanced_settings_content .advanced_tools {\n\tdisplay: none;\n}\n\n.expertmode .advanced_settings_container .advanced_settings_content .site_info {\n\tdisplay: block;\n}\n\n.expertmode .advanced_settings_container .advanced_settings_menu .advanced_tools_button {\n\tdisplay: inline-block;\n\tcursor: pointer;\n\tpadding: 5px;\n\tcolor: #000;\n}\n\n.expertmode .advanced_settings_container .advanced_settings_menu .advanced_tools_text {\n\tfont-size: 16px;\n}\n\n.expertmode .advanced_settings_container .advanced_settings_menu .advanced_tools_button:hover {\n\tbackground-color: #EAEAEA;\n}\n\n.expertmode .advanced_settings_container .advanced_settings_menu .active {\n\tbackground-color: #3498DB;\n\tcolor: #FFF;\n}\n\n.expertmode .advanced_settings_container .advanced_settings_menu .active:hover {\n\tbackground-color: #72C5FD;\n\tcolor: #FFF;\n}\n\n.expertmode .advanced_settings_container .advanced_settings_content input#import_settings {\n\theight: auto !important;\n}\n\ndiv#updraft-wrap a {\n\tcursor: pointer !important;\n}\n\n.updraftcentral_wizard_option {\n\twidth: 45%;\n\tfloat: left;\n\ttext-align: center;\n}\n\n.updraftcentral_wizard_option label {\n\tmargin-bottom: 8px;\n}\n\n#updraftcentral_keys_table {\n\tdisplay: none;\n}\n\n.create_key_container {\n\tborder: 1px solid;\n\tborder-radius: 4px;\n\tpadding: 0 0 6px 6px;\n\tmargin-bottom: 8px;\n}\n\n.updraftcentral_cloud_connect {\n\tborder-radius: 4px;\n\tborder: 1px solid #000;\n\tpadding: 0 20px;\n\tmargin-top: 30px;\n\tbackground-color: #FFF;\n}\n\n.updraftcentral_cloud_error {\n\tborder: 1px solid #000;\n\tpadding: 3px 10px;\n\tborder-left: 3px solid #F00;\n\tbackground-color: #FFF;\n\tmargin-bottom: 10px;\n}\n\n.updraftcentral_cloud_info {\n\tborder: 1px solid #000;\n\tpadding: 3px 10px;\n\tborder-left: 3px solid #EF8F31;\n\tbackground-color: #FFF;\n\tmargin-bottom: 10px;\n}\n\n.updraftplus_spinner.spinner {\n\tpadding-left: 25px;\n\tfloat: none;\n}\n\n.updraftplus_spinner.spinner.visible {\n\tvisibility: visible;\n\twidth: auto;\n}\n\n.updraftcentral_cloud_notices .updraftplus_spinner {\n\tmargin-top: -5px;\n}\n\n.updraftcentral-subheading {\n\tfont-size: 14px;\n\tmargin-top: -10px;\n\tmargin-bottom: 20px;\n}\n\n#updraftcentral_cloud_form input#email,\n#updraftcentral_cloud_form input#password {\n\tmin-width: 250px;\n}\n\n.updraftcentral-data-consent {\n\tfont-size: 13px;\n\tmargin-bottom: 10px;\n}\n\n.updraftcentral_cloud_wizard_image {\n\tfloat: left;\n\tmin-width: 100px;\n\tmargin-right: 25px;\n}\n\n.updraftcentral_cloud_wizard {\n\tfloat: left;\n}\n\n.updraftcentral_cloud_clear {\n\tclear: both;\n}\n\n.updraftplus-settings-footer {\n\tmargin-top: 30px;\n}\n\n.updraftplus-top-menu {\n\tpadding: 0.5em;\n}\n\n#updraft_inpage_backup #updraft_activejobs_table {\n\tbackground: transparent;\n}\n\n#updraft_inpage_backup #updraft_lastlogmessagerow .updraft-log-link {\n\tfloat: none;\n}\n\n#updraft_inpage_backup #updraft_activejobsrow .updraft_row {\n\tflex-direction: column;\n\tpadding-left: 20px;\n\tpadding-right: 20px;\n}\n\n#updraft_inpage_backup #updraft_activejobsrow .updraft_progress_container {\n\twidth: 100%;\n}\n\n#updraft_inpage_backup #updraft_activejobs_table {\n\toverflow: inherit;\n}\n\n#updraft_inpage_backup span#updraft_lastlogcontainer {\n\tpadding: 18px;\n\tbackground: #FAFAFA;\n\tdisplay: block;\n\tfont-size: 90%;\n\tbox-shadow: 0px 1px 2px rgba(0, 0, 0, 0.1);\n}\n\n#updraft_inpage_backup div#updraft_activejobsrow {\n\tbackground: #FAFAFA;\n\tbox-shadow: 0px 1px 2px rgba(0, 0, 0, 0.1);\n}\n\n#updraft_inpage_backup #updraft_lastlogmessagerow > div {\n\tbackground: transparent;\n\tpadding: 0;\n}\n\n#updraft_inpage_backup .last-message > strong {\n\tdisplay: block;\n\tmargin-top: 13px;\n}\n\nbody.update-core-php #updraft_inpage_backup h2:nth-child(1) {\n\tmargin-top: 1em !important;\n}\n\n/* Restoration page */\n\n.updraft_restore_container {\n\tdisplay: block;\n\tposition: fixed;\n\ttop: 0;\n\tleft: 0;\n\tright: 0;\n\tbottom: 0;\n\tz-index: 99999;\n\tpadding-top: 30px;\n\tbackground: #F1F1F1;\n\toverflow: auto;\n}\n\n.updraft-modal-is-opened .select2-container {\n\tz-index: 99999;\n}\n\nbody.updraft-modal-is-opened {\n\toverflow: hidden;\n}\n\n.updraft_restore_container h2 {\n\tmargin: 0;\n}\n\n.updraft_restore_container .updraftmessage {\n\tbox-sizing: border-box;\n\tmax-width: 860px;\n\tmargin-left: auto;\n\tmargin-right: auto;\n}\n\n.updraft_restore_main {\n\tmax-width: 860px;\n\tmargin: 0 auto;\n\tmargin-top: 20px;\n\tbackground: #FFF;\n\tbox-shadow: 0 3px 3px rgba(0, 0, 0, 0.1);\n\tposition: relative;\n\tdisplay: flex;\n\tflex-wrap: wrap;\n\tbox-sizing: border-box;\n}\n\n.updraft_restore_main--header {\n\tfont-size: 20px;\n\tfont-weight: bold;\n\ttext-align: center;\n\tpadding-top: 16px;\n\tline-height: 20px;\n\twidth: 100%;\n\tmax-width: 100%;\n\tpadding-right: 30px;\n\tpadding-left: 30px;\n\tbox-sizing: border-box;\n}\n\n.updraft_restore_main--activity {\n\tposition: relative;\n\twidth: calc(100% - 350px);\n\tbox-sizing: border-box;\n}\n\n.updraft_restore_main--activity-title {\n\tpadding: 20px;\n\tmargin: 0;\n}\n\n.show-credentials-form.updraft_restore_main .updraft_restore_main--activity-title {\n\tdisplay: none;\n}\n\n.updraft_restore_main--components {\n\twidth: 350px;\n\tpadding: 20px;\n\tbox-sizing: border-box;\n\tbackground: #F8F8F8;\n\tmin-height: 350px;\n}\n\n.updraft_restore_main:not(.show-credentials-form) div#updraftplus_ajax_restore_output {\n\tbackground: #23282D;\n\tcolor: #E3E3E3;\n\tfont-family: monospace;\n\tpadding: 19px;\n\toverflow: auto;\n\tposition: absolute;\n\ttop: 60px;\n\tbottom: 0;\n\tright: 0;\n\tleft: 0;\n}\n\n#updraftplus_ajax_restore_output form {\n\twhite-space: normal;\n\tfont-family: -apple-system, blinkmacsystemfont, \"Segoe UI\", roboto, oxygen-sans, ubuntu, cantarell, \"Helvetica Neue\", sans-serif;\n}\n\n#updraftplus_ajax_restore_output .updraft_restore_errors {\n\tborder: 1px solid #DC3232;\n\tpadding: 10px 20px;\n\twhite-space: normal;\n}\n\n.updraft_restore_main:not(.show-credentials-form) div#updraftplus_ajax_restore_output h2 {\n\tcolor: #00A0D2;\n\tpadding-top: 10px;\n\tpadding-bottom: 5px;\n}\n\n.updraft_restore_main.show-credentials-form div#updraftplus_ajax_restore_output {\n\tpadding: 20px;\n\tborder-left: 1px solid #EEE;\n}\n\n.updraft_restore_main.show-credentials-form div#updraftplus_ajax_restore_output #message {\n\tmargin-left: 0;\n\tmargin-right: 0;\n}\n\n.updraft_restore_main.show-credentials-form div#updraftplus_ajax_restore_output .form-table td,\n.updraft_restore_main.show-credentials-form div#updraftplus_ajax_restore_output .form-table th {\n\tpadding-bottom: 0;\n}\n\n.updraft_restore_main.show-credentials-form .updraft_restore_main--components {\n\topacity: 0.2;\n}\n\n.updraft_restore_main.show-credentials-form div.error .restore-credential-errors--list p {\n\tmargin: 0;\n\tlist-style-type: disc;\n\tdisplay: list-item;\n\tlist-style-position: inside;\n}\n\n.restore-credential-errors > :first-child {\n\tmargin-top: 0;\n}\n\n.restore-credential-errors > :last-child {\n\tmargin-bottom: 0;\n}\n\nul.updraft_restore_components_list li {\n\tcolor: #BABABA;\n\tfont-size: 1.2em;\n\tmargin-bottom: 1em;\n}\n\nul.updraft_restore_components_list li::before {\n\tcontent: '\\f469';\n\tfont-family: dashicons;\n\tfont-size: 20px;\n\tvertical-align: middle;\n\tdisplay: inline-block;\n\tmargin-right: 7px;\n}\n\nul.updraft_restore_components_list li span {\n\tvertical-align: middle;\n}\n\nul.updraft_restore_components_list li.done {\n\tcolor: green;\n}\n\nul.updraft_restore_components_list li.done::before {\n\tcontent: \"\\f147\";\n}\n\nul.updraft_restore_components_list li.active {\n\tcolor: inherit;\n}\n\nul.updraft_restore_components_list li.active::before {\n\tcontent: \"\\f463\";\n\tanimation: udp_rotate 1s linear infinite;\n}\n\nul.updraft_restore_components_list li.error {\n\tcolor: #DC3232;\n}\n\nul.updraft_restore_components_list li.error::before {\n\tcontent: \"\\f335\";\n}\n\n.updraft_restore_result {\n\tpadding: 10px 0;\n\tfont-size: 1.3em;\n\tmargin-bottom: 1em;\n\tvertical-align: middle;\n\tdisplay: none;\n}\n\n.updraft_restore_result.restore-error {\n\tcolor: #DC3232;\n}\n\n.updraft_restore_result.restore-success {\n\tcolor: green;\n}\n\n.updraft_restore_result .dashicons {\n\tfont-size: 35px;\n\theight: 35px;\n\tline-height: 33px;\n\twidth: 35px;\n}\n\n.updraft_restore_result span {\n\tvertical-align: middle;\n}\n\n/* Restore modal */\n\n#updraft-restore-modal {\n\twidth: 100%;\n}\n\ndiv#updraft-restore-modal .notice {\n\tbackground: #F8F8F8;\n}\n\n.updraft-restore-modal--stage .updraft--two-halves,\n.updraft-restore-modal--stage .updraft--one-half {\n\tpadding: 20px 30px;\n}\n\n.updraft-restore-modal--header {\n\tpadding: 20px;\n\tpadding-bottom: 0px;\n\ttext-align: center;\n\tborder-bottom: 1px solid #EEE;\n}\n\n.updraft-restore-modal--header h3 {\n\tmargin: 0;\n\tpadding: 0;\n}\n\n.updraft-restore-item {\n\tpadding-bottom: 4px;\n}\n\n.updraft-restore-buttons {\n\tpadding-top: 10px;\n}\n\nul.updraft-restore--stages {\n\tdisplay: inline-block;\n\tmargin: 0;\n\theight: 28px;\n}\n\nul.updraft-restore--stages li {\n\tdisplay: inline-block;\n\tposition: relative;\n\twidth: 12px;\n\theight: 12px;\n\tbackground: #D2D2D2;\n\tborder-radius: 20px;\n\tline-height: 1;\n\tmargin: 0 4px;\n\tvertical-align: middle;\n}\n\nul.updraft-restore--stages li.active {\n\tbackground: #444;\n}\n\n.updraft-restore--footer {\n\tborder-top: 1px solid #EEE;\n\tpadding: 20px;\n\ttext-align: center;\n\tposition: sticky;\n\tbottom: 0;\n\tbackground: #FFF;\n\twidth: 100%;\n\tbox-sizing: border-box;\n}\n\n.updraft-restore--footer .updraft-restore--cancel {\n\tposition: absolute;\n\tleft: 20px;\n\ttop: auto;\n}\n\n.updraft-restore--footer .updraft-restore--next-step {\n\tposition: absolute;\n\tright: 20px;\n\ttop: auto;\n}\n\nul.updraft-restore--stages li span {\n\tposition: absolute;\n\twidth: 120px;\n\tbottom: calc(100% + 14px);\n\tleft: -55px;\n\tbackground: #000000DB;\n\tpadding: 5px;\n\tbox-sizing: border-box;\n\tborder-radius: 4px;\n\tcolor: #FFF;\n\ttext-align: center;\n\tdisplay: none;\n}\n\nul.updraft-restore--stages li:hover span {\n\tdisplay: inline-block;\n}\n\n.updraft-restore-item input[type=checkbox] {\n\tmargin-bottom: -5px;\n}\n\n.updraft-restore-item input[type=checkbox]:checked + label {\n\tfont-weight: bold;\n}\n\n/* Hide close button on download window */\ndiv#updraft-restore-modal .ud_downloadstatus__close {\n\tdisplay: none;\n}\n\n#ud_downloadstatus2:not(:empty) {\n\tmargin-top: 15px;\n}\n\n.dashicons.rotate {\n\tanimation: udp_rotate 1s linear infinite;\n}\n\n/* Activity stalled */\n\nspan#updraftplus_ajax_restore_last_activity {\n\tfont-size: .8rem;\n\tfont-weight: normal;\n\tfloat: right;\n}\n\n.updraft_restore_main--components .updated.show_admin_restore_in_progress_notice {\n\tmargin: -20px -20px 20px;\n\tpadding: 19px;\n}\n\n.updraft_restore_main--components .updated.show_admin_restore_in_progress_notice button {\n\tmargin-right: 5px;\n}\n\n#updraft_migrate_receivingsites .updraftplus-remote-sites-selector .button-primary, .updraft_migrate_add_site .input-field input, .updraft_migrate_add_site button {\n\tvertical-align: middle;\n}\n\n#updraft_migrate_receivingsites .text-link-menu a:not(:last-child) {\n\tpadding-right: 10px;\n}\n\n#updraft_migrate_receivingsites a.updraft_migrate_clear_sites span.dashicons-trash:before {\n\tfont-size: 17px;\n}\n\n#updraft_migrate_receivingsites .updraft_migrate_add_site {\n\tclear: both;\n}\n\n/* RTL Support */\n\n.rtl .advanced_tools.total_size table td {\n\tdirection: ltr;\n\ttext-align: right;\n}\n\n.rtl #plupload-upload-ui2.drag-drop #drag-drop-area2 {\n\tmargin-bottom: 20px;\n}\n\n.rtl #updraft_lastlogmessagerow .updraft-log-link {\n\tfloat: left;\n}\n\n.rtl label.updraft_checkbox > input[type=checkbox] {\n\tmargin-right: -25px;\n\tmargin-left: inherit;\n}\n\n.rtl .ud_downloadstatus__close {\n\tfloat: left !important;\n}\n\n.rtl #updraft_backupextradbs_another_container {\n\tfloat: right;\n}\n\n.rtl input.labelauty + label {\n\tdirection: ltr;\n\tposition: relative;\n\tmin-height: 29px;\n}\n\n.rtl input.labelauty + label > span.labelauty-checked-image, .rtl input.labelauty + label > span.labelauty-unchecked-image {\n\tright: 8px;\n\ttop: 11px;\n\tposition: absolute;\n}\n\n.rtl .button.updraft-close-overlay .dashicons {\n\tmargin-right: -5px;\n\tmargin-left: inherit;\n}\n\n.rtl label.updraft_checkbox {\n\tmargin-right: 26px;\n\tmargin-left: inherit;\n}\n\n.rtl #updraft-wrap .udp-info {\n\tleft: 10px;\n\tright: inherit;\n}\n\n.rtl input.labelauty + label > span.labelauty-unchecked-image + span.labelauty-unchecked,\n.rtl input.labelauty + label > span.labelauty-checked-image + span.labelauty-checked {\n\tmargin-right: 7px;\n\tmargin-left: inherit;\n\tpadding: 7px 7px 7px 26px;\n\twidth: 141px;\n\ttext-align: right;\n}\n\n.rtl #updraft_report_cell button.updraft_reportbox_delete,\n.rtl .updraft_box_delete_button,\n.rtl .updraft_small_box .updraft_box_delete_button {\n\tleft: 4px;\n\tright: inherit;\n}\n\n#updraft_exclude_modal .clause-input-container {\n\toverflow: auto;\n}\n\n#updraft_exclude_modal .clause-input-container select, #updraft_exclude_modal .clause-input-container input {\n\tfloat: left;\n}\n\n#updraft_exclude_modal .clause-input-container .wildcards-input {\n\tmargin: 7px 7px 0 0;\n}\n\n#updraft_exclude_modal .updraft-exclude-panel .contain-clause-sub-label {\n\tmargin-top: 10px;\n\tdisplay: block;\n}\n\n@media only screen and (min-width: 1024px) {\n\n\t#updraft_activejobsrow .updraft_row {\n\t\tdisplay: flex;\n\t\talign-items: baseline;\n\t}\n\n\t#updraft_activejobsrow .updraft_row .updraft_col {\n\t\tflex: auto;\n\t}\n\n\t#updraft_activejobsrow .updraft_progress_container {\n\t\twidth: calc(100% - 230px);\n\t}\n\n}\n\n@media only screen and (min-width: 782px) {\n\n\t.settings_page_updraftplus input[type=text],\n\t.settings_page_updraftplus input[type=password],\n\t.settings_page_updraftplus input[type=number] {\n\t\t/* border-radius: 4px; */\n\t\tline-height: 1.42;\n\t\t/* border: 1px solid #CCC; */\n\t\theight: 27px;\n\t\tpadding: 2px 6px;\n\t\tcolor: #555;\n\t}\n\n\t.settings_page_updraftplus input[type=\"number\"] {\n\t\theight: 31px;\n\t}\n\n\t#ud_massactions.active, #updraft-delete-waitwarning.active {\n\t\tposition: fixed;\n\t\tbottom: 0;\n\t\tleft: 160px;\n\t\tright: 0;\n\t\ttop: auto;\n\t\tbackground: #FFF;\n\t\tz-index: 3;\n\t\tbox-shadow: 0 0 10px rgba(0, 0, 0, 0.2);\n\t}\n\t\n\t.rtl #ud_massactions.active, .rtl #updraft-delete-waitwarning.active {\n\t\tleft: 0px;\n\t\tright: 160px;\n\t}\n\n\tbody.folded #ud_massactions.active, body.folded #updraft-delete-waitwarning.active {\n\t\tleft: 36px;\n\t}\n\n\t.updraft-after-form-table {\n\t\tmargin-left: 250px;\n\t}\n\n\t#updraft-navtab-backups-content .updraft_existing_backups .updraft_existing_backups_row.range-selection:not(.backuprowselected) .updraft_existingbackup_date .backup_date_label {\n\t\tcolor: #FFF;\n\t}\n\n}\n\n@media only screen and (min-width: 782px) and (max-width: 960px) {\n\n\tbody.auto-fold #ud_massactions.active, body.auto-fold #updraft-delete-waitwarning.active {\n\t\tleft: 36px;\n\t}\n\n}\n\n@media only screen and (max-width: 782px) {\n\n\t#updraft-wrap {\n\t\tmargin-right: 0;\n\t}\n\n\t#updraft-wrap .form-table td {\n\t\tpadding-right: 0;\n\t}\n\n\tlabel.updraft_checkbox {\n\t\tmargin-bottom: 8px;\n\t\tmargin-top: 8px;\n\t\tmargin-left: 36px;\n\t}\n\n\t.updraft_retain_rules {\n\t\tposition: relative;\n\t\tmargin-right: 0;\n\t\tborder: 1px solid #CCC;\n\t\tpadding: 5px;\n\t\tmargin-bottom: -1px;\n\t}\n\n\t.updraft_retain_rules_delete {\n\t\tposition: absolute;\n\t\tright: 0;\n\t\ttop: 5px;\n\t}\n\n\ta[id*=updraft_retain_] {\n\t\tdisplay: block;\n\t\tpadding: 15px 15px 15px 0;\n\t}\n\n\tlabel.updraft_checkbox > input[type=checkbox] {\n\t\tmargin-left: -33px;\n\t}\n\n\t#updraft-backupnow-button {\n\t\tmargin: 0;\n\t\tdisplay: block;\n\t\twidth: 100%;\n\t}\n\n\t.updraft_next_scheduled_backups_wrapper > .updraft_backup_btn_wrapper {\n\t\tpadding-top: 0;\n\t}\n\n\t#ud_massactions, #updraft-delete-waitwarning {\n\t\twidth: 100%;\n\t\tbox-sizing: border-box;\n\t\ttext-align: center;\n\t}\n\n\t#ud_massactions.active {\n\t\tposition: fixed;\n\t\ttop: auto;\n\t\tbottom: 0;\n\t\twidth: 100%;\n\t\tbox-sizing: border-box;\n\t\ttext-align: center;\n\t\tbox-shadow: 0 -3px 15px rgba(0, 0, 0, 0.08);\n\t\tbackground: #FFF;\n\t\tz-index: 3;\n\t}\n\n\t#ud_massactions strong {\n\t\tdisplay: block;\n\t\tmargin-bottom: 5px;\n\t}\n\n\tsmall.ud_massactions-tip {\n\t\tdisplay: block;\n\t}\n\n/*\t.advert-description {\n\t\tmin-width: 75%;\n\t\tmargin-bottom: 5px;\n\t}\n\n\t.advert-btn {\n\t\tmargin-top: 15px;\n\t\tmargin-left:86px;\n\t\tmin-width: 100%;\n\t}*/\n\n\t.existing-backups-table .backup_date_label > div, .existing-backups-table .backup_date_label span > div {\n\t\tfont-weight: normal;\n\t}\n\n\t.existing-backups-table .backup_date_label .clear-right {\n\t\tdisplay: inline-block;\n\t}\n\n\ttable.widefat.existing-backups-table {\n\t\tborder: 0;\n\t\tbox-shadow: none;\n\t\tbackground: transparent;\n\t}\n\n\t.existing-backups-table thead {\n\t\tborder: none;\n\t\tclip: rect(0 0 0 0);\n\t\theight: 1px;\n\t\tmargin: -1px;\n\t\toverflow: hidden;\n\t\tpadding: 0;\n\t\tposition: absolute;\n\t\twidth: 1px;\n\t\tpadding: 0;\n\t\tmargin: 0;\n\t}\n\n\t.existing-backups-table tr {\n\t\tdisplay: block;\n\t\tmargin-bottom: .625em;\n\t\tpadding-bottom: 16.625px;\n\t\twidth: 100%;\n\t\tpadding: 0;\n\t\tmargin: 0;\n\t\tmargin-bottom: 10px;\n\t\tbackground: #FFF;\n\t\tbox-shadow: 0 2px 3px rgba(0, 0, 0, 0.1);\n\t}\n\n\t.existing-backups-table td {\n\t\tborder-bottom: 1px solid #DDD;\n\t\tdisplay: block;\n\t\tfont-size: .9em;\n\t\ttext-align: left;\n\t\twidth: 100%;\n\t\tpadding: 10px;\n\t\tmargin: 0;\n\t}\n\n\t.wp-list-table.existing-backups-table tr:not(.inline-edit-row):not(.no-items) td:not(.column-primary)::before {\n\t\t/*\n\t\t* aria-label has no advantage, it won't be read inside a table\n\t\tcontent: attr(aria-label);\n\t\t*/\n\t\tcontent: attr(data-label);\n\t\tfont-weight: bold;\n\t\tdisplay: block;\n\t\tposition: relative;\n\t\tleft: auto;\n\t\tpadding-bottom: 10px;\n\t\twidth: auto;\n\t\ttext-align: left;\n\t}\n\n\t.existing-backups-table td:last-child {\n\t\tborder-bottom: 0;\n\t}\n\n\t.form-table td.updraft_existingbackup_date {\n\t\twidth: inherit;\n\t\tmax-width: 100%;\n\t}\n\n\t.existing-backups-table td.before-restore-button {\n\t\tmin-height: 36px;\n\t}\n\n\t.updraft_next_scheduled_backups_wrapper {\n\t\tflex-direction: column;\n\t}\n\n\t.updraft_next_scheduled_backups_wrapper > div {\n\t\twidth: 100%;\n\t}\n\n\t.updraft_progress_container {\n\t\t/* width: 77%; */\n\t}\n\n\t#updraft-navtab-backups-content .updraft_existing_backups .updraft_existing_backups_row {\n\t\tposition: relative;\n\t}\n\n\t#updraft-navtab-backups-content .updraft_existing_backups .updraft_existing_backups_row.backuprowselected {\n\t\tbackground-color: #FFF;\n\t\tborder-left: 4px solid #0572AA;\n\t}\n\n\t#updraft-navtab-backups-content .updraft_existing_backups .updraft_existing_backups_row td:not(.backup-select) {\n\t\tmargin-left: 50px;\n\t}\n\n\t#updraft-navtab-backups-content .updraft_existing_backups .updraft_existing_backups_row td.backup-select {\n\t\twidth: 50px !important;\n\t\tposition: absolute;\n\t\tleft: 0;\n\t\ttop: 0;\n\t\tbox-sizing: border-box;\n\t\theight: 100%;\n\t\tz-index: 1;\n\t\tborder: none;\n\t\tborder-right: 1px solid rgba(0, 0, 0, 0.05);\n\t}\n\n\t#updraft-navtab-backups-content .updraft_existing_backups input[type=\"checkbox\"] {\n\t\theight: 25px;\n\t}\n\n\t.updraft_migrate_intro button.button.button-primary.button-hero {\n\t\tdisplay: block;\n\t\tmargin-right: 0;\n\t\twidth: 100%;\n\t\tmax-width: 100%;\n\t}\n\n\t.updraftclone-main-row {\n\t\tflex-direction: column;\n\t}\n\n\t.updraftclone-main-row > div {\n\t\twidth: auto;\n\t\tmax-width: none;\n\t\tmargin-right: 0;\n\t\tmargin-bottom: 10px;\n\t}\n\n\t.form-table th {\n\t\tpadding-bottom: 10px;\n\t}\n\n\t.updraft--flex {\n\t\tflex-direction: column;\n\t}\n\n\t.updraft_restore_main {\n\t\tflex-wrap: wrap;\n\t\tflex-direction: column;\n\t}\n\n\t.updraft_restore_main--components {\n\t\twidth: 100%;\n\t\tmin-height: 0;\n\t}\n\n\t.updraft_restore_main--activity {\n\t\twidth: 100%;\n\t}\n\n\tdiv#updraftplus_ajax_restore_output,\n\t.updraft_restore_main:not(.show-credentials-form) div#updraftplus_ajax_restore_output {\n\t\tposition: relative;\n\t\ttop: 0;\n\t\tbottom: auto;\n\t}\n\n\t.updraft--flex > .updraft--two-halves,\n\t.updraft--flex > .updraft--one-half {\n\t\twidth: 100%;\n\t}\n\n\t.updraft-restore-item {\n\t\tpadding-bottom: 10px;\n\t\tpadding-top: 10px;\n\t}\n\n}\n\n@media screen and (max-width: 600px) {\n\t\n\t.updraft_next_scheduled_backups_wrapper > div {\n\t}\n\n\t.updraft_next_scheduled_entity {\n\t\tfloat: none;\n\t\twidth: 100%;\n\t\tmargin-bottom: 2em;\n\t}\n\n\t.updraft_time_now_wrapper {\n\t\tmargin-top: 0;\n\t}\n\n\t#updraft_lastlogmessagerow h3 {\n\t\tmargin-bottom: 5px;\n\t}\n\n\t#updraft_lastlogmessagerow .updraft-log-link {\n\t\tdisplay: block;\n\t\tfloat: none;\n\t\tmargin: 0;\n\t\tmargin-bottom: 10px;\n\t}\n\n}\n\n@media screen and (max-width: 520px) {\n}\n\n@media only screen and (min-width: 768px) {\n\n\t.addon-activation-notice {\n\t\tleft: 20em;\n\t}\n\n\t.existing-backups-table tbody tr.range-selection:hover, .existing-backups-table tbody tr.range-selection {\n\t\tbackground: #0572AA; /* #2b7fd9 */\n\t}\n\n\t.existing-backups-table tbody tr:hover {\n\t\tbackground: #F1F1F1;\n\t}\n\n\t.existing-backups-table tbody tr td.before-restore-button {\n\t\tposition: relative;\n\t}\n\n\t.form-table .existing-backups-table thead th.check-column {\n\t\tpadding-left: 6px;\n\t}\n\n\t.existing-backups-table tr td:first-child {\n\t\tborder-left: 4px solid transparent;\n\t}\n\n\t.existing-backups-table tr.backuprowselected td:first-child {\n\t\tborder-left-color: #0572AA;\n\t}\n\n}\n\n@media screen and (min-width: 670px) {\n\t\n\t.expertmode .advanced_settings_container .advanced_settings_menu {\n\t\tfloat: left;\n\t\twidth: 215px;\n\t\tborder-right: 1px solid rgb(204, 204, 204);\n\t\tborder-bottom: none;\n\t}\n\n\t.expertmode .advanced_settings_container .advanced_settings_content {\n\t\tpadding-left: 10px;\n\t\tpadding-top: 0px;\n\t}\n\n\t.expertmode .advanced_settings_container .advanced_settings_menu .advanced_tools_button {\n\t\tdisplay: block;\n\t}\n\n}\n\n@media only screen and (max-width: 1068px) {\n\n\t.updraft-more-plugins .udp-box {\n\t\twidth: calc(50% - 10px);\n\t\tmargin-bottom: 20px;\n\t}\n\n\t.updraft_feat_table td:nth-child(2), .updraft_feat_table td:nth-child(3) {\n\t\twidth: 100px;\n\t}\n\n}\n\n@media only screen and (max-width: 600px) {\n\n\t.updraft-more-plugins .udp-box {\n\t\twidth: 100%;\n\t\tmargin-bottom: 20px;\n\t}\n\n\t.updraft_feat_table td:nth-child(2), .updraft_feat_table td:nth-child(3) {\n\t\twidth: auto;\n\t}\n\n\ttable.updraft_feat_table {\n\t\tdisplay: block;\n\t}\n\n\ttable.updraft_feat_table tr {\n\t\tdisplay: flex;\n\t\tflex-wrap: wrap;\n\t}\n\n\ttable.updraft_feat_table td {\n\t\tdisplay: block;\n\t}\n\n\ttable.updraft_feat_table td:first-child {\n\t\twidth: 100%;\n\t\tborder-bottom: none;\n\t}\n\n\ttable.updraft_feat_table td:not(:first-child) {\n\t\twidth: 50%;\n\t\tbox-sizing: border-box;\n\t}\n\n\ttable.updraft_feat_table td:first-child:empty {\n\t\tdisplay: none;\n\t}\n\n\ttd[data-colname]::before {\n\t\tcontent: attr(data-colname);\n\t\tfont-size: 0.8rem;\n\t\tcolor: #CCC;\n\t\tline-height: 1;\n\t}\n\n}\n"]}images/addons-images/google-enhanced.png000064400000013341152214270100014245 0ustar00PNG  IHDR,?PLTEZ[(nIDBE:= ]\[A8~@ ^3z6}4| _2y8 _FOK ]>L/wG+s0x=O ]c9.v` _:5|b ^N>-t>?JbIaO.u<<)o?`A=:e0xafad VU `MA*qb _;:,m*k@Nd `1y^5ZC)p(j];4u&h%h=0qba,7~-o2sFvc98.pPf`[ X?91 ]VgdPWRB]$mT+u5wWH7y2rϯLGy9iӱH?aC;|Y0%p*j(eS7(s&g];87ԶIc"nݎhW>9}f_52v%mМ׿fÚ܂ԴQ@ϮW-s gWA=~5y"mka W@ؾ>б#szʦJpǠ&mTVNNHt-uOy{,TȽDumN>UaPHFGTINeĺӝURIDATxIlaMcj LӈĐD5VzKqpÅDDƥ҈0Xc{p \߳wK̼څx;?J$owF;} {i-֝B~e&ݷF4VP wi|yHK-'=ut~ce]BK[W^|1- ښ6f.m \`{tqt] N7JJ8Юu:/ 曘SKe\gϸ0KڲHz/BYںʶl1cW$/:hӈul]mz =%}8=eƱ寥.|G̴a,V Ӭ0J(+YlwWEyS+y#!.p1"ԙ0tIڈ ҂z~4Bij?V{apA-b{!Zi5*EtC F?9a`1CbҰh#m=!щ5S 8LC*uyoVJ00zGl&:mr!XX{F;t3 CGձ_yyꯃuL E*:;/!Ҙݤ{ǪK[fhsWL4ԧlF[*R/wڶWq&>IZ 0G:Hg >ThǶ9qіR65\PKVeV[3͝NpU-4ڔ.5/Ĺm:}SW54ePO&-'UK,dW\mGn6$O*}XgC 몷֕ތ1LASUJ4#l)|M٦5hm}숫k73M4N%A.[jRM84m8:/W#&z#< &mSFqU:b&SGgh.eܶM{n%Samyx^-lFe[&R6M%eh>n at;+̱u&@.یL1؈8-bʭ(]w)C+~hq*'bad X l t,i]29Uᴍ&.6RGL>[ Dat/&R\.$NF98T'm4hS8^ SS=eOD+D*j[DSN|8 NlGۦ-S 24 xp)EmK`k͍mS+3 s6f΄ukWwʵOuI8GgӸ)h*i8^lc j#Vgёhʦp*+*G@ &l t SIΎa/HjMp1CcZ{䡲6VJLm!>8WO/F.rtތ58XGL!M֬i[l-\kX Nt:D]a_i^qqpL5SS &*tX~/oϖV)]ŋakwDZ6zphϝ[gj ڈCtm>m:q5LmX#O3 }e;br 4sLõ\ڐu5vJ37qe:br \-8[T逃m¹ 7 w %Inۆʲ+98 Nr"88?ʵ[\>$w莥LR8,p ] 幧. Nnqy #f8my.lʖgPywҸ y$i2ܐ߾Bq+09$"3\n(3⠬B.efY$BV(B.+ryE)zy{^ 1p\WQ$_tr2>m_ԅOC ggǗŏezڌ 1eqOu 4$ο.puGv/F(%p,G&q[KյC; py'|`Be8;sۡJ q )k 8`ybvIhM-ALymxR8>~5yҷ6ufPhcoy;1pB]G+>T@ڌnvc/lц3 10яEܟ jq0q۱! J A:ޒS)XFlȸ!CvNM- A\Â.lJ=eXMƍuwhSݎS+8:]6sNqXI&O<Ս?n[F>ԊP9cjE}b9{ nq5ЀC@A{ q+u<a}~7vV4؈C2`{8k;98o*qE(ꎁq6.!N8yW2o1^aq6.!) Tխ 33VSI99]طGjuvw|TCc%KdOٰ*2 NN3d/@s;C6-8ߛ%_rjt6N{ٸ8S{UqQ\.l8m6?nP2723З\"u&lQ`N_\{ 5Sl\F u!*.C#7,'m\ɚ53:8^Yê 0$8c@Jv\pͬ(؀ps~tyܙ^Mr6;3:C{M㸟X?u:3ngփC̋S:Ly:qUq>T8=p5s֥:DhUqP8Y8$Wl,·+Z/xm*)qzh<ҌŹ{PDu5z36sA'p5jb<qhD_V̝{Hfv1cNVxȬ 2ʴ_o38wg JN$I$I$I$I$I$I$I$I$I$I$I$![IENDB`images/addons-images/cloudfiles-enhanced.png000064400000007257152214270100015133 0ustar00PNG  IHDRX# pHYs  sRGBgAMA aDIDATxKv!Lns΅^AIn;HXA:+@VfD fs0w@\KRݿsԶ!^U)†&:?'kmGǏqX AG!2E.8~jl_d)0^gSlz9rn(m@T`C$opm\ؙ]ajxIl!D+29ƑD78[fB=Nΰ#CA]:s]8z6QVP L"lB_W#:M`4C@P0gBp)&˸4!Q1AAΝ,u]?& |zj0R>;8'}_lᆯ`K.ձ 5 A GئW, ~28HPЩ#ql\!:- "q%( 1A÷x{ yx1xqKyɍ!#~>WXt6~ ғl{rig НO7#^Gc͊:ȨxoV,MCvdoF]|ztpƒW5|aATSmdΧuPW3&SQZ- 9èuR8^hrԫIczu_B^`:g*0^;7F 8ce~Zfx5j+}9i Ѝ~5?RThNx~`ݨ;#ޭ|0M_+OI Au"ʷq3jx>/JjO%`p&'' BeAeU[xy|y ?MamΑMa<hUbe"Uh?;p\yu>.?aMÇi-e(W<揦ߍrN<0|o?@^gNi^9|l:{C &]lWW4VtW,s*.:?W*wmDoΕДoE  ?oR~G|y<[ the+ =~hzKTѐAhuSRVI>m.cBA1cM=lv^1sfaSD|BlN";׵ňS'~դl9o>>":d?~-EQXvᆪ% tI9}%m;z4<fFnX%O%:?9-84o f}V:?mz\JHE 7%|hg j>v,j o~VpK_ OYQ3[X0;w{{)M& M&ۊN?TYǚ>S|vN0Z\:(g [S(ۖig|jt6*/iеE_'5R/AGQ^2 =G$AOVGJ\GC8i@Wh,AZiٴM? CT !ᰈj CXppJR|qCor]-u퓥ap ?57_7#hȓDF`_VK-m>>!M*ɵ]ؓ0&jM4,cd3EH Q%}PʿWF ?N?CZ瓏+ B) C $4@ّsT0HןX@DHߙTC G(Po* p$:hW8![@~ޛeܿ@ Ȥp1X-ɋoϝJX¶fLx}O[qVvrW C OxR;G"}T ߽3$ޔ4>t 8o;Tw(4c}+fhxw8ncUS'|n,p-^|qaDW \dEy!m94&G0Ĺgƿ#'LrIZm\-w>u> Dr: 7j4&II1N 3p.3uS4kWc_TfUM@xPsh]ttENbg- c봀[G!_83O-Ͱ% #< @) DQ׿2t5;yؙǽvu.mgQ 4TQ'ŭdj x:Q$6~"f%\#>ﶡRo~2`Y ~+.D eGӖbY gDC ONЄ!t>#[O')$1WʼnwÃ]!K@86?F{s%,2l#IP4$h_Jȷ[bfQY Ds 'h{5g Bƾ;WWo!m~,!~S#NcgZԩU_Ixvbe[MïSY6&!AN9]pP:ӕJS "Ԑ4@iU:F=#/ _Qo-7VX'p<)عڳLih5O:ŀw~i8_Gh3yCи.`hS? |;?4 Mۏ0 h2gA/wyfPn4^Eԡ#RjO_)HN?\ƶzo(Ћϟio(Z-~?;DzYs! WIE݀A$Ngէ8DSL&qۤ%jN{Y%<ۇ|+tIȋDx\[+Z7hz Wb P'N'D$NpAc*cT 3laƐ;vEцaLJ (!:BaF$*?r" W`CS-TG % 6xߘ0N'AIENDB`images/addons-images/autobackup.png000064400000031756152214270100013376 0ustar00PNG  IHDR8X3IDATx흇{U~}__AD(" TtRY""PeelKt4+i~9I>i9ױi'}=al c.(,Jf1P2Y bd(@,f1P2Y bd(@,f1P2Ybd%@,f1P2Ybd%@,Jf1Ybd%@,Jf1Y b%(ln 0p'&--xC g1P2̙)v&]2LusҤyd9-sm-uFUA?ޱʿhD~(쳹ҭS$[^}:K>>dtY(IGW-v=uM A+oHsoWS|ץۦ_='.HxP4F [& %y7 EEe[ՠm4ɋ)u1oDڲoKw̐|4Y'UfK(h qM~QD_$_Ez?iN +$=hhj.YG5'՜PupSg_y P|``!QH8q8qxœ,0C=7n*| % xN0R GJৠ-/!> v y9D s$z6W)dHުV}s B5lҞ#1s#aQ7J9wĖH{u1"07K <3؎K?{0E# \/Q-LLA$zOޫQX813>R͝ÕҜ *9^sȪjaAԫW+lB9gub["AS祕qtNBFTLRnN:d"ҘK7-\ P$kAˍiH6d}nQFy KC^ꞥ(:W s۪W؄r%UyIAAQy^l@pLn\pQ3JԙZLjU,__ؘ~w|>q%l!9Gy z%O"bbԫ8h\pM]ߤ"+ b86WPXXTRF1/"]rPE #Qg6#Z_iT ӵ9Tn0,}2K˔>1,$Ig$&a.ArO7:J.W*U8?>)** JS+J>{ FNOpY Hr}qab45V7W$H&S>uT/+tkvv&]D98kIt:׆?)JaJS @_BYRRє+UjVS{||p)`Y;c(- EU7T^D]D*Kt϶$,ޫޫ3n,&e'#T **uWP* Wk*҇SpDZZ4fW[Cg R%s(ŭP*GC7>#bl%Ҩ(.ɘpF slKOC@9p0! #$DA!քk6v;#[(%P JX鶩pR.L }G c6u -~#Q 1jC?G OٔjmʶB RZD *SBdyJwR N/>  )_?Q\Wf'*3_h26$$6U%~TbzFJA@D!!}9a3a`>AcCDKC5@FAmS 2#VUQCS ߼2\>-,.2(QH#PJ͌ / PP"Iܿf)X{ȹ䷎( RImϪzTzrv妈7(ej:%5dtKDkt'ůwIq;wJZ$%rr [eW5X$&eTj_yU ݋%]^'b:=\4RccJMM*NP)>cKY6Pba odkQEwCy쓙(6}J.,,2XHeyyə7,t0v!pF! OK-I냄")mcYYy %Mb"&qPCl"|"I  6;6rigplW 9 I/={#;~u#>x+MT&yBeI  eP Vb+ PIm!aOmԩ^|׳M_uϤm?*[Y[IF3%R PC9_ `@$ZXXĒOxNl"7 Yy%ܮE@|!$فl}7v: Nڬhh$q]Q8==36.$"DRRDR.K\A|rFf ; k!nYzZxH/(PE@ˑPk5IBbʣGyPY2yNJhl{ KZZ-E VPmhAq acW\r+:Mfb-,E<)9-7 -vgMw=q%TSv̵b78QKpTׇz66\J.rԹJzBBPA;t%'^=ÉKq"@"55ڝ8?X W `Σw\q!_@m#p 6yC*SsD}Um6PR[&`>sip2:wCiyob?H4ɭIkp)TS_NEOWCpPφOkrӡaWjhyu? !vR2:[JCԕgPˏY2xJD /EU#$h;`"RO:}-d'֮"@Q'DnxAAc۠T]h3e#]nA\)75֚zdD0d$h[}_/)k1אJ\ypSs*dۧ)յ:PШΖHQ.G6eCSck3VbQQY< JRT/F_}:Kg HYy{GRvf 3)xfY5+sfND4]CܛNdVUC)~/BQDݣAQZܿP 7MuEA#yړh QO›`'1 ʾ\alTu"*+hR@y޿guP̙c U\ &EDs3RyvK"P;eoJ^(ٿ4BT \+Jywe|V${鶈:!$|,.0sUVP':}QC ~dԈ[ꫨy=uv&8AMC- oPP@Pi8)V[4|֋iޣKCH~#r6?65c̯m{#o # uev5ahK[7PW偵!pI 3#%i`ԨmG%Ħ(RJ+qeQ°D7EäkbkmgOϸqPIV;2kģ#s YP cg;  i_[ʥ I[#Qg6$BѴwS b{k 5$br쯽ObSmdS h5T휓3*-{LXKq$pN ֔`{?6ol[zVc`{-aM5je/|oC$48"R2 "IY}ڏ;9tԯy_|媙, \> 0eM* h#; Oƛb;=~ PsSڗi8D&F@mu7~៎`km5ߒ]O Džh+ ,\m>%L\զK..,X&*bf{)ctb JOjl: w#kZ -Fz(cjn  aO{Fq%8=v :%8]_X@)ʢyj&u 2K 0(n(M,13T8ɨrccze]]}plflT4''7򂤛}./躦U :/D~"GͅҖ E^BVKTJ<0--'O.}ʼnIPՇ~T#KpeQ(@X?yk;DLJLd4?-^˝}-H.srzb'?m|@w\jFEhHOJjt>;sgM)0ǥ6BTe7<4u LLBGDzҮeB,v TVVv"#1'ܙHO@S\~hKB,mH,Աgui:|}&fEUFqIaIX+3A|bP=&;Cǝm!A Ssx1HSU>q6r.5g~:ٳuȗt7ZoBcYմKFLb:  EDcb~1p%KR}NRzzzgD6EOty:\]Rrw?139RK55 KKń%E).1!1)y}MiVHقSwI$-(m蛁~-'4u6( FhVC{lR, g]n,&y &TI.=ϳ"[[3w6ye::L, tȗZw yX5fEQ#v5'] JeRr9T J4z%@XzN$\D j4f'GSw5#A;H\p)/ e#>Bk58QZkM#q4gQuܹi%|*Z%&p_,n͜s9}p(q(:$Rl5(nu7""w7W0AU5K(J )#5ٍ)!4eO}5l753Z:P En+:  ~E ێKzƪ$naK(N`OELJ)Qc!4+F:Vw~,pg4.[CBBBPFݚlW}2J\^əҔݓf-]ic\~tOHÉGK-uRaٓy.w ecT"NQ|=UdM-/\IK& ݞ8u"uf Sһi8-~eۢ☪M6E"0 ZfDB׬=hN:#B, _2{Mw#%mVܥզD9cVMMӹ9T6Sc- Qkp wZ-cK:\e/u>`y -u-(@Nͥ#?tIy2W&T @6 d@[(ESoVGuGhW܎EN{suku'xH(G3s<~L<6.`h hv$;h 0ݥPNu!R-B˙mM6h~*x] K쉵V}ǠX{rP-,:O;]bA;M{q%a7rXl~rPB,˨/J(UB*0˥AIJ-uP@N%k7W8d%!R~ ".:۱(.AJ(4EnQ6n0G,+v*s K\Ej[4NQeFSyiM⫆Ֆ T|ՖuE(-hBk":0C [-D^>լrI|~[1Ѽ䂨OZWCiiHˍ[%vO]-K T \ܹ%wբbK$ oԘJBdڀkK?N=-wƀs9D93ZɥC$˧}1JA.$Z[vC{w,#v~빳9^7J\z<$ak%wVKEBCicWv>x9E.VX6ަz )<1!¥Bs9Cmͪ|C r^K n7F, ¸3_̐Fu;@Xǻ-)5efmK2.?ot~R'K)X^z;wgScc3RR3Ҧ&㓎Oyhm 4̢g;1V;-w!˚G(z! BKzsFBι@*<}k;BIM7m֕[y<}l2[֊ŬcH&KeϒD5FN꫔B׍Z*A%$1ge g Q eɶ,C=2B^YoMhDaf.6k80ӟ1h~^n]TCK-g (C-\ c;x9V:AXjB ^0 |5+ddxm\!*N%%JD7:"܁ ͺ>ROgNOɮOsILjpI:^^:+UE}CAKzYhyHC>vQ/B(c!d,niP%i9t(-²NGJ- ~#$_/=KS$*Z%)sSs~[}4yl x`av;+Wڸc'ҢѤI '0mD".ñ?7ڋM Hw!((Mw3@0 ne7~V5ZZ.W*UU%T>OGIJDiA-\.H<ӣIߠ#n~KtFI%͐ T!2}SȡR;儨htOPbrS뛐tT(TJhb qĬ3_X .ry kyPȻ~əYqIJqQHu<} O 3!:C_7ÉKQЬҬW:.%zSpx蘿A #r -5e|B2>3Ϗry߿M0.%P~.#1ǥ̐8^KQ9 5Uw&SC`!Tԩ%D&1HWXx v}8piwg(׋AYcUV+2mO:Kb\m=° P[,Eex~[r =%eZB xOFQbP"vע$Y@I#>2{_5anv1Kx~wN!; EŏB=-W4 zH ?  g/~5BdDLՙKƒƒc͢- gjw R <["A;,.%1."7<8c%:V<%%&jLV&y@{K 3Gű{(D^3o4>u:@*YLD=j֎| ܎z(0W"2!=`AbaYjB'}Trӈ)i=V*+ǕJJ^RiXc8 A,%|2 H6= &AR >x'e$*P1RVS233"($enr|%Hc^g޴2Jb\.-ұ: }( P1yٷ6l2lA_} 5eظV'](IUQ[.W%XLI$#㓔 JTK?W$MsX2(Nɋأ )wd""#[j`WwB2^vV^LjZ sV.!Uª+ ?D6nӗ::m^18t&ov\qp / AeC`.N( sǁZnkMYzXq/ \^w1.] J^ !XoL_u /NOTk%!)A/3YKWN[j #}{EHp"PW*Yb)'\n+~sի]nغqժ__|Y<#Bf?^n7D|P&Ƹtj(s.hs 4s.d%+.Y5mɪKW#"gӕG>[~glnf熒}NgS+zo V}cWr5F0'Ҷ0NCI̯˷ǹ ˃BZ ҅m<>Z. JBdrCڴ1X!`1ɠ$VR6Þh ;jji$4Sgml;M;@مfiJ:`(rQN%1%esdd;=A"^B"Qwh(x>pp!S2"\X,a䥃BI+hjhYbw?hu pPCJ;q#(JN^ubKQq {z%'fd2\:DF t8A@P0N CIںzh}k)`tD=:~ۗ%H{ըtܓ]s9P%uν!t!/!kp_3AI$č\>N޻К|*A\ݿFQ!lJv@tւ :F kPL W`3UOҵAr= 3 C*,z7 j:qRHLT6S\245A ){/]qם{)"h|0P*x=ڋ+9Y--oe8,b%(,Jf1P2Y bd(@,f1P2Y bd(@,f1P2YeLZ zIENDB`images/addons-images/googlecloud.png000064400000013506152214270100013534 0ustar00PNG  IHDRhhM;PLTEB}jt{~t{~t{~p|t{~t{~t{~t{~t{~t{~t{~t{~t{~t{~t{~ɴt{~t{~t{~D7t{~t{~t{~t{~t{~t{~t{~t{~t{~t{~t{~t{~t{~D8i(t{~t{~t{~t{~t{~t{~t{~t{~t{~t{t{~t{~t{~t{~t{~t{~t{~t{~t{~ڢt{~t{~t{~Ƴt{~B8t{~D7D7t{~ofB=b[PBD7D7μD7D7I}N10ۜD7D7D7BdZOCЬͣϝD7BBB߬ۏ ہoj!BBBBnҕw呮ƗԄ|āBD7AD7ZMHxpW](ɩ|tm@D7BD7{ѱC;˥-iίLM|ӍXBimWzh`~9{X|BD7D7BD7t{~=1ۢ;wFDA3<@=0L?4u?|2>1R@ۃC6-ÿKXWtRNS^[ht+P ɞ& >(!VC)cI50:Ϛ^nڃ |M޷ <ʏ1J?8(ݻqSJ;hXJtpYlbc`]J UIDATxԱ @8( A ȡ?)a uCFv(57T%Xɜ۫ג}!r^1fGc6gO5xjv5Og=p‘'N|DQЫW {GtE]Hf:l ; awϾyƿ;>V=Gg)HZxQ ʣ!)[RU/ _y,R X$J!F<tz+$5JI +sP!<gren9ss=zeEzl_4deE$ xk\seHSPU7O>=$އsխʷ )Ybx'[ːZ)8wI8YBX!We@/N Hxs*OY[?FR~ gY~xA г_c3|nJ/?#]/iyTu~8>*d@$1T @"cIvTABfk̕<&oBRS+g|=!HHifUXr24:YL#B1Kɺc#tnGq*P*8=Kb_K2T^r8Mgk{+-o#Lh/dQAk5UbIY6P1(GH|+e5%)\x"ݙ8$왾 ]Ⱦ.P BORK4% Q?zFa$ݡPU,3-ʣnia 3\ ZXrq#4xQےdSg $iF$=1Ozcd]ۑkMc.zd 0pl֚ "cEA0= p0Iͨwq9f?w#auB才#ZbwJG,YaIjs"ewZ7G1_fg>6Bs'W7GPOW-B T|FT svlG 40E^ai#j'1Vhc;[CE5"ݽ+*f ح)t8GPǫ"h)5Mjz(L;w[5q4\h!55ؚaq];"N45qj==_NyRb;QC8WesE}43zK+lpW|$͂KWbXZFHGwh6C h9A=s;CVG=f!{x_ܳEJ/7w,!nqo,v̓r^wc΃ o-1nPP9wZv#|2%Tv9?4 ;Zx GsCǎKh4 `.9$z;x">LZe$dm%Z![PLePI+СSB 1 ;a\Ѝ &xI7rg7m;Sp~0~#ax3~ߦ^kzt;GD25|]GY7?L͸5s+5&` i>wZݑp>v Ń̠c~4Ջ)x fb9yzр 9ӮHأ~8aA!b) .!Gp;!Ve?4کI@ЇyLί .I4 .A!$ݍ<ϯ.q.3._]U&V}?LM34߉E^ v7U&cc7 rH~ٽKVHTBto*o}sj5.{\l'\Yӈj4_9 $ v|ʵ5$'Wh#yqYK~+LnhtgCØszaȺ-uhʏ\nYBϐcaik㛍k&_jgȆt|ښ`+Yd KPʫT,e zqhC:`0IWH/LФQWt2ΙT*nE"M"h41|-2baO%zΖC1!B!B!B!F]SPK]]]M)8\:r?YUnmHљfhnNVTHAuekZuMeԈ|e^Z*Zص]E0 "5 Шۨq5ƓF {jtz@U`D0w;C /K;^UX5轺VbzhsM)=rXo2.K3J;t?B)Kˡg"[_ -*B77_6LzE@$Qb,:9ui嗪S%4SRTZp,jwk\帟"^BifK(nj*V.KUwSȣ\ТMCԲCV".+W."0D!"KJw'ꪃv)HD RۖC/VaРPxՙ\ba% =vnL/T14cuaµKﴎ'" ]g'.wK^q⇿/<EBuX[Y7@/5GwE{.o B78hFK)B;4f1q|ڶ)2M[_-J^]u3BKHf\? $4ARh(bj1٤,p3Cw(ЇEЗ EN6:."+Lܴ,Y3;SK}:cS:11GƔe >tst:faڗB/o>Ecӎ:Xt"K0Kt)z\rE}dY.d|Do)Z1{bLKSa9t SO%CArFJR:<Δ2X_  R6"ׯA߄:04pFj\t2dh_ӄjC=;Bǣ_C8 6_ ?r>N*44iJC`ݦw{ 28(V^a5?ؠtW?G.z# GA@VD 0z`Aw;`C{ XN)vYhaD^9\Z4}-)ΨGgwtE@? M9B2-OvYH4 6n;G1J);3%Iy!SƬn 0*E׼`})tRsj*б 6;hBS>i`;݌/E(,iDJ n~Ih"0~lo T M -kv o3j@h%4%M:m.CX o M q +,8*[n9quoOøv7e>DtI5͎jO\?fw}2)?%A>>>>>>b_AUUUUUUUUUUUUUU=8o\${;̭IENDB`images/addons-images/migrator.png000064400000007731152214270100013060 0ustar00PNG  IHDR,?PLTE#O"#vv#E$O"Q,O!N5" ##ON#k|ON##kk{k}TNOOQP#k}Egy~Nk{OONk}P)uk~?UPkydhVkxUl~jrOhcPSjwO"Vjqij\h\On|igd6uMRQhaafOe>c*R""ZNkvXim[#j#fF" ePjt` "#NN#ioZhd#MN1#="#"#" #" "   -tRNS٭ֳF 5%Pg1 !yI,m  ۡ곽' LJVE("~zi]RM:,b21XTC7-rnvpiT@?<7Æ"vd]C:&700,}]ilggaU IDATxڱOZQ pzaBMxN$$E ,& ℮mX1it0o{|6>aki|%!B!B!B$v1L92ivkڸ-&1MYðl8HհM7FdlG-LJ"C.OL \bEjqsz;ppppppp D[^\KkMh|4#W9zL)IK~mnNVn.g'm8%Qo\>|bq22,(>n6mnNVyn#uN/q]7*IR;8ɨ蜓fBUjQXغǤ86&xh0mr'NY#̧=cX_ƒLj-z/kAg` 󯽖WNЙd\TI/Y9rA׵_(Iff%gcGvss,cuk[*iE25ҊkcL*~nE2N]єm?+ͺFz_7ck1nVc*FZQ*6o޻U\?#4ftQ_OPjb5uT[룴Zn}A~32$ AD!&&Rz޶s9\_SϾ<8l{owm;k#q;ttC#;xW'(|p$rxsb p\|ԁ_á\:9<{uѢ(VpO_CjpOijB#En/KFp\Ep\Ep\7<8|.?~ KqYDD19qE?Q/,qo\$* 1㴖ˑ2o --[g܌SsƓdyvBJɊX-UY+(0}p@i.ù\;ؽ:\uW6w|?Mk$aM93߮tI>^.) Leph]2)-sEh tb.HThj&^d*ۢh`%ܴH4^>+YTr_]ǒdeBYRlye[e~?kWJ4 l9i0X  6Mۼ%0)&1eppBmzYےc|/citHOR|\gc;mYZRЗP9 vhfdYSpm.b2Bl(LHO2\{Dk1'?3myƂCһ#8C,Ḽ676ꣵ ]YE!d]]|U6@CW{*3?ϰde(۾S^Ư+mOy yCVPzK1)RC<~|$ pp"8NIM`&æ) b)AEay9/b&slyb,=3c y:ߕ/iPpUSÅ9[ ,;O҆Ŏ :.]؍zj^HP'Tķ 7@'#e:󝼱3%D?)rGmRTMgpSdЎD#1+ Ɗ@ᶶ^(bsf)GqBk Aɽ%(Óڠ=4/~QS81۝gpcXnNkbSxtrYds@I< m܃q־.um1ғɎ-6Ĉ 81 }bs ExĴ]q G8X-8Wг'q9HWafEɥ|b~2p =~vB-$ʤo$ge:@ުuS󻄘8h6%C]DrBI 'FsyFGq){* ఈ=ٔP+,|qf y&O8c=ג/(8-& ]|)B,OBW*\.R[&Pi I4 .jɠXފ YQqjI”ԜJj :Id'v&FWkr.l~wvدh'J_W|p8h`b]Wgϳ{+%ʞxk#7F_Ep\Ep\Ep\83=D.i/{3hmgH0B-pOmrʎ[8Pvr > Bile{BV19OR,9b5` cs\0?,o Kn3"=QEMT27!9jLiT:@h:P2uTN;})U3ק-mu6Y/җF%h8"m vIZۉ]uI,. 4og h+ov.yS@b(-yw?}@u7X%M>oa PܝJ$QH${6"'rrvovhҘa̕'~6=YZ&Mew3H>sN7#i3xc<'pa-ִ[@ܢvjm|u/~pg%R#8t}<MF vm| OǴ( YˇPk p> {Jw kIa"s,vW5r]3-l!GzD,C gqy09AAAA: `IENDB`images/addons-images/reporting.png000064400000005511152214270100013237 0ustar00PNG  IHDR,?PLTEOdgVD[^N:KadH^aKpЅWH[orSikG'LD#J+M.RMR3k~HS🪣ДzDՃE]?:.zO=4Fv[gy|x׏x}㼲­iM䐷a~HW9ξܼ۳泝@}cIȸeۀfnSņ^鼧=~P݋rՅldGتʢ±嬕٩⣌n϶Ɏҿ˷w؟חl~dYȬ{j`;RVUGK*˚庢{|Ɇq^S HIDATx Pߺ׍YY%&vMLXˤz0%т.t%Yo$|Mt:Nt:Nt:Nvޜ+ڋ 3Kwط{i7(T6;ȶ0 *m7̧FKui,ȸnSf&Zt2/oۑ dLg 3 <:ps7lg[s6VDu-[AcX%C,0N?;Cc Go=LO(*p'R=qF֓/y+Z&щpS_eİ8DpS8U)Q0{q;13D8IA[VY=H~sdvMMfY7HB:ܵL!v C e eBR!붹%"]͎Ʀp6wskAaͩw-buws 8Wd<'wHɎ젲)Ԧt#ʂC֔k2Warp*?Mnp87N NNqbLk{SNe^:n) gԖL;ubχCYqqZ`"NfOupNpħ PŪ $qdL 6Xi|ֲ~[TJ˶#@ .o"φ!{"'qYtuAtLkP{ p}pYeWPą I.KOuH⦗gpk[K[[2p~sb Nٿ[d u} 4w 2NXͥ! s)0||0<.ށ圻n !Bp(6{tڭG` "0y^I"}?}Vpx) [SgМy]@B97۱9l-8? G4NrƑ_XW!]7>sC\{>?8ܵ.vf2[.Q!5)Rb{!ŤҥS?]Pѵ$%Wi0|M@W?AGKᯏ@u6E׍PMM88l̖JieqvWjپ 4< UE Á R*(ۡM5mh@ m6Ŷ0hG 4'3"٬-mQZ}*d)(!=:[3Rr$ G;Ė?5F KEma( mD9GmDفu-Cm \׍,:y6>pZ[[ȴZ¹HrCuSn22{o延W(<+8RWko.ba? [« ͍=jZqlJVcw]tnSap`'"'FnK^c{\&.!el4诵(L:6Cu?QC(g{+Yciuk2n<# GVjC q`Q#)۵K[&S%t{g8b[atHnMg.%If8v66uwgmdk,Kc/b[I`cJ>pz61ȺŁp?xXcmlQne=.<"ab@[Tk0ڀA5xNlE0Tl cN|  G N3zH\Q70E@ sj=@Pw0r10 t KAЋ:xuCwl$\6|'Fs9k ZPmsȸ`/M"fQ0 F(`@{w0DaxX0ծHe!R ؊Bni2YwbCh1L#gH+r@sqsqsqsWIq2Dqt|{G^▕}.a(ufiwYN.@yHHkc/xl~S5[s}fkpQp%}dgp5/47kD[PQ/ϕSJ(IENDB`images/addons-images/fixtime.png000064400000015075152214270100012701 0ustar00PNG  IHDR,?PLTEOdgRfiPehD[^CZ]F\`:=J`cLbeH^aI_b.BY\1Uil`supm~*exzbuw}hz|ZnqXlnt4ֹ?7ծ]prŶʿµ縀꾙zڳww_ȠܖЕƻ¥؋z̜ޝԁ̰岒HļĻsϹÆlBȾXȽe=TYPڑirIDATxKAgx fz @ AY "TP<T `/m*]8uck}dddddddddddddddddddDaa<+l9~VŠ5h׽|QʐEdOjR2AM֧z!}hSƟq˶˷=b>KY+mk,Jh Aa_;ERs2%^޴6F:T8 #V%RT, ciHxu\M DkQu2*ԛ >8 Ύ3m.Dɥ@gT^?cSvҝ^KckiAg#D]u2: LVb'K=ލ+%<-EAŒx XOՖ%Й56E輀dGI>{•e $%;FM[+]i]B U/?p.Bj v׎=i6T K$P`|۞K7@᷄cT%r)aE߮dWenn̰a#W1~D62KعW -gC'8bnxZl#rKxHv;<۫kw F}K&g%&6gr7N㤏hFBj#96$ZOw/I.J w.EXFNX/6 ]Mt|*q+Rsr Hoӛ;u9z"6)Z> z *Cr]oH@Zϓbm'9h{UF[9ҽs~QЮK]I>JCYaHW+ |Yfw*6r]/f4u/Mvˎlceak"J$Vk#q,٤XΒ$jf$y,N,7P@v]Uϳ='v+^J:e%u|b|$tZqNʽ/l4_m`s4K=<ޭ4$Ad%vIȊ[ӕM80c8WA8QL0܏KrVPM<' lM7Lg{nAjO Lވش< JQZ_rG'rCJiq Ѥ!-LdȬb'-b pl$̦u>i koSd|W]N#8&l35f!b4;=ċȁyD&C{'DE%ְD{]{L p﷛Z$S^S_&]Oc'MoGwEڴ,\ނ=k輩1C:F\L$l`+i{@SfȤ m *uC{Pvw&B9|pۃ}jpObTfq(9M !TeKLjCە6Eaf 1.̂1(QQ T|#KhbUDRĺҙLfҒ~w;|;E +@/5f>wEMܩh#:e'B#ўXv*ˆ1-;Q?(7ާZ$d6{2,ʅ]Ӈ Rå#T0Ao/1g&EQCY4ϊ.C sR\"%=Ew~M v7 .u,ƥTSq(,2%&~łT\Q(KK1~L"VdJ3*ף 9e;w GR$PyӡO굒pܸ1T{$+s[< \wDJ f%;f[ꎉ,\U-8!G2RJֺ0 <ĉ+,4WwK,Si6XjUrH".۹jy4'ιܐJGf2IJ୹d9 vlVMs=1@Ӆ%cLs_C0< } ^/TdbO)tDڥWA:T Q?6!ƽIgMRSD#;Z0F;{P&x ^EZDe7 D n.}M0QnCw 2AXP.?,(6GcuSYyb >Ô䵄ӏ?Л9nW\{(_SzwMCao=GHt B:2NZYEڊ2эz އJea^:m5'ڔ y>_NImv\5*]55# e[69 閟HdϜ1fF+'Xcmlc͛#cٛ;I鯓 s,28.[)jC}J :PW,Pv0-h1#.y =m:X˴;ztSI 1Ck I0e-$`q NȈiS,FzQPs6kVce}70Qv?U<֕P0̴&ų2Ec%9Ši u{\Njb 1DPT$^|TlYlV!'zYP#gkg8Ae**qȩC%ȄEE[4J?vޫ6p+unzx{ElBpX_) gn9-é% dXEfC)QZq6wzJ7,ۇ_>޽C.Y)K {oYJ|o&Uӕ]&6,B\Bnv*eo6]Avi(7V쨛I$Ѵiʪ4*,߼CYMeX|pkd k$TGbN+Cif1ĈOͭ^Z?~jif CƬjg!) B,O>> =%1%qɋgheDFHpos "ҿhsǻåkV9޾◗)dⲸ^^[,0!nnkͶ?Fkp|aJ.8%-zzy  w$0p$ω \xX`DN}}OQYEKB該趶=A7ظ\bhhn蚢Y\dEJR33<Šnz9B4?U\qLShQ9=H$厗ۓǾ*7 B yqx!& 2! ,٪Q^5=)ؾao77FL]swJST[~|_gҬʔIKU^*S_e{p| %jq㰻ğdlzbmFWqx9Ap#.?saqCN7>^«/;LZ&tRNS 6IDATx  g渃>&W%W%W%W%W%W%W%W%W%W%W%W%W%wA`q"X:9j 28(6"^N.v V t= sX/ }mDoc;Nc;Nc;>0 !82̳3%G6Ǿghf~Qt^sY_z7Zw?˫8!qx]/ja1Lis֚ϫmѩ(,z7,[:u}P?K O,mpL.{WEn+Z+Hd#:$zҘ=^%I3q,ÐINT(ͻF)=E;ǡhȶ3ZFͰW̕੖ZQoꏮmh(0 $lBPdb6yCUm5 'd4Da*4$1DbPߦxU2Ǒ ]QP ֣Q=UPUhC \z|.kO4hOmKPz pqqA!'@(Fy>+nzeC{B}aw=ME#z3Et~G*}ImykK ~{]^d}ASn/ױbfCGy1^rL(i2\Ew[-O֒ǼEQqܘcgwfXewaٕkOPP@P.40TD@9@RAPP@ԼHJ+Բ~@'3,;;ywNԶ7^ q; kdh X/};ʿg[%NYi;'GG'qPNǘ$n{#tvH_c7myƦNe GG> !V,@nĵ4&.zF׀L- DG x -\V;$ Mpԅ ̥RR;kZ\[G ]zɮ@8y2PImv[WydsJӏJthkΝb?j_6_0bU϶'kK[_z)󥏗&sVOkwvڬBR[JzOg~w1 !qxP$#faM<7L&Jc˵33nZoR8gFےF[E'.-*-$zmF7nX<ً޹?Ӿ O􄷔x)h3u9C;Np-Q HǰX8C9 DD":Ф8:|;_tˬ#\&LpAxNFωkMs̥ѵugVd3۽ #]ݖd X!ĭ,WPvo I  D A赀jAy -*#uџ7['S(,:t;b䭭r8PȤIL~޵z|1Sep `cp vKz$ !\u7w,4|A׫&{)Ôs/LzU?"'#?,H3Vrt(pE&$G1d]E:?,GGq?ce,DZ@l,frEzeW&JIi['?=A2< p<7|W}yR #AHxlvPӇ]uY#8bXl6gp{w=P3y7Mx)# i̳'r&ϰmy ImIP(' kFyݐBPa#Iv>S_ .VɴpMj ܋m76tgNv#8WPZn|plL08En4sHJV?Ӽj6* .sJeuWye2]F{Λqy5H !oi.dcS꩹ʜGs?f!n O.%лYglecCSC#W5,Eqc]l`;so'.tkME:R#!*8Ю1ñXʴԊe7awnM.<>]oNCڶvm!(FY9I'8UzS28hSb`);t&͘⮕Elƺ19l b OqL<2zTP LD"pw`\&FF?!;IBqX6-ak+tS'NG!BŖS1gG9bhPq{(" {.@g:fuBd&tN qಡgJ[QiTںF7tWoUG#X(4pyXq3^k쇙FkA8 e YQ\:O ŭ4"9|ÊՉ⊀!`ʚrH͂WWX; }ݽc8 H 믿biI04 \e )i 0hTfd{Jǃ<0NKrJxTGEiJV2r2p6'F™;yݲocoe38rr) R )a3{~X鑒"<3+Xx.`epgܪ!E'[ܹUK]vyf=U eD>pXI-ч-)K/6S<.D`<秤 @L c(}9lʊ `fBzu/z0욧op! \0jL4ι2C;0jށOC%lCIQ`~GK$$ÐjR;] ~)+Y05iNVBx7yv <XK=]`╇?  KQ&o)8'{ +j #z% A8AHXA>QTap8.Cr뾠;,:)<)<{ lFR6lo1&s/Ǝ :qgoYBSnxgت9dJχ?Nl c}Aiaai!H[7u~=JGhQS'XsƠu  vϭ|>Tlal0ots.=Z_av&SFn[5#mTFFN9t?Wf'L9@@9gqNްX!`0؄f MvK&*$,62r:lc|zNm[qGqs)l t!G(X*K'kt4-ff;|q抲aG\JT 햹:(L8|9uS9%8cGU5p! &zpЧ xr{y <꣥܍#QCm,endģ~ABF 8i7Ԇh]کVvV3H]I ۼdVw͜QCGpǯ[t2,Q<\F 9#ғi6I+b tߘp.$HF (#iv*d|E9< [Xh^pޚa*=],/66L#\7DqY# 8a\1$sCBsO0>-n+y\@Sw; ]/h0EDS(JaQ~7alPpY+\n}ŏz3@]3l@4\.캡gewװMIgkglddwrR%Q'pEGNy(ΏTr(f&)7"B  a(p#YPk JWwu ( p,4L=Z0qNR+K W#h(j>EW^"DHmC1CVD,GjbD;uaо61a^]PO>a\Djr,4?|Np?8޺uWW^!RJNE[/ETRiK0/))y{5F 2d g=۳yu|>=M9ՒY ~Cc1%fAƻo, syĈf))s g-5 s܇rQk` Pj06/.^.nH"3L $E4:rH?xIkA%RW  Wg,夣<7m^Mo hDNE!Y?5iK\b9k\ky~JÄ9fv 츶hU5BN`LWXt #r9H Iя]2-^$#''qQFؙ򊩙ݐip'p^ȂlMvEo]^zRJIebrj )LbfYɁ]`^1-yDPIW~pfT>`‰KQ(Xkg\K"BN4=m}/MP@\< E }݋ZŶB+iPb|` *Ŷ_{CsM n(['.S?''¬!3ć:rtɥ/>SHQn½$9B)jG'pfFX.pP/4< '6!jCZ]ՠhgo0T=C϶6061tXwg,šIyGW_])0|y֩6[Z V|-*jO^|Vz =q0X/r G& OvKv{И@T;QSS| Fqx\Le Xm3#KRD~ڑ~` B>38RFךI\0RzcV=MEp] ׁ'%ȜkF/),<:=|5:,d%|!=bF<཈0|9Jy?<ggA.- &7q9aHȃ$$;ï$-݂'1x(mxZMk.G/x@.e; )9ӵ}r1O( Q҈WTk2" ~LJJ:!PsD'6G~؈oe=?|7!WC{T &qHK"p ,E: ءuLughz$%2BC9buқL>\#hI48B`tK;mö.hI4G3"/{?F$!}^|VڴmSjFˍÎ E>sf3|0IłAkkhm֦xeJ"8*}zϔR=ls,!ѺxVaO'/H Zɝ}W"FXF7n%Fjyt2Ğ={.ƞ=c"ܻwkeQVfV;*áolYɂza!j=oNV:CA)[D7Db밂c2*^w9Ll QgM&4 o E.ܾ}{kJ[ۧS^o_Zn][Q`@ψ.hz½KBCTrl4}I ?=Q_rIDZ`fOrBqt>zuύ%~W\)Rtk]rr|X"D81m4cwtl=^4h g5e*!=S(pTXYBj'9Q!5T?B_y]hxϴ 7^H ψ73FFMMq>lCS:VPk"~vC,:@dlC(ܬt@{n9ނt Փ\t5$G2(d v# n/E/g%7\dUpW]h1bfKt.)Uhbx,j;ZR«\@3veұ0ltw6,_nzåf<-RѤoș@pv($jFtpઝs[*Cr ࠧ:>u]MіoޭI߅8!g Ex*nUiI2,ҦR[_O{r{Qrv6Y$g]^$; rDH-^/g ~ޜORyŌݻ[v" HDؐ#ۍAO$k!\nrö`'n-repk6Ӄ.b /19&3Cb1~\ΜuYNƔ8) J hr* ̍РoSsRīBy7@ڲiN-1BBQrvFcqRO.~o,R8uhȦnXw ' \<$tx.[aY"0t"v${(.K9b&(in$ B Az33XNk"AEnrt~,&Kir\Wu돴Nx\4t.c>'u"c469C!lb1ӹ./򰀿Q&.p,j>X gd΋?šz7R~ȹ7/DgMw[yl&I(M?ZOЀ3UȤ:'LwPpsO$+`EИ t].vwaVtL?rGo_|4]^z?',ksdTWw}jډy,r{@aS_ -˯ze;+>>~A\\W ]W~u&7-m ߌhmgΜ[9Rޏ+:ëq ~}͹x1hN9s.+vP&ِgcBՔ2bnʑe4"=hܭ[+D_XJ/J/r6hQ>+I>w\ ;npU]nnȺP׏hY D*G&6ٍ&\;{RE7dDtO?eZ\C>&`مJF.NK[qqrlRM]]TpJSR*nMxT{Wl6(z p8lܘ8QQeJ{{{ p<=v5)]hO@IU2}A?YwwO;).6F)ި=֓LA;'uEL ?^eBNZJ]7̝ή*{6 3s;:^T> YF9}P6˻ĝ7]_4"f= PUitC <~ԍp@gw,C|2*Gz*p9-/9PF,JŹV2Xpƴ%R]_07b+6$&[U.y܎66v6 ?G}D J0OINt51BLlD}4 t8979Kbh:yYU5xWj/&FHECvwXbz%~V.yjNݬn=Qo|fcsfޔ\\sFt9m-܇M|𧌡jnó0՝&-{a%BM_ȷl'hܝzhx*)Ȗ'ۤĶ¡bA]@9oUuk E#bAI@Eƌ3Ko bȰdn1ȁeH" ?Y0TM+ÇX䠷0 4 Sf$ ? ,f[ΏX`S W(B ܡg*KHJ*TR%T.rI%K*Os@ v@9999999999999US}IENDB`images/addons-images/morefiles.png000064400000004275152214270100013221 0ustar00PNG  IHDR,?PLTEi&8N/ɱk'지Ľߡ\p.{jOT6m*cG8։Ny<ܘPG7B>41m'ǿd5y)F6̶ﱎJP2-A,q(pSH=t4/,ӾՄv݄odTmXOD_D9W9~*괧ۗlw_Z+IDATxAkAᙀub" CE! "xJ۴ bmIo\ 5ay]H\sxa'øȆY8K|k=q Wq .@%ϸ*`q68냳OX\;=q=38>-gq䧃18>YXq W}lqtK^PύK'XZ?p W ~g\5Ž~yC.yI#?hqK~ ~]786T+M8r?~{ű GǟM&X\+'hmqCpGq&a%ac xN5uAb&OlVO3}&')oqh }bY h& YDٌg#0B'!K FdH$lW9bIC>2uIL$t8!2צ Y_t\oF~%@7i׆kR wf?K/sG:<P7o_0֚`K__Bu sg4'6wH בMf*<=ýwzmz?(>.紡00{+.05-DZ ipUi9H'R8\ϐ4cuU8NU ^Ymw6k#7;١9DawE-BڈjHPܐU8U3RO[ N"SyjMAnui :`'wWevd [ wӜ 7֬Džpё}Wq1ᄗBo-Ab8UxemqL7+fy'Џޮ hlscl B t.αO"\T[p&w*F.- W77@{ӯ53p3θɣ%8-RC] '\ ֐]h.~ys= Re ;"_11p |䎽n}v@ q8p/)As|bxZ|Ǘ2c0.^Ϡ:'( YRN*e=AB<$u*1L,CTP bRuٹθI)"( )tbZNK(kdӳIt'}zj}Zlp&-A?`%*iOM>>FGmiˬ\(-_((((O#.OFM IENDB`images/addons-images/multisite.png000064400000006110152214270100013241 0ustar00PNG  IHDR,?tPLTEQfii&DZ^OdgG]`^D[_am,j(k)PehɰJ`cLbeg$dwx`ecBY\Xlnr䙥ZnqF㔡f!ǸͶkq2ﴒThkgM{@u7o.v}ZTx;лa׳rĪj|~˳w>UYy9PTꡬYU ̾ƽ:; IDATxIo0?K$-^,? m@}V$z@UsO Nʔi <.E<9999999999999999ԀWRk"xӸV=,o\_8;"o{s*K.P3)"V!8I\p(TAQrzQxr8yAXwiyӤJV{H&}-X1 5*!*xX걙g†w#?q]r@)9~Ga ]VjD𝹲|BNΈ\,ʎR rJNc4MXgQäp9!>[0 #|<Z%)9k/BKr'UaHdEt+sZA7*LÊ(?] vw?'] ? fCDXIB]N(,5'hm|<'EP} ru#WJnj&9)6(GMnZ<1#6@r s/ `fX(:IhOrCWj ~ĵ0$c9=aJӭMCa>ޘ80MeȼɌx:7O(Pyz}kПĵlɽsOgb?yM:Ξ.⯖fcO)UsǏ'2ÇI'BܵTqLiVFwӗt&TL36hFCEn%&џkpl&m\M&Ē?G^ n ᗔ PיAĶK Ե5vƣAƠnm16mc$.;ۆlץ춡PWhםyi}GC|<=3.d ͞x2Tr4AA*MT }`0lLt5oQ,7=Q@j 0˧YhMnlh5:u,R`p5-yjq4Nw%kJ髮Nr249sLq/QN1ښIPt`ނ_O)U8N){XER5JA>F:)Jch\ ĕ!* Ėg3 f4"㸙[?>.|B8^E/'.Źzkyw[7*p4O/ZOБ#`cxDqL!88888888888y#dFQ[Xc{A1mLsMmGH7eo? ,S!\x?!5)xTh"5`$`R>v[#BqM䱢Lh+~ >V Cs2"NY hܷ On]u G4LA<˾qR+Mɬ.5saiϸ88&5;`,]+X>ӹ8[0ge%zqġ9WW7*|gtç1Mqp`Q4rB5~\ZS3wuD=M[zf̄f(9הp_a W7YHq-W7|MKk ! [ɔ%Fԣ0[%&_ 'CZ*^T$,vOG;ۓ2#|:!QJCAAAAİIENDB`images/addons-images/anonymisation.png000064400000012710152214270100014115 0ustar00PNG  IHDR,?PLTEOdfOdfOdfOdfOdfOdfNdfOdfOdfOdfOdfTddOdfOdfOdfOdfOdfOdfOdfOdfie[\daOdfOdfOdfOdfOdfOdfOdfg>OdfOdfOdfOdfOdfOdfOdfOdfOdfOdfOdfOdfOdfg?OdfOdfOdfOdfh,Odfh6h5OdfOdfgCh0g=gAh/Odfh0h9h;gAg?g?i'h1g6h1g=h5Odfg?h-h4i,h5g8h6h,h6i'h.g=h/i*Odfi&i&i"MdgPdfji$i#j'Kdhi!?cmAcl=cni%i jEdjIdiPde;coi&V ^9cpii(Zg#be]ueUfGi!XT CdkGdjbi,i%j\h5d `_Xdbr2k(h$gDi*i'칒UdcgAh2g8i)6cqh-i#]e`ge[peWfHgEh/jίɩ뱈}vjeZfOfJEg>y;ӷxeSQ}AgTGE?'IDATx Pl"@QKHޠLfFKN$~,JS뒾YuӍ&oWx-g^ymcMӴԣ8<5&uu>~휦 Jus¿u,!5O17Rp?0vH!40|"⣏)r`ɮOBe ɑ2i`qD:$ʭh构ؔZMm'LV2Hv;nCB uiP;=/릵 Ծj(VXx<ÐMNYf! - &\SzPK/9/~/vU}?5Er4eqMg0~^>!yX݀&^<(;8W ɬBp\UᎭm2t #D_{?Λ.7Vk}}qPT]n:>_tKU 9vB`YZlafh?[ hk$W-U{7P*V]a94jo(|Cw۾o O*8( 71\n$MbjW7oiyW UsVhb%+> c0\[tc4V H7yN;q1+Iͤ/\Fkkž&I-`jEa&HRUV=Q,vD$P\಍Εs{|8ʆ9$qqF3b熁YG$m@p@+Ҭus@x =v1i}k$w!kGcA׍aq$0 O!9XW>`̓VA5CkpVLW>;N+ThN _z|?7_(}BH'q,e&L2 jS]H%{W=v mku3s=AECq&dŖ6ݽڒ}vQQloӷ鄑qv*'CĔȺ Sa_Z 84Y2$8V}mAv*k{dD%DȥTW}FzT  䚟ADŽʭ`/z6rr}N4w+g=~p7ҜE3TEL[F_F^.3d2ZBL)a8mQ1d5k";,R.fzU'*)p2<R Fkj+˲vܲqPꍔ%rdۉ}UbD8(!ߕ7k6R=As_ -#uEaˑI>Gr\N%5#)JZl'r`E`'Hn?-7:L$̊ y?깇Y$p]!o9|~z ß'd.Zn [N2( u_r%`V ,74KlS벚~g !2rArfI9;Y~ RDME9o9.-u\I## H6.Zn${Yȩeͮz/f+k ^C]LZ5%MR߷ k7l=sT?f>u.z&!֡{ЄcY~v013;p Z|Ϟ/K` '+= ܨ\+Drέ'^k(@y!4I33Fݪ/OG>C=?ra\0D ~3Sq<}:uN8 @ɥ*¸]4(([ 8t)0t*T\Nlt3,G:mܬ'έY-صir~'9m^|\[`0alw4lDڤ-&*ԽmPtF1I=<^;#WMMn)`)?Ӳ<):^I~0sR^)Xpi Lfr7gHVu}tʅ'z仉WL7Љp91Ǧ~:l}3akہ)v#*inys1 sb+={!K>=U6=9X?gp"Gy1Sev||H¬ѳyr; t9b~)7PSbNFϱ6/ۼT}Na]a2%PC1g,R=rPEs-Su/?˱VČ@uWD~v=NӬKXtrVR`᭒%Vx*{%W\l‡5 7OkN2 jWX𧯙(74= TkA'î!9l~ř/X4>(P)naW?L[4YpFIz+MQgגlALnHp6@/d2eRPG5r Z8!%Q=-;Uƞ[Yw9@mXY%c@Vwn|-$H<XEؑIuYF-CXRy/X6a!P 6z,dzX}9znH/8Uvp"U:_#κ1ށ cB]xd=Sz:B@Ds> #L~ԲfP3>㌕J W.O?=_0 )X}+RQn 8dPц`ZNW7F5p ݾ(+ru2T$nO"6Kw -,_p47*޽ !ūY7Cn {0O՛Iw+w$`ņ鍽f?E8X~)H9"sf?phdgw>DC#BuKnǟ/OkAicВJ)O~^tEw]wn/*dAK`ƣJbS!:%:S;;o2o[UӅ%Լ!wLHqDq,z-DJdI@qd-شIx%$VX|8K+9?oVw]4(D¬+e/J(r7  c}`GhFOE4x;(4)@T0ΕG18aQVH};vlFͺM9^!sL jZvݝ( >b8YnFIxh'^j$MX28% f W`Z$}s똪&BjwY&;$(_VɶM$'KV$rvJTD^E\/w, (7j% 챒4g{E>Uk%<`A,dSYȊAg!lѼ zPOcnP2HDE27!RU 9ּGIvaʭ:28`[0Ohw6wJGZEn peN6 J#͠ߴ'}$9IENDB`images/addons-images/morestorage.png000064400000005405152214270100013557 0ustar00PNG  IHDR,?PLTEOdgVi&:j(RfhK5aCY]^VPjn߯@9ӡ4f":Р4;RL/K`cYۧ5OF\_FbkKRq1i'cHWn-i!﯊KdhSoߪ6i#θ7}ewzZorUhki\|Aw977ȯ񻜋vh*¶ItҮt~Spc\dag8׽ҩە`ke[fKgBh0*ҽj،?[d|fS۞wxWVjWMөEàEֽr{\a IDATx`v 5 >Kap"dat 3`ᗸpUtC     aht>-fbV 6V8."ܛ~R1پeqԾYF;L R_Iy:Sf7o#QƭHHM&y䚯 '% oVֳ5}id'?Sٻ!n _^vb܊2,F)gTKYd<„WEngEaEa}„ w( NQ*!M*8&\_&ܩ(L(L(„S /+S&\]&ܫ(LOQfL(LCQp00NEaEa=„WS&\_&H1^E9fM~i5c F +)FB(Y4P(% "y\D2f듞vϞ]…x,b d~mEbڌ,\)]YJ* p%H?p0ÉKV*J…0,\(J>7&*8-M'/o;Uyx{!–&Z)g pY)KPx#w3r Sɵw&"ԿXJMخKёӸ^44ps[SDqex ?'LX^ʭDo V Bٷ!شAB>(dkq>0p/⦞䢰UV ˤ6 ] #(d(v@6 @v=Ϲd&Ʀ@ a(`B&1UM&ažUv^^% I.!TTZK/-mYli{<>ofOSK1UR|W$۹+|??&|VܧJx: ²!ؽuB4|]uv(Rrя< Hal/Rn|g\Tv(2[eQ 'j$7`ⶃ[&^mr<ϥEJԺ]"ۺCÄN6aRmWW$\aq2`3]Ckhl7Qd gӸ J ?;=-rfj. VBp]1B܀ih6I1%+`)AؑU8M$E40rct0JqJ ͐ssnS*1\3bei3Q1L.4MVOTWURZ ASF/X0 U , |:LbYFfP b+jTWP%#"Jkun/!t'T_8&v'rl!OzzL#"U7Qtb!Q)|Xq 硅XYϜVg9LMѢd#BGGkCqS[yo˭ qX;":i9HtܤsoS a ғ("ݞJ?q'6M] dDypx?'K}ay߂~r߿&toKcT;P?{` )[rBA?9qr3C>zKqPcrPp՛1QcZ \ךӣrmSΥB`6zLsȥSrY #r3 x5ʵV"Txcy`^*tTj[,7Vr|$9]-DŽ윩WTnT^1]8- yUrM(kΩ[K-cx5v^ʨQ# :s] %e})_ lrOb7E|t}sI`TP"aŷ_ ØWmra 98ҧ%#POr c9f@Pauµ{C/l n_9Kǘ`L?:1p` rwiHZcV%E-6]k`d5# oZ|V=nBI-bWQE^JsOsL3AH렗W2`X IENDB`images/addons-images/onedrive.png000064400000002357152214270100013046 0ustar00PNG  IHDR ߁PLTEJIJIIIIIIIIIIIIIIIIJIIIIIIJJIIIIIIIJIIIIIIIIJIJIJQ1tRNS :ϘoK ɒ5Z+ֈvg_"۸|NDT?1&fvTpIDATx钛0 `8! W\侯Vr- ݝ,;L%"+@!B!B!r^6.H~ș;-d3xiuc< z.C0c̰p/fdX-yuu -x4^ٙFX4)BrN&&fA*X7 Pǖxʹ6Vc\o4܌M?]=+E3g'aM|G0ď e&E94$J8Qbq {*R7ww6l8ᘁ0iA`1>=NaY1|/֟s,ƗflQ&Q-^thq9q #1f(I^ql"@ Ky=lAs:cSi!+UØZ 6M1J|e؂ =Fl V\|s(m+^{mð ? F |+W,?A=N)J(_LHVV ̈́a[&V#ReVCT@Z'5%b_Duۣ2˔獍)!>isTwPϽ,Ǩ;\PÀ$+gT.V$L2؉ HaA+F=7IwV+]#YM;ǯ%ˊʟrQozRlQS/JlqϺɏböQ5TX w=곁*=Q*YK 0zڴvq]'l^R-Pd|I}Tovƾ=Q%jхv=j젥P uTYIv@lcwN3B!B!B!_^&Fw'IENDB`images/addons-images/azure.png000064400000013054152214270100012355 0ustar00PNG  IHDR2PLTEd);t1̘q d .6- yD'%:"QC4 p]GCn2 &쉉^=[07E{WҼdGO~F 2$`0" &rCU ܩ"+lv6͇{4?p{a'M'[oqjض3.8%"0U@X;3!afebDdRw)$1(Ja<$Ii)-lْ𜆖ό~6tli# {/R]Y%kׂz:&,|nOD#9qn #i/85qZUAAfiiT>C9ny*咄ou"Mǡ] IA,i#S[S}Kyy X'T|UW[e\hK6N/JVow5$=Aa4F0N(6"Q*ß}ut޸*X[.4#s)QR0TpC< Jr89uZQNg`/Nj pS_YR6 Yz/VX363BX>Kv:e`.UF;%?WzqBB6Ku:\+Uϒ}.tYqAAfRVHfհ*Ur(r1N%FEIYa˦+4i%9ecf==_ڽ*&^ջwll|jDvD_^m۬ܦ/u)64'6҅32㢠'[q)A0švdqrRE b=HֲphjbZSϩCzQ:k-+3f!{cN2mئIDiW :qѣFAPj̙/<|HA^qQ Yum$C%tc:|hvxڞX xa0޵ׯ?zDA^~uXzU"].ShZv^'چ xӕ[gϝ;%]zcsϚM٬rSZ2FnmmM1œ@  y@zh@\ o]HJT次j Æ"j7;Ufͪto{O.Ѹ}ZLJF͘jjj#+-(@&\)#Db4*3ezO}qyyuQ@VVb;0$;郄ͫ cB1wDzUxufeQQh^Tdɠ.fR)";Y&X ȬB-+cL0k9\Hډ  pV࿌1 7VQZ%]KdB*{]Q#`QAH#uԑ:RGH#uԑ:RGH#uԑ:RAH#uԑ:RG%:vԑᯟ> =cTt- ~}PԳI%Z-u"4i@f8'!1,{c[.KE;i #d2I&{y W9%0zCao}=։-Ϗw=#2r p_ıNu&imc]۶}>MBݺQ64FXgpݿґ]tzȥK]MzepdV@]uw{_ZyS+{]-\b+g>dN̽ i-\kpH;u k^|h=ڎuۂ5:${32ԍ/zَЎAK}8 4S tcfIhrhĵ`TU{_?DDtyK,^<3SKYhվwۄoָ \'b>Z5bϜe'dq2nJhN^b?:KQAH#uԑ:RGH#uԑ:RGH#uԑ:RGH#uԑ:RGH;Z=#u1&Ss1W!K(0laHmVP@ɧVHw[V-2r K#2q2 q02ˤQy'NbO ?)-?\Td +d Fp{B8JR1&Lܷm@dj#>SSY?ָ XwL3qk> r`dj'kr@VW9}7:MdOG{M׫dm;m)Lc.q/:[!(p!ݖNl^va๓jDf5.uJJ#Nf%J.QlLhU()V>_˩ gn߭.lt {lҍI PՎS\x i+ IIT6T%H4z;&M\fk3o8˨KSRdY=0c#.+S''4:.ʐK/x0H-M߾߹_.zUfQ,Zpƌq _~b&~o@ku#I,-MFD$IQ h..O:C ҝEjU\Cr |m 7KBv<MKt6ʝI4m37bK>yւcx?jg~0%y<! ͏):;BD2--[rXz]{ϔs#cc#d|,öε~FW1W @ᢊsnռoacÇy !DMg{Jv}GzͷsԂX  V1*9qxF\mh0Rk^onIYYپ.|[M ߿11j 30dD@wEp :?8nH`pۡ=O~ܔի>SSs]M"9Yѯܾ syw^*_"®$&&",${rzOݿ|Uͫ^?ޜ0*ng߫(ۋVRZk^(ûu+ve:z{VDŁvPg^#L7:ei:AA*b'` t 4X!_I,=gs|6n8qcX`]J|Gw;z((147E;{CONTch<'.-,X$ԇ͞=|x(MZrB&MFwƂX)6lK6fÂh(I]>,n44ǂLdHM5@Z]:P]+P j4`Pxu0uBcOKKanmP::WE$R1̎d;MM;x@ @ @ @ _7 F(`ϊT5Y[-IENDB`images/addons-images/moredatabase.png000064400000011503152214270100013653 0ustar00PNG  IHDR,?PLTEOdgNV:Pegi&;Qef7D^j脯QKk)WVJqCҡ4KadҁNYVO`cLyAL_ijZNΕSRfiM:<_Jbe Р4{EMpBBX\McgDZ^97h$JJ`cG]`T-vF:L2QQَ^.uEۭBm,ZnqG`iyHv9j{~kZ76֤5q3UikOַ˴ޜOcuxP|A7¦[mc[T[μǩdtHԢ4zo|OyYДм|wtjۇYWشϰӝձ̎،ƀTpxܐfdsw]IpCƿݷڪSd`~\S}QП4ǢǵչVݨ֠zyPjMI=ͳՠώѶrӶlazihfuUͦE?4  IDATxM@!9 xrBVhz=TAu}Y=,^DPND*̟>y{?L %%%%%%%%%%%%%%%%%%%%%%%%%2 W&d#C'TY;uɀ,Kxl{k#{8։2pg;y,ӄ|6 U6lӹyZ]r\w\˺CKY;s2\7GvnȌu1"Cge^c'lt.(hv7\42/F39_3s-0G͞G`: [FW~+e.l@~wQ-n9ٸFSۍRi/ 8LJhU0kT.85d $T4ԛu(( "aSw[j(Jzž Xb2j^oPAdžIFQ@-GiZ2mHQ`=ITbdQ1=;Ȍ\ኪ@Ǣh׫J~(mp:f_>[7&ioR\}@l%Bt%k;54FXTQAiA4a>NY9>l [Ϧ5VBbMrln00f;-dk < cEҫXF648 ,_14At|S=֩(R焑 8Q/Iٔߞ_=߇?pj'e<5^nWebOkhi⡳~zg#7B\W cr 72hz˰DupՏk^0\JOjHz#{hO~^%T8Z;ա$\08G8 ^rx`IRbŬåf-a5aePv^t[N4Mǹy$ɵN#蒴ė+6Gm#mmoQ"+nT7c:IVS&x0/>[}*(B:`xsd4&7Nt ˷N#A>CL(k]}#$.dJrU{9MUO!]rܥv/w +IJ/nduw-?qYY(FOYG`CDZ=( NݹӎzS~8P=vX~qb]QQ)â׮Trd jR])ptJ~~YaIl|Dw `,}az2o(MA|K$ ̈́qyt`[I(I ʮN)2*fŐjZQv?hpЅE"B~xrRרJ̢}_˪*4*{))J/?)))))))))))))))))y2KQ?s {hΤzTy͕\=u|t{ws_p{fţO@Osbѯ:r޽3݋am<ҩ]=rtaA 0pkkshMG8- .p{qZ {]N+G04]5]g{Ei .qK}o\c[~97KKܕVoBK-JSȮgAe˜&*h`UI,*ϼkP[+͘ܒ.9 ZÞBi7zo]G'|27aɭځ-CC{LD/95YʫΉ_|otTy DXZdHʣJb'mJ/)e {7~[L zTSAZGhmۉ7sP1YK*|#e  ׎ 0,m AG=pRȧ;\;LMW9~Įt=+;m5y+ I5:%۫-LPWwʻm2ܻ?bAҷ~{w4R/2+\ ,{Sxk Ԉ^8jXڿnߖe yf{r 1p06lSF#:Q;# #i.e҈ތui9.,&zgaވ5 %U*&:I4q{F/OX%FIDZڃ\)[w4sf_\c8 vQZam?-BO]| rc#:cGg75n7;r&,iD7%w'P"9~hp42;zc."#nF C@ڠ!{srEKm{f!JpA;M}:>vu}Oϝ?-GFKѲ:䎌\ߙ,}N&nKhD7 [RZ$iD'rt?T'\D4K-4}4&l%kKvmyxkKwӡ6nx5"$Ȱ+dvJٓ%Zkd߬JobU;q1n UQ,9ښXe5ٴ{[AL|lS54'ar/l2lS Ԙ{jGJbebF ǻǹQ7w~>n1bNplh) W(((((((((((((((((((((((((((((_<#vIENDB`images/addons-images/wp-cli.png000064400000002555152214270100012426 0ustar00PNG  IHDRddGyMYC69[XH*洕3aRO!1vn]bhaᚯrQYh+{hH!F4RB%9ҡ} *bI͐b :?͂NF!uCbĝ}v.O|&9d }.Xh\+,R ÈXEk-.x; }# ߃o"oBkD'_Fk72lNڕ;qKi!p4$Z^4B6EWjW/x.6+A$Ӏ߾.Ut<9Ƌn.dBlre狱'KðZ(*|׆EeWef-G~[//{AY[|b+Y~K>Rl1\(|?#!Sk[V>ժCl[TׇE'fI{-{6ޥ=i-[Mpbbֲ3ZygqcK1b0q G=#i[Z 1l w@lO=p[yǖ|5qNK}f\[\yU),7{nӚ5"UȯpAh /xn3Z1pC *|xqW;B==Ox<O.B#`!Ǒ4Gzoil#`nxrIfXo!WCyyRwrAxnca(o9fBxk Q yN$ 'B|E0N$M H R|ZA&QFP!Śdb% `YZ2t1 lq,@qbϱTKx>fsrrUj&( 2@GrgCru۵"wnGmZ4+T3L:u_9s>ѯwlCl Uy:'ys! Iϴ *5\ʋe ,ír֝wtΙMCk)O+J hoNܒ.HEy)5oܵ @͑e 6V!!4n(䒈! [扆A y2:"Y˰DŽZaX:YG +~.0%P%v@p6RlcUkٞ WRy VjHERڸֲŚ5Em7O KGH>[anVS->폡6t*-'Tժ|.ߕL:O,VJ ZN |{tf{>IkPkO{)Ikє)bWSCKWrk5kǯ@\X>Y;֠ޑ؟D콻Nj==o+wHjS)`3~C{8&&&듈 1n$/!]fb[>XyM$}Z\8NcǠ0h6z,QA댰8DN1O9ysj;'#/{mޘjסHz\׸ĵS_eʔy؀' G HڸyvG`/ayq|yq|l 扆 -X\xd J'j;#8j~ 䊆 *r,g# \ ac6d^߰Ӊ|Jw>pZ~t#?7NMWݨEBkiŹӅu771Y6`ؼ5`s3@_hcٸ6ȯMYeKC#˳ p-`D`,9V +5Vm}=|>3rwVưF48&,50z-b#F欉[1l-ѱ|"["cJsP?(An޵Ԍ% rJ?πwc`c+6r17ȸFlIl$Wnqa`g-gsO1qJ\gJ8 /?c6\,84˨3Lfg¸#Nab (Mtw8:/ WEƺ7no;t64~mj6%mP >ڤxDW ]o1 KP$!S~:OU/q Sj;#1Hc:>-j靮ͬ.9pޙ:ߋ7T]ۄ| n gנּtIKMIm}df@|DwK3iM+&MbS>GLhVآ@?F2?rػ]@VBTG &aTO7\c֐r9#5yZp]ƻokJblou6w1x`?dzt2@xrN~;]W[MgzL7Bulz(&߰ DleddCB´5n+iO5 iMi{biI& N4&UAlp|cr$Ζ=O7> 2k R;!:զq)4\cY,6OE5pO.{i^ ϳ=t)6]KW}h`e`0 wi=Gy1/q28F xeЗ6kboۊ5mDNr9F)F)n6q}؟ְUE͒}f\CYt1 G40}qV${Rlڃ4nowM5ň%DZ~3q.ZDS_߇ػu$-رD7W\k~NdYNM~߽4i~VԸrCE)sB)SL2e ' yl>}Ӌ10q9q ]-+DD;m`kO.yL(㒺C98*.3ur-@ /CܥTWV"4{Y;lx@P]6*08B\:RZ%m~>t՝BTd,x7K_G `] @:TX^@,I Ùdg'C'nԽvRw< ""&`ObN(uZߍM+.]VJ0[AMX׺ALB f+gV +EH%nV1b!6xluIKv>m!nt Pf7!K+&!- 0aaHFך)*Rj_׻?lEhdJW8pe¶l뇽F~=LALͩA$[U[ۡ!\?TCCC1pI:L~ ҂yJo֍HzB`Ŏm .>exR3(RXnv7X2qGlw]>Smq*lE$6&2ȵ ny+~BGS}[,"p]Hl >UfcVy"`t468n ],1h Sm Q 퍴nµ{5Хڽf|V<E>Ȼ]ݐְe$K͂18X-q"㮹moV>S ]gGb*z3=HdJ|[P"Ow*q}x7|%zcݏ@jo:2rUٞdnno*:l=!v9#l[#Xb\sĶcJ|m@o3 7!@|Av. 6Үc{");Ywa+\-·s As)3]gPn@-yD.8H=y!6tTȋT|ʨ9 1jqIGQI;ΎLEB!@b(ڀ[]qdH^%57.1ng9_68gL#Y33st1Uۏ8/&>6= aD<i ]MUyxX3ZN.S b"+1:^韮Eב*8L}GgHM nw;oA.KCW9u-i*r77k]SL2eʔ)SLO~G݅I\ ؛ NئF"p4kNݑC9P^S?rq N:L 2rAPw&Ǐ Ou8C$;C8EI(R sS9̆ωN0Z8ip2#VWn{;jS [9ĆqH_t1g>=ASH23D3՝b|HmBN3 ɻ:#5KI *ZN(s}*nd, u;6&0MO%HO~bn(Yhるgp0's9Z)EYdΛ8qޏ^#$D7"\?TDh2!GA[xSzVkE7Cju"oxNۏP whSo?E8[>.)~1|!9݌LNӽ+]#G@w`3)>vݎfb}mwEgf 4~b 5*2as (F`X]'2Hb!6xX8 $h7$Hb" v 0Cٍg"v$r*&2`C"ԓH8$V=g>pr*6% 4bɄL &VF7HK͆X&@"qka7:GjdewKngs"!E1*Ӊ%s><cqd쭏㉾x<'O"Lc\$S$ x@NF.ԠT}B,2` dctmobz!X%ȻOQ}@`8ÄPw"(җ,2ƢPL'6A}G܁> bqPģF3>`G>oL]>Wty@BAxᫎ/]gmC$3ރLn #Db>M&-䅺î/rBDǓWS~A* }SPQ}R3 kvXC`to;ҙNK?  o'SVm"]eOt@/A iLF($ngQz* bӂ7ܫ- .hzzM ."):EBC:='wa?i #أ>pֈL#i~S#{>!+H :c ȋr=ciƔ:tf/{ F9jH&iI`Dx),b7?$<.R<8;^HUYʣK2NK⊺B'+/Xy&-Ӫ;a)-|lk8tc]*ntm ҇/L 6!2:eBq:GH} N14 Q&R&L1$.:WԘ<퉤&DƋ,VNG'$g5~N>lLѧH㕖mB ++X]{) TևE}.q~$# gmA<ӫ- wb~t%1۹j5r=q@ ,N*!k{?೮~(y|m;o]&Np혯OxVQJVDBE7|]\QaM#ur?F9l.-t*t,'#]B"1+R- &U6Fb%R=IdWf׆K,7"9=ӄ#lPV2E_硺HרC\ ' @J*V*T }JU2U(H4~FS鈵" nI Q:0d#HFE &UTIljQTgIXY %=JL摗Y+U҄RKu汼E\rڍO*נ$լMl[ݺzVQ]:5kS" )H v |]a$ V LuLuyofrmz@֓@P'IZ$S$qCw4?@{>X%ITv؍b[J dz!.JV[)wrrDN KaZ2#_^4[Z&HZ$y֢)I{ь)}uH$X>Uh @BST9t*lj꾑|}//[ZCPVFV͉iboے۵rG]k[L|ذU v>>S+Zy_.S2J[Rn]ϗ n~i0$=ӡ wlK{svw۳)ϴJDBתuu`F#*F}e^U':WR&JAJ|a7\du@;{.Sg(m.iO$AQ1E}qqofl{]ѷqɾ?F콞;Ru"Ѕj~<۬Nҕ}ĥ~Ugq@uowO7FK>1/q zQ@K٧;9NJߨ>$uiއ&R yPu=)?ABw>e^ c1| `qL@CS"*D<<6a X4!b=uai$~8Ǝ q#c(Ha1j% D+uיA .e]*q.XX@$S_n},=a):`UE.1ANرVIkք)Ua]FQq?Ǧ"VQ\%zsq))#쨗qI_._EoEMyߍFSAޣ3.۶IyçXt ~txwjP qKf佻@;۶^OKi>ρhSu]b޷'`^sO<#.AqF:{H{dUATVUwے*t$wt@-L2eʔ)SL2eʔ)SL2er x2ewOtqn(S+ B(S+8D(2e'f4AtQ,{Dp[;ʔeqPU%eʲVtcau)   GP_-e\pDgۀ5]Sl`DLY7_P!2e\Tn2eA0ʔ/d$5CE2_6P?"n*SKp_-Ȗ*Sņ< ސAWʔ+A@߸ [2e  A^TQwX2f#-OaDa5TLوV@3P@၅*e9F#|"&MBkHp`aheŦkcW"~ (@"5 =pC 'XU#m\pT_"b, c 0 Y'v5^m<\ EW"b\&(!33~OnTDo+f8\l&LxÄ ȈXA72?|2jY,r\bN `&Todyh`p~`益ae9^/R=g$*~"P@f c2TVvlZѐS  2 .)^ %dhဿ 0V1!(&ai{ iL|ބ+y"f(3F*HUЩyewf y0@ Qw^h(1^$ۆIE> y%12Z=):bH?@ n9.P$[ B5=+ _ͫn *R^=ʲ YC)ѯsLo; 3fE.D4(6[`0p aX`LZL Uejѐ!fR/ ebonȝb)A8/mFQ;'CYےЈavB"b @ )O{ W,? 3 SM oz:e- pyh,HDR2K `&T~W%}cA>(lxԣ2.'EYʰwdUc%}3 &p B\O.VBkz>&^hǪ'Eۚ=± Xրj7DjX%|'q$pnEb0#WE݆)thTOLۆ"ccXt`Ypc xK7@m!'-b>(dE{A)Qa= 6{Cx ߼w.XA (v}413+zWQO2Ҁ@,2f}W&B7 Co 7ܹ\ŢX- !SO2l[x̃~;2&ɿkRoezSVArE7j"  ʇUSO2+@8vGĺ,nDd_wξ.RM7@:B/JXER#/(i,m,eQDaA1"RBD& w$|( բ s$L9OBm/}xfTŷD|F(>VׇeDXkȧ&0g>i"ua)zN⡝A( 7nUS,y@oޏ`"\ey7*MY"odo8ex Fz(uɼ ǜ*bAf,@2?܏{^=uÿ&("Q!FgE)'V9MjE# MC{_o[(Ⱦ{p@0@=5ێ˞B1Fn1<`o#>Axj`"*qmT bkS>ȸs> .ݳ'lzS=\pM^y~zP GeA&̊O L>@H^ .x?qLL|\ЄSzo{[ ̣>Y<_%#;_A#&PzI3'r̀@!*:~p|U~7b TkL$a"=#O>`V@ BM./ءO1z \L\t_ #" EPcx>O9ƷJZh6x!Q9^n7x7"8]҅o @b$ߋ?,}O!3&W<]yYF~xDټPYxpSpzfOvCNZ ! q#L05*Pq ʕPqs =3 7AR;S2?Qx轣5?鏇dt+K3 ; -;F PSnzafzsXFnB8UF,e(D1ԕD}Wp^q/ pɅqVPSj]zzs f8A SyíF%*q^t1z0 9E.2r^?q}a _Eu7cy1M>祚uO^sGY;F9\d4g8Śb|ǪN1?yݗ CH@n=VXѽfkmr9NY _t٤w9?X_Lp -ei]/gbX俀 bLx|Or@xŕ(y-D瓦wDisѹ *'_nʲ! H<}矗\drA.71DC /r[yhg20S.lr]u[=Tl1Ƈ]ŋU:yW?dQ^i,@AgAtC&0HL/*ބ>̼ߗ30",4g[ :犰񊫧<6 p)ʮkg?(H<x+~ o߁B.X g0 b&<}5?BZ4+ה*9b}PrqZ6:/ =N{]J7x/W5L !6iVE}SK!uºu'f-v4I,gy x;N"{ݺ[ sꩿ]5Csua?[S bMɕk ^|9h*<=S'N# 3r 3Kk >z D  ^=@Hʂ.*/ĥ\tg<=^)ϭiPX=v'Tgs2uwLt!,zꩿbn(O~ۀ[`'7 @NhɩkrTrfx 5͊+s؝,q@\wb n{Lo&!8>,x 怺U$BJ~Q'z,<_7᥸u :aJCAxj^<5P`F2#^!J.|7kM01m[OeOv0x|` 5EW(I> \ P)P":*q Uf?<%VJW<&bkV۾Dgf L9;q6 DGN=9Upɕr |5TDi(*5*Z-bMl5j!0]5jAgVAŚ* ,(@1,E{?E2ֲSȌxsnEaA;nbyaxmiDSY͚ BDPCa̼^J7Ax3ʖٮ\x?J!yKNwTx)Apah&M8DQm hE!g[{6::Y> DkgfBl)`çCė *<-?޼wyt~RfxN5x.ath S;bܞ؟{ػ":{ty}OxovsP(vp6sJg £^uAxZN7o1K!8wl႕ 8-ODB!L={]7O7Wn:z{zv|'Ne/es*> k0Mx5s7AxXxq ~3 9ߍp }F :~S`bד8^Eѿ7}ѿ7|> IE؅ ˳ԃri'͛ 5 g%&w ]S]4{Q& 1/q G1%@x}0avЋ^"j׃*zLxrn唚bNְj*/ J(zV25 b zcz$-Gz{(eE7o EM@ $჈c`508FBctJ9*/DA_` { 6PSvjEbdt֊_aDr gcp78Ə"csXq8V{chHʼnB>z~!'7@xYu{;jܮXPNt*oجIr&:'?|m"q>8JS_#i3La`?O}_kq̘J()A WǃC=&1{;sLteѱb s:>E ClB0/slJukYf-{;)UhLeGbJ^h)_bk:e r.ZtŹ-|k;ބ/|8Υ5Sכ7}bΕܮ뱂ِTK Ұz)sILt| %5н^ ;]-̥2;/ƖYx16y$Kr,IϜ$;Ll1N[;i)}pǢU fDSҗ\Iub-I_/_Eҗ KR ?zOa'\,X` 4ñ?dBgVLiG )v,,F nX`|A|Ez;ELp\v7Dg2l\ɸ"0XzPB=Y|mc7luLk6U eTx ps4j{:,>tpB˖Į 71r$h6Y̼3\#>1ڞAU@)˸yǰwOK߰+jϹx ݼyLtM@XP醼RahiZႦ< \ÕG*&x8.8PtVE=5ʲNm ;b <} hǬ鴺9Z9z{ЩcT3>Fr9MpͤaYprM,xN4Lp9ݿ-nz'CYo"Z/7I78:Ƈ3+uu҇ D5g{B8Ypř gWX%;\?G=vΞU9}Jc Șgx5{wޒ'n.I*!壎!k98ѿχ=8tAs8!s-]Õ#3L<`+p@l=ey=:=`ڟmdo۪Uii-LkLZǫjҕ;M\~ )CթSWVf-z)[me+7J}_+x . ƕ- PWL2eʔ)SL2eʔye cPIENDB`images/addons-images/pcloud.png000064400000001704152214270100012514 0ustar00PNG  IHDR(( H_PLTE;^5H|&,Dچ#3=Wg#6Po "HxcK}Z^lh.)$4rS<ذ>rR+tRNSqFΨl}r_ZVN)' ױx3!긘<50g6+IDAT8R@at0ٳE{bz$f2&|!|V{C x E#?X`wS NPkn=.f \cܶA^q1J,Aa{ āO餇OiAlc@+\X/.Z-uZ,u2kpp!8Z$؍I~s4x-0$l'$WЙ+8bs(<1aT!m҈G$iwW6!DB\8fJFN}5?\K=g -˜!\:^%xPF!$ Xp@j_rȈz2tNLYb;yi ؾs)P7A CiԆSz?TƺO|j4o<ϴğ%5|tk o+2h.FxJwX,$RDzI}PfKǶ}4V$Y$.S2ܿːݮ́-aD ^[&VLmhY`$R~IENDB`images/addons-images/dropbox-folders.png000064400000025726152214270100014351 0ustar00PNG  IHDR9ugAMA a cHRMz&u0`:pQ<bKGD#2 pHYs``kBtIME9*IDATx]y@?ϴ W"p5%Kڐ}Zt-JDHf!,W--_B lu-YZ;S4?g<ﳜys_) ׽ҳӶmѭ;wtR/_Bb4 DGY WON}Hѽ@-vho>Jq`V\P|ㆢظ &&uTV^VtZp<2vN)[V}ZR3f`gllۖR{0?_(,/d>HN8;S X~-ZHmlg'@0Ԕ{>]~mJiaG>??Ydn$f`_- /)!؝;CH\򷴤.4`; 29q R uV]TmJ}VY؁O$yHS>Ÿmbee2 g\|'O@EƍkEϟeLo hk׮,Ӕܹ 2Õ+/GjDμ_дiPT\L'll@57\UJ4k أFQQ0e@Z!Ƹd>Nf/^4uPÞOI٦P`ݻ?g5I:v\nbFg'>LVV0AwTcG/rqyZV֘v]Ν:goYϛ'b0ŅRC|U^_|gF*Bd3,ۼi4ڵ:aaAJ^T7QAxҳ'@"4tqډ/*.fhg%be0nZ:%/a}PV2]O'2a^b"xzx$Nݹ391c(텢 v8C'(Ƿ6=]}Ǐ[r|>]* 5?k%ڝ;Ҵ+QS۴)Vଢ"%-Q͏aAЙRDj{7iC=㏶Z"kkl@%GEVS{ @[Y{bz$oތ-턑zr}|KH W_/4[ !"c:Oƍ'G[_egB8)0?yNRݴ$866xܾ́=@傤-[j&tr6o-kܹQSCM `pb(F#G,]OڼB/^ [G;qϟc+~53AH%Jf}<{%Veě7=z Xo۴ tD+6[q͚Ұ;nXj]v voFʶNw' ,\ωRE;/ghc~pt4e`VwfM۷۶iMzcٕ蠪j&, XB!ڕ9wouq 44'sh@L S"e۶ hjB7kϞAhkh UY1R!+<'L֝?CLM!KJuu…th\y(~h(t)\KjC58|R@@jڢ.fkKAUUa/޵t1Qߍ>s 3UX?E"rvC.Bpܜu[C/_ZMMd} /xѣďEGrr&7QQ SUb,ֱ(,Kbv*-E'O'vaUZnjO}[CU5khy#Vk$/Y fJWWt0$PQ^aaTT(z.9=p p"K'OXA˓ZZuj*yB¿JA`G^Hs0ݻq@[$EbhN<M{*Ѐ;n!ر*N_R.>จ%.h)̙{YE.)z@~ߣXl4[1YٍwPeeg틏79{=|8Jeؾ}MMn䥓|Gsj_ 4$-[[~Yo.:7(p.`Acod9(2 ,.P5o -u\^V[2zr m햄 VWWS(3#hrkn.ź?qvM҇BÐ!("* jn$'(Յ7JY.kp*puÿ;F{3vp~ӵJct7~9: P -OX׮H-~ơ!dl/" Hk N::99~ӧ7\o|oP}f6x8+;;[nҴE듒IPLC:QD""yr:de=|ػHԦ (+%;xOfϝ2g8zS`v>hg_I (C Ezz57'3 f^ݽ9BY@RReyq訤5࡯/SY9໔ MБCjAX5Vik ~;vGuO/ ôMD)6tv gjG*F}~'Nо <kvs}X1}zc±֍8w/JH`Z|%07L$ֺ1Oe=21-ݻuCXCB=`OȠ]RR*-,3JkyiiiS' +v-.\.bY ]M/aҥ/d!ODMySv(vq ϓ O ӽXi_ǎB!~5qbc^Ms̙I$ (b42RXҊ)O6RS_@׻ VWW#@y(UQ|wwA]_Ckw. Ratb"b!]h!KNn>ÇjT` 9 WOyeħa(=~Qpzؑw`uP>ҬlM%rvzYn63@}RU\/n벂F(^Fb.FW?m9D^+vuêUWbƴww2_D닻8Ap[$vvfh%E0--`rʇ- ˭{-TV;Y#[E&^y>$M۷o_E)pe7iӚӧ&#@#"<}QFr**h;K Utt!eTSPi CmV] VnjF+֏[;OOJ)A"^JgnRPt :T)MT%; s0pq}!;zx4K(pi^Axn%%vvHM[[8IbزeBA R{-*.inn;.?j>[p3gA^IO`{w ~J[pMc:cJKkS1ݏڴ 1~`/11aY%$6[,Cg̨t'ΝjI4Bn};Nsrj*e[T`w2>.)DyR;vHʦ .107mhٳϑR]ڶ?mF/^B{{~!(yw uV6E ;ȉQЮl!y!LA$r97o2.~vqdOB/)A3,LpAAϙө;{V ;Yu5:t)?iYN5$DLOe_T֬Gqs36G P^JJ-x|ǏFy9:1y2 EH-221JXg۷ܬYBaR&MU__2"M(Ȱ}V۾]bP(̄ 7_,!UDTh@Ǔ,!DFYC\JUT3W TU>efѤ0Qʘ:+dHt.xM3o=۽{qbK&&ۈ:a޽ʕ߭l!CX]##*/N{Nɓ0aPg[>)@hWI 7oغu1n`,"#!c FAal,^!ɥѩS;P/0gvlqҶ5JjEUT#OO8HNU(zsAA`믌G.kK"++?Y\\:wӽ(4L=p %$6zI]E^QGT1ZĻs!ϏK߲ lO rUמQìmߎ548xPd;:>yy͚5)$%I~~TN2mYK(AY܂(RçeXʜ:+p]$g R\-܄B'$؃Y<7QeA,[TAS"+8r}i{Hxg߾F/_9r%ed$d;[[ SϝV{L= .ӦA~Z&BPL颊<  |?VEyyijjxή]_$< fnnu:꼤2$,6MU_Ǔ+gmG$&6m-B(f8S(2A6ԹgJKqBaI \|Yo]ژUWCU?}YNx` (7fp[}{SENx~S BWW=\|]y~y\_ƏEG^ţ,yQ`>DR4m@) klq/]L '&OEf~~ QR>=K{;gvYXw A}ጙY2lXvSnq`VoBOGEԤ-22nh}VkrQZ**Z͛~0N37+Յg{22E#>}RS%n=,-[D+WYڵ+ub}PXR~Ș1Gsmj3-~iw=CCpg~YP 궶pԂ?y@\.u #{x4yZVfoJ|>ovU&Ԏu@ w05M<2:uӧӁ"=]a11Cc??0$륞c)5IQ_IҘta._ޜMAa?ˋ5?⨹s;'6JO[|%=`צ>l?u*:{[޵ yxa!N9~KAtnhRqj /4B:&p)rmBQF UUPX7$ VD|N\H:[= O\;R ,g@ U !OmgW1}8'7 yA<PYX@>W/$ٓ<9m04DIReXd<#3,>B(_\ryx(/ih3v6MX E_v6 CC)k=\Zr Ν-[`D~>\;+?BmS% tA*T_䆐 Nܻ֭$y z\ܓ4KacVÇ=VD?ϚEicSp0YrAhh}}͑"L3X+`c۶׷"ro)cݭZN9>sLL(e]C&&BQFO :ҁ|:2`x*W䐛gܿA[vJF+akݫV|F1 sZIcϞ/VS lm"*-ZSaFEh ;$Oyb́KBvsq, ΜfXZ2X7o`]TH9ӧ)H[RSҒ_>iLk^@ag~+#GbloOɬCH jJH`gKH p`V#G*2M|]~ee OΎ!!Px8g *҂O+&_=]U-6ϴin }H mmX%~ㆨ;e`ܹ02kC *۷Fv l]~2%ѵ;wZIi=5V$Zcc'kSS<=* ZIEʰatR;"+V$\&Q.> "e * &)bbly5e; >ۖƬAH,V2>httڿ 8w^B}䋎y{ yǗ9;nj3?0r6!$- pٚ.X]\ +m vq$9:#TC(x2R*UT࡯۷0C qԣ_N` W20h - e=21adI|HHՒ@ɽ{:)uʂBAQoެcks㐗u^9QIne@b&BMKꚚ2@cFpUG}}p i6m z!!Z33JȔ @Æ=_Z^Z*H>v,x wr8wGFNwC`MM!̯^ y_GO$Н9a~E@ P AZJ :,] 4a,:\5mhbEԴUxd m: YWeV5l`9 52%]8={HG߶4c%OxIIշ  .V*,\;>vl7ZwPkWo}v.u6WRj!xPֿ?ܸ.Z!8[/__D>٦o Z|]j.wO">$$,Iv| 6}S7|_C^66Jn&ӽd;lQ|;xա޶MkS4ߚM|c PZz:q"$ݽK+8aPdq DG?t租km\رŦo IxA %%l'<ܙ6KM?{0Moߴ|;@Sl6}S+@- OдiaZ`75 P ՘KBpm 7QU|S_MlzMMp|Ȣ"ʆSWwQjERj!fgt67o^eXQ Hz{R& KKE@j ۴m޿eqqB5~u>DRS]oQIЀ9ƌ (KJ]p\z:.^+oʉ;Q^먉]8^vvpྛ%xx@~IM(=l DOߵkK]u$]صY:,7c`N썍II>%gfg MLDE Am[]7~,>c=-&Qm 0 n^̓R35̄(a7Š&FR3:AhH5k6ϯ{ITp⭬`0K<.]߅9-U蘙 n]۷a@IuMB  ky  7V}V@J#N>t:dT%o]Y,DL(?j.uTSwHٲ\5#Np1u!:Qe AVdܷϠС[97oҷ?6!"-o.o_z"!0x .KD%oڵhW@萗.͚WwpMS$:-׮/?_*WmD$>oq+,Ufܿ??z>ԩCH;nTI*;ޱoay捸`rry7#\rtij۷GmlMMX\kj*ts^^lV/_-.]ӧyY"ƨ12[YD_G>e 5J@yy0qh};?-]ܥ |Y֧]ß>{ITL†V7n|<6._V: ^~JjWx^_xEgN$%&ꏲEU2 U?(L=:yfǺK~Q΁ qo ".WTӧ'_zxm+il2D 罚1CP#I=go{zzed$*̧>U4/pڭY# "__? rlhq#x'گZ]Dan.'БSxoJ 9^vv9}<`RE枞PՍo(DGG&N_*";@:1ÆQT׮U-a"=.]R[Y<%GG )IUG$&,Jj %i?`@ѣJwEE3gb9s'LS'"A39mRn`ײ&mz?{y s@6&OW]x,F͛+@~ [tI?׮E,(k^ZnH"q֭jЏјѣ)XVI.zT>s۶cT$=1OV^*=q<{Ved^^TQס)J?c׏(Kh!eAפ8Aﮁ [۴!nB|iN׮ҥK̐F][ 0\YYGcqÇt,.,)+QDBk33uס_ժE?ԽY<7/^TwK(lUBu=Aދo+Mo)PFL0|.oP1 /DبO?7PjDOjy T|6PwVj8ZhUVj8ZhUVj8ZhUVj8ZhUND׫Eʪ hSyQ }D_QOhu& Y, h|~aΜ q#46BneN[ϜQ(A *Z>b{sݻ ml `PmOOAQL`>v,/u˩,2`644 II͛&gd@gg;w-&vܙ{X6mZw:m~+C@..D6>`rhKlif6zeS =[6$ƒxPHOCo+2*ƽiuN"#fj)C͸7=z([O*siv6vʔ]bk҃-ܷZsФ2gYv-Zg@uV^y khH?.5{ K+-<>[W;92\RFJ;66C{.αѣQ[{biӨT2*@5y1x0?uuK#߾ȷoP5i*@5#G^a!|vuEAYv;"bOJ P- 9`ClkX|t2EpL&X%rZ[榣]^K2|¬ ƥ?QpW>' p8hХC=?Y P^9 vf$ԯ_(ݱc\%y}E^^[xQr*˗DXUrK[Y\MqIjhj_ LxNWlX'#2 `?wPg@7nhh…Nxs+Opw QI 2{RכywѪ%2"~Q3)*Jj *Ǐes_ȭ}#XӹsCj㯺u tﮨ|G$%o5:3vPlYa9K~U>]B8̣3bbhBԩSreE ^{=cnX6/?n蓛sv{ܰ0>"v/+ {K˖fܗ dY( e P/,,9;ucƀ3%W}Ç>/G4:+}}ȑ9e~byo}$h4SR}Enݭ9NNnP`;;*G nFĉbOFsfM e 33nˠƲ'm'_.{a],P1rPLlm`EKW}r+YO#}([ls(R~b7h9]YbFfxZP=rX!2:~|)>c#"` hiȈɓaѣ$okfhuP T—/WKe!/ 4cx-Y'TlKIAJ v:聹oH݋;zae4ogJTm V@/^`ڦ(];Ee(+O$FbIWSR?l8Q%l[[D\ޯ(@9U_YC$&h' +LMS??l<=9ϐ$:13VfJ DI[b~)SPc?sVbЬv99cBǒ%svmXڢEi|=~ZPrTTmhoėz{zx qڵq53lAE_ΎE|{$>!ܑ,U%H#3euÆёH|* FpxZ )~=/&#:TQO5d ݼo_Ҳi@ $=']wœ &WWݺ1z/s%m%eLH@MU.nn::vӗ۰!^Eӧ\%"Ǐ[S=(m$DG E$Wd=+u;wrp w钴BC%S"2PY^7 JY h/##$22_?үL^r i/K=q!ͱ&ؙ{Jh\ylGR 7v"Z9qbcyiJ8wX6B#Fp grNmeB žpA ܶMU@ c R#@0YX%^Uu +}A{KJ!I\mk+cLjU?\+H S2»^pMz2ݸܻ@ Ё $MnpŅ&6 hƯ>}BÇV1z4x汱AH[,y䍨 ;66PN?FefJ.3Î7>~Ko|@@a[U;J*Yz{Oeifݽ}{z/_}))c+<1p+L7Lul[Z2%ױ%IzTSQQv݌ƍ SJ4>[SSVRm6Ϟ8 - 32X ̧slhton®c^fCKs҄ȷo/)@WPAw~o|d 9yNA6! &'ͦ[*qW Z[Yc,- /IhnbuUӍ:8 -MXA yĽy2cQ {EXAܣOL5*U ۼ\ß6o^ۛS` ֚bϘA"nծ/[f<35[ΟO,tsczl1`+иQN=!Y9bݸQ9ϹI+ݦW/lj9Vڴ)j\냗-nPPiBEmeWO32  aٯ^=Ç3z{A(.\L=4 - __b/RLJ cT_#R&NN nn:: 9;ǎř: ZA'h qq#GT͗k6Уj k>nXŻM^⧱x={3jU{bjhz =?0 ׭k{b"(=#h`ǎFIиQnm_{wպ!d fW RЩQ29а2ppP۸QWh@ ˫"7EKqqVZP5 }}+*,`Lһ #zz Y ~1:ijՂC'ORwe9q99?s"SIE];wVavQ/w!!/ 8Q_yíhc(Bd Jݵ:(&=7W}z}<`ZF#FHH<oL4E6HDxpbG;%Ib12(ȟ;J p@ÎDkݫiJN?`j*xԈO* wqf"n'wwlkDve5a%'*Y"(sZ[U?= oao׏y d7h bʏzU2+X< 79R 5$q θrE8wLJvvn|%`9-03Zo ]\}uBٲ a'wa@(e) (ojXchحDYZc^y KO۷(;v2~ſ';= Wڥ*jѢbvc%tEXtdate:create2021-07-08T18:20:57+00:000%tEXtdate:modify2021-07-08T18:20:57+00:00AIENDB`images/addons-images/incremental.png000064400000002240152214270100013523 0ustar00PNG  IHDRg &PLTENcfPdgSbiPcfNbfOcfi&PddTffOcfOce:OcgezzZ7KM_fOcfOcfOcfOcfOcfPdfNcfOcfOcfObfOcfPbfNbhOcfObfNcfNcfOcfObfNddNbgfAg3OcgOcfOcfOcf}}X_z^OcfOcefESxxROYEƣDh&7LOcfUӪ@g2g6c[jYmWVSwQMJeLTYcbbd]eDf@QzeQTcd]c_vdU|eReFg9g*Potg;TROimidZg0R|f@g1ʷ9tRNSf"3w˧X [SϴG:âa-'o桛MԹd FIDATxVAᓄD1vgLTWRԖB+c$&JE!:L1#>3X1T,P"öR ,e)KY:mOͩY(}SMcbV٣Ur(1=U2N4<,7:*M^M<ɫt"IQ’u3s5[Jږz\\{%'>#+">E%fJe%iPiaPNѦJ,e)KYJ86T!tqcCd'vJʧщRWFAg^X b+ UQBfJ@Z7[O^,ˆRN0kKwe[EU/F]Y71|էnL$>8)`EϝLTPVgCBM J,e)KYi+-Ms֖14l_| ^A8?ЬOU[Yz¬(fΦ3[TsZf@TQC/twUg0:-um+w5ic$Ru\c)EFP nOJmYRJצC_kwy )wyr!͔~9GEsH9x0'׈;RVVϴԁh{*TIDATxӿj0"q"'Q-d xB3i&C.R=~]/wGS?g:hY\v#˨cjuR'4Zןȥ-2ܮS Θ¯%]5.|'9ڌ[N:9[xtcW4OJ'.rXqj\>bb0q'?9dL{mfw!q!q!q!.3~1{^a( K:c*'[]+II@( unV{boC%>uc.O/cgO-c 'q{Bɋn~nfO4p3 7fn,!?SP@&ǀ~PQ%0]R2JٷeY?C{*+tDO[eM!;c8d2uicԏlib*byW^o~.'Nł3(:.J=,\.h:9MѰL 9wq3)\Hpo3 [{Y3"H\LsƋBJ]N&3dR"0Զ'i;+ b!]+vͷT-3cf};_3i[#q-R" Wl`'"^:¹*;{KȥM#&/!`̩r%=V}!9n¬i #JUR2{)+\%4:\1;@*0l#Mդ#V)noE?ȶ$^v DcuQF8uZVc]ћ2-B-{;z;1!*9ч7A,Kidg^Y3nJ-3 @BF:=ZU3|‰7.pfŻ*B r[J#:K[ c/e&|!jӭsi¦qp.h/+Ü |`Ǩ?}kVNϡ0i@s&FcKX:`,tJ  yBAhvm >N7E"us+"]]70ۇl.~] RsS+RvV%i Q7PFIN)AO1fn 7}ilZ0 e ->8?>X(1ƥZy(Z25A3B 9ȅ9Ar~_@p?]ǟg>rtnxA0r r Ox[NƮk_NJf'Ļxyr{&ܢ>.gt"ӃFvL%R萅OhC人AʐUb)N.zceB( \ sWe:rR|nvf{HKz󼨲cWuΞM"֕>h JGG+vOQ4+Pv}f7d¹ϞDr\91r㇎+]2r4iq3RkSqfIFDV߹.K-]pLƝiӭSvf.m2nY[,m 6<óaŊU@lber^'^ŻSSt9\]1ٖv: Ԯ G5w]IENDB`images/addons-images/sftp.png000064400000001770152214270100012205 0ustar00PNG  IHDR,?PLTE8i&k)_6=e%h&;8+쨁^y*6ﲐl'86m'{*|3L,9(dY0m+GymjлݛO~C30.ǮaU?w:r2.ֈև|-|*m1 IDATxrP@n9<yd\(ՒE?` 9'+Ź._<'r#sթ ঔK.;9_:'\&\&?@VA "ըsmds7uy`9\[~R?7%V'p~aT?h@9_*wyM. mn. fZK==W\i{KnGQi!ٶϨDHdji#ί̊ﵔZnqp/\׬£dՈ^qsDdkH^a|9^(R(ѝzxLWx=f0EUU(;R $;LTy=./,F%O|σH0i h 濄f J;4?鉟F7Jtr<;(Mn2ݒg;lM377=W=d<0<MPnZ ^)Bn`[Y!(5Ӧl9S[rDO$>̀2˭[%'/ϯo!{^ !GAts'%WQ]W0=HMџ]>`ve/ .v>Lfڢ M*Fnb %[|w{ `_,gvrW얯rZA&uS HvvW *Ged]}np#'"NkHFH.rnp#EJuV Ht{=BQ탮i.39-`~6{1)vu@y]_.}07#v4~Og-wL=X@{Zf8|yAk{)?}nXc[ʥ&&rai|ǨQ}ʱ$,!Hp8pQr1*}wqi^Ļwvfps 61VQ*}7N7!E3ܮͣir9pKdp# x .xêbp_plgE$xdZeNqd˯erzp_emR 8_=E;(VD? k\YVeuP_VOSn+W݆M 2_8QO#X6ȣq8RpJ`%Q{D:<9(+YI&n~h"D2JE!xTel])8bYvKxfcw8<(MCmDP`)} ,ݵ7'阭PX ' V&< .d66y E+@sV*U%Rfg8aЁV_ `h5wϠҺ/#.d#b֣Oj.DA)5ȈQ~F3Q2wyݴ-jn"C4N[f]UZLwTVNՎzgB$DA:dT{W~ 4TPkzBOŀC{AQcUmT^0.[Hd-,Xe:t RHV7V;u9U!YC^}udfr;6$3b̾)$;`ֆ| )A.C^i_u%MS/ZڱY[}RvUzח1L| ֒Z2dI;(uh®;ޫWP.J/VjϑJH+ (KqKe.0t9Ӆ޼Q-T09Pd;%5$w"' MTC:x teFcݢS &!Bll>rʊi׬ŠlHF #{ɻ̦CIUo6)x_[m8Re%:43V#7.4Re]G#vz4Cb9,^^9c1cM-s`VIENDB`images/addons-images/all.png000064400000014457152214270100012007 0ustar00PNG  IHDR9ugAMA a cHRMz&u0`:pQ<bKGD#2 pHYs``kBtIME.{ "IDATxy\G_ A(&D5tPP E/QU#f0A#D(geD%5]?hϫWӯ^@#..Xx}p$i ܓqpI GVOƵF)kAJs|,,֥ఒdjIBBk ad_ĵ26?:cFݻ ŝցu2ɿ5Нe֩Ӱ@:k5ˋ3443C)NN8Ey{?+1Dz PdH+~I9sp85l.K#磧..LFV@G2E.7dC9Էѹ 4 85V1n!ڽ&$4M ͥ}5Mx~*CY&*4a61n9- Ǻ:kkfiIc8^}<׺+MB0RNW/g _z|dd[:9y775b;`rсg`ނsJLvV{)8ipqZAV'I$6ɓ9t(aʷ/@K]\#bL@en>#A!;~<- ߸ˋy uZZ\+6Uq=#AK>8xrx3=Mrt>/WZof1jݩSug_@4_?|dbxJ2srHxŻ'NDW+JqvG7cxbΝDɹsd2&&DQQ` Ly=s>-waԪU`Okk֭e-]:a KG;!+iLu5Riq ;kVe_<kk,޻wsYmB~ַ/;DɕP).,c4wݺ7'Oo4);eTBfy3CFF)"b*swlh\^E\+%0:3,EڒdqL&??LB ژaϟsH/\pAMkY ,V\ֿ?/kx[O\+֙dܿ;U֍ k7orXgr*÷,-֋  DTQb]?,"_q r@3#j C^C+)Qǥn7pYzqķ|byݽ{ /AܹhZl,lSpkƌ66TNNb7DyAABl(,$2S{ݾmcT9WW? %ERΜ Y<|xSN{F7r0mO>0pXzzBcb GFӇp>{Vp41JLIDaYzzF&j$?ټy{{\ Tځk퀰yX;th_hpW&9{?equu.-Ҡ/xzWF#2Irllwo/p&?}u{k>Op)) ]^f}kq$K~4MZĠ;w+$ݻ !] WNn$ЯҪiۛ._0r$dl٢^k__p޻/+.W_'EE w 7  wb,.;S^,Y"gl ΝK;`zut={~ثW| ߕƫF4 dWZH}Ih(5wl3%r0wu4喹u4ľV7.]0j ZBc4\kQt@#_‰7ob]-n=;&0t7 Ϟz+W(!]Xrm)GGX)pG% > m%~$ŊLo!\:yk;Zl#r=--{3s&Z[mh: 9rd lmVUxR^ut_MD#Ax$a IŽÇ7xKd Ӕ)pLJ1*ٮ2~\,VP=j9H@kzb83T]vF1 11׷%ǿ}Wn>OmmbG4{]tHGd-1hŘ1dat0GKmm&O3Jݿ_vփi-MߦMK6u@ LUԒU8ϯ)GS`tܜ$GG L}x΂=Nה<ꎩ4:)IYpp~>Ll_bA6&:)tiZ{SNw26m |e^\ zBA9xC[ d@${Ů^-mb; dWW$:h8:rWj ƆtOR…H;;F(xjcА#V j萎NmGH`[H-YҒ:DGo.Q=oW-#p|<j '$CX~w-/זED;c[qݾh @ Coo\=S wsIa5ZŐA(lRƎOaիT9AlAcJIil*@x.kh==z&'VJvvh'ݦ"**eEЉ L?6-SghPf XX@6|B9"غ$EF 0~x8AEoƫc[ yk acT̄ڏ6;8F ##i`6-e0IIH,kÓeqq`UWcWhkj B m )/OmmC,\ JO}pDiUYmḽzTE$ *oWmYӧvq49kkxgbp2}fI23~JEzSN+\Y[PA )@(:Q\P re%  ]ڽx<>gP FFGzYeo!0 rXxQGLLP>_dLj5a,Eos6llCO!%M*5D @-i9#S0$؀,GǶN}߱[\9?Q 66/vMjgBİ ~L!>~PA]:g(6!ƂfaFFSmQQ|L:Ek #@2E.lo^^2}wwUN*C-II$uBLLwcݸlk5|'+VP(ۻ% qhUQ ^pi`B- g!{hxXm #G`/_ڮZv@bc ^D27+ )-E`pc|ttd<(%5$<6b]E",=k5룏!˭E @&*_ 7lnnm42)'2GĹsonoBKPkxACzψw$g ?mXH^E*joPzvd07 3'nE_|;igF]p=(6m{$N7Ǿmwq1޼`fhõk%;\ 9LWʧZ5p֢Di yT{r9Uhhhf֚4h }[A~/RnxyxLqC#!rn.d__-Fg'M%Nzb@QQ[&p=5iP"1_`éimHOan P`Zf,-ۺi1"j755x*ZI}0P3AH؍ 3mM+h)| B!-}-8=5oJCcv5 Ű!2ihm-\\rg}~mR=ᣆՋDR)[ __R{>云aqD7eGӕix.WVb@Y\j*Ub޵>xYM%/ 7Y婭mESď%tEXtdate:create2021-07-08T17:46:15+00:00%tEXtdate:modify2021-07-08T17:46:15+00:00eXIENDB`images/addons-images/s3-enhanced.png000064400000012611152214270100013315 0ustar00PNG  IHDR ߁PLTE  2!!! EEE泈Y󂂂%JJJ}}}```[[[;;;)))xxx,,,VmmmŏhhhBBBȨ⠠{{{xVVV跤NNNB&&&م QQQ///Ÿۍ؅uppp???555ޜcccaG׃ܒ888q222,tttmO6һޚ}=iى(IDATxK@m: %|E$ H?R4ej ugX6 fBe)'+^s nI7ȓ,OXRJZ e/KaNXҕ`E>e5Yk ,ces#NrueIxp?϶& БxdNVDCYDH#k ė,a_Ǯ˜te &yS:I&^> WG$KV KTLeXNIkת30Q ~15x2宇+Z]QoSּ}?*g=Z\U^cSv*Lw|@*&<<֧q%r/ZJ}.$b]~EI ٚR,<s#\†dK\7M|pCa3w -Opd@ey#h4ve4թa,S*68%4UޟLyjX G9s:[{08=V 7mYnEK2V(Y-3j#|@7t-t)sE~'"~:&~dZz*e|ұͦMwd< 1 9{m-iy-iwX8E>!VȓCYx+ٕa8oO~5-ˠ޺,K5S? -~ۻl%kM$4WZ"k3"6X6D;# YxyE ?'d= #!kM%u<xD~ lڗIxa=a8[ zp<]O|;ܜUÜb Zam:#'p6kLgbl"ĸW$y &cu7Z^WʃtOL\z,k wՑ4,4Z^ʭZ+ы&ɌwW B\a]sJe$b3?t{Oaan_u]Yi Փ9k\U,'Nb;W=Iyd )]ui|LsvJNv$nVtӣwD 6 5rJ6,A9ʻ[_XzT܇JBWV].+ citM+LNhv)*bosebfHjyxDFLw](sv@yo| ?7+BM4#'j9,L3cf;&ڸX0O|RsaߙꍸPӓPYZb)2Vs6l#@`AƽQ/oar134[q#*u@I ۰`tT#|I;t.NqTGWPFPt=6,)ͳIV1gӶB !q wa[R uYNalY=/[gٖ ^`JͶƾ !Kf$wXf.JiSX/$Ao%w`Q%4.ﭽ..h}s?BmJ[X`1ٰ(Ts2Xp k[?]_WJXtaV+3WkMqKaqIA֒jikš_Qށ>+噬ѨDvߺryGHԢ Iz $>,Ԟ`-W3u7~[[K.Tfv[^qh[&Y_Qa,`&ERE^ӥ/=B0(9;ܒkxsKE ƧJjnR~Aɩ;/ݨˍgeUY|P>?L`/Jө !e\c6]`Z0Gnm{uMhH:C C\6)[ jFJ\5Bs8L&#CI{:fBeˣa GWpl;b"Ef<ظ /QP nVl~ TI햋 >u嗠\Q 'f/.Kf8g쯬<LF\@\g+6췄Tv2nEnnif㰓TU Hf ?ϑ%zqI.Y2-&@^`]W)kfk4ͦv spaZ"r1+?r wi|au{Q>^V9/IҕԳٛ*n72McSweq 苠X:7>"BA8`WBon4ܡ ֚`Y6j8ؔ)O|\eXwoMdd I'GEJ Z_\8UkDZq5 J@.s8_U62hgq_5ٍ /AhHS04']ߧ8,#|yMڵ 0X2jzRt>яrk0<:ڒ!,VoD'VK1!T9kޤ Y>vkvÐ~) gWΰMčEG;+NgR''H{<x,'KfC7A`e+9N3\`PSgwVN„ %jh~˫1BGJ ;oI^ނUfǗ%I7~Tմ~,hւqNY *`6;WHcWG,2{ m4õ&Tu%99j6Kz,ONru KFԲEǭ<lZm;LGo$qSDI>&`dZ)?9؞`rU+\|-fƑ3Iz’ۛa !H~Cl6snL:K`Ca$sM2;PzŌ|` 1u*j2[!n8,/)X-/|c)BMcUFe4b:kΟ r!^@hՅ3P(V6,,znv +.KKg5%~GKd (1@dt3nO;򧘽 ȋ* ,.* Ȱډjma4]+F$vk\fFhJקV%"܅Sr@E>Y K(pKTh,$ٻLZ-,oa,[kQd\-#y k民V,c4wC{i#okU& !TEx.s6A̢*<2X )XX )Mk|N£ޑؠ֍v݀?؜, cʏD8´7{tOGZ, '%:C̠`6E9nKII6A.+F¤m#l선\ܞ6Qiz*u@҉3i)m?8/_􃃽ÿSO?T>OIENDB`images/icons/dropbox.png000064400000002631152214270100011303 0ustar00PNG  IHDR((mgAMA a cHRMz&u0`:pQ< pHYs(JtEXtSoftwarepaint.net 4.0.5e2eIDATXGXiEh[1xkx`T',aQѝy] Q QxFB~HPD%B\#WYb4k45՝cz}uz9^? q}Sl+O1BU}&~GTwڒzgEo&@"Hn!Sfs\4Ϙ m͒yXMHxHC5N v(>m b~މ0Km$H5xQƁ:/9EĤjӬ~}ޮH^kUZWQWʨ(I*t~t)B=cuK;g24DlmEم~w\)SRpn1 ~u$(X嬘Oe d\$|JxDba2ZhcpWUCu6&Bi؍t\$^nTJb#\lkTgaP8F >1fUx+6ԣBok* Ǵ}zU}]1'ؒQQ0%vpɶ$*GAM}3vͽ+,Iq9<'lV %D0_6stwQVO5^f2՜r^ /4ZXnnA( w>4>; S.7canNHWD/Ft([i[>/>42ۻ zq4WV:7@(54&9//A(/󆏵cjc*ob\rUMa{1 G$5_5WnL(kB Б/ۀ ]*`]4R0X/8{v8vIB M"~tBIENDB`images/icons/googlecloud.png000064400000005435152214270100012136 0ustar00PNG  IHDR((bKGD pHYs   IDATX{pյ?k#9'~("G->@ wj[NӇZm+#u;R+UQZ{/贈@+HS1bxW8B۫NN8$Msor Df=֦"{l~MZWWg_>M4֋r"*+SPIo,y Vu['Z[KUUwکg_FQo֢mѿϬ~ӴtI޴-ػ8ŪiY G#bDv=֏vZ=Wjkku5jRޔgǝ9e FظCr6jQl""4>y ЭȠN%q1y-:,v^8`E1XD*9[桪Tl!mOC,f/TVV G~eP7gK8γ1v`-xq/=By|-mmmXkDcȌC9w料1cI6.yM"Ec|pA3TԣtFpYYrE9l'^k1:sAL%s>SVVVfsK)y c}G%mIsZUZBvy|>&Md]@(K&<,VzvN;)K&9Ds9:ԶΨHޘK/~)8|c_Yx :ОG7"vxm4*qf¤'=æ孑*mP4[&XiW+!-zV]NGo#-lHjIɤ+w1&Mf 㫾59#;ͺS(|APzS_U˧U#wiZ ؎j/ X [ &5:SB¹=n~\9 ߎiT#Lٲ=,Rmā51+AF-F;)kd3 X$pjf[nmG_O=^@6 AU)--qJґG(X&zI1]M^A1SRQQɓ2eJ$Eq7oIퟤ'?#q:՜vK! e3RW[aߝ.3*JьZ\:7-fB AmRWVyeSיf^ "(BIj{7555uRFkx|vXomzW5gșyלhii9c KA|>_R܉{mr9ݙMu"8`tZR*, Tg߈aH74[ڲz%H +X}O4X HќOm]})bڇfvvna(`%JEfn=6p~H}cZ%ڞ[:.%g"$X'. T=Pe[?)턂b ̏/?G*' Z_y{[8D}`PKr/~/֭Ȍ*a) /Q)CM wW+5q&ALߢ)v؈Ǽrbno}=-(-;EO髀 E07Onr`<`}>Ç4}kk+jP>!lH14T!w?HQpkcj2 dȺSheєuZ*qDA1mH@4̹vs7Q9q3np Gv3(p˦]͈NCS:C" HEp3`qDuqf]Vrrp qgG7[?3ur:{z.5k~x Lr̼ :v87wdm5jwuqE]M ܴρ"4{-"L0!(+g2LօJr]g\Y=Ǘ0OFnjܗd??r(Ŏ89b=Xk6G?<9/Ʃm˨UX.dd2ٸb@HvQ.k'N?NNSN| FpZ #JE^DfOMsK"1k6LN$"i՘sѠ\:F!~-slΆdI\b=}3{6#u?$2paQ$ 6?y! 8-P-ZdlLxxUk_d\Hy4E0d@tw[BKB1C~k3&(Ša+Gv UUwrChhCSS&_,b5$!:ߞ)ǩ;3IENDB`images/icons/email.png000064400000002144152214270100010714 0ustar00PNG  IHDR((msRGBgAMA a pHYs  ~tIME+ "tEXtSoftwarepaint.net 4.0.5e2eIDATXG{OA_è3Vk "EZ",<9ǡ/Nr"0slh&dA B샃D"t||L'''(HP*t:MlǡB@b...إR_(L2xo+<`  cٔ! wqPI{&^Sj9p>n(j(p U; 6u)^n0AuPGN9}v)/_M`M2t#67:}vեl$MV0 !+;lكN{ހދkOmJeEp P$AUXr]8Tov^u-6?!ՆK4,!Mp.xz>:=(Z%na&真thCBПІ6'? Fs-eoz3vp Ml7V.q6?:#x4La>HXxDr"V7UAhQbIQGl( `=9 6E /~ІbT<6'n9KLlW_ͮCǮ'4D~`b-b~^7rm ۣG<fLBF cD58μG.p.Cm mK hd vW{br"3b<&%fQt_6a0u[Pt2LEIx\jGK~F(zŶim!L7w`ˋx}͆,`>5ovrwmW״6Э$,q] /9##PpTA1|\G:oo_І¸C 0o yrI2Kv;<_/Q0GF~*Foh( W_B sy~ mXX~n9ER*>f%u3.tæ|MNLSqtdɋ'{X8s8ukVPPDzf'731ttXR aP/-5ZiBt Q xye"RL\Aj1p=[Tމwr{[?7K" ޒ\n/{N)Ϳ",+DCWѩfDlD%'aZ_\>fu8Cz/ I$1+B9߼xqi5SUD,+b>b(JFhhb*RŤTp*6iׇ|TY׬X2 X\ܤ5tr6]Ѽ\ш!չr݂N7r*6&6s%Hf/eШX RDb>cjjS M~B?mjG%\ Vae^@DJ#*ryWT+' MTw>_/g*5Kc?\[!hDE5b-2J"W"7$[L-wl*,i{cx }ĖG'w?!UIJ-o ܽlZr1,3nCF8Tfu-Ǻ|~ lժ[%_/>E+6'? mOhCB@qBeIENDB`images/icons/webdav.png000064400000004372152214270100011102 0ustar00PNG  IHDR((mgAMA a cHRMz&u0`:pQ< pHYs  d_tEXtSoftwarepaint.net 4.0.5e2eLIDATXG͗iTTG{{ 4l# 8DvQ1 DL$1#L4h @ډ?ڊ7l-XK6iGmhAK=ttw?Po?C٤"~: I:yXC,C*1%d0VQ;bkѬƲوYqx94kvͿmƬ!!;Ofu}\(TDF΁w -vHg৉Oz "|>6)z@ @@$0DbEooņO$ R_`*"#0AAAX,Ȧu#DpX|!<RUHI9%nP'i05rf> ynAbL' bh Oi1c}:},:\Iq&hS/F=R2T 'g FJx nkȻ GP)vL'jVU?&O PJ🺶}idᏰG"b5Qy\BO_DJh:a:ЂxڼO(RC@ }^2?0 }}u!36]b(|1;V;uwȰP[Y؆B3k_AvE~s|S3s HHLGF /a߁8t0z>~!'cK`M[鯬` `D ~QW@jlss7_ICnJr ^i'cq^]/1E f7_-v~=h PL x7t*)UbJTlėEz:nrRvc #fĎpY;FYPn CL9%kUQ91#esYDK3ľ1ʂNH϶"qpg)%b"|i+z`itHiRn=5[bz̢$O/ M)^NރD,h\m"qp /[\ĶϷc3_^fTR{zYظdw 4Z^>s!2K{'mieS_ &uAAQn;麇>̈($aO ],leG Dg~ME)9B:u[F'c\]\wpu+kdmg CLoc 9L2kX ;)9 Ȼ c)][d'Q001qV7 쁥%FX`4ͥ3Uj0_H7AL47BֆV77һ(0*!+gɮ*|hoƧc0sV _t\1-Vv ǒ}PD-# i95r+km.)׼bF\&3 ƭPL_)LEBKbfƬDxlwpp 7%g5;'Q3% ^BMX ocb{&+L}O'SމvZK* GK޾hjTbh M-]+h;T*Ʀ9/g[Ѡ1 ͨӆv46%],Ⳙ={6=A(--CKK jT`;}wVܙr=yE[ o:ǽ //O(,<[4{)jtoqUܬFCs!)!)!)!)1G7IENDB`images/icons/onedrive.png000064400000002106152214270100011436 0ustar00PNG  IHDR((msRGBgAMA a pHYsodtEXtSoftwarepaint.net 4.0.5e2e!tEXtCreation Time2015:08:28 16:43:43N.{IDATXG_hWϹ3ٝIćRm4RPk b)ЍH|h)}OZZh (ا">(AmDJhJ* ZƝM5ǭ&M6{{7;{)!!!!!aF^gΚm3-1w/·XՋjԴ~&a-R\0ּW8O*M0nLU."l* mTa6dczI9&[> oF"$d_.]W!0(e1ɧ0Ңb X;i!sl8Lg5ȑ`gvbJ~n(Ohb;I\F_7E/..-|zLjpcOo2bwoIk65WAx.9Wc 9KH˸Z.K1%fD}kA3KWTG(<.Zk򩞫*oK'}?YlfPY2d'郝}˵eCV%KN',y]x4>WB*on,Q}}B{V?"cv3n?6Uڊ%bY2 ^«on!zaɉ!"# Z(>|*bg,6r,*We\[0^wJM(;[%A]h19ڬ1Xݪ"3]VaHJMaCJ/i2:PeN`KڬRcBi0wxv;F!9/BzdW?G-6}BPdv4US]qw+2݂폍(/8x+|pʨ4QV8ܯf EB{IENDB`images/icons/updraftvault.png000064400000002572152214270100012353 0ustar00PNG  IHDR((mgAMA a pHYs(JtEXtSoftwarepaint.net 4.0.5e2eIDATXGX[hUmE⍢4sd&JDkU>羛K:-hAVAATC} 94ZA+'Mf&|A2|{g}=)tSK!r2/1 Ǟz\lmTkxw&z+b,4M<]Jui(j^?׹Ԑ>G^* wj<h)nz~M Z2cFEܮ|'[XʸX<"+G{C:hWF8 4S nf*Zj<3J0HvyPV(\y0S> Px?0;L̥y(0,n0E a/Ӓ̏4q;oyx„Ϡx v_3u?`:a=S~{wcS7wOf/zynA ꤫a4!Lj_j S#`?XpBOF]c^uRGJt3I11Z]|kAgH qM̠!#}qFjøHwC z o4!Nˣb.Ba IiBNf/1 E"]>iwݎףovOt3#h!}ŎQ)C`/Иhx]6.W:IE^ ,.V޷]Ӭ)t&xcFFE7b+CCq-!4895!so2/fVhٿAc,,c8-E $wL} ;-lfh!;@aU[HK hCt=H{ڣF֠ '蔼iR~AvǦ:*k`9 ))yt(.{?LIyT\z&fz>_tpw[y\^wܒe9= Q?6(&1>y%!;2 ܑV.]hGC{5v68P'%$DiKicG_e=PRBqi% lD؋q]j2>-$&Ap_ KE6 ;Mg!$]eCRcpQ|¬YGbj+B5:a L_+7AZudʐs´>w!nYG_?=&/x59$_]AW[P&tQ;AiMfJlLƻzZn61 ;nA|ByE& n7z4`9 _~~LGOQq|"jԡ$QrR ǯ=%c1]n~.հC:*@Xg6CG]?ޒwY1d`G ugr(C]N!b5ERԤu6K՚~fYnV y<&+GQ]m!`ђ~Dvy S-s7K]b$t=+|@FҲ 1dOV29 ڴoD_Ҽ4s0^y9|~ mlQPr U9BQ2+IENDB`images/icons/backblaze.png000064400000004501152214270100011542 0ustar00PNG  IHDR((bKGD pHYs  IDATXXkTSWIn< G0 >+ZΌu9bUm;u:V;cՖ.S]vٙh*"(PIB# DY|g}>g_Q~3wʙ]hzi( P6{&oJq7ʤ7z5x 1;:>, ]^fv T]`YT>p#ns{e yIwȜv чSs)x/jM@-5SG:^#) IqN@IV!U|74EYw0{6(%\{#5 PGjkB= O?[6V  @n~g5o0E0H8>QRQD-L^ pJ+F ] ?ff Jl0|nT/x+vOkbN`0'U^wE$m)/:"w+"w@Ƨ *XGLM$pɬ#ONO 8+§]Eh(:E!oxp9폘=ӝ֒=VZ6R&4@ш>8ەg]o.3[gbi rcR?6mwqg b:em`2-6;A OKN(Z-pYKff/PGḐK5 q,b,ȷn $(lLAI}k/l eu.9 dv5A 0 yO&ëw(cy7 [4YK7bbx#/)x$r51OLF'H`͜M70mvCnɳN`o FNZ_R< pPQ@MǛ2#cmG|~gHܲ]>EJ 0 ۉeg/MaY wD.%ߔTxJK Ӊg^ -y+mdUDڴ̊f̨t\JnXmQ̂3d0-#<, CkzG`EbS6HjVl @̖dD}zbLbVA$Zˈ 29 IHo:G\־BKln1g/u 1N58>'(JX(+ a&4e8.׆$]-N6@\KלzZ⪭YeN5ڷTŅC;4ufjEZ,.@U龷 GM nئ,zPmW>MnziCν ;;1ffmposD@fNM?ewIh,+"#dPGL^|ɖA>Qݷ AZA2*nந:;aF W__1g=ėVqin "t~HqP4c \`] Ti{bL!RZQX@6+g?u-8V{Uq[8_C r}fK`JڼBL}cz}w#}XerZEPPI^& =TN6VҤVJ~4W郚n\*'Gjb.k{.𫲷~Rfvr3!?CR41|yh7܀@y2`a_*^*Mc%9p 3 ʨpME82t ADl{*TwAШކ>.Br#hέnhzG!Ir7[M!p) ~;7D[1E7X) -UH a=X0/5ȷRHoI'$| nExJibh =^/==2Ǐ;29j}ppUN<$@, $=$ssuH@caZ}9+WCAf֕-\G~IO3\/@R#!):j˭?3<IENDB`images/icons/dreamobjects.png000064400000002154152214270100012270 0ustar00PNG  IHDR((msRGBgAMA a pHYsodtEXtSoftwarepaint.net 4.0.5e2eIDATXG͘iHTQDARPPԷATFeAeD-hbIoҸZقib:Yfen{}s&;ssߛw V iM0iM0|jZQáwDG^oɇD=X:l6xa:Q% ^Ŋ~O*EffofOx;u-E u "G;]..'pF; HӁr̢B=B※e0-2c%٥<.sB=Jq vS^;Dur JI "Il'p-lH ^gI  8 % `"~/i1nunT\@.T`YB:";wbŽQqiL7|h%mM񦎊Ia K҂1Ye~9PBT&OU ~ sORyB;y iA[Bznf`ʱ4X>IIyǚtq׳ذHyԭ$ph.;Bn2TxHkh&ņ#oqZI'B#P\VIʲ,/jpJRRyr$ <6C~CG{7)ߔ-9,]m kb|pdIZ=úoqPt JUw KI;ФFwq )LO“d, 0J S੸\g vnxN#& ,~Q͔83 I4%pV+?q+_,)@]hO*b|[|qcv9{TY:D>G-)kΩw0!L''eUrSt+[ս~Nk&N?G&nIENDB`images/icons/s3.png000064400000002066152214270100010155 0ustar00PNG  IHDR((msRGBgAMA a pHYsodtEXtSoftwarepaint.net 4.0.5e2eIDATXGWMhA.&Mlj vŢXE)7K{.z xs UMICKoEA{=n{i5m M=ُyH®ݓ’x<$6BӟeQjі̪y`Y=Ǜ]g[>P̹]{&73L@XiDT{;+L9˭R[fmX pMFbM$|$H`,L&e2$e="ZX%wB!&3gr9˲[S,C%;~p O;[`׼)`}s.Ba+ϒK%P sxfűMp0@-i|MG[j H){Bb">TlWo ;yiqz;zS;zB0\xez;t) H//eqKқ/pa0'rtv( r"Ϫz!xT LpVGhd'% XL7]{(ScJu+ -@]edr>q5efFIbŭ+n}Q<-E`~ptvǚ8ӝ{ )>.$ni dy2ە!qD5@ G9!Y A>Hxb;_^J C Cݳ%"}  fH^GԔ!nIENDB`images/icons/pcloud.png000064400000001704152214270100011114 0ustar00PNG  IHDR(( H_PLTE;^5H|&,Dچ#3=Wg#6Po "HxcK}Z^lh.)$4rS<ذ>rR+tRNSqFΨl}r_ZVN)' ױx3!긘<50g6+IDAT8R@at0ٳE{bz$f2&|!|V{C x E#?X`wS NPkn=.f \cܶA^q1J,Aa{ āO餇OiAlc@+\X/.Z-uZ,u2kpp!8Z$؍I~s4x-0$l'$WЙ+8bs(<1aT!m҈G$iwW6!DB\8fJFN}5?\K=g -˜!\:^%xPF!$ Xp@j_rȈz2tNLYb;yi ؾs)P7A CiԆSz?TƺO|j4o<ϴğ%5|tk o+2h.FxJwX,$RDzI}PfKǶ}4V$Y$.S2ܿːݮ́-aD ^[&VLmhY`$R~IENDB`images/icons/lock.png000064400000001512152214270100010553 0ustar00PNG  IHDR(( H_PLTEѰ켼✜|||uuussstRNS@fYIDAT8˵z0jDId1v<$?[I[r,s_?>!@:{gMi9uobҁRZ~Dt¾pv|vx+۷tRa_>ԫu+^/iFxj@9Q>V0|޾HN{TilڕOݏY+Wy+PTA|"޹;HQjVR"tȟ[,[P\JegJ("/\F@@g!ɶHBӝM} MGțXJ"lycV[Φv` +gP""@ d?XXxKn7Q -gqS,ᰅ-5d8| 3ֺ(W I"[ǂdZJξe2/)r|YSJԑsd MsUq%|)pNLagF?AQ,9-/xecc0W d* ҡTQ-yo@7=y)˃,ZusDZs44͹ mM(^ d8E:KIENDB`images/icons/folder.png000064400000000770152214270100011103 0ustar00PNG  IHDR((msRGBgAMA a pHYsodtEXtSoftwarepaint.net 4.0.5e2eiIDATXGӽJP^M@:;%XAPz΂PA+%-dHmArz^p~˟$$52rBFN 9!#'d䄌1hк=NHN kGw+Y0K30w_F`oWo v qEOGtkω|߁,r5>ʡ3T":B]7)!ԓw~-%H102U-%;q^Q$ttttt#] a qZݢ^5tWG d䄌2rBFN 9!#'do3IENDB`images/icons/cloudfiles.png000064400000003360152214270100011757 0ustar00PNG  IHDR((msRGBgAMA a pHYsodtEXtSoftwarepaint.net 4.0.5e2e!tEXtCreation Time2015:08:28 16:44:344IDATXGŘiEߞ= aP\ ,AY "?0QQ1?C ? 1F%]e/EdQݙ}kg>ɻUlU_U}ոHES2IM#9|r(7ASQg-u/bjI\ь+pN1r) JRkL-`ʯuf.am?>k;pօZ9 ئPxʡr|Ǡn:fsP ]gPqhETDBȩ=m[QQ҉2: ./eџjY{Lrm>`_5ͷjP̎ 6|ݶ w2~90ٝ&wl̬cbНC`bٻԚ٠ %!J5˻gp-aɨp |Va-S =ŝ 5|Ъ"95(AJ[PVȴ\8R^I^rv-2()a {OF8fb, zPIהsEɪԆ˭ Z4dS~=t]YK}up&ϞIn0Pҩn*t4gЋ$$Ap3t_"4=Ț]ig"gg@ qۊf8VmBy]EW1=E_. A9N ,IфBa:=m<3Q8 H;ipYTBA;v?[L-P-NsgnG2( aE6P5TId:]SK"-J[fCtK([){M-2@E8f:whՔQz!+nĮveDgzO[f\Jkj` ]),"Wn&t?)JkTA]G"`:i~}_^42n;l0zש:wI Ք> )9X37=Q /diGnzĻjiNiPA>y\6azm܎}lEGLҗIENDB`images/icons/openstack.png000064400000003202152214270100011610 0ustar00PNG  IHDR((msRGBgAMA a pHYsodtEXtSoftwarepaint.net 4.0.5e2eIDATXG͖OW?LCDEi\ѩMt,e***xAA9rJK/m skp"M~9{}|x5\ћW&Xul&FGa>ӠM㨏܃ڈmhdTyKE5ס|́pQ)U]R_w4"0 A GIL/8,5KAI^|"(W/p8 HpEi_oi4dTA&-VA~&_%eG+OOy q Ƹ|t`3(_<}3BǑ_`p "gH *去A`0OSǓ<[y#^5ƽy5;\ {sg!cq\z u /)  m0؏5ԄYQJBCs3g<,[i:Aqjg'཭lPSR3SߞXgOɠUY}.znZ ]X jv`JXRys湅,g(p.n:H6c{nVV305o uY75 D>g ;SOsSO3-9,}Ju 5|1IX PNM(_Mu^1y%.yINc+Yr;kq1;[r auẄ́`̸i `5JО!t)`>.Ƭ]U(T5%*n5}T3:&3o/Ю1Rn$z tukX-sNɄHch$6^So|ft@Cr 2|6 0eʁd=~v)spѲ.SfIoUקT917_|oqLW|џiP>Tzԇ!=Z(CzŬ(=]H]UCH-Zf1S2}0܏סJFJZu3UԞJYfg0e\ޑ]s)$½;IRc} ;}zv `vLqjˮ+<`5مF#Cp^=2zf(!\]+#`)$ }9e](iy~HW2.`A *)rJ#ˮy.#Kt:y`ȻO0gN$` >\Ô: L`L/OE0:)`zI.5OKGI9 ~a⨟G)y5%*+ LPn9byCx4PdX ,tc]|'o#z܂WJ.0 thO(o"ŗ sK0hmL:A:o:2'$@Kiw0Ds!=W)= l_J\0 ǹsy '͟O].ZL`zt]caǒyؚ`L.zRم#@rOK ee8ػ`2kSؙ-Nt[qPi1L n]SP; ):.2ݩOe[VBeFЙ~)vkr݇جE<(Z:ϬC"`c%AH5؋@* Q_1-9Tnju`ʲ˽N1j:-).tG'n7"R#30ס=>>o\ 콳B1փ)pnPM;bǬ\뀈]FSϭ1bWq,&JT0en.GE.!Ӎ&)v͢eWn/&IR֊1盦kw^N{~%|4N]"TM;^nF z8LQܽd70e"="j5QSI(UI8 Z0dBD($ܒ|6y $m_ٷjt"gоc`> -I&G0:[ ;$ k/@б-IZ;ν8`Az|eEwhqkY6|ұ8wh V f8' V;^m^Fg3ҧjWOEL* `R&EL`R(IL"x IENDB`images/notices/support.png000064400000006764152214270100011706 0ustar00PNG  IHDR,?PLTENE#D#JNNs4 ##N#NN#NNE#v4 H"###y5 #KE"##"#!N###N"!E##LM#LNN#""""EN###MJNE#""#"NNN#"#NMKNLEE!ONE"ENEENN"NNOMEN"N#END#EPEEDHEENDENEEO#|6EENA7 ENEEEENDDOK>LZ0P/c/ )&m2 E@G-.κtRNSװ׳ӸWܤ  ي9VlJ@?$ř|\*"ɿDD&rgb60òn.xx_M+toPH:41۵;弴tj`PH4›iƹylgBĽPDK ;IDATxgwVGR%Hbgo"dLB ePhKH+YӶt%9M򷮮kKr\.r\.zL&1y*lS%7did?=NuoD}b<Ϗ<g> NT)gū{G2W5679XLVǕ4(ۖcN)(M5zA[yJ96{ G l<p_%eoV}, ppD֗ YMJ"^ =CKn59I]ul4 }GcrYZmW$m)cAµyLE-g4s1W Ejx `^/Bx̧3B[p߀x sYZ42R%<Eyt0F0d"z梁HƤQkV͓c/gVWI|jj ,R#(,͠gZC)=kW;AG#vՀXqeVRυF˿ `6vܾ4q(pʄmG/: 8隱 XjS_ya47&Է-=ܡ":vhqhWh,Js􂲮f(י21$  'L]0è{wC9 &/upgix @Сe|[$8v8*\3 Sf˖ET8b]yO@T#_\$ϔS/LNa#v ^oqtDK vXTXdzHq^:2 >a#zDI:NB]c.xf?&2RONIs1H"MX{,AoRGqUI8B|1Mq)qɛ:6A#>yJ!ҸNqD4ⵟ@iu*qu-'KPAB-:8d N\=f ո툻ZtAqB5nqêqD cՈ 툛L}0B#S[q:(_-qydxVyLhƅp!ZqS׭2eOܼfg Y#4nףG4MpAl8Gh= F0N܇vujDZˠϣMq-=Ԏc.wJ'nt-u.繦7 :DW9xqDqo)8w*x˽Љ t}N9̖%K *8rBP&A3OS6%ш}ug^3g_iı&\?J\' g}n]'nq Y\i_{]T QW5WS845WW#Q tBQq;v-iyH{Gڥ׽ EK{VBA-Row+Ł [n\-{J4dqO5%؞(C~'Vq́4ͣq(1>u0w`Qmo!Yqv}=e㍂Gx?),O*θy2>nc"SvA$s<,9S[A.&0yn¨f\N K+\=PZVq 8jbOCDZ] 6vn}29m`qM4`9`~aʸHܤ>uq'e+h,z E=fr., ^U|"CT|CǽP}8W,XLb۸̌t?1ndռ%(ąU|Qo;DL [3mliz*5. Sss(ڤ)SEo%io32s@M^H1^2U-qJpǝCqlJEQ[58r5%'oM3a*ϡ_[ov_ZMBlv'ˠkg|`\eP? 'DMhL6‰2ɉo36d׀ 4I)þ,-('Fq'hL4( J| 71IGTwhYPY;D4kc.{-Wв8Ӆ[-odZ,Q1LykBHޥC&o/2T̙dqt\H~x_=UIU]Fhꛮ5BG?.ݟʴ`ೢ+Rʵjueetr\.r\.&BÂIENDB`images/notices/new_year.png000064400000022653152214270100011776 0ustar00PNG  IHDR,?{PLTE@@@A?F@@O@@BB@@AC@@@@B??@@@@@?@@@@@@@A%\)tRNS qOf,> [ {aUH5lB%09$IDATx\ {G d"%)MSZ/,lq0׉3ΎiLAQ#%qJyl&2&rØ5X>=u {R#J|n_"e<hM(sB$bCS 5mnQ̨Z{\ sn /P4Բ捥aHL݀TbZ=q3' (A:N'ρE@1(QG[` @V[Xz[+tOv:˫_6C x3DyJ #KxUpuBjD|}1 )+4|/u6èS92Iy g!n<8oUuMb#E R)@a cq@E ~[-Ē6P$ N.=KX!g`SAxr6)ȠUƦGL]CIkgDJ!W<@J196A`\fښU4h1暒;TZ.o@pd%4fuZکTpQK|Texop4^- i{٦pdd W̢# *^^TчXFȸ+&atI"BSf+f):vj˷%i\%ּd<[)!_uFzz&Cxg Dg4*| r(Є)|ܬlbh%N paOBjdX e[B^{5+??ɇLlM(*e"PE[NoeJI`\h澟;WH0&oHIT4FpJ&ۉCn?['Bf/nIE0[yPk ;bD紸g-TaK'҈D[?s99L*c4v qXW&gRQYA6B8W!W?ݖEN1ʊWh"#xE']d9wV,6.9Op@|#f] qzꙄ&2!uD}j5 x(}3[ uʝcqfi`L\m4U%V|2paDA2iW$|C{_hl1+AtyM7#e謠{}5dž>bNHSOIvi&O%<焆/RZ<_-~Q)fPH(מ`M8!;[Sm`>uY'ߝ$FM&Bkh޽Y* T$6*qsWa!O|o߉C]T y-kauu!9T]\1 QC chG.xC{f\Hݸ61CE6R(Fk?5hϐg ]o-i|p<{'Ёw8T7t H@3lB 3[2鸑^s8x@tQ4W'ښViXLnOe_fG0i[`d\!K6uڪI"S4ǁ({vqbAKe2'?YLFD} !\xFl!^*YE9l=|-:{hY%T3|Ø5b7$[||!A#x87Rį޴?ĢLW,INjg^37ׅ^޼}pI7 wRWQdCqX._|k?aNazPZZ%rbs~ >'+S2n C Ӥ,Xΰtȣ a\9mHQ)|BA;/7OVDޞrA|ĝ5 V[F 'h9>un [d*RP˦S#&Ni @Hj9I {.];Xi5SBrG M1W7H(Yd+pIͼkl؍/rpqd Lei=eSW_)W9НgP1# VPrfsW.@o"bKX%  2,JtCV0FxAS+[pPVCB[yr1Rl4=6TI klň ;vb+'^qTQ~%%L|]VOܡ]9бWIa1_K)}>t5}64b L(jzADf< !I|UWiG7am8AW鉯/ZcSF?DfW8. (:'X*DG2uN2 y+9eλ|hbQ97(C)FJY6‰; CQtЊp#22wi6p<5 1dn|:&^㺋R63Wafӆ6qU }͚OwžC4)\J] o"#bu{.q7Ndɒ`dK#HV4Ӕ48%աs,V+$\]R˾X-Y?( /3J~M>ʨ%:7ïeM3xB ,naKX^J!Z 5_e5O֮(,Dz%ψːF9! xBC*uQ$eȈP29 +_V썕&:m$*D[f (Sjy(EyKV2Q20qzTnܭ冏׹k UYYAK T"-S<Jxe<:fiV?DLr Uv?"8iGE4kl~7hC=Ʒ Bet'Qq';)=2*'.G.XeM$a,bD9~$>2HrtC]!sR%R&-QaBsѣ"BI_9qKE@m@_\ ;~D!H)$W 3ynlbF[֗GdP=9S(kElz-,CN v O *ևkvw8-[DvU>!Wԓ{ dɀWO?f:AͯKX4o`섬AQ2m)lCi!`j) jyX}{psͤDϤӮ-$\۱hK]GR~&y3qQ,o9_lpd_r~B٢$M̄ GOr"^OX1v9E'a5 g[% R`i3|<ͮU |~`ۊH[SpϢ|zLO aQLyP,1^y>mfwם&&o-ん}{ޒI,OIʫPCTf};<_TTi-6ӗskuDpþZ^gp6~\ >56nʍqֱΝ"˱;=OmЗLq<,b(]ŶT3-Klݞz`zn#ն0Ջ(k)}-[$GB'n! ǬD_znm"G+P]Y6JDT)9?vDI=+ ^hϔXE~| dl\Y᥽ R b̲i&aߢy!|9j7 T:{܅mVMv 0H%?Y-}T>^j!|nBN$iK|°ʁN'iH%f`byjQ/- vpΒgYAߺsz>m7;P՗.)X!W;X0t2F;1-y|-]rE)b~.}?. :2u%#4%^6q]Dh(J\(P )X tɆL~6-eeaGNGxKυN"~j=?k)ZQ (P'eV=T=+E!;,9Ave J2vDX6)!uζ~8zw(N)C  fQ( K$OU;%}?k-rqX!R 'CUI: Ϋ Vos,Ul7@2%#rJҡzpRYv=nX>H0-lV&2Oq9:j=$@T<|Hc C=1 SS'^^I;]^3G H@r7-AS9xqC gqR=m *H\)VxSjTS)Hv5]=OHw2eʴ\PO јә'u;:9-M<"{5J~ӞyncpX{rѦ=P0KO^1d'^] H%"wL+X艄c*|ɖrbgIENDB`images/notices/updraft_logo.png000064400000006101152214270100012640 0ustar00PNG  IHDR,?PLTEOOOOTQOOOOPPOOPOPOOPOOQOOOOOOPOOOOOOOOOOOOOOOOOn0tRNS"}ҝ ʹ/BȘꒈr)m5;f_OHUZxo73 0IDATxk@eQP.xC}N)j;|م`0 `0 `0 ^a/t>=̧Em5 S"$s0m^}8OIFiX&?QX&Xx"+B}S>G*}u<7x&\G/p #DFb< r k2[DӊeTrf ;dvFrp>#cO$[x:ؗ7|)O[ΎP\FK(~ Z'^ɋs&h,4RˍCbCu#AEMqHZ|qreS Ըؤg^Lyql%nS2yq4C񛃷ѥqX-e3G_oRSmy:EkNrPj6)+{egvFbMo\i[/g [cFt6(a9kqa |5<uqieI4fUa8CU[ ?amдl`Lpfm Xy}gG.i [bA-x9"V -HLpJG{_"]7s r.װ\vKVJ.{6)5\pƅm?H/l.4{c8RE~FOVNED#cG$:g?ĤΡ &e-)Bx@iCbF*i `jF=ᆢY^D).G3ڎ1%ئӚVNq~mp7)Bu _tV8sN?W^bQ +)rvT'XQL[ۍ7{jY7;_n\t,J¯$p;wh{YN\.GZ}G,Z˨x2G %*+D;c['tsjJ=A&jИBK_<`QiM) n<#t.RD`S] ]4J)sl5NLyjO"TTs6NãDot"R7&֑ƸasM1>aph Il;NYN唠}%4?&d{4M 41HFBݔʏDj\Vz(SP2Z<Z`zQ Dh`yu.z& 0nH4LeB-fxE B MhU;iN1u;);,%:Qθ&;<Ξ!;;v32e*aCNy+ܬ3WBH<_!B'$ɜ.ПWQȍXߪ$DY$#~r K0&_~_v؆x6ex4 }=W2} NhKJ_ 4ɞ^ 6cR}̓_"bzOGl'  :R)c7&ٿ<>}q֮ eڑiIBM.mY00HE)HhB)u¥fo\E~#c6%o" d{M)ax ͡|vo&H,&ɝwz9M@C,`^{G/r;F8}(O8c?^@_B*b>o?&oXoNbH?A3l}^w3z-m**^f>uP"ϣ/y7`0 `0 `0 Ok]IENDB`images/notices/reporting.png000064400000005511152214270100012170 0ustar00PNG  IHDR,?PLTEOdgVD[^N:KadH^aKpЅWH[orSikG'LD#J+M.RMR3k~HS🪣ДzDՃE]?:.zO=4Fv[gy|x׏x}㼲­iM䐷a~HW9ξܼ۳泝@}cIȸeۀfnSņ^鼧=~P݋rՅldGتʢ±嬕٩⣌n϶Ɏҿ˷w؟חl~dYȬ{j`;RVUGK*˚庢{|Ɇq^S HIDATx Pߺ׍YY%&vMLXˤz0%т.t%Yo$|Mt:Nt:Nt:Nvޜ+ڋ 3Kwط{i7(T6;ȶ0 *m7̧FKui,ȸnSf&Zt2/oۑ dLg 3 <:ps7lg[s6VDu-[AcX%C,0N?;Cc Go=LO(*p'R=qF֓/y+Z&щpS_eİ8DpS8U)Q0{q;13D8IA[VY=H~sdvMMfY7HB:ܵL!v C e eBR!붹%"]͎Ʀp6wskAaͩw-buws 8Wd<'wHɎ젲)Ԧt#ʂC֔k2Warp*?Mnp87N NNqbLk{SNe^:n) gԖL;ubχCYqqZ`"NfOupNpħ PŪ $qdL 6Xi|ֲ~[TJ˶#@ .o"φ!{"'qYtuAtLkP{ p}pYeWPą I.KOuH⦗gpk[K[[2p~sb Nٿ[d u} 4w 2NXͥ! s)0||0<.ށ圻n !Bp(6{tڭG` "0y^I"}?}Vpx) [SgМy]@B97۱9l-8? G4NrƑ_XW!]7>sC\{>?8ܵ.vf2[.Q!5)Rb{!ŤҥS?]Pѵ$%Wi0|M@W?AGKᯏ@u6E׍PMM88l̖JieqvWjپ 4< UE Á R*(ۡM5mh@ m6Ŷ0hG 4'3"٬-mQZ}*d)(!=:[3Rr$ G;Ė?5F KEma( mD9GmDفu-Cm \׍,:y6>pZ[[ȴZ¹HrCuSn22{o延W(<+8RWko.ba? [« ͍=jZqlJVcw]tnSap`'"'FnK^c{\&.!el4诵(L:6Cu?QC(g{+Yciuk2n<# GVjC q`Q#)۵K[&S%t{g8b[atHnMg.%If8v66uwgmdk,Kc/b[I`cJ>pz61ȺŁp?xXcmlQne=.<"ab@[Tk0ڀA5xNlE0Tl cN|  G N3zH\Q70E@ sj=@Pw0r10 t KAЋ:xuCwl$\6|'Fs9k ZPmsȸ`/M"fQ0 F(`@{w0DaxX0ծHe!R ؊Bni2YwbCh1L#gH+r@sqsqsqsWIq2Dqt|{G^▕}.a(ufiwYN.@yHHkc/xl~S5[s}fkpQp%}dgp5/47kD[PQ/ϕSJ(IENDB`images/notices/subscriben.png000064400000007211152214270100012315 0ustar00PNG  IHDRlg PLTE`_9gtRNS@f+IDATxڴM0Ӌ9B߇#זZBE8 X} d褄xU?mk>~O VjYl RHy)}!R'ɹr NE2,Sِ"C24YO:o&8)D)3@ℙv*!Y͐2QqL~;WR5_5UfR!qš'fugUӷkLҪkV0ҪkVhV 2Lwl^ +Z}l 10Vx&m H/2#0f^^ nf@-⪽1##}b툛ԏ/fZas._ޤZLShͺ4TeypCp;ޚ~ZP[≙ވ6 `4"ftSl'l^}͑fA3957oJठ<49 ٩5/@j9ѱs +)ĭQ#R)nMd5 , I1O@v4H͜"j0dFR̈2}FΎ}̩V?IN"в)_Siex ev*@:F4@1W?,hәԎ $c"M> 4u?)sFQk) Xfp(5{&&~ݠHt8C m^:1jw oE; wma)`^%Ј`l Ԍ{ԌZ`R3->hC HlEAbLr$4BkBGCseWڶ*#76kfoD1Ig;H*K`'fz0ˀz'f3PtwL(ϋ'ncf/[j}Zxj<P( nl9 \iX5sֽcFz%<`93 Edش{7 4*#eѭ#3 ;l NkpncsG_bFi Cj23znT5-~ZZ1p1@ۯ~"Y+PO` NH"\3o$Lhs183'NyacVO#_H-TpLLG] &2 4XWIy ^1Q-æU'bN CWr3T4 w=l&ΏZ0|c,N Feژj=a^1&t*~G眞էg&kD \X19d{fWPQ5r F,/ЩG@ 7fDcઓa&n-0 a6<1ۼ%af|0bV0f^a&1-/i:1T373&"nI*3$`F*7M9]N c=FA}Q1qsC17 0c+Z9r 3ӱ9rL 4q`鶇L"+hPGDCw gfO7W q 6E|OIٜԺZ!G~܆^ˊ}1ԋ10>;#3,U>;:!:Uw}m:CGVԔbvH1%q ha H;< I1ʩ(4쀨[efB 󚨃ӹ W k1N[t#TC!|ߵ=@`\0)CGާ\M5k÷tI 1 s1>בi0qtPƄcEaLd]müY'%~*Le#8o. Řm$"zT \bSy'VCjr2_&s(&7WFR}Q`X-͑b\}&7GBq < s]}o6a^hވvVOR`Rrs8g`F`sb⬘ zc8%1lx&ٹr *18L} I[Acaȹ٩MѤIh1 rRSM5Z0Gf7xcv7#аY=R {ؐItY:!jdxY3n7F>10-G y"'DcKɑ㞂´9LM0gNH1rhFOjI:c30r NU`*P)U7 1y_ORocg1/cuR'pLE0y \&g18#ln T߲b@%nDƘM#;M؆d1 }gm&'[1/D00vؠ̜tsm,i 1+(%9\=h=YS4&,ށ9#x#`b<.])g&9]ɤM&8M3& {?SRvn&4-n6>2%w;-G' n90f`_cnn&]FN !$ʏ,%`zHk7!a$`1dd1лp_W]LdaC1S=Oy'9c'P2133^r}>ax!kbk)`OcޜZh$䌯5p$gMP)P4ge r &(o!b˩CQHs3裘.GQ1~̔;ծ.GvA(2dʸ۸N)k*JyN8D\'3AR =9]ʠIENDB`images/notices/locksettings.png000064400000002405152214270100012667 0ustar00PNG  IHDRPLTEi&:m)b/^d$9;5N[}+G3ݝ}s*7.20,5y)l6OͷŬuj`~<ֈ-*IDATxQOP ឹNK$!78+`w܈sKܒ.sD>/W$ic+HЛAݚsn&=Z\GR⚄̍}{kuʟ{ydQ8g ?!ȳ{a.F$pwc+xU1,t6`1`( [&Y$&CɤuXAk  M9AwӞu8;m#]4.uXCJNe\o:Y m¸ecs(G3~dqkqU}\% nWm[v[d/qToB9ǯ]ܶs]s>7 9J H:J?G{ʳe |бoَ5BKk< as+s1/йf, \ÝΒ:mhcUPfI/rOi.t}|YUĽTt3"S-\U\4?r[sDeq^ fp(l 9ܷq~p1{W!A ʗusڹa ,"tU!+,n 0QwY}? sKKa8¸?<5DMk@S-1XRh’b/G#$r!ZAjFu<]R}1nSRbأ{x1oL]Lw87]J87]Kݧaf7)\Rx8ZDGW7 K\OŜ;2w3rפĩTۢԖQE L&86]fR1UdITEoUў&'E? Db[T3zT@t j&:73ѝ:xjF[yCf&5r<C.bHbIu_3(7H)kr#e\3q#qVJ1\B-d(T$)ڹ.zZ2Fz)1QGbm9xcm% Ս,g4G<ϻ$b]Rl'FYqN+fZ;G|J|d QiJmq ϗԙ?I=yt9یx: xXqڠ"KX7% Gƨ31q#sҡ"&s bME-wpZT&8=c wó'z蔿6q7s^i6NJdUHFP$ GA l8>wu|@q0*N ̹dNk|xFؿ5i5PЦ[7"X ftj>r9RE/=sjrh[},&Ï |z54ZC&42CzZ@-(NthtA kڙkzև_ Rׁ & |h3(WP, Ϩ^Y$T3jܥ:9j礑ϨhZHHړ|WP["Z֕mgg>;r9y^&+ntk9@(z0שWA'y7UוW5~y҉sK8Y<~(ɲX/n'$ bG8I6 {gc}wQ$[{޽܏{IW )Ilc #N!L@@p3ҁxa?/\ -uؓ)^=awl^QIT%Q܊5'Pb!F':y3{x-!Elik[`#t<*~ ŽL/(C ha P%hC@ Y9cd/4CW[c>C3H-@`Ɗ05֊AYjjIut]$FG\qF䱄.lIpQ↔Ap)D-.; 8^ wRiHvu m s#a\M8::'!\c&OL[ ԋ׼2,O|'%H&4]OWJr'̈B0|\~W0HP=F}B g>6 S8ept+6th+4thp\+IENDB`images/notices/spring.png000064400000013314152214270100011461 0ustar00PNG  IHDR,?PLTELM܎L]ڂۃPSYPadwڂLT{ۂJo|PqXQg}aYkݎN[ciUhVgԉޏ~PlvjMQ[|xKYU܍ٝSghmi`IuqdVW\֧۲歗PϘ[`޷OgҞgجVbaa۲]ܛ٭͖򾊸ͧKIN͔SJKIJJKISOO‹͓RtRʑROѷ̑gD̓PQKnVRMHӗPg⼅ζ~ː詊xXʾ̤ƁodќͲkW޽΅_ϳ㣚m٬ɞvZݶݙd֡ؖΧ±’Nj}ٵ{א%D~tRNS }9,&a# k\H0=+ KFɯqWNBʧՈQLc?3wW@qb0ȺuL߶-̌˼gWݔmV;鸙(IDATxk`'i6i$d}ٺe[eeZ[FN|QAы x ;<(xVAd ^xf-OͤMN O89qz'S E$T?bJ*HRyt]$`b\*p*akV/ݝq^fbъq{gPb{r728*qNx/Ԧڏ(r{JNqNdgU.-B/>!!Xh7s:9&=ޞ<>w*Cf d;Իվ19}"R K<B}Tija )N@>Dl#2eDk0-̙ 'lI2 tlBcA(B6eZ]-/]W'›?$b /_>t!缇aNA:/x@oYgS.b7d*LtP 8عIvTBWSg/n)yPKv ~06ZEAh]*".`mZIC4Cx)U'#Vйacplj베$Fh-H! JRPVΚ1؈ gѦsb"JcģcΚeXE~D)/#R6̴5 (D:;03J[ȝ@C>QYf]Pa`<0 hN=^oOg<:n0A,Zi f/9k@s ljsRy!Y7ɘqmؙS2u{a!] }XxEw5>Alʨ e 漣(WԧtWG#%1c7\Ɔd[O~}Яr1Fะi 6[xtBR¹Q#TψQdiCLD㊉RJW'gׯ&^v^׫"~(s[\]sJy/ͷoW_mhMzs:G&lLX%:Ϥ]{}}C.$½'+ $v)$4J9zW/l˒m גnƻ3Q<Cܼ_)2SViTׁf XdYqqYY / [flR O2|p?%VIi$;Su ڵoa\Mm?[2qee lZﹶ5mȭZ+J %A3zvՑHNˇF\N lՊM77Me'm?LЈNHKl&*hg֩bˌ5ѮhZm=N&r`3ix\q Q:͠z̺PG hsl&V%2iӵ25AUueƑiSmW`cis_zf ҟ`\FP>c1HK[-H(22, w☌"Uzc%ٚt|j~©QiI-Q/hp'IO,j>_?,SU5RB˜Z7ElX & bZ/eN8} @]-ESrp??IB6P&ˎRpge pP"D [" 'z@(U];)lIlt9WM3OlX8uuBFBb`\ށM1g·ؕ&4?PA mb,&8`ZcDML7Ddz-Er)T )hRB (N  .+.cy/~'/7}r{hV8AL=-' f??'8גwh- X#4.O%Lྭ62YiÛa.Mi׃R~ 0 pqs 9+n-Vl<ΎyKo7'eYA;V3&pшǸf]ٜ p0cxp]h ܟ!70j҆)pYD-fGd!ܕS'(pP+#9qxVՓl{}Ss6Qi &J9MMc|k+'(sbl'dD&jˠMw5= /E7tK<%.eŭvNd&.=>]\UEh`|%m`e?צڠʶAkwp*N'ۙa ӎK,ӎӨ8A;n_+ю㶍)AgD٫>4q=\U+ݸj;k;m,up?RUS\vV ;Jj;M 8@K )["RPQ72Ix/F +g!.K\־qs7st|ë`/r|dUv\^/RgӠi?{i3.;H%X7<.y;`_]U%I^ZΣܽ"y1ltC 6_) Rot2|\~7\9.JYtQ&i˟<]@(~k슬a9,u(jfNteL`Nd5vPYia.6Z7cpG@&s9G2q٪ý a+{530vG贯"4 TB Kׄ ^ŁpvIH+Mgi ?-79v ~\OC$zɨ@ 2ukiytXi1t0Cbif@C/];(^o#(|@eD < {*A+D!S4lN U݆"s=RKU_Hi ٩Sڸ-|^˖'#c]&JcִeuWyŪݴW*A2׀LIENDB`images/notices/wp_optimize_logo.png000064400000017660152214270100013555 0ustar00PNG  IHDRZρbKGD pHYs B(xtIME  XF=IDATxy|U?>i WPI$Ŋ:?qGKS8 MBm\Яˈ3~pe#XmIՍsV(-6$9׋׋}=9{Ͻ                    B>Bb{Yq֯on"x@T'}`w zm7+f XR&H%RKZ,.J(HfOm3uG^ Od|3"yByfDcNji>x>C]A5keu=>U1)gY42:/y|"8G`6n>guo)^`{J/1ή8 pqt;1ԏ mh/eXo.X<oeyyi \*+7X.ɓ٬KNFP3eEiVop%ٮ([[+}(R,"&Wjn+QOnC!M6o0m';sOKi ߉=DpA]w/NE`vO̔W "Y-T~&1!c=5Ђ~?N=X@/mV']{:$Hb.i* #29a̍TpMen.'c5hbLcמp_"!1e oGD7x±Dp>MZ|_;ܳWQU_Y5DB[!;Xv鳼js|`2轔e]i",j aȉleh'KJS7WY \$>`&f/8U4f]"8A=ӛ{9O$~fW (n1z9>Ӂ#߉lي_Anj 2?lT `o2;uw',#RdXƄDX), Wu+ryՀVw4a4á0#Ap^$C(g|+ nM/ts ^@zHdM fH b &PUҖR=^&/ǒpz<ٶf#Kg$^etf#Yr<7xVW 9?5_¹Ķ봡FM_,MaDx' bɲ }ZYrC-\-:u0Z5SL`CgLw_fm s^?u .ֽ±m&&MCONkXR|/9^pM!Tb\ȉt@_I0> {D yR-ƠDj`,f„H=U)=@; 2=\4c8a}iְyJs?Ba{MN{NӖYpVψPO$~C> J.}38)2J&ƣZBٻD)@5ɐT0? `OFDp`ل>il8$iu @A|CFyH''wܒS!6J"umx)l2p) :.:򬭣fd8~\Sj{4>m|p`aP:-h1qm'gHl arnB)KXWFKe ibk@|`6}],~&%_o=2ev[ATtSpل>->]JލC@(?ҊAG2c'_sI$ޔ x"_2y1%CK`uRo<ӎɂ_*`3tJ.*wZ:O$_~. %wc#2ҷ#,<G҆y'o~)}<4_[@2k"T;2׷loGy+AI:?) r~K* ds /xqۏ$CILc"G'2M44{,*/3 aRwMd |EΰϏg5i֏"iR2蛽A=lːچFKJ/YPJ| {u%&-YE`( }V i3,D`,: >^)凳 < ׭`}֊$+Gp-FUQo=Qh SNXȡzsSpOt-Q0> >vSBG/ `a6gC'N_럷iR}O/f#$^FH>.\Mb<;vF%짏2̗Wwmވ~aTKG#L,ق,>AQODFx4́b|V߫102b8Rp_t$1HC?)HY.H`m| X \Jcr㗬>=JZi5QM2Tߎg{)fθ7g-2u͞iS]uq[u]v'ji8+3ml}!ŵKI} (e ;uҚf͈-h\48FU!|5`׉j51]ƞ܉͒SW _IZ^5ErWurjD'vvX1L ~JK_ְSbkKE^llsewÉ[ھdMe@g^5z"r\SA8vG$1],z1D+)}Ixv&X6LQI} l hb6XE0uQ p6RAL!d㚂CxwKŒ.GaK3ؾA߫){M"f3kS@tEi>9V\XV'u&N-S ]<.}Jzr sClB!i =ĸ(e8 &@q`/9IEb qGQ[^o!mkp/nҪ4Dng*_ WR(mPD,Mx" 28ק|doomZ:IaYb4z‰b"vYu_]DޗA ~4+J"N]KHMZݸ}p2ZL%4FH5~:ax") lw%c2軛Dp]&'xo)'OߘZ{r"8Í LeNв;cv?զ ߓ)"NQubDsD O 7W2;G'O$' &|*įU~= [^5X'tH^=B/s"k=X|S8ؼ&.b^`g-:\'KkS; »; ǟ!G}TWG/äޑ`Տ۞ǤM5h&MwZÖl1ZSw* Ǟg3]8 W2~f_=/-$$j tx>L_-6:v+~Ճz7/B\v]*wcYcLt'{ /UpM3~;;1;QԔFwnUQt"j{=kbMs{WQbm/A3 QԕV˓AoJchK+@')ٟ-b~gT__"_Y:1nUĘӭ>\YnBOi)!uO8-e{J1 XDhޱw]_~$+՝I#ඒ5h 㚜ݘ.>p#=: g~m,\{o2O|`K"&; X7x֏ sܑPbL&.`@o2soXr+-stbOM%; g7wX_i_-~0_;|hVz{K"38SٙFwiȜDcpIe'W~ `%5`fQ6";܊x12%8"ɐ/w8v]K`R1`ߜ0E~nםjƖ-z'+R!ĮTmJQ6ޒ-RUCp\3Yxx,oN婥 EMĊ.^ئbP ߱I5gJEtc;(IkÛ^ifpALṣ$D|>:$XNLAmzNYmӷ9)8O>`e7n|N'[N$~ypxw$ @pϰT Zzg,~ޕei>_4fpORff~نu4l4[\$wcS*.NHEOYLysz+7.eCǔR}; FbO4Iþ Ö-4 bksB[O8SpC3?QN)ְNJ #(%]Įx8 h iij#-i88RlJ&oHL*di fbCD3uu;r;lب⾭`q8^qGg V/Rzq&xS8IG܉ ?X %]ۚ/گ-w$~b6$Iq^}Ya ?} T-XΌe >eå%UecljW ]bW8o%oF$`6xmpڮ~ۖ幌MA Sl-@Aξ&V|;Bg54O(}6-Vlz[Ke]VZGPOv.°p/cA"TTďu4|ׂ2=`T&r<]ᘠ`۫]|w)[IךIdb8$RO\[,V;)42 ,}{8>\R`gl ln"Jg,Qub7G nPMZOeךyTGl`~@`$8js00*(Ud~؂s 60Ӕ"mp|43;( _~HB@Kzu9>]:#:Ro&sDB(ɀ̨q_1.4;9D8O?*(1xrމ{&YÁ=4Z|xƉRNkPCɕ̸!1JK"m a[8HlkM6t[^)t5i5/uGsEfmK澾5p[;4IYeU~ `o'[]fﴆUl dcqx" l;GL}10ׁAy"'){ktUpBLwZޖ$ʡ{AK#Or>V IvH+uht;:^pIEzᎌe4+`ً32*N|Ħd=&Ҁo`@n"i?cSRP"ɾ ;v)-K)o90v؆+Sx/be*2sЉKǭ-Mu8w -]Nlj2iچFGl5T#yG: ÍKɇJpEMٶJ#JpcUYXW,v-iil$z1@dq" &6[i 3-}ZTC8ivR۵Wz .c{ A-fuTSڮĀu޽-CLj"o[.ĞP6%+Ga-3x-\ ܛA\*O8@Vw!{mڰh[& yזڒ_ !N0D9r73(ƧJT.tb@iќAsIl930VC5=Y7[1o+U@|7H)Gh,;G5DEo *8R3k=ץй0}㚂csYl9=)`Bڑ{A2mECz;O`מx}tXKG=d0? .}X>-fj*$0OP$o9MҚĻyOǗ𥉉 : [醶۠Y/sMmjX6>wIX:rtQz2ȍ{cNa9O)Dp[*+wq7m~ (|2\^!4rla{K"sDx!f[uwLI('EDpV,5ۊWL""?b~@&" Ѿ24@o0Ps}^8z^Zew^=gdH&lϿr ůkಆCaČc42&OH _@A5kPePp0'͕h?f[T#{i1CE={.? ͈'UYk2*a`4C=nQ[lj֢-;j0/gB )n5S_7}As`AAAAAAAAAAAAAAAAAAAAzi I+IENDB`images/notices/ud_smile.png000064400000005027152214270100011762 0ustar00PNG  IHDR(GPPLTE//////////////////////////////////////////////////////////)/x+.-*Ω$~SB,(Ţ" -Ԯ%|wa2'!=0.ױ&ʦ#% r\kV jU dQ ZI *!*ql~fK;H9۴'ܴ'ٲ'{dD6|:tRNSgjK5, bR uE"˻|n?Y:죕^'őBir#}LGMNLSqrh68N fu܁{Y-V0m 6Cᆄ횝!b6FNn .s1#3Q$J螃n7`n8'0OCWGM4ԐEzCkZpZVhwK>LԽ܀+Dƨ>aDB/FuFX]R %^RMj4 H+բi*Rx e)S,>KޑLK]g6RPu Τs``{RɆ({̄̀aC\؂]q! ?/%A0,PP̃ ?~/eRPoV#!ܔ HJ e)vA-iCRT@""*R4 ]QiSU%#5.*ļTώQ%$^JT%-zI|[:IsÒ# ),?$d,@⃨,$ςYKN!_J|~/ &I\E !KC$v@d`ʈJ%^pO*> IJDn$2'ⲕUHe?$&#oA)yܠ/-.|^[q$O;$$3w(InJv2w;,Pv,H$jVůP<,ͼ˨M?v Y0 J%ůxuwϨ)EZzdOHY*-.h_]Qh㛿8(kqH JC))A=98U %yF+CZMjD8 <;݄fggP2{tYVENtt[BgP = bK~\$fV9!pLA6cLSIhS~ %Z_vFFo%rơ"[^ =b$/KNoy?V$Aܶ% /n eۗT Ϙd"{Ę^ܗ"TIMq\R%EΆ݅atC6ͤ$\$W}qiyAvJEnTCɖZ5Rꇊ졼\ܣ& Qb%Rk~J\KҦ~J>jɻ>E}*l's=7>ϣNT7XE 5E@]M6UwW!qxΎt]d)81 G#8 2'[uV[%!i?9#臍9e ''Eg`H9Cănr^\Z|1|ssgt-85Ǩd@!3?@_%8xx;ɽ3zve**bMSC73z|)c}kssMhc0 0 0 0 0 0 0 0 0 0 C_Ԭ3)IENDB`images/notices/black_friday.png000064400000012074152214270100012573 0ustar00PNG  IHDRp|PLTE$:tRNS "R֮)޴GƩ=1ѹe[B~-tVpM`&95ixlDIIDATxr0 o8wBfB1ؼX2 Ha1y*-}%:~x,ḷv {:E7ݠU.A-r7Z xhM>&UUclZyt#7|-͂c{MڟF~irtbI\G Ǜ5_Vd8Tv_.],l-IQTð ǩռu5#LqC\%tT|F1)f; X+[Q'n(SwB7kt +njsBN+= "Z2ĸ6]5<.ۥDe&>meDp#6m$8bk_ӒNj\ !⍸VOEL*ĵNͥ)qB 1I21]X.qk4Կ|S8۶!oYO1HĹ <y [lo Vrz%nA+|}P/~1D.Cꝸ 73a&^RqO&YS$GȏR!n Qp7 Y"?>q+\B Kx{h+\DoE_'+⚻K8gȇS'uE Io_Qj&7b5dң,R2s}ݙ5kQ,qX B:1Ab")+܆dwW2pdmYȲ ؤz!/zXsM#"YzqI5STw,:C`Rn׊64⾦G55bGEvٗhTEώs1si@^Ǝ Sl3R0TuVɭi^[ek}1-Q"LJػ?+ڼS=oG dHI~P*}TdGt"vE%~*xd!{'!6/3:(7(5nTڏX/VUnd`xhȉw}Q8$CajnެNb9.TĢCSZֈٚI"-?{* N ,ZAׁ"C-~>̹(VPGB˘HlNgX'[rc~?g87EybL_]B[\@3kqcJYZsbcr} Z!^ž2lMKӞ!5`㕷Y-DE`hc&xq >G𗁩69p'i.7k 5]ntq 0r ̥H:v@ XvAi^e5Î._ۚ'ɶ{ h3n<HB\2]gfh GtUtt睭\"(,~4B9 nD6o.A<>ьZ, vfB /lبK83)1]j׬4eY}zgT3 b9E#^@JFE$B{ ֱv|[ bB7B+_cu@l{ NgM6FĶTǑ8wKǜX$|&bN=gȯc؂f%vEl3ىmzf1~]b М 󆟍1X SJY֝Qr< LY֕H3Lm2;).wZĵNW(~[kMa#'Iط (ZMvy# RjEǣna`zoW@P!3eYF{nQs̿nfdn0e!:1z|feQn[[ ˕6}?h ;6YH8 Y= <&GhsA$\ۿ}9lFmQUz3N~= (Df;CjR ~B9,(TʞYR~/)ZL?gm$lQ;(5ړ) +eI [3QfN)YH3<Qz5߁czҪkvwTld/Vy{^%i=dzSAn(5'vvJ.g8fnjVr=\@Q86ÓCLA˓zq| X|۬CMp{LhQt6<{y;b\%@o*"NxS 4(ԾE*Q5q rT5[Xӏ?T[DXJbH^\ltR ՗R|c8}R2 y| m4Pm"TS 05miɔ(4H) jB+x $(ḎV')BMcXGPL|02m|JS颧]=٫z: !Kgh"M:QEy0XϷs1Klxw|Q~U@Ei%37H;x=%gݎ`\\s'ݏ84^uH2$t=IUu@b* 4i̋^ [.}Y4pǬj{,R]AK[IcMp *;R^UBz;aW'ua4@c]FЛĞ( u yhuY@U#++0؃.ٞ=DXɹy8޳(olLbt4|]Hv0*J 3;,﵍֧YZ3Ljt%#EMuGTєlll+pʪ[e4_|wj # U0̪#_ڗjy j4U>3i>]+77|VE V\;B1Z{Bn3z!~p{z k&֕7jw-ਂ3'@oٖmbFn KuHz>)\K6Ҳ vٸ(?y[X60<Ӹ,s:&X "Ȃ7j$DQ.K8k74кna&;28?]y1xAC3a8b79-q C-qn}T̐ey+{n|KȔճknT2 ,'oe-`0 =lN<TuᒵPYu+ -Ll]˔ Uj0~*v@$ۺ%!crg7,{0E ݔpR_f76RL[ ^:R,8p@ܴG1(expZ,8}κ;6nXp;W xO`]iYKSh0a܋``^,`dw~^1u2Csa|>ntwn2ߪ)1@fr{d1L/WrLDt0`S`^s7t1%'ˎhɮqJ+?'yde2ɂo]rO%hbƌex Xs2"'k_>lGyOxTx22fk1uUI%/OÎxS&/D\$B[B,% MOƿ&ebZW v8;pm y7`Qv32l_Sۍ*YrY.⹵ n}LE&2YD"^ʷTdNNF׊>)Tٌ3 b՗,{y:~\>,C\n0Agr2~89ÕɂJU)U*SMfne' Tv)f=X:n`(x#)gŴHEe7ݰv.@KS17U?.F&YbJHpT:4qw~o7~JKԷg787P6ftA6g9l9Ye/(npSt*2{|cto+TF'Ph{;Tyɦ+HEd(i6}ԍϊrMvr*n*Qwim?(e*9Ux\2HÎLVh OCF[yvdCOL"]ij(A% D7qLeoA' k1I&񞊶~*|EV8 AGc@ (S,'+߫H='v^2۪gʝ~:Q` @ki i~g',edܶ\ KlQHOYenha ',ѵls-3U(s4UR-`ʜ*_${|WY˲vn oYۄd\^&A*gxvnx&l$@`!j `oXZo/ 8X @k\:Fp^:S/7^CZee2Y)[T+(ժWFI/@ꉁ Ts ]2jAUn>*5_&S] U&Ŏ GbNV mmkUL.U='VNmev_'NibYﺽW,X[L* /(6N9B7N9}v :m:g ėͬX  wֶ<w A@jsC JqfV8|Js8Op3!8e,@w͖/;q 7a3~a(}(Vϫÿt2g5);Ha``/}C~W2Z~287"?@0mu66-HANi?a8 Y,bQSIvVMnpGT!d.dح4E~vPln2 Nh82pjlNtE<dQVn>"]\Xu["7~cI&i,VCk1I7}U%A$+ ؍r܎CvxvFXKSrOdPx;ɞN h{t-M! o\$9 \v`x WaU|n)9))f46_\@<ܾ!˕=׺P(n'i~en'pILN^n:nnpKXWkO` n>Gpp3]]]W7 G?IĐ5Ϥ)tcx>^nn1(N0(A._iơ!lp-AP!͸2fև>9B~ |Q;ӗ>`Mb6X,Lݰvn"Hm%33f(gü)­b&8&M!a0gJ'4fOa{a*}Lna$a8p(##m#Xe]o}^zgbs?0Ҷ, |AFG,g(gc#-^alm:ʗ Gq_8KX _66lS1 ų4e s̴'eaq-lpʤ)˶j;dU`k;~*</y_.yG` Wl~ |?lm3E/l_T6vC 27T΀X ȱ!OY&=EAc4j*Lu|+=o;.A>gO> Ժt?v}e4m|%峎<[ů ;.}Ds"U=P?4/*~T'7.oןsh7|n}數tij_Y|of$2딱ǹn _0DM`|PI2B@0_{/Wϊ^i,!e >0)" &@Jbym?s³1C@^) W87BPNp2p4s6PƦsxɶKe׍hi -a%kIu:~ޔnu@ew/ tƄ__w`YI Ϯ硢' UفNo, v|} َW| ױm$]vō/۵S:gx<Y)Py{3=(֜TvZvkY Phﻱ[d{DJzRw& _pB8f8Ԁ'TS|IRΟe>䫐Y+H4Gosd7z@Eii8=2^7ey![B!80)OA7@VjZB`)cBf & a  f”-KQ,⳴&+&k-rKo>6bAp+wEM[یI ZSB767sO 9_^F?^Vc66mxQxrr;\oS{)jbUѶk' ۭL|NQ)d8*(vR%iq38R`#c{\'v8ߣ4r/gzo+`7LpjJԦZE_^ECoU@6C :VU`Ɖߡσ;74\?tU`gvU )Xؾ1Ap hf`8,}b1lKJ <}}DΕ3pVcsBքܟ,B[U_ ق )RV*^2]tJ^OL*t vg'HOŃ`UFE[vO%=n[p29UdE>Jantbw*:n@12϶ YNnh@6Z:)tzx%=+^zK@ ?!۞n 8u8M!XนpOGݜ"iTK*PB=7D({VE,\6S|S0ySh44Fe;r{e(ZX>%7"N+oB8o"o Y0wzȋI?/HC%ԼDz߼ênenWNUCUWUS̮6VòGW\E*(+.#+VS z"m'ֳPD ]qpyx*y'Z/)B6L/+s#v􋱛jqCOVGK~rswkO,]8s> 9T) hŕm/ FSe]DnS{2]ٵ];zvH];qSgo}'YTmL)svuU6ra /kNmC"b~(eҺ_Vg0}h0oGO+[1~oIq[&`7xelҙC `cS(e8B|Ozf _$f<^q d_:3j䎍H3 2Eaʕb64fs Aq(%e fd#͡lp,L^[&o IDATBj)WL{29E,W[pBVfc!c<*w&d4[ '{sS׍d*pCc,u]WS%niۮI/kt| hD:;*,[.2;.Yq_mYf'P+[2]mzOfBݢZ`evA k7.W 7u܇eaU٠СiuS2oysGqdžܠ$q.[Pd(1yR߲LՌᰖP 0 0 su$[Bm6x k)YhސƦjsegart9k_+2b"&X18-F>q)sj ^@z#SM|w֪oPwc'[AfABƴW]_E{4Tчpߍ"h$w!ջp.pOS^=YT`i,L SGV6 /ڵv=zYUF)-jMU'/z^d ʈFb  TDog%' R&n`XY;*=fKՂ{#㇦鞊St)#}ֈtyVD+- 5DaV` xcծ?U} hꫪM)K'P+I j_>&hy2hD{i:Y hcU}`73&H˺_^7OzFZN^0ep]/6:սh3vN񲥯v?vE=FgTU{iwYv-t/L$1gv)k5 8]xƒ7!HBR\;Tu ꩂ)TzkhEZW{ۏAgidTd XrE{󲷪~YٌCT L;`z ƂyK(Ѵ5ZY蹲|̙}n @rzrs(xx}򚳖{v?v{ՙ,  \C:V*^陎'tMckOϭ_ɛONyoc @k]<{1g9ϿyNwj524d eA%GX&p`ì/l|gӵ'8-M3/C/ ^K|? _ {u"lEput 4*;jkv`s^LIFF`F"T=BieeoOqŇH׏V?vKke'όD%M%#?^wY^BS =+iOLNpY?7L2 4_ZgugIôE~רJ\_0Kl-v&.glPr1SS/}d8FS~o"]ld%_xzQ靟&`,^Hc#=;{̟?(ŎʾI|VdD%MoPK^+.Q_umcV-JT@FEfVK%ZjG3.3M\&aL~ ψt-r_'N_XӿX &"33->ܶ`mEՏ]҉jVLMʕhў6_2uoL׼l|Yٵ oul#ҹ (&jDzs#3'~ö_̺$8㰿U|][Jۡ{"-K^Zv{w1@#%bAKc}otܼen L׵?^jNւ_@]hBzG! y0j~f4<7o?O$׈th=|a͛;n_~NeX2VF `%S 8eq-Mz{Ӑp -XE~iϒQ5JH[ ,d0ԀZw4hlGr7b@_'ԚiI@Ga*m*T&ު2tGD_*xYʻX[O],""-4_ z)=#S1ÌD?_{I} GNА'i,2|J<%eh&~SY&5eRuɠNO$oM5cθnjR= Am<1MKEUEd1%Ђל8F_(5ĊA'bloa(2[3_J725_y:oSVB<{DY& FIdTNU]7Dqm~+dO&ߎhHnx_hڛm >4ki"VGSȡwri텏FSv둮+Y&̏ךFס+6ZoE 4$>~4 ]Ci:v`덳W͋aͳb2aqQ8fq n"}d Ʉ|]ZI-UHtjLcA,kzLsRM-( .76#'Y2֐ |%]-F4ie3h":ZF)X*QɺZx_wI[AO/0]ϞkQ+11G[~:wz*q _ngŵV}@Nd$@+-387U'@7]01Ic}`7EH٢[ctqͤyhM%f~8r`5Ju?MmKAѶiho(eȔ1᎓Y:1u~Q&E715k𑌱=@+w)kes 9 Er 5zvTfZT zS=?Α;OMD*J"Iha;8<4hvOE}VCG/ $>zc##{* =@zs{诙۱%h2v|qSwwNy90n, 9b''FJy3z{K@zFqG'r ]:]ܟՃ3;.`T3}%6u+IQG{'{&x4SZWoY}m+z35ρ }$6NJlxsVVrdvm:BݵQ}%=ZqϨGJ?kǜܓN ŇOtnЈt oh[Yqw}ꑞ[5{B '+qwXjDO7N V#0y3c Pj?#] X2@SMOnn|c }-_m+K@-P \ώuy.G54޷:Pӓ{ui"-P>vU_ޟt==;00(;V?~i6 ě(E`}mfO4{ǵl?ХgT#i[}=+;kF Cߺw3N;!]#ꕟs{V.Ңo>9'4 |Ϩf1N;p}IV}`/n|q3 'ӹ9D}-2;liJZW3Pu~й`5WDzEWh*u4>XXnrI7=e{2s=hqwfl\Lj?(u=e[l:0|Z@wrħkL=) =]sWٌCW 6qw3#?A&SN܎_so~P4{cxueϨ=`[ct@}+Ηe#ii 1\`Nq3&3=>k>6挜,/lY!+fr}Os~'o7 -gq-;ǣY@<[U ,JZ{N? @'OYzWI|t[˽CsKWDl2"Nm-gQ-$6=+V]63aq.N]Jn|&ucz+9Oe=gUrN{v.etMĦ&77}x. kvL]wlLEGx{o|;y_º~aWiͤˍHo<uoiPͦIH1GcpN $6ߝV^U:y?`xW9^p}m0=SH>(j E,&0鿎v`5MwĢck=X~/ k'*Tn {`HIii7=Lӻ.tyB !Wep[4ѿhu_oڌ d RcR?3%.8Tk]EoΖAܺt+ߎNwl}'TTW=qa5/侒R̶/ۙ-^Ԏwx]V㮢!И;xW˞ ̽+<̮Mw뽻fjzom7~k^jEYd<}>ӈK*k;{( 'zg7w~z?fԶKFdS{Mk4 - ˦FL뎿mnZT#?-պ7}p>kZ5wރXIǾy峎Z]9gaG@5BP˟hecscXv%IUbLijuA ֦r-[̺*o@O2p ')`Q7gOVqekUL T'-qQj. ׽E>W>dϯ@0`#$65Sv,=恿f 2U'ތ-ivx`W}ͻǸ%s{X$^׳rfD:ef |Qn_˵ `Uy~N>e)\M je>kOY'rщ'i(R]m@}xS>ZJѩlXlkt¢֖LꡞQ@wbc{ 4do;lN%m1ReP^qeЗ^HKn`__QnαL*dGɞC,!K%jYH꟝$hg7;l+"q i o LugtIuW<;Z,ȪuUZ:sR_#K*z}g"My)g;4-@wl;U9oOL\}ȩP9g!mqJߘd㲎 *c ?⯝|R^^ ry[oiSQ}0J5|'߆T:_x˻g\)s̗ߓi<*_&X&U윧77Ξnw7~ޤ?5[KqZςz_籌| ]KKƦxF[2a7n3Fv@㾇VB;Lm@Q'_X 3O騷J׬`Yc @'\\ Ʀ!r/uU2Me3ֆ>[,vq;߰b7KHB3>Kx}8-_y+dU I kcHW@9*2*3W6nyQUցs',{C[<0L3Tt54 @>%{U/4yB2d!:s,LJZYhmpnSЗsL9PDS/;y3x+W6μi)hLg,&\jo0ў/L-k5{e N>VI%PM>q" k_ipoVAIپ5 Mc<Cl:`t~ IDATL=s%}5N(Q)nu?[ NY_x߱=L,dfI/Pn:-FWzDm\ ,y*z2^:&))V? 2QiH -)ϺhmXʁ=-wVZKީrwGϛ(4||cV^XQ 1MKn $0=uLϊv^&@ex1< Ū i26ߒ=tIP.~4^:e3H CcxϢGkhYSo 9 vczn|cNǫnjWJ 3At︍1d׾WKc4Ȁ;/ +|^HbWeɂ&㲥|}!+fQ-x"")5.`rU,6N9gtM oM6XV.y~GKZ୬{PsYC:e4H 7 e߉FQQ^UYM`n?߆J7 nG0t/!a2;}i(X Sخ]Q+.3=%%_u~ˆ~ہ# 5 SF%4,^yu/ @ya?/gzz2hvVZ^Jո• '_ڱ}332 z=uaG$ Fh՜|UV.(xHik+xi_miu?!j7.yvL@C6'|+i/ *>R;gn#@*O\`fI9|/7p|F+q*A(M2Ȗ=GW|,&Zb*3}6tQ<=E _je)~82=5tm 1CXxc.~SW0۬J>RV߇tlYg$gxV+%h\4GU'?}Dc'=-kgMy`~y*M;b?!,[!׏<*層le d kA2w<ˤ,86dd-oaDt~+Җ]S8?eF2Xr{Zʗ ~&}hOƼ,XYa9R;CcV-iL\?8o噞,ao @}/V+ٵS [Y;)ݾ)+rB< #ϯnhi1,XUx8һk1Kj$ зOLS^׾&J/E:WnXTfNkLy1ӈtg۾,|uW>jMG峥f : -~߂P" &|0* oy1_ķ|_C.iȂ+z0l#qޛg;6zk>wm; rq :SKtOb cM'Һ֚/HOu40tߠkefTï+kk v"=v+=uIZ\N pl^H+cvOG|5Z߸=[H`T kђ:0"j(Π- *>Uyb/O1LO7> <pgv#!^R{c2qϾ9m'Zzzȥ>yصt= _[] OQ_'Հ'gG"]' q"P+IDSӴzGUٴMqW\맩đ@q /_歮\0Aή<ruT x)-aQ$ l t6|JAuLQs uмiBjr@>i2wm]Z54l\yکht@}5ﳓ_;9M%uP n*LϴWRk$~nA?c-X\wS"ݎv 7Jƻ7dVv񗌓ᤷ~8bZl}9u3歪{ [t<޳UfX2VXb[dx?Heژ3LBή^t-dxo1Szmϟ]/S@5_c̐MͿtݷJWZxsrZ2(,ϟ"X|is 3JGLC/fjU5O9; Ѿɣvxhg,6+Ii&&~ч@o$=e?eQ(2,ݾ[dx~Ӛe2"uḾ x@ziK+,74f`Bw\|ٜ-L*he?Nۿh֡44O<$8v< V|[eZ9Md`لdvYuN1[੨iP'OGxQ/c 2E֯3M MV5<&ԗl:'+2lKȾȟkQ#߁ݬ@IJ'?*hB׭eU NN!'Y&~H|nP+)JF4b7e$OX Pyhh"r4MDLo\6jWPw_e q{cD{/5`:]w:(MmS}-L<7]hS:l2d*\s|]\d*mlƷ6؛&5zO{ُ?j֣T! V &1sַ\:}=Ϧ*4hoC6W$>W?qF5nd٦҉rK2_d[t2aٗ<Uow/A0sd~!8ZG&#47 ~\l'0D 2O5!XPػJ8^/FVkZvlPʙlKdYe'!dL$Q=[ `E\~r8!"_+jP*T}f63FgDgw2ۑ*F"MO$Dhz^ ŃO]@toOq)=Ր#?Oa֋'[{)lپtl'K,ψ2ԷF,Ub۔@ߍrw[ZyGfɅ_ ˶5vm# _nB!@d}Zzyԇh4"%uMm,!ļ7߽e-Dr5U\Q #do LG'?B>%9,]Q$.w:<Fa O~I@#H=A/8mSٺ`D5rBBn4EeЮ"2s[W:2H"$٘~y!`ǓMCtrC wR CaW '̌!Gn}$coqű +'7hOQ #ӤNN7 F7k/Y9dWqU?{9z& -PC@UTl9 tn]|2Q^.xS P1BA$ ][:9#Xegcd˛K-a2tXҽ"!޸(2P ĕL>.2f˶xeJo4"eG2?Qlz64y6{yI[|:1)MCb _?d_94ONv?!@ܗ禹Apé ɽ оy5ݣR=M}"~\9!~|̀x m]@;ju@s9q(l0^o߸U%+*^=?$z:=]BF &{2'^oy2j48HGk=7xM3dsV=D :vR͐˿.6Q"*HQ%}eh/ZT1B:AYEmh I=4-bP.MhbOQCu?;x0U)׶XЎgƚ7E*@ot|mm?yVr c"WQo5IԄ$%ZK8yĜo%CCyCƇ=q%4ɵiyRB|20脆 OfmB{D90`T&K}$ukr]C`C]CLp? ^~D(]A+!D0nmlk&My _0orC@;Mh gymJ_"yf`;=39ϊ,ӺsxQVrҋ~Ujh` x?3T]s)*^~l6t>ͽ'{{ yEhpܱۦ?,3[^)xFDv}8c@dQ}L"\.Dh/Ưbîn`2cUZ?aH˒_m cKP+ :!8yM`I]CL&3G1X(Bp0&5~TXLبKsoy e/eu pdtugFˀu hs6 sq5i4VrqVzU73UVsm=l|m_hݣuuxpY~ȬD<<0xx: 9Μ SQu$>Zx,|i7SR_+LXvpFC"}mg*Grrho^h)^#R=f=߽B^sѪw/l[U*D52t! x~wG#rkXF?"4<4>۠hK//UOHKAzBlFc~8Jmƾ@9vWYِ J :;C.FiӴv@%%U JVNk2Dwo;w#p(qy>&Bs4m:HhGʯ~Rp u'M@Xe{2Sƶ*&LJ#nItD]Q\wBU<%ʨ-uoss`ycVV/g,H'3$ 3o;Ē]9 r%co`VUDf9ߙ,xHޯ$AMi[cPC]sk_VOy@Hm"5g15Ü3Y(<7Ba),#FUs| Fx2!?$Ms}uH:[$[(4;䅟1| 3mD/kLz2;V:M\uo;IœgHQ6F]:e5ZG\"Ff*XȔNBIB'\3q%;ɱ*F!]}yOFڏc\='}y]OF棩,O:e%׉/6yg$* d {l%-Ϥ FOB4l; [7YJom77y?@ _B籹:Dt)IOh&wہO**A<޽@c‧5#Ͽa v_ EIl}h##|<- S5俜1hGe=rL}杳9>Xwsȡe]}m]cbwv$[g؆#OWkhh HUuO#3iM)UY9z|Xׇ3 t<+ژ}jƁ2]ק2 =N~Llgx0[s1ZԙFɦU1a5< (8pixIW+j">'o C o gܔ\V]ј[7Dτy&}gґ/U26Bbɭe|\>/WwjVy⭻`0x2:39aQ0M>iObF1fiR2D-Vtf0E`#b5 B*{MOS xFgȭN;]!3X$ɥ/h_~̀56iOβGK%;xSeʠ۲xUjC%Jǯ %%7ZձJD;铻{Q17?q0n(Ni`"!Ѹ#5Dtɂ`7/wqUN wnRxtRgx=[9\ ۻ㡾o-eu'u{).\yvWÁ>T ﲂ18'u@ԡBDt*Gy{tiɅ+! c;p4<߰TZh5$WD,(nׂWOrK˚FU_1l$o&bG}uhy@sc۞dn N⚧|b 21E4\2yM`r)Xd~^&_J9l`WS߿hڜgOpB\9 zxhSmk@ xwHp dƚ|'f+~RCc [|[ (%PI Y"%<߳( «'x G<&Ihܽ4F-]ESW( DT:;7 V"15O况xre-i+Qty8 Vͩɿ6޾ާqlÓ=]u WX<<B]c2NS6:mu/7-o:+ &DP8f6+"W&]˻v#NiJ^OR+uж7yefZbc{?_hۛgek;ۻ㽶OCfpO>S' M,.$7h؍fY]grb G/ݒoABR\qٵQ _W5۞t:[oY6~>3]r!e}tw7I9fj.!w&xDƐk]Ҽ#c!w߰Th@RƼFL2NXT!*{i]|ov>垡/>;;'wݮ-@Ό(&`ȴIj:W]d5@{]CsAp8c(0`xیa6`#1A0\π0?xl@)lc\a K~5Π>jMPڟOmv61GASdz1/Z-q]1ʕoMbA3esuxy]ҿkoZxfrKvUNMm~.cH^G.~|myxˮi"BnIG[uTI<ɍjx4:| cDW]19 \uF[nx]{ yEcJES\y/rj+KsA~|t`Voю#T9g\3Ythɾ%s'O_Jr{/zok]3ybкxu@MX0mԙh¿qI544#usF-2moNԿNc5ѦOg TL\vkuռ)"hB.~ZU8r^& MՠLr JBO/Wy Bn2 L%sPwń\7C)(:lé<57np*KΕg rgӳT@궻N;c4448FCSݟzu={`U[v= F%;G1Oï^Y uZԋ\ ?jġgx[y M Ʃ9RKf0=V)WȳcΧ0sT_S\I st7{pMNX|R# Ϣt^g[t;$Iy,TݿAU:~47St= yEW4Gk+y5UI>V&*YR'g^7Vԟ3nEoh:?;{-UVgAquz ۖ3˯zL6ضO{i7$z[V ?:i IDAT͋pV7x&ӝsZBtU_F꽑*r! >(D>e^[r<$Y,|dd.Cޮ6b[{nǑ[񶻫}3G3^MB7O"O#C_[Y!Y8,^y/0-#'W@Mxh88-ljmwxU1a[/x m]97b~Buh'BgvמW~壡_+K3歴j/k;.mwާ vޖ[htxjȩ>xgٕ'ʽ-sb{>]h5T H~hfA( KZ8~uh=;w\%_y(S4)+gxLK xuJA2k'"//<u 0 5aqOݕ˯zBa\yN ЙHEy:1lvsaަBa z'WNm>u(N&#VB'Ξ<'pI}x @҉Yg=2NǦGxr6k @hEQ>X8׊]e~7a1~ϙrׯhqoPT:.(.z2OeXr!"Ҙ iCɅiSư{ĩ?Z~PW*[%Vz|ccj-9Fg$ ir<Қjٶ9%2MY BTk+$`Ss)㗾~x495/uC D9)#DjM,TO,(@[MfrT+O{Vط`$=ۗΜj='>ECjh#4&GFf y=oZ-*^*fjGXr۳T QcJ=),Ɣx2rG SW`]?4H gzJt},ʲ%|{]Rn" JvMVZn;ley͒x˽QWa")]h,tTE(;OM0C t.VóHL%G&b# Å`n/8W]Qͻ9| xlNt}[ ocNx+CRo^,i/%zTCQ*(rgh fO~Wx΄OK>کdl^LV/ٲ ײR ^ Uq39Vȱpcɧ)tNw+[;u0g,lmӶ]{WP)X"Ofe9v|g*y&5>~mYFfCU XC"Z|k]7W~Sjt}vi,tq u`C<0/^w_x`H%G* p:p1CAk rULzjg\n~{_g*4TUt O@GzGwAb7\e-J_kGyr{) c Jҋu:?<`E#= Cj8F- {N?QnSR|/Tꖷ sv:X0pyCpr5I8)4nW{ e<&O~Zv?&njJ r> Jɩ=kS%khĿ#@ƒ_ usdGKitgLUdrȈoAY+z3w*5~#? >_gQhGF|vr1C x:!7KEkpse L^ȴP7׃9/_}{9=ۏWz/gTNL7!q-|UV[;~J( Z}{-:'ms"ϢrlS#}N!6]Wi+?l1x^}{^ t!?dx)%!ʰk<ع'Yjx JX"&"i&RGbakZ*Rr5o?h IMǵf jp}Kg393$x 4`;s";RqkGm+b3Dޚ@Ms@H β5T>(v psjϭ甗7l 'a5Y}]- `5v_I0igv yxpvSڎȜ۷)Wń(J5LI4ޜcc][^<`'x kY"#;ҀkiGꋼ|EcZ(qGLxn V߰TH6~"Z V2zp;~ģb=ߟdrm# \/P9VJ$wF{܂_MVK>u;&wMh%SL{=$s$u;=nr5(fJݳ}o3cW?e@;-Rtg!'u;oNU*GK*FwyMPKγO}ǖˋx7&Jw$Fܝr{^'>bF!w{42\Mr|^zD+$I@=x.{Z*G+ ͉܃]GZ3(a .5d K2l|.o{o;>he ұ[p;gv؟2}@ҁ9vzbmw ofh{fܹQ|Г=Y~N` Lۏj8#^V]H.{c 2 #{n? k iT; oG0ȭ8`#_ j1rRZ;OsSO_=̰V]qƎ92ۤ]'Ij8Rc'Xҷy^a׮=]g˳km5*3)ifg'ī oeyfߌcѱs,h=O~D>^o&[sZ>ۘh7?8'0>ds]fYՇ6[wBʯ0yDdr yVY/1R>sU97S]C=3ig05`r aUSϫϬ[hezpi{}:+|-hS7c\2|̀9Нk!rl_CR;W7Hkh{xTƓYKjॺ?g'3}³U{KueVg''m xݕw[зO+xx~& =Gϒ5[?_ҷ?44F׉&oE[6@;sZWVxC΍@3ߛFN}9] =3\ztڮ/+lKDoyx_8m63r>h?n5XdblY+8r g5mauv:5L)ߔS}FSpU]7+:ٵ d7Zfs,mcSH6Yѳқ?X^y6+YȖmeo.?P;y_D6ɉ,3g3xN`eGl9 +lsoLu,+d Eoz?9liπ϶jh]C@%4;3Wݣև$0|TnOS'5x>.!(3(hn/^3ꠣt7)wܠ8[ e79NV r'ݘ-H} vߗ`Zn[ej +誨Y:s +? N|,$`q-5``ܳ Gu^h0!7&7dekkbx#z8:چ?iIl+!ngfvۘ`6fǎtrcVmg%:?W<Ҙg,`le;^r'dھ f> 8'62_:+`d1iEI[pp i[ts4ɜ`ٵ<ʬ;I huc%0_j[r⬮s՜[V&z`IJT0%\6˦, kCYݚ@󞹾?@PVsגgzGN50lg_KuBtPh00 R/y.nedǻLGI7򒓨]mپɳ>Nek˄ܦc~x _XH}DC@Hwlw#[]ڐl-[9'X\1~̃Cok+xvc'}-[4 ׮kvx8<)h?O1$='z9c'cv6su 6_t錄f3~FYirמ&zZV,(y{)K_X@C:;ӛi,4%e2B6s1 jͼoKl{}S :c9@a|6rޭg:7> yu Q+-x_##ᡳbazjv{;]j8Nhh[0p3_{"Ult4[MHK,E+Ƃ ҇ , R6ZDEDQCC%BbIns}~;g9np̜{s={|XHtL30Զ|^J`lthr6YeTL ,h]9tzy~#"izANe6jSW޿֓Lzն-_~L[wnwheAW޷[ V[|r{>򽽟vAQ]ڳxN7r 8<}Ĉӓ\*~0؈B:Mu_\|[Du/ANZIq'"%AJo-P҂hlJ/DQ?ZS}Zswqy`* B&ӿ:xߣa;E^Rryk4Vs ͣ]zO>S6 rm\f.Gn%y\sZ&5&T:'R 'BJ疕 1IDATɪ5&Y4G 8-`ā9-rw<ѫ&pa,k,\;.-\Ne,_^/$T޶ӇyV\/i/3Nۓ 5-b$cOuݙmOC#8& '=Ym]eOkֈn'x:tk" f5-17fp8~:Nm5/G+:llNW{W.<_z__Վݯߚ灟Y[j^i_mn5]M)Nk @ڱ0Ѻ~Nf!rKm4:dYנ&dfe 2(OiL,εןau[,{c-u.:&N_ڻx[g_ypñ޸1Vj'ujr/O_4[r1]Bg[hFXuN[N"kIb6@+6PĠ<F(sc2s t 5e>s<9xcv/_3yɽ]*_/L}Lǥب~ sz$.OqvIc=ZIFlqʒl2nUW.RY6ϔFV;6zp1^f{ήoNuϢXYxkcoiTovޕNΗ=KS?$Eu_.io-(~# 4y &c)ڋ6OjrRG!/uC~ӖR+x9iyrQhЁPs 4i8V,oӄ5=:4?֍0[֣L귤7vMϪC 5Kdz$96"72v޺PC.IF@#udQig? aNic>(&]q/oXkz_aXt89sE>0٬fˑq$.157[n6{`a3|[y 9g?%pp"|<g#מK~+Ke L4ltӿM{;@_iQl{|DĶԊ+D7Z@^zc92W."t~w L_tk6yrcg^ɟT6=.IdK.n /[Գ^4\ %s+m޹xJr; [Xm_G Znyst< J+m"x$Z?Fn< PyPRス0kUN _3n8Oc1SW=@FOojH%_:3sݴyۀ65FekvÖm۰^㑾s -Z[kkӵPS|:k4\I9"VMcK|Mc"!͗c<xדj76íz1v+FxbġTI{ZBzһtwp뫧^?Fٌhr ߊfb[(ΒKPh,Ev3.Ulm^$?8ZFo~o?ֵS74i(R%\cMk.Cpl3kJt Ǒb]C7ݣbKNt=lB@;L"}a\ q\%$nqa c01aM%ë IENDB`images/other-plugins/meta-slider.png000064400000040233152214270100013521 0ustar00PNG  IHDRcUtEXtSoftwareAdobe ImageReadyqe<$iTXtXML:com.adobe.xmp -= IDATx} \EdfLEPE/@AWW+Ȫ. 9ȝL2}_ILB}ZLիw8'N8$!ĉ'Ɯ8qĉ1'N8q0ĉ'N9qĉ1'N8q`̉'N9qĉcN8q~$O]|.-Am= AkVM=ouh#ڡ,@QcXK*wbl>Q&v"B?DP4]x*# +DKA3dhus=!%N2NG:rI1GzIC1t"KV?(5&ڜ!2ǎxMHV4)|5TĊnI6ڈ޳#rq9Qj6sq!8ךb\S';:Fw}zRQG TXcDjcDe3;uIߋqL݆طx d N-x<{0: C{&-^Ox?~ "πt1&06I:9`EOXvh}̩"#=T]scH3]ֺ{`]6ǡJ"/@ڣкΉ'Ɠi O@{?cp} hO'N8Q:tƳFh;F@)O)N8]ОYhoAʡ3 Sep('NV`<ڟRjjh~ĉ qhLþ] Ih)Ɖ?r ӸFOiƉ OyN'NN0 ڷ~w}O7N8`oc]hW)lj'Xz>8qt<h #q<>Kz8q:GЪN1(=`a@M&;/C5fS`A)$ycd ={9Bx yM9Ae;y_ǰOyTf6㷖Nv1%6U8K1Uqdyg-ХPCv":\EλQ~`wϋʂhp0|AD5gWė灩A\m8Q8݊K>/ kPk 6ALo$ؿֳ Ҁm_§j2GV D K"oD_K:_WwN=-=d0σcI_ !hޜcKcWw]V, T(n!w L2pS{,//du2qdlC'id\* ^;:uLcfqJo(w(6>t[8P׿Ķo9:1Q*JՌ=|ĶV<1;;[Vjn4.*RzVslhղAP5*I:K bsd>rޢh@n1z=N?M> ㌥WV{T\&KBy7)UEh8'6NpH]/RqeAi[KeJ>h@fym\n!h#,%f1ńEGZHT zρwu > tfQH!hߙHoOg"`EᢤhK277:Wa!IvaE']R$xLo(|6C c& Gu@#Y7m >j휯:(*bZAxEbQicN²>I"EZD-0ꅹṙ\N̑ZY"(*:ؠ9|)jgw:\cޔ#)895&HxaN;NSF I:y7Q}"$Ri-yz؅=cƷ|/)~Gc6O/ Ƭ9gc~0)Mc'rl@e"簳gC-WǞ#cIy%|~ϬeD4VI$qp^h2G{\cr-3HG Îs3ȑEW"SX8$P>7Ѻ m18] ↌ J+v80wl`|1.A^sE`6:xV~1㩄1T3˿Xpz@cǙԀ1爪1v&8XUu yAU(f1ΤLu U`aBdb3`_ mtӰ\= qYH>ŶiX`  ^iZ~U1@}pX3=w`i@)j[ 3k>E*߭~ ~IKG9w̅}O~1y803/5-1`ons|xP@e>Vh6aؿ&nyk ߛR ⌻CCg26۳.kӞ%VdN=6(x:Ub2Bd-eჱdIl߫RN!2tjl!Ϭ%߁ȼ]j2[D$fA&\Η>`F6QZA]+A:1{`B/Nvbrb|qJEq0}>h'kaU"˯R2c摣[J g o)n8hycGcGd Qo #jFQo|"G"DI:xTba1sSEE fш1'.҃7}58fnr^73X`,H|k~ >ݢ/% 6.L5<76x\4.5O9Ҝy%,#↑Rn 8|b%Ùk|ctt>bBUIMcRVܡT*MeXEC=wټҝAY\lbw`׀t$ $aYw'պYK? 7ʬ` <131DT=X!+5M|x޻b^ $XִN`<(_b>0r >H1=~ 9arWr4Hu7"N8;.+J&4S0)[jaLNvTk |`Fdt9$dXp_{7]X&V1=, n D/=l&~ʍT"-祸 =-]PQ?+bYWsTTU5"1W狨F% [W@zO[ ΄„}JmgF=\fA72ӭšaϬE/lZ <2!-x|D X A&(JƄ}, "3r6aTyg-,}6u}skݴ4l}E =O/JEzn0s>wڌ<&üOsC5Zݬ}MX~_C=d<`z|v<gt'GEr:t=z0\Zw.Pߕ8r˷ sgU!$?v]3ꤋ?Q•61JUïkNo?ŊI SF7]8L+'C5ĿLq2^Z-^WPG9ſlý87 qtu?)j3_b2>V[kL]G<"Rb f-122ۚxX%C_ɹrɮֆdXIzrgɞ $[W`SXӠ"Mv=YJz$y~'Go5\dCc4CCzbig@_nFeܧd= }5^*^%,}e.a:ߺ`&$suGSsJ1ݐ 9-.&PiiEԪcab$A% Hde ]WQV|A)U$"A @@wb,ก m{۫DE2i>|:cPʪW9Rf UXsVj H+3s\ +w~.A _8}m9<: Wrez7:[X|/^qs(kk0z[ 6<8oQ+pz,y #%W£@p7m|_<_D5蝻Îm(ow5,[]MzJ0R/X"JZlߦ&{۪W?ҕ4TW%5w(w@?9>L oKxS4+0h$Jnp Ԫ hb1>DX@J>E%Bթ 3EFNkZ`tnνTMvG5,@D"cCq'+{GrTiډh # erl= ֿC V/($]sCե+ξ::x=qcD'nT*g^7Ņ>_:up OanӞ&;cޭn-Yw j/5ن0&j>T5d @%+ix/!BfP|F흳}YIܽ$G_߸يnZHB{Lcq7AÜ71- fțO7\_uj}klPz+?;khr\9#i^ջCz ˎQݹzf/91ػi9zvv4(9y9:P[|7Ee.hs0>%WK#,)OO߆vaY>8Z??{>tS;iak}P}%, f/AN:52d}`)uM[yXpnCRk\BŮX@A=7oUijƾEȕ3Ź73p;fRBr XuJ'v<2LXD# 3v.,+ `MI&nu՞z,d:DGG@wO[XsMJ.s1/o|'6*͡w%0{8${/$d+a4=5,5} fF#I9虵.[_ ҄9nDZt ~>0kf)`\ۈ&+ riad 27x/8r 6}M%׸9u_w='~r{Ϡ+ϣ\fkݢ]m^(zÄGZՙ4?)  K1Z_Ye#=A"J NKI9c, #NQa ԛGnI(/EhBLlEB%vt| F9XFdbv HR&(s#p<1˙>YZJ Eisqh> Gݯ`8LbGӍ^'eq0ԌLz;o)3~H)W$Z|e}sW Z 2 `!GOeD?^+T /4a,Ly8ZҌi,lJŌE_@R*~"5FZcj;DhﳝOa (%TuOr?1p}7sko~o1Ͽ~kn; +zPl9=c\nrvks],(ڗ.aZݥ b觠'@/qE)Dm;;M56p96M(Y%V=$ycPOȨ]XetJ-p39*OPE ;4~,knK@ΘG:k6c!> F]7r:P؎_yT̞jTB9 :3_0{Qa⧾`ٯʳͱIv93鱏__yJROxtl$b,n7qKkؔ2 $bnP4(k rIesd⽋4dZosC IV(ChGVѦܭ/q uf 9HzܜU&s gWƴL•]%\@`wch{ߟL?roY 鋑;\WLZm}S։zI T#Iw%[ y1 To?rGH42WM P[,Vk؎rwPKj9s)#al\VK4 ҙ1N޶IOC%hY)5z 65xit/rGHX2dpL )Ѕy)ˇ-b+Ju0Ɇ#%4}5C[瞗?tkcbtsˍ gc[s~Y0dO=5MAY^25v0 ACnchZNz8$Ѻ6%ZDju/ 1MN+}9~y_vAΏe o ƒ,z8)LB8uL!.v_O(Ս5u>(vg^Qg942ĠTQ`0=s6 \[>Zv.L)u}hH+Gopnage"/<","I}Ys١RZbX4d$JݜoMb/Q|W+Zʆn>Xe yh:faD2R= Bp^+=><#2kڥs3d:n'X̓ rw&b[tڵ2ѾZ iYrKO|G*1hyEv8[T}jhԣEl]'rFԹS=5Mc |6:ss% #U+9 {c&xˈ\oO$T{1IglõR+"3 l\)/:v+D/kl 3R{t*DLW 7F{F+A0ZDdM#5D7v^" ]ۗGHiz~ c: #3w !ߔ,NZʽ!Wl ZLF?=5oټ!cִpV1n{\TTN& 變Ujri-QaG#5$eD9*K]O#uh FR5G8&rS]ڰܼ1W麁FEv,$:Q\10숌/1GJrU޹+f.rSD`9ֻ[>ܜ cEIg @]j|+0Ibߦl(K(p+:^LlͮVKnriW9'$GH9}Y.)i[|*Q*g\W |ԈsWjd$nN튚cN2w#[qMI 7PIF/Z) l !u\$Cn`QNկ KwwZp ȿsR]R_QyaPܞ x!8>{Ō&ƹF֢+0u=%oI3R^=]h{]Uև䒪`R"T]4A3\!+vZfd[OjqA$T7>س& ߷>NdA$Z7c&YN?Nۗ{NܿDzJ%h.JϜGxd{I>KVIէC(-(Z@7G,ȯ|~EB14p00Kd(wnY6LuKEÚh';Ip @ˏ,dKt] 6!b{yzwC=gcC^n|ߖO+5@}^}nwEcȶ}Ù#j]jF@p ;&*17_岚/KoU{a؞Wn}0’4X FENwL3- 7Q$RaQ^v}€u%߫oUMlTK%TGya_b3`פi3$j]$gqSJؓa3zS欎ImUjՃЧ_ާZÂO%Z__߻G 31/=_1lt3 } Vo:~3>zt+ۃaw&ቅDQ0NT\rVAZӋaԟ]| (;Ō=.LзMS:_%QLs[ws[Oc>BpdeMV!=d T&w}3g GZHnQXVx{2r 63C%sP )4=ەʆ}py0:I)#5ůsؓ.#Sn(%ya|+zR tލ7 )J,C('gӕV癵vx_Wfk]gdU8=}' $euJ0ex=n{f#lP?eR^8M3S8V,z%{fS*Z9"?o<߷Oɪs%v*J#8_x7Q!́Z`"K䂀<0.Tw]Y ؎ L[$b~&Gv<VdT#Aݞ,U V7",R9/:c '%I౓F24G*. f?AEn|G^ yzW~=AwZӲ/vp\^"JMs7'&_}]/_\HhSϕKn/Sc?%U/ɕZѱ'(DQ"_ lשdCO7Gs|pu] a3{g@/e/TCz歹8goVGkXp?lЏjE/=wEvd\]Vp1̬D,0/qpm׿+N6T>5xw ~YGkQxOmzt tp c$?< Ntթ`??UrM\LE,45 HJqErRZ4DS֪7k!we3Vz~¨=9˯@}-2cMAXRZx,wלXrYE.wzg^46sИ4F{b^*pELf;o ?X҄qpדL劺k@ %:E?YIKdo')[.V#nꁒxͿ7 ٵ$le*P_#9I: H(՚I|c ]:˕f n|E7!y`x0O)hM, H\mخ}1޺*33D/?¸pxgJe]3gof$jS1z[27Qq 4vv]sWXw{*]jHA aҡj@ 8Doѝ頡AhWuwZّ A̓ү U*whjGmS v 0l-h<+ṓgV`NFz琉<(6V(< 㽉g:$ZG*;A6+2|oB;@+T9)_"& sbs> 3IYPSn| $ꡱnK&S3kbQKr;5Q#wcw_9h#=Q6&pmNF?1` |a2uh kfh$|6룱]Qt |StΌ_pkQO̘GO)r Iмc?8G&in"}!%igc ^t\DC}  !о* y?%O W+x/ l ga hc㱽/ЍֆrK x0&۩ѐ~7kiLw<=a qS-'o2EG*ǦL; : (Ml:oDT= Y)1(3g\iz+ S!7Dp0(ORvoY>w6ϗWG}(o']+ؤHS`wYӮ]!e0]gI %a dreN8xqm'ا] ~O=N8o`i*uMӎ'N+#LC: O9N8`j epK 'ĉ sоq.;|qDLXiGL~QhiƉƹd o=.>8qt1&‚B}p/",a<'N8-)-8v1ĉ S.pAvAUX sp |>3n[AXfTc,;&@ă%,>'N8q0.@[v ƧVy4Lw9|{\\;WEp(Ҵg̉'NogpĉcN8q'N8sĉ'Ɯ8q'N8q0ĉ'Ɯ8qĉ1'N8q0ĉ'Ny 0^=nNSIENDB`images/other-plugins/updraft-central.png000064400000012023152214270100014402 0ustar00PNG  IHDRcUtEXtSoftwareAdobe ImageReadyqe<$iTXtXML:com.adobe.xmp ^IDATx $E.+,7AYD<`D,(:007F% E# ăcGAA@y#(C\cUnA9tgWekkz{zf >u `Y"11@@b b cc(K֞wXJdHۑ׎ {G(Cd'>gQ@ݏV^3d";Pq"5d%[@g{ !d$;@ַsJ@jQQ ͘1fKdoHIm".Md!E]Sڷ&"Y"A؋b>OxcoHy F FvKɾogHo^i` @^}:gD0s"#wDPMv+mzAE>˳+Yd`"FӠ9 c o/)_jrEFU M'8_u[/#Ij/="$GpU _ү\gq_<<4^q̇5}9M՛żH>,;g-2"|~(n坤d>JXYVɶc1[6b\făl8v{*P'e^ǚmBB]^aCO* do.3mUg>Y U-!7cL1ûxfMS'᚞hP"K|O{@ުq6 QĸjȂrHeRfd8Z=K8#H]ZlX^՘D5g(,/tG_b GCzҖt[~;<#x=m#4DS2aIFD 1qZGOU/Q(ږc֣@\sD>Qx]\=G T{H {`}< /ӄkcHNă6-+=PNI ݸ(78Lẃ6<S';i4v(E\#,bdF(;bG Žl]5mǗY.|/mҗD%"şo%]+˸k:kGP/,,y<{b<^IP_KJFqCXK( [D#}X\,n@.>NA9g{Qe|<d(ͼ&Zcwp<xF1D Y٬ob;{DvMvqQn;k :(<I2 ^LN91G=t496C19\bɿḗ@j%jȩ(ea_t(#=sщq7md?ud':/%Z;G .\9S^$lF.Ia_TVY+뤱XsE{fW\2s2qW~p_ᝎDZ5{zqO̸!~%iq7KK_ބG[ EҨClE2p2c/iquou>7K$[Yyd…NܜBDNsbj=}uDnxA.ؽ:q=^,jx^ω 74y5m/sW!n:ۖNKju>P#{:=]q)IQ1/ycٵ sǐ3dW*(/פ6bI(e⁓w5";R 71x Aŋݟ4mj% ;bBˠcy/mQmUa^LY0Řhө G>9>8m\0dv>[(}1FqcHEiZ xb&9F,ɣF>K/T=b\C k09^_%ܧ"' >^s~j 3<<\KwbZ8&0lb3x̿%d'+Edu{1٭2='_Esr@۰>+:(X䏋`E;k=_"mG͡vyi>.b7ЊȮҎ GIDATx] յ=M28FAQ 5~;5q&!$b0gDe;wڵ^Q]UV^guMwwLTEmm( hMP(J BP2V( %cBP(+ BP( BXP(J BQ~hօ6gH'#ad#; ߽Xg;#+,1wL7HvBH{]Q>d42Fify^sJ;#߯62KF^4!Bi)akF12kC>r׍k䨔؏6FN4wjCt((N*`q#tH(F[]0202UBP42FnǗ[.@ȣP(d2I1e.0W#Q(["?A'B56H ]lF}8Bpl6P(;6{q6ma=#YjdSIޅw/jع$}yZ|2 Fƚv6^]s5y_kdyHS#] ' $ yB6m8q˨U*N NmĩoqSBBs!P(#_'eP#Yp#FaP(1ρz8/elsۍCGP2nNҊ4'NNjpy)/딞m}GyB^W)e3oEi*7-PSU6@`<E~y{Snʳ@},s8~*u?ǥHri2S22?w ~BYrbdO9k4FVH~v- /qW㥁ɳ \eNg^%q$h[Ooiyd|\5:'=RC?AA$xσL.LdRGJYH6&w1'hq78 !ayԌh;X[$ӨoIY n8n.%,N `(NEt1F8Ԗ}nՌ]4ym!gx{qj$]c4;I'X.d)NMaMOBgwY.!(g5l9(NFFUϥ&8t29XaF.K0 y8[}89p}[+ ikƇKۉЛɔ >Og+4z.<~piC4],H>A) &.$ WZ.|.nxD6Wan}pǍ{**S.#NΖ#꩖9C?q i 7/IMjpF3 ً MŃ~Q`UiZ_ߠ1c:›1\<8r/qه$X>|>(E*f̴s5fVJZd-'i=і?a2}řh8~G|Vu&Բ-(A>b_i!{G&GFhHQ@CK#4raP(=G> X]@M(@tS ӹM $x!"ϽyCY~`F-Fn |$/zY} hWX, Eٓq?K4\$)<|o@h׽g[ @"CXR%ڝoKa <bzAX?г)%Oӕ$M]Q,|UԠ[lG)/# ]^&r'"4<IyDϵ=:``m rўXAA3=o}D đC35?f88JE G+_Y4O'~+ľ@^3Hti] ཚqaD#@2߂|7$|+*"rl{53x_|y|% \)T5-Z,ri{:|}n_҄VM?ۣ?~|V2ϧIp*ݨٶܟdNz%B}uWԄ8)g?ܥ &ڔ[g$Qoza%'z I6B&T㐱s7k<`2ƵN|FyV$WkVGQ.xr$T/Ipz;Ϸ \!c;%3iΥ؁1;ݲ|Wut{uz>TOt]K1Zߧ+46Udm{Wڴgt`p!5A k x| ׋MJ\op]%dA5 !骐vB"D;5Q!\o6{5ٞwٙbdz$g=`= Xq{!C߹Ǟ{B~?W7Kݕz ϹTϽM VѬ v-Լ@UK_L$5:ϸ=!.y .tGR)K:[ّq&|Anb@w\ q>809}y -Ѥ=(`ni}j}~I!)>LBLwi/fqbCptR{{j| y$7CIFqߣt,峿@˩,i~.8(0r~'!_KWN$BQXAEh rs> W kzR׿U'?-"/ŮЊlJmޓ{޳5 իrH+Pn}}'cP1pUzQ(f:2x\{4O/f&pFa?e?¯(%!NM/m=VR+Kilk*KDz*Q6h[CZr3~F{.@nL`yͤ[dбl@H~ WU2LZGGx}}.NP7 f!'=K8Ш-ၧRYWC o$oxYɻXq d Nr8; ޒ%"0_H_gq>"m8AN(6DЏ}|7hW<=?-#dU w -5#v,ad][@;o7A埔`a[{ς9!",zx$ .h:÷>0^OP+ZRO~R$\J]_JO\MoY{ż"c5[]:JyKC^E뫄 RZ%~1jm-MYX?n:%P7yJ*<&6p%MjbN Ljw3Wl2 l0&PiۛgJ9^p )yA_A ߭. wxe7VumneƸx?b"/v&^L/Hu"{%WmF(Jsi6fҿ4IClu4Bd=1z~ 5jm6WY]Ga>RE*H %_n?ZU/_d$d2OW%Ab1݄y4~[Jh?l89 VZ%Hrh#I雎iq N#5KI Owf+)w 4ȠaH`3`' dE`$!?w$Q 6'>L$v[&2`. 5 NB6`.YNBe45H*[@^/9(se\rA1NJNkLVn BC"{>H}bAApmwvE rׇ݅h$xC'Rwm )DkXDž' !ij\WKK C·Jxɧfc-'2-i 8Օw,'5?-wT=b\4 [$,+mhsIi"(׷9`1,4@at qQԔ8)߁R>g.c"f19MԌfB&CTN@=8Ւ^`ry4;M -w&RKoA MiR7nAgkICH}z?tԭFE_m`rNH_I]->|cVH,,R̫t =Vp'ɲ!N(/a߀tc{`$Y(@J"d;B}"1Z|_^A+D023|3m8MI`flٰH -M /_P#'F,.(|4"zQaL <ʴv-$ P PYZ\rXIwrYEWvT 32 xV)WZQh*HM_؆/j__Sj鮁߾kHSՖsf5z-~/h.9P%wzHyZ ׄ1o1O&c@$s?NUV@I3+7OqC- a`b$q?]-cOD cV1#Gm +Ot2GS+FZhgi؝TK麫i/"Og}xCC{R쿬noYA &Je+-'B+y$}Kn!o.+P~v.p79 %0Ar(ll 1Jp {\y/g=t\I_A 3N-..>ռbi؆"Xнcr T} 7߉tb8ZK8+ ]9b̢6(jXۚ}QNǠ Fc3Ac4o_]z-5fE+Jr52vZAZ5bР\S.@4xjѤvG|VecϻJ>J2+m#'fKZ8A9YE ~ow3֥1 c<$ro<~oNe,ȴ:!oqam4; SM=n_\X UbdX=D# RQ(qt?{v`+$ ͵Flp@U =x8 mE}%cHAt6B#n :TԚyHYd `JZkXD"DA oJ7Leo \(>}6"+6/iu*+@w>*x$b/uh(B.PQv%Q U&P( CFC@]KĩRxkt8(Rq=#wP_IT"DIҋ?P(J?Pv3r fNa[:n: S /nW(+ "9i( BP( BXP(J BdP( %cBP2V( BP(+ "`VWIENDB`images/other-plugins/aios.png000064400000025673152214270100012261 0ustar00PNG  IHDRBN]hPLTE????????????????????????????????????KF??????????ss??$Γss????;I??ssDBss=CeV??s??cUΓssA@ss"Гs-j??7PWN??tPI??YO=C??>AIE??k[GEMH4Y'xr_`S1^#5V6T??xb*pEC6TnXfW??spljwa ~fԯ ltRNS@ 0`PptՀ@@[𠋀` `L00аPpPpi~ٵbTm)IDATxkA%{C~%F6񳖊&)gǨm-%Yy~=?;#̑O~n9gMӹDǨ6=\o9z4q:xF$7"QULk/d' FlnSan^<[xQRh~~*)< Wb(-Y=V>ȿ,|Z")r8QD"vЁd$@1 92QSK˖:N,y7؉T3 Rer;Gf4,6W(u1<)AhJDG"Dg8J Ms}AdOa~0DW"h*TE̟ Jă ]ZDX,̡FP 뛔DHyD"HYCj֫DߐJD1(be 8Qx 3F+jjђ]M+YAǘE6"Ώ#♕k[v ( yO'A"{w~mdR؝fL U^K'A:=3Cd&;?H7A"Dv5n ~IH8!mHU"]A!$࿟fOwYf5îf,h~ 5$Suk >*\Su`NY} 0/B|VA`na< [ݜCMr3畀m9.1U'Dz nN 4$1ɷ/Bpc؍(-qj__R_D4'g~ k\Y^akA:IJ1g~pTTs]9`?E ]9H.c qSu >yS`w$:-wșt`IمAVb0?J% p p^ p Tkku`ZEezkkvwRu̙Ca)qTd5lPY:2xMC ^- )YRuD P,ElnC]#?ULo=9#(]Bm)M햪"t4m-1Uǜ~ U-!o5͡; Fv_h=Aj G &AtQl9#y3DP*ʞ+n2Ruէbl{',^ӎ"2TsxG4J46*Kֲ8uefhy6l em\ӯX6pL:;T oHAPɾy, i#BJWIKAr=zdHD ėCYH!e5Dxm@T3xvwy> D[hǂRhŠ:z{C"WzA@iIiv,QQlܨڱAv|/˲XbQcb ڈP|dd"҄N ~J"ݒl "3%;*uĂ8˨bB1A(@IJvf<6+d;;E]3k^b-eI;{ʇߠ[Z +rcp(AGͬPENj*Bx4ܡйug y~J̏;W6 fð@IK$m ż{W-̫P; ' 3\%(J%t[~c|Ԗs*Tj j˰P#x99|! f#m0OM5b;T C] VN8@+I@ f'?pIF3*dX7bgAd43Lsoo`l'a| A+'%2I||'/?*OSz5 W!Ä,xBϼ1,Ȼ9+ ] [!wLu@"3<9L)+МUjeŭD!1s";I^PDć+m˯Pp>R|a.H▴?)-<%BwCHih0BӤD?+XaE{2xа+$#N/nO~w( J"\!Bt|Ph3?=+iT0_-Gʎz~H06EB G(krvA!S(Umavȱ:" YfP4C;BM& 6%#%W!9 Τ}o @%zλ99ۿeUF9Ql=k$G2˪I+OZ\82<, 9w L Dq*d<Do;Cˁ%/d < u"a .S֡PRF*C~m&r09B02Is*d\X0ֹ}`R(_iqPMpy:D`.͞"cP5:[߬W(GB8&:Fz6Op)T29pH[FBf&[ qÞui3(ĔUfϬB/GB59evB?R?lpK!#0(ı*clcW'2IB  EtWG5T}y|wPUE!~m_w&'P!r.n]qnֹ*DΤ-f~a:x$xIBBe:K{kpڿ \ђ"CRi7c QK?rgqC*:Mζ=BZ0T:֘}BV W0TOgrBU"{(jdۥ:O2*t7Q6jVRf&Z)SF.!8iD>*ܡ]r9b0]?~Yt={粪5 I4!B)( "7I?391[{ϥ_g2L 5EZ!XG8"($PO_Jzx#AFJ~*{<Z<ԘVR E.܃c13Xl,DMHo61.Bv{e&R cAAǾ7 41k^E*>^ I(t,\frU(uafʅIzfyN议%u._AX8f^F7 }juj\!2B'N |Bwοbx6+BsbQ胤BF)t'M0+4$JZwZy'{G)B`ewug:sv j[g:ҧ:s38fxFsVrS:wÓ =0+02e::U6{Ð+kߊ+at Y3+e-YzVhAIff &Ta~A__N+t\B6|r+jCwY:jlY!;)$RSغtcVC 񥄚Pyq4:.ɍM+|;f٭&ŸP֖rIь;BO6 >4jY w0ϕPyzQzR]Y!sY1`kQrK lE6nͯx.Ah8'fhef"BiR/ϒWhW(BDQ.?VTv@xKBhI "6{nwubfWh@yeұ.ev1N-P4;*i,w-/]!c ZBDy?:(ΐ4:+G;hF}i6WתBA6?ip˩P>k#xK=cKeȏbd`لzŭWDI>tКsK;:ȳ'(jVZB-fJpbIz4nn_(Gi.[J!"9qsƄ`@.pA{S>9-SX1˵!l6a95 OEMx0VZ'r;hq;n¯lq?p W 5PZ[;QvRLb4WIa1s|wI:,((qIHщe^.P+\+taTwo"lfp@F2 ],h(U;˿0\^gCBx|7-UP!eq#Poum-5晉¯GPDߺ@2PwaȡByQ-c#(D菡\(0?J(] =!` ),sPoaȡBwy apOS(O61soPoaHWPks*_3KH xvB! ]g?X*)ByhluF|>= t.9N;~3P/g=!;/MP^$Z %}VG N 9ƺ޲e q'?vv   )DǙ:D,*DgY03h@ #FUP ha-W I[*?dQB# *D3O; 0 Za Vbm@s m5e#z ߒ6O2^&ꢢ0P) ~8:aza g7 _)ߐ]{ńSpw#w =7 '˯bʣBk(_n$76 ݃g,bBvU."BG:9 :A. [SL@QB0VlBG:ޙ57N5h2b}eqqa  (-:f9>d%K(W{X둭җQThPLBURuqj6pB&dPՆV62Lca m.p = S*98ABE0ˋ3;} If'dP5r%ȠBorAp[`R eUh1N>a» mC%)8 S|VqFX$3} yGXb[Q3g`!RQ,٨b8씎 N!Z!W?YQUK6Z-B6d0[aax #®F .vZ`3uh a A#슯eMJް \C_c*^j sH؎jl&qD) 9XBAscCwWm4^"Ll3O mK`J9Զm !!\ yDDF(.BLPG&qH5WX̓T!t,k+1( #MPK_h D'0…uBZO*T+6"D"J[Q2reHh'GGVf???r%a?<]tǿD%oi AG !:^3qD** 2(;aY<T`95^k}LhB6her'P_ܪ؃q1t*t[b dusw&'paddK⤾ EXTOs{ >6P(.]W"b jUsm L{əP/-]{ui@ԇy>ݙo?t,)kPڮ#A2+=qWj6ɣn" s9J!tk$@QR{3_&(spͨ0•LvDwRn1h> 8yc]c{%`f0߯joL֍pDm/FܮZS7O!)W^  Jn ?Kz4 OK+ACoaz<0rkkm@obƥP]6%VlB\I1#Q0#iތk|% u*s#I3g# @bT[f4"N?P.p*]:QD0[&}3=A Jy t2S*nPTm/Q!ji(_ B-8u&4aƧ.=rx6/3m@:AP\PʪItgV+$Y *8=p' E|BFDQ07qm\6wA4,ye- Q/%WT+ғX\D!>Vc O9s ׇu&Aytq0:f@m|RR4#W5UUdBHngȁ"8icl֦s{yr Mf+1:52Q`fUх 0 pHn "n5`WxMu(DSM̘hCB` ))*_RUP#N"M— U)]v(BT(ă9#dpz:ͷ xl}k]ؘ{ Γi"NoW^ 8yu@^ Xv2X|^G-<zvܲWߡ3E39'_՗M]]%^ywuUJ Z@eA V(D˦cNc {½0@z:09䉙bS%^@E-Jp1ӫQ G<krѦ.{+ A46 'T(_0ـv@ʭa?c^c7s0v- ß$ocX!753b2ռ5g#+yO.؜]\tq:D(~B[SBqǛ?8lve =EiB^ QVmeC ݝO)Yi5TZEZ%Rnp}JoS')al QVDt9\@!`!kI,{fTBR.8 QsV5uBJ-o׷ٹl\L@P%#Bu՜r w08,,Egp!*K։V''1\WA=­F&6^۲m0_><$tV(Za;0K\hvtV2`>^ ~-(lI0:^4|N^hANJ+ZfM>a%|;xj+ g̅P>˼9r8By흯}ѝ9< w&҅!]+ÕxA0\e⚊LJsl f2-3Ǡ@Y^-Zo~3$d渲yv w]O4IP'vO-RdÙIP&BX"ܹœr;XjMJ$d8F2z`Pٿt"Դi$~>~{#Zm!W"Q}R`%tZ fG 3qEvZRHdӷjbQRD=!=B)D:=!%-2AV^j_ P֪U _ LK/q\yVR; ^"jPjuZk,ZCvzU+r)([ATKeZJ9HY mB x&jE !BuVRqdKG0/B)ILR9'q ֪ VT̥ |ztoA//J8R&q,R(D+Q2e+t2sCTKPe'Dm6;x zL4vs9 ""Gܟ_Mꚍlj1~yuz.@4T@.66F2xn.6o!z5W"G߿ \"_c'&h}^ n@i)`'n =}.[p:e4H.?^y O05LL IENDB`images/other-plugins/keyy.png000064400000023215152214270100012275 0ustar00PNG  IHDRcUtEXtSoftwareAdobe ImageReadyqe<$iTXtXML:com.adobe.xmp Z"IDATx} ՝==73 17" #I1.MlbLYnYc6&zAPQT@@a>ޫW 3QSU}iu000. "c@ 1@  Ș@ D@dL "c@8.4dSqdZi>d!E?_'r8uc2޲!FBa0o@ 2& $F|VtۋTa[8)w cWkc$!xJ+:zDB~.5F){gTc2^xy:2,O3,,9wsJ]sGWP. 2dezo?b[סn<7'ի<5Α0cVb`81_y`( "c"㳗N=;o\lg3Wiv\wSU97\yr72Ș,#c-@bzHckS(U˓))`$*X9-^oi5"c"OZo84-$J2Vהw]yknC~."c"K8˯!}"6ՕmD쪂smE@rC̹G"c"AFC;p"uxlBj)a}M#۷Ŝ-De7OJeȘxPqV4ed:\A FlO[x䓨KD"g䯾a#bDFVM `2orf f[)ĮY&ɠcA ?H6G儍*USX˘@sd- PzT˫bjr{VZ2EJhP8("wDOdDH'xy!+kW̪i5O VmҹT#QrΥ)كEK?t Ň$gCV4v^I\m N2crv,inD no zfT9]Z-OlT:^}Jo׏e1"}îրXL6>e*jhٴi!LPUi{I˛E%Fmh?hD;gF*17=cN){"|]|]]\β|="y4&΃V̦cE.[NriJγ~87X3*E'mEdžGPz*0I"cBi?CCSLc%9줬ދο+> QDJ\f]rP2>k5eL̝ͥ?exi .fd)h&!Pl  !jyF3ay]3rg EV뾆|8ڬiV"6MnL "%C'STC uZ*XtWS RBYCQ=w%;';7U3f3hyen6B4˹tl\t{z@dLx,6qDLFs2I 5 .ߐQۜ/1Z:8]qD݋1h}~d[LE09*6uժ 2k:u,=.ls./zO?Ul[#1ȘPOʡH܎GDQqgb}9#Q&2[- l.A Zq!<"]JskȅX3f4a(a* N9Kw_:$Wnr>Նo `ҷ; CǠ}L/ [J>L1x8مT;Jjx-_.A6G˹)D,^ Vԛb,&kfF!c@8(!{\e<&OIjW+1΅lɣ{phy7Ȝji`^QS s94x%4Jnɧ~S*Yݯ$:*#-!8fO (^#u]QEHQڐj Fٴ'Ah3'ضX~S!X}4Qí]RJi{̅!ϏB%s!z FM\%@Cڽ>cRvBŊı-u3.%-_FNgLP#Ծq]6&>D^ү~Dg?@ EMȴ4S_,9"yMBxŽr|f5ߴbrԯv(<Z$kи_ 0cz{x"e#2{1|Uupcg[1@xyz+9q5?\YOYb۞zC;e7Xy3.r>j\ׯLItK,!B0A|m[b.agdSg"Yĺs1J:N8@VSS!*j&(jmyKIPs=Vx)85>˃g"&V@4NI!B˛gdeRDM߃؞mKb@*"J,-kWQ o(=9Sg =iʲ]xҹU{ &[B{Ds.7.c$;Z:w :sFRTKd<:~Жn2oV0g;)߻aÉo;̴؆< 95rj0fVW?vTx8 AS@'d&(ZV(DQo'+].}#nx6]+r [Ⱥ뭗2'媸T xASՒjOUSTžؖ;u!6d3eaW|'̖OCS;7(ʬ!X`\aO| ۧ _ [p٢UĹ,O?vݯ:*Sؤ"}CJTmdk#"24f'XPa.憾n>tvE]'Q6S[5[~2} jb!_CEiX̊mY$E%kSDԂ} %c'Oq"Y]DԄ{7!en-,rF+ 5fz >qrd h*V?Gz|8ضud+l&UDƃOwy}~'jj&9 BE=tU)pk*t' heT->\$qEEOۚ8zJ|mڛSkyWͻϮA׹ZM q )@3W^L3\xH׃UC 3!jd:Eb2ۧ:tiǃԑ}8NUryHߪ+"Tñtaڑ#CtmOݫ5f:<>(\a"Șt{h8+{\T=sQ_Q%'XLijyتG 4f:b;6ʙR#2ž{cWz,NVHi&gK22ysY Oڧж!֋]o+B*c+DJ|mEEڄS|^2zDoG#w' SѥRt8äbEOR- 0d/ɟ HrT,=dZIu6MwbMY03˝<6*6vՋColFj.zN. O,JBm̙@Ϡq&['q㯿uzS!j+^"\5Fd'Kd3> {oc[؇.1dbx饤dy?ܱdbFIV_ <8n7M|}ǎ4#@$to(R>;_+KzL9@UʚiMYPB+FX s]9ȘkȴfqދVņFE&ĞW%NtoFjo&NT;wжT]7=.rɈpK\{) ulm@1f%L}PǮj5N;h\w6޲]Yun+=*uz?䒙Kx{w(g"bҖ*2FϨ)&[Z%ɽSs[NNt &60l""hc/Oh2D\v(oFOA6(uc $dJNUY)gS=.W D%ҥ"MUMϚ%yb7 Hhi $ur#.ԣhzNrPo( r@Kf/՟loXUs`)~%֌BɜK{5\ [i}wf9C!W8g*6kX)dYD, gi“}ѓ傘݋̌G8 *לn.}0+fh)9DF\g+Ur27EzMa!ҍM;Q2>?+n{׈AG,v$ 7?#z2zP?XT$0u [D/z0K(6|(x! ȲiUsLkff9O1#(A l^'+Лn vUYs-BFk_o^@D҅&L͏ y"(%ݪ/DF&̓s_k-t'uG&%>w?I\(zPς8BI؋sabxNpx~%?9ܨʏ/:|\6) |C+e $Q: j%'/8G~l! 0n;>} ?e.`R|0H,'Wx;#3q5cנ:JnDm|٧AU_ώj$3ijU,XרtjG+ X>f) ?pD?bف4W$x?IlXm=W">K&"Y;,Hsz$vlD!ك!p^`DGOM mоH}[,pr=Dg“H՜ǁJn9rnUfpriY?r3p$4A1;3I+žJQ02uMY ^>͢Rӿ9ԋK>ҋVG-ϣ_?Ա}- ^ϾMu9*h/P:]j"z4? J_߯hJu-Gɹ+͎mZ/މL,& 袏)SS+=j˻\RR.rNG jVݺgS11A/(e zBwNHtC[4~yMR'qH-' 8Cڗ ?!U6֫jKI=9v3uzD`}P <@A0W܄+#kJ4ʬa[ŸjTd M>(Q^q3e7`;&r 3}^61kB!DB 6 ?n,Bz5?!0j*Z d2z?JÆ]7dNUPF Bhܬ~qR}%2@h+EwF`<ڱ`2> GhJE= n*c-f\DO``hMuL4x0䑾`H]e kD1PH=AcȄ>B FP3v=|:ڑz ']at4#يLW4_bW}ÿ+5oJ4@>3)2"s鑠e7 H}Lul(bkB\.EKjXEgJlq؃$N.gksX4k]:G|Iku7ܯ7zj׌Fd4Ӄa|IQ$wtwJ3HA)s$"3"

C1ﲂxƃHs(삏e0!C^T]\塹DRjuiKjGy2A%AKrF/l a9sPߥ(5i}72;L=(C 2)IUj>U@j 3f+ktγA` ŷ ;梏b߰EPbY(b^L4bg7JDufJи9@f ') PZY/fǜfI:6?e.S:2.'Rbm&%H\eHwz ]}Ķ='*=$FHǩa|.Ypya%V܌=[AҦͅMSSnJ Z/C*Sm>2mT ~X>Š5KQy-KGvm}!r͘1td;SKum?U}U9yͼ\0!h{iV0YY#;X|/UJvW6Br^~ (92}pX0m'njuƅfHC΍Ȝ|W^^/V\H\.BP|8˯#֨欹"OC-(xuXYrP2Q}cM2ėЃ u{dqU#..qҧ#q`NwVFhP?Ӭ ڛ%=ٷJ(=5R9$\RBj,V&aEF( Tq zUiB$y0'F<ʿ@m2AJ d s1oѳbdBUJJU6s!|˚ņYs8Id52?LtTU"C2\颏*GԯX^p5]RƄ>)sdy_CXTnB`v3sXj8Z]dVa!CJ-aB82\&2muX,[ '/k;8ȳ!?b".\%g_riI{vn4=Ct.XTOE:r@ԮQ&ݍX m>cȪ?7R6-&wӐNc;>e'21ݛd6Z=*W{R?O5sPz>D웄k ?dl2n>|OHa{zFXT%\+IX䫨R"c"㳔-BϠkZtjȓj.rn#Ixy(9);@dLd|d1m#H1ޓGj!b4-{ku`;o=HsimfӕȖF6)LdX 'Ȅ, 0ȘȘȸpE6 -.+Y2ݍeLU&GϤRx} m`Hx*YT0ȘȘȘ@ 2>kAx@dL "c@ 2&1@ Ș@  @dL g m" IENDB`images/updraft_central_logo.png000064400000012676152214270100012722 0ustar00PNG  IHDR?w pHYs  ~pIDATx{lTW~ǿ6cmb%If ws'kvvđ* B!JGtP:B#B!JGtP:B#B!JGtP:B#B!JGtP:B#B!*H~<RN.f%/Y$֤.cq\BLH@mc߮[ئ8.>Dj,pRt:Vh*@tJQtG*PhrGB6SPhT^5JYxR(Nw'KeI8 [B>v9 +R7A^VGHX7^JLں-f n& 媐9ʫ &Y!Set1 xFc;J(WI<̊YMF;J. B*Fi`/?~8lI8n<8ϧ-"PЭec#!h҉'B¨trL,K2ұ)]»JG޺vJG³)]6.WJ(5tq6k@x5tĕ.`td)!B!J[m%;z&u]Ix>.^RJxD~JYz"]gE<Յ1D5?O@N;|·r +KtzWRMzCSF%i)]t>X'>Mu0,fbnp;מuЪ| (]IٍR*:CX(]"FQgio*M|_wL{)~g1nctF46*R.H `v$s$8Kug1cAP:T%#. 8O%q&(Kxϱ&c2]$&l\IQy, 9n!ؽ  7p⛑. -jv'&?_NQ1ҥBԳ=oդtlD$Z(K__A(k!Y5tG wxSL~vެJhmLS:FqJaܖnudDt$KKpP7vf$tprJG#P:B(!B!JG#P:B(!B!JG#P:B(!B!JG#P:B(!$zL^m]~/&q}ɋ13:_8[Tie'tSU8tHfӝ ;kU> oE~}ft$kc[wg5be:pXq}:ti'eZ7 u \lޱcljj@3K;l5~;/Ch@bDD%+DTΙ92S$bzߪ &X2uW.lX;fEhOD 7ʂh T*h?NlOx{0YܳcoaáTs&ybpi̸=8l Ad(S]U˫P-cT@>+9hE{HIHra/ޓkܴړe͌_NV2;9 `} |ZQɁkEkFlZyoxӎZ7 -Xz,Sn|=umzh ܼ1YYP po${m^95ZWj冑;(ں N'dߗI aC(6^ 7 {hǤjX#mC84N#9vII\ a[M!)5xG,7hv!}ZzV| W['U g hYO345YV6[v>}wUH}ۗi*Co6_jft$kft$krl"xN=%Y]nBDaDR3ap &֡=ZѰD$М|Q4]Zai[Rsa+MY|";I!? x G]:RW#pRygƯqW(2+Ddۂaaáׇ~ &Xj-68)cy0}PZn6Ɔ\[`+Rĩ6*jK푣zߠ)Nwakn0I4˼u68go/9^IN&N$-*t1\% n[Ky*GVjtj6 !i*3CAKQ23YVCw,*|J ޒ$s==[$YǗss"bͦ]fMN!ʢIhfmwW$9dt1F2ѥ-QO۽He->u,8װT!gJw5(_7z`D}]Fs ܘ{X}!YTGPZ)Qr6[(bFHV_ymbE!{6%,9*FNx1dG$]v~ayM`ZyBn`1,6wl27wj[vРrи;R횊&M}v@ ktnصD$]U^ nfs֌grnDL/*\iyBH݇O('Uĭ=bׅZкah./#;ws3y7 ΍-Iqm'@g+oM$}:`鏜qm6JSH;֪EӲ;:C1\ym~Cs [r=E`RtJWU9wmD4O:)?3:5~p3~I5aM+] ('>}[-/;pV[E%.f/8:~p8_×O=eNO'?lzh d)^T0Pz=zVn޸f9c*VÿNL{7 yE]Lj\KqRî8ljVO'(VIh2͸ I5ګԹGX)<]QeO|6ԙё,q~#o"Y>rxgFyo[(pHE%..N#|yV#HVܢ5y+Mή]Kaz3"bqf|Wd[Nq.*{T.2Dr,Oj2s*CyXln$i펗][кaH -Z3d>tоku;z/+_TR4%G.P/oWN,ESy|RhUWvOgoLIW{ǮGv~ZwΧOun|{y|ş)NE4A9Ɖ;#]"s`u'15Oxb(Yt,it+_l"joф*|F !JGtP:B#$9)B!JGtP:B#B!JGtP:B#B!JGtP:B#BXP:B(!B!UtIENDB`images/updraftvault-150.png000064400000014356152214270100011546 0ustar00PNG  IHDRtPS;Y :iCCPPhotoshop ICC profileHwTTϽwz0)C 7Da`(34!EDA"""` `QQy3Vt彗g}k=g}ֺtX 4Jc `23B=ÀH>nL"7w+7tI؂dPĩق }F1(1E";cX| v[="ޚ%qQ-["LqEVaf"+IĦ"&BD)+Rn|nbң2ޜT@`d0l[zZ ?KF\[fFf_nM{H? }_z=YQmv|c34 )[W%I Ȱ316rX7(ݝ ⺱SӅ|zfšyq_0sxpєqyv\7GSa؟8"Q>j1>s@7|8ՉŹ,߳e%9-$H*P*@#`l=p0VHiA>@ vjP @h'@8 .:n``a!2D UH 2!y@PAB&*: :]B=h~L2 p"΃ p\ u6<?g! DCJiA^&2L#PEGQި(j5jU:jGnFQ3Oh2Z mC#щlt݈nC_BF`0FcDa1k0Vy f 3bXl `{ǰCq[3yq<\ww7Zx;| ŗ]8~ M!8Ʉ*B !HT'\b8 q$C'bHBvay=+2Mv&G&Ec[ [bDDĐ I* Zc0&8(&iYH~Ho(%46h0װu wKDŽ7EGGDDōFG7FϮX{xULQ̝:+sV^]*uՙXXf8t\DѸ@f=s6'~_ ˍ̮`Oq8圉D]SINII\7n5ewrm\J`ᔅԈ4\Z\) /ד>aQ1n3|?~c&2S@L uYY5YoóOHrrsNy};_-cZuuk/\?kÑ)*0-(/x)bSWr±^$E[nEmnfmOk%%%JY׾1ꛅ ˬir]+wZiYYGgʿs{?T'U߮qiݧo۾C*זԾ?=xΫ^P֡ 2mjTl,ixwxHȑ&JG˚faԱc7sŨZr}wN>8(mP{nLGRHgT)S]]m?x3g]8wn| ƺc\x'ߥ+=/_u=wvWO]c\n}Ϫ'l:o\:xviMoܺ~{;˾;y/Ylx~XHQc?:b=rf}Icda)iDӤ)ϩV<|~W_}oοDΌ\«ï-_w>~f~#zGPQc'O%wu pHYs.#.#x?vPLTEi&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&j)i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&i&utRNS  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWWXYZ[\]^_`abcdefgijklnopqrstuvwxyz{|}~?bKGDj6 GIDATxk`ged  ""hMJZEh+>PX-TEQh1@6ɒf33dEf>|Hv=ߜ{>g$zu;vlߴ/2ZJD+n- (e{ܑr`[lXVvkRdq-[n.ֳ19~E 56.&XǖV6aq`g^%6t&M;7`9PKs.5$Yb!0H"N+.%:Mm2|ft *D0O,eXw13Huݫz8"ɹָDy9#-eX_ՙ]$,]b/Vu3)Qr$9*IfXΡx*m}K۷}y䫖 <׵ג~hoA+&L8wvXoY̱h>Uʷ&`eӽ&`-0[Wc0@X*j6n3*3+l,ayO?za#zYjXE驦O60u{]ke6Ȣ\)lͺQ: DZϑTO&驝caQBϺ&&M?s[D&=HCCOl*I-T'czûWf§?b6;W|,l`Cрu!XxP}RgK/7l V=8 Z=I+%zanojzFK̇nȗF-{TDj Gشlo>S^OcT[Cʿ΢9ϼc ,>pX~*x)D0ZTr/@B%wWV$ G Kr:vXYl$P<5[{S_]Ş*򛆱VA^h#Czԙgf2,8I>$y+Ķ4c`˪oc +McM" w!}*VgRdE%1UNRy[j_6KP5>e$"!FZ !CS"P+`$緷V$ G-`&ڻ9?#G_]D6\8\. :gWӁeטUdR]ʐC;@I-:1`E- hih#2 &[$$g)Vىuq[Ow 6\IENDB`images/upraftplus-clone-screenshot.jpg000064400000045676152214270100014205 0ustar00JFIFC  #!!!$'$ & ! C  RX  xeZ ((@ H((%IDID J$H( @VJ$$I@DQ%J$%( (Q%JPJ TP$  (HADH(IDHP%Q J$%Y(PQ%Q%H(P%P JID DP A@P$I@(J$JQ A@H(P$H(@ PI@ $.GrnydIAD ( (%Z$ADID @(@(vW!fa%鸏@Q (IDH((A@VA@$%JmOnGy׸ْ Q $AD (Q%(%QD %ID  2s[KW9kce@J%DAA@TH(@Q%  NfF7 ?6NmO.bݿym;r>E^h%A@IDH( $ (%Q@@(Q Q yN9s-s>̓hd:o,sN׌j7vx~OB~@@J$ $I@Q JP J$J?OO/dߟ-s>̓hd ovs=0C('5P$HJ Q%((Q wGMO-s>ςhu:]4R_.sN&sM0o;[>h(@(J$ADIA@VADI@Q%J(-wˇgreo|wf;e>N_al1ssԸOC{^2q~ߧf=q}k_GeL;Umy^vq9X}no[p (A@VADI@Q%Gt>Eb'I%YkktR{$P;@::'ѹߕ꾃r?QɗyٲnA9vζĞ "=FDqn(ipDbb:53>ob]UabݾIb{3{ +Sxuټo $@@HP$I@J$%@(( $I@dJ$( $@H(Q%@ID%I@@P$O/^X<`Cy`=0C;@ !126"35T#$`047AP'CQRVa =WfWWfyW:cUOi-<eR~Oi޻>_+N|䛧x- 2e<\Sfy LOU "eHX 1cv^5iz`Czoo?uj ,\J9Դ^G(|77ʝ~Bv<»>]\ӏp_RĜnKΧǝi.!`Me1 ު+c||ں1dIߗ[0u ~5R=&N{$U%ߌ꒶77ʝ`DmV&<6l I8Ldu ,> UZW\M 73!>0`@$~\fTvTfJ | A$';F9m|6fTvTfJ ٠|/3w6Ys~yg1~yg1~r$W|{_I}0x5,f6}s94.,g;(rgAdt=^xO6Adx0b"?%\{r=3 D&mj^ډݦʉ[Qg^K#w6lSr9٦ rIƿK+7ˤPL) o&ufwEw]/s_Yk~Mv/ʦU(0{"zoϗ Ք؉(aUbq9.[4am,ĚLcÜў+@ ݵS̟I.NdzPB^+4LJ0{Y-2w\Zݓ-NSN{2}'b.Em%T6 Yܕl͐UmUGSWvj8XqȌt+ gA),>ȌuydF:#^?UfkwΧL/]A\U&*ۙs1w!M12_Sm{^![t&*۩…s;Ty^{hTqrht fGƨrSEyviE$NOV8VUMt \KZvߊrYlI{2ҋnfjm'!1qZ*DlX iR+BWtxߌBcIɍ gH{EkcQ?)O)*40Y3{1>ֵB^sp>yC".w{J=p  ,-MD*SI?Lϕ:nC,0ƒw?,_1^ȱ1蚮8 OF2hes f;~ßϝe7}s ȧ%#N|Ng7'6erf`7Q!hO SX5%oqb[CwN!#N1`#yo=}ʄE>Z^e=A,N*`ys} &2љAߙqپQe%Uswdz|M_UM|pIg̶!c!=.obǪ)R PǮNZzGٳrhǽuvmQ[2Kavg2qE^՞(D ~4% ]]1^Aq$;(V/3t}USP9"qBYa2M3 }!GXE2B dИ ى9_v |/QO ɹ9q.G,dTE$.5w_2gLqe (Yޝm|*;@1{OzIGkeJ/Pbv8?U8?_ g/M#7cvUsH{9e'4Wuv/{eK7ղtῈMA$ :ӆ~G!gjpjuML(5(WƆZdeVLdz'Oav9O.med vџ+Ɉ,c.X$)jWr4BEM[H4ѰK(toWӚ { &.yOi-0v&&4Lh1cDƉ&4Lh1l1cDƉDƉDƉ&4LhcDƉDƉ&4Lh4Lh1cDƉ&4Lh4Lh1l6h\E !1Q"Aq 2PRasBSbr03#@T`Ccp ?90u޺_?o%\3OW842Xoo Cr<1}$ߨr8Hje144}GbSmT;r+h]S2T̺e7.>\f7|#|#EseA7˜ݣ5!A݇VC+ӌˉ':ѩӵE`{v\Gepn^y7{pXw #"RaJ='y/ʲhP|ܥacB/pR?b6_d,8MDL`P9{:^*n~«n[<*{6t=7Z;\8umuDŽƹ&-^jۻO}9mD-E.!?YDLfzafC*W'LBe!I'V,9:/絖n^(IMQSW+9> C'cZ:mM`FQ=6~kM6 u0W=(4&|A5iϕ%Lu 8;B)KKf p(qԽ;0{M!}k/.^ナ G)ޡڥ{\oՈ*+Q:|P3uj(**]"sPHУ@ڦYFLh2:J9|>ONز)'ZsZ/Pti5aPYJqe`>k+cLQEwJ!v ֠hNuiީTAukv}3Hm,U|!ݹR7&СjfQTC7*oYzd{23G=d|IcGdz'nLhm +*+v!WOS,lV^-PoQr0'$bqEu8;VPϑء_*9 o6iO::[7/G9qV񄔝sgaQ[B4eg19nnnnnnnnnnnn|w|c[s222223̷w̷w̷w̷w̷w̷w̷w̷w>eeeg1----9nnnnnnn&N1r9zu#+.V]˹_A5<jj][!}~=>v _*F z_+? 3 @(cP%(e܎^!>mL}ܛAFHlQ:|΍w_2zU?p$8I}2u pnVW|gEk aDDE 7c̟Ж O{r9zfyg:z}NQ>?{]\ӎ}EzժQOk"=>.r}wJ!C\=>oއ{ww# ﺍ>RQOu7RWz`G/W;=D@>x˹_|3v_D@#onݻvtƅ).5Fn]{Ie܎^zbz:޳Ua[ʰkwb.3^cVm'jS]K=zp*(B]"TwH̻X,$1H>~E_WoHGrs"X] ˹_z\}ks%#N׾EfIW4̳Ѡӻw#U&ߦԹݜ%"wT`>g˹_{3K?c^x=lυW?3UY=]?]=[>c}LFC3-[[}>g˹_{NǨCAq$8HSG/Wsb\{r[O'p~(}>R>STG6.reܙ:˹2ur9zG/Wy y*J0J6؎ 4[A}O/=!Kׂ Ep1aÓ_)gdAQHH~'&|3(')ID-Pe]s}+>V+PO37I%2;KMJlB)֝w7_{vH2s5Xj]~vI[=SmQmɍ~hi//*fsfaJa1NXW@0piŪ^١rۢN&x7L}6tOGݷB`۪QO4~b|9@Ѭj4X+3}4S4ڔ0֥e&.iWb]]֨М2m#6_O\~&[++=+:.!8q/?>mtǦ- E !cZx%É<@kq{j9W8;U~D][$ e[F F>@#*/}\#Vm-^cBsS,絖pMg#cp/z$a}[mϱ Ё8:TvIq$Ryf'RW!s@Zò5KVqE QVuxf! 0 2`Q܎^ȉpC $wn44e3Фi.4az\wϢ^7$Rӳ8j#p[N2┹AFW&T(sz+xT> U6L'X!P%mZM/,7aE%pQPЮ)H 7w<2a`tΈT7Cz r׍Qݎ7Tcr9zՖCDNsP˹_mo8KK>Xf؇VČ>.r} o~`Tk0vKgx rb /qD9S:mf i^̧63lOR!F xD5z[VǍ M]{y%hSQcf:"S׵TcҪne܎^ݓ7ex9K'2ͻ:wC@eW |OE1k}b6Ht]b1?)ŷ+Eޓ4T뿤( ue܎^%:Z&kZcz R'IV7R\jF&TZOR^=2i2_1e[ݵ$|tXpA`X;XK6ECwCEjy*#\0GTՍ<"GN_Xd}]˹_Yw%' lJ6' r ' r ' r ' Q9NA(؜r FNA9J6%%FNA(ؔlNA9NA9br ' r ' r %NA9%J6' '0 14P!#235"0`$pIn_Wö6&bɯJb3DS/ ek#^.>GiC DV0^J,q.?MJ蜛懐B|e7k#+c#e:\ Cxe8yٶ37hywлf~8nA=Xe;?i4hxUjkkBZa^['mNq>|Gr/Z󅗧qHӯ;8K y{IXZq%ۉI+bѲM]pڳXnH+I;b*hRry1֍ink$!{$yK4o? ,Qt :p 7MǷO^X, NuXݒ:>LVkIó)6)yKIWlZǹ{u((&xıV+xnU!ZgҴsU%]U#7^Qx I~wqZ)PTwrvjFK?k7΀b $RFnN]('9*ʲ8CT!3b oVՋYv#Y]rj,7FR͑S#bh-krnIglͩbznj \ 6!T%?7nF~jsro*$:ONY .526*ͳXùkNś!E !cS#b3rg-sI՞#7g斝G/1vՔp~tKIu;Q$ߋ|Q-K-uLtXeT)U H@=g1R,IH%mJ2'a }fMf7I==/u ?ϼ%Q G\"j5#3V/YT6Mٟ/.|F~E?!Y'ԬщqtԞY V;Շ\̕[HqބAչk}hլ\~7B+W~vJf(q{ŗ)VKK1Kohft`K^ݺvCeqB~0Tc$ְٝ3Ē9V[+elV[+elV[+elV[+elV[+elV[+elV[+elV[+elV[+el6!1AQPaqR "0@B`2#bp ?9vgMa@zȦOؿژ~fPẓϚFĬ>Ϣ<(AI+ω\4fFIc!7o{8h>&2M yŢp/uF5z[Asx{quX xh>cQo{s>|56/' 2EOd[I ާ-{"+ps8,ϡ7u'|{o*=yofuy?} :T"q";zjޣڷսGuoP;zjޣڷ;z4' !@&A$@qb0R$& ngAm|-ru B 5^'R V_S3v4LV09J许*3PxqA s^Jᠳ®ǑUٚ0c`#dPoC8p(J@UH5MSB <Ѣפ'L obhn`ƫhxN+t+#E\H <]+5 3(JjgRvP|3oGIo'B:`@@U 3 dAM?X-'SH`M% 0I*B#L$1NPYLpv? ADB4."$uiדFTBC(H$1@ !1254`#03P6ADQ:,S, 6"cX,~=?$!k>HvǺ“_яn \YS9 :+n$Bib~B 9h<^:ݫcAJ-#^G|v *]Զ tvq^gl-eO;>s*C_6.RI%]Ed.sӗn)cn8(/mi>)R-,CȌҌe &0-&lN:8ZB\!>?&YLL1'f|m^6>(Y٥íYF_^G|ZgڠvֿW9UJf3PE 1 Y(|VimÚ }[Ջ,~1uͼi>$ 뽕]Աd=τ ܜl[ 6uqGTg;@crp7лL=hu}%IqPWbqD}5Dun>PNwHAV꿰3DcqTO Z[b3DcsknIUG`I4J#֎Pjin\eWvN]:uw\3kuͮ]:u \Vm40?3com Y6$Wkiny6\\ j6memyn%A@R';P+ :4ea7Wiomem֗q-Zˋ{)/j[k 0oje4SmRuSrxq8iC}%ԲJ弩,9jz9\,ȘD!|KZ`ʻ::q.Mcߧno3#f#5< Pb"xF-\4B$̆^kӺҸ iJG*lx}Cmu\ ((dt##ZgY}ud'i Lo$w;sT,LwbWp Ks\\U [&'ʯ1wɷiWy%.t7O ͶmpbHaV%Tʈ0:b|FS܈ݘv5j`\kĉ "[3\>:^x 7+I,Vs` 7&xZjPH$n>upپ &DƚVj5B_ew&TGB%OE_|GpKVMj1{m{IUlA{uBD׌Ww^*-Zg"dt:ֹM -Z/o[ h8HWYyL+RdlsWryg(.2d?/&lf<."ڍrpD!˔gd~1ePzɵjųe+=p>44k.z* xgS)])!ɹJw#eHN}:Yɐ؋$S8TfzCW  xc\~$*24WĘ(PUqŸ`֐eR% 2^m73yn=[d2R &gmdԘoz^ۡԚo5<2~a>MW\Xi-"}$7|RBRaCn";5&RVێh;%Ã9lt#ҞHif6+JG=%1&CJp:=K(ql7c,n8]ԋ׆ل&^J|ifmV' ^WsU>5$-Dܨ锟Y"5-jy5,31{u嘎+21:iJ{SĺҟZI L%,$paUiA=NԴRBVBJ9ZbU؎8#Lb65d'^wY9Vy7vһ@H VV: EYm;doYt[C>[$gn:2u Wu΂ܶ[O7!S̵uM|նS2ۃv})DG&Asȏoq T-r)vıu͖Cg5Y5Y;dMdMd퓶MdMdMdY5Y5Y5MdMdMdY5MdMdMdMdY;dMdMdMdMdMdY5Y5Y5Y5Y5:!1QAqPRa "2@#BS0`bp ?|ڊijNmE|-ʶmģZKY?-}힏./2r5vTlzc3Sxωۍ\49j}Т V(Tҟが7j} b/4Kk(^J."7›>''~Uݫ};vx=yWvݘ`5w};l%.Yb*2?5*2?5yop7OwG6|ju9"yqS@x=y?vxt;o~zf^)fwUkj2@aڶ^k$c{Z {`[ڶ@t?G vH2clW*A و+P+̏ݮd+e}>wg^JʃJISy%]ZvY3/O>fw~kgJۓb&VðqE}F8W9eZlϕl#KYF+Zprkdir՜]ֻѨQkhj{mϞu ȹMtkژ7wL<9 ٰt/ -|F#Sötnod!!+W߬:Sõ3t lHZ\ J_75uEo-\Sn0i*(D UlxEwtolgF$EW1o{$e 3L4*,dq6J|֣j`r4\*$csk$_xu~; mf.?wϱ$CPpŻA2 /ې̾'^ZrW shc(ӆ![VA{Y,S{FdL^3qK%EYDŵEɋl(^6Ź>5[xV_Vֶ2haP&Vbh+aځL-j=1.Xm4eBߐ$>œws]ZG*&g1%@+>0WZJe|<']]һWJ+עrwON'H\2Ƒne' #$%ĩKL rc+u*dbLG)~ͷ5j\2x5IWjdm'.+4P|6 gS#)ŇRR lȷimages/googlecloud.png000064400000020407152214270100011017 0ustar00PNG  IHDR~a^bKGD pHYs&?tIME  7%A+ IDATx}y|T9wf2! EvbmkQZĭP[k7T! u`pmAZ۾\E.Q@EY ;HBL23`,s;{yys9.̫oJyI EEl,Ś9AN9&R+egCe1n;AN {Ĝ `$_I|MIS$PJֳckOIU$,qJHv؋:ɫBuAܳ!ras+* yQR?PV" ԁch"|5m#\qzJ3h<ˉ;|'0 !V<\=ϰP؝v }]4<[SIYX!ګL ytwc}."N&le$BJҊ %~ TVɓowQe+>6 @>p҅@ރ5&."Lo&섃$Xǁg >شG"|WU~ԷˢNJ*Holj^f/kn%}b is" FL%yeAcØMlrj2bUnteA[)#@vSJ k2r{e;k6(4ؚP#:[M#ZWUF薓kٰD-]:͌tP3鍐PFU9~yy'dW^7xZYU*{gJə?$AY7:\ڒ*Æڟ ]M8A2[nrYdyZf*-DhW6F^(p5KM;cj9F`腲ä4$٬HYiЈ7O;L$L,h!@,1yء3r UDZsRX4Xe*D0& (GkdJ~:w_HsAHђotN$ǻz,d_9t8$=,O!椈k)s|UEC?' 4|*lr!oI"R"HjD[<u50_ϗ=ҼJ2z ܽ&+D-!q_Սc0}nSWQ7,,!$A"W1 ,>7cMQɁl?C 2L~+F)ˁB;K .OZDLzUH<˷;VbM %2cA+0"nk~A_[ןglx na"iVXc@A߽fHN 2VݺuC||~9<R_lVVkhG&ꣾ' c.!z!7lQAή·u\XzO堘˸bdzyšg C~S )(CܸH]Hnr6QCEF / ?1ѧ[gg2!x:a'Am`QQF8Ed6RXYdlu!_ԙwX6mZzPFǎ߽fU0}\ԣs;cƇ m{|ҽ"vVY*~ ktwj;>Rm2`Ͻw"߻ ? 歭Wl"K z]YNCI ):t}C VvQ*[bPrG,Cl^g`C8J4pH$9ry5lwexpتA8Dxk?TNuu)sB2&C7 5U:痚܀!,?uop^__JHMMMHi۴AI9xG)sE Ҟ={:lf޽PJDg=حC;5$M.Ax4,qׯ(7|'Mu\bǎ!κBjvE\AD[P pAz;<\.رSibx<[7g=ҢG/8&b"~  GY6y=υb֭!)-[rBwڷX]a!$Z֫r! e%4ېHzm6ܹuumowZWWJlݺ5IAQS-ֽr0xͰ?m"n_,r\.) '@t/t9vX7re6>u" 04IY (\+7~ۙtiK&~",udaoẄ< " d1uIu,nc/ǵb>ÜQ (GYVP2Z>[@?+DI83*QVOS$\#0uyP=mD*AhJ$+h8Y[N`#+^ %d<ɺGXcsu{:WiI 9"v/DUQ^ φ^yݢ<5{F8:3Y@afH+aXo&xWDIc9&uJ6R)l|i;)uP.V ՐwfC>*#`HWOtzu-N8M\Ri"HѺ`*1% h'õj^4@U$M1dw¶6Ͽ'*\dfڵn m"փgiB{ i'{lM},&;a=>:(+Odmʨ%_ *X,@Џ }گ0ŕa1 nd!mHDx6j(?Ȓۈ^%@8ʔFC’=h {C%qE7&0 $^KS3j595sABBP 4w>yLt8.h߻o 0}^mQk?ܧ$lThUo`+} wtcPMiݓ>d' =n +#/@PAVP o=m+wJ淇xQIV$<4Bf8]l4!jwY5*VLn J>;knv'u~); qWn8$vDO7q0?yJ ޙ,i3!on%vz :5-. !:ݙ Խ7Pm;n3jMm7[\*S\5uTm!^ HhSmZdG.A|)Iehb:mDbAQў`f`K1#TA!ldvN΅S%b&XfID/J]y?gy0>++οXBX,Hzvu g784ٹϙ2j)L|ڗϚ=Ĺt7=3e%L3: >l}31Y͒ftv$=1/1!Bq:Aw])_,K[#ip800p̟K\X\\A8"A 2++wb6D+ˋN*c%:MΙ&̔#Ggq8£3̰C㇜VN>N_FINq*upYGY\spÑL~9N@4%M(biٹʋ #2sٴW[nlyyw܆q56L[ 7t6PN̽QD$2&lYA7&n#7@$A.(rp.Y\I^M /9e=+3'p@pV-G)e:O j/ _6}Ѣvݐ{E ٴxD1e]"ni˟nΜH[J8 9g%,ӳsdxܹs{  1٘XqLSߕW^^?aRb•-3{ Ȅ[עnӧO&>D1}Qs P&os8W;ΠOIp%!3\JL!|T lAkEhlC1=t:]L|Y%xgӲ^ghAp%$-M32~ג=&7-M,x/L I `Zth?Y'ړ);c.WϾ-G~oM@z:L@w}[zhc !^,/t9h#GB%ǒ%K4-Z P_muy>Zɜ"7@y P^L:Mfp-ӳ8`Fyq}e/% L*/~) 03eNA-+w2?p`>p$am_ 'x5l buZvނZl7j $7}1x #ٰcf PQM# h=R^ FP]Lڻ&Ș??>&N+0r9RdWƯ+N';WbPBIyCGFn6n*x`fI'|үYp>1/`32X p[ ^˥q_\HΛ 8 96T|8.]I e0sxeb2'\:mZKKӲ! ӧ%gI}P]|~CD<<1yomܹ xɇ23S.%Qd, 6CjOl/B[J \dɒ},eO[#&IfoyQFrX̙ha~/-(x@p_MZu΢>N],֨L|(h#-(*x}r໳YPR8Q<=;wVY4f.4<a 96@g ^$ " [A0j44gBjeDsC&ʋvem%…V A M }fN}JMkFx,V>5͑P#rMfg=mM) -~:8MW/3w<HB FA9*H,s o/[ 3fhL#H $6ѕG-p%@ߛp<:M6yU׿щmfA' w ({oИEo!f7\`C/v MkA.0:jx[2AyMdlQ^L ytZDW l1ϟ{,-@  ӭ%̛7o;ibg&8Q GD1H'z%t~#`*&0Q` t+=;Ob~0. t… Ӳ$ &Y?Нyy.b,t:kX~ lRRRRk>vi6}tŋ j5PB0nȑzpبѦuL[0}}?'uq[?!۲~[x.;-[Xgpo]r8RQ3ёL1ӫ>z}{@c˹-ّ#A 0*Dkj~TBUDd̎1£%b-4X@#B1f2 ˃ 2a+g:~i=ǹ\;l8aBS{ A{c`F&idnB\OLa%1񑦃Q4Y{V>ِ Dߡ&%eDt۸"#1F{bii+=1!(=#M8N,b8P^ItLJ3ӳ*c-g)21@\TV\?,'iYFddM-mȪ9윜њ@>% ]ND@[Xp/`UOI^Xx2k6[,X`!G~}<:g [Eܓߌ2Olw|Daq6.JʛϒJ#Lf Zyi9[uD 6? {uf33+qHkyʋnLs7ȉ2>+M仌Pa7Leҳ֧ggޒ;>-3gZZvBZ;?QQnCO{$gEMW*c."P!ߞ_pF򢂜nGLzfV{l(J;]q3]_m  ^`I )_.()XfVLkiLp'燂iɁf3bS z8W[} f&H,w%8$@_`Qx8@III4O!6 J&2$Noc-4F&nS_}˒rYR.G7( ^yL2@ nvc;er3$!`81 8(Uj&[QZZ:]l*퇯q \͂xCA}IsiGO&>l1Wϟ?IjrVVebuYO arEKQqvBC)umoX (=sbY6fFUyy5DԞ(E*D\q";Ҁ1@Z&ct)|!U+!RT,:s!RT,P8RU,"^'U>*pe@íYRU,!&>ҍ(?39اmG1>\d8g- ᜷(V"璸I9s xӜ撸>\Z]2dt"/ElWSޝh Q)`b60{ؗ/Ӧ=iG]Y( 4fh![%K*Eo )k #.XgrAס 3Dq\]bkgO ]C= 9 ĕiC G>qk{CRM0iFWIN&5Sb[遄)>#gO|=0 H=.@^N$LEW'8ry0F,bXH+=rnHAXS9N`rJA 8&X P' ^HSf~??G◢E$LWBjVP'-[fʬ 9) 3)YYǥ67#E1 5B-1N*C?mCJewW{F֩e1eeGm"uzvϤlkE4SR7ACZ՜(;mM:>ixʥS\nB:Kw iE ,m|O$̴eOީ:t鏦H*/(45d {T $LtX45 sM-BP0*rk l} KNOcpHwdKlU( d9 I.n2iBc$+ԌHjvdkoIH<X7LIRk` .Mʆ!QPK%ů+M[vkrotOR ~aoS*6p5ќRB% Ń@ؔI /[!qތ-=h(4|@=!UA:$f-!OOj-YChIL\a`J|l9( =gңhДnp]h<[V3*5w9I&hY}TmDu]Ϩդ{d Y(,t>oIU$;1!*qSd$J~CYπ&I~̸-ehk i'_-cde#m5}qJyIKRn12H*^چė\2I2+ ?LR!5#+24NׄrIm;ɋ^e[d?&yC3 ю;ϢNBxvJBVk-;+){xd=96 ǰ\ ,Ujr`mwaNzkX#MцM8#/7{wTB-ojQ RY*KiӍ7WN-,&Z_r͠@ǖZ\2D$ժErbT DQ)_c8f$a>}ީ݆ +rȪy؝>-q v)sYi,eNl:ˬL-d#LĬxesv#׉xe+m8ҥe/l,/4M¡zyθ(ZOF8~v6k&aߺU-v^kv&dٵl=(NdU.]L+Zثh],&Zs+Q?rwra gi)lQWIU_6 `=>3M& =izOUz.o\Z7vm bOGR璽QM%Z?Y{c3Im#!!XͺlKu&&?6f i\j4ƺGPPGN##Vz դCQ{'(6;Tbщ}0lGŖ:^qr_(6ʻjb[f3zb?"uUckE{H-^;7{OKFHSYEݫQ,z4؁:F!iz;9RN{- 6>ZQ,zib'⡜6۠Xe^ A""*5cb]n٣ɒtOJ)y 5ӋE=7!bbnѴX`o$ͬ)V-Fq>nV1Ŷ@`b렳nmU;c\ n̬;潂XV 1.m/\澂XK@b`]CSlS CņH9]hm>T [hmZ*hmde>Tl/46Ų#Ş#EMM%6"uMߡ0;19O[Krν`s "R$JImCSlՃv+H "Z](]uޚM!~oWΡbHb< ] >Γwfxqܚ.Ż3] OxJ BQl[D44\/ 8T Bey"l,xk^ ;/)zb۾tUʖ]:..ߣDhbgD0]%SJj8ܲuM"VkY<{"> KbCDAj\h!рJ6[O@Ş=rgRlBr*EgSAC05,v v{rcRڋ$(/AKo)փ)۠J60*v"w j:Y~V@z''=o߉ ._Kli~3k%=H\dO*U-ݣkR?Fn>Amזe4z^;\c܄֔ŮoB:%"|(hUŞ;!*4.6G~6gm>Rz}¿-7٬i2H‚ƉfbԒ;=b=E}b؛l|_ĪbZ#ɧ3|EbģΎ|vwDX,,Q߹bHukL0g%++EK%Ng i~bbb3X5smil].U&1 KM}]i.k})PrO.6袤XXUۭv"R,}B`JR C$҈_Wf;Cy3na~?IM 2Ѳ^p̰*S|A~s6+-p-,""\)Hmrk+n%X0C^W.Xذ=3( ,1k%[ݷKMb} RΈ_,l.:S[ߙKON:2\yaIxLZ>|8l3"k7],ӹW_t.ROb!)ָPZ Fq-ŎwPbEOJebbfO@α;vh)(iMVHMk(6KR'8`\Q0MJ+Z]N1܀J΍!@ΐZ/ֹ4gBz4/٤FZ"-d]X-_/8S ]?g^l3>/m|+/bπ.w=5%Fj՚DWXu(b}wH.AF⯰``8.NA.ۂ԰X ic/3}f_.@7Lƺb30w8sС.noRzT-6 >HR ږG(o]]ueK0iރ9݁]|bYDsv{4ml{bc%‹eq- m+cYl ( >bC8؝l)v  XdPP=\fFmnX ֋%K}͉SŶ_= 2{zl(73[lȻDn?Xްg$.Em'*̊Ό=#@<]αۻ4(GVZEx%jzI{&ĽSf65*˲@? akؤr&R !FDZvOQlC69iS.]?̴'Rx8Wj նje'NiXPuLj_Ĭ[~b865{E# x>]@IKKT_lTA},,F'Kծ9?V6}w늋cPz6R=F<,ڀR*|7=uvկB!gb,{PmzXK1<žޥH|@'[+c.vbGxPy1!b=ee&st&r_ v^Z)Oz -:nJjC Ŏ8s/+F pK$`9cqs "Um` 2dBpv)h/߻Za ,&]ҽ4+nיOo^\PCc%Ε+bsn.J5i;]‹ɍ6&m knK:H'{|ay-/V!F; ZH;}TS^< o=;ML AY, ⶨR'X*ovb_􋥘A"N`:Q;iUQ2p2f`P,QYE(dX# \@"b!L2o I| rU(A (YO>xTWV .~uŚ\O{oT,MD-1`;Cң e1հ\,i8=76+^KK6.`ôk%Ũt,_,yAF:¿fx}[Z͟Ly/67Xh.7 1jyC>Q|S!= BRB ¤W,Cx7]辑"a'tv3D[,V4\x`gRMFJfcǰmv?1m K}Vp^ ' ^byCHui" +a(kF+V,LGzŒuԭCFT[,JGR|8lQ:bx6!5\bP:"x5y#FQqج`zO RARF #cjogR:J6t)O-JGR?m)Q:¶t.skF53@|~.XP:eP:BJg,)#Fc #P:B(!Br\ +tI]W~RJxslDJg,|Z"]WEWKqbŚ+ g~@_ҥD:+)dP;$|q".SV/Iwjv=L錅֊]NsmOgOw@ &k76!-R5h6H&,.KFK_^uZ}N둶NiJ3;$H:?; Gc.Kz_4"ų8-‰[EOsS,ia?ŝPےqtpa,ڣjJ ttxX@vzlLD7nG֭G:`t[*͋(M:lꈑ;\^ 0uK^$[ a51}Dd}iͼ-95x]fO++pqrG6h2.;\tW`,@p^MXn@rFk;[qsm객&v3JXz!\rMv)yIAļ^ܼ Nk2K~zt*.)r^.\qY)A6zX St=[+=:nXF&6AHϜORL׈i#bנϙL/ f\'[Zp5N}ϾdN3d Vq@/twJT zhM|"?l*8E@v%-dړHgOITJg o =lJ[g CAP:Qe".8O'su%(Kx/%1LuYT53k.iq.-U Xe\j#<˴./o7#]HjtD/˥J!Uu~oecل)P6J3 ¿Q:Bj"<Û)Vjm<'J&D,Rjqu',o̐ϖ{N͌] H"^+к37'?.,oT~g*)_o^IqwnV>L.T)HrrE/b8lxK*a,Iʊi]|Q=0\}c>]ݳp YTjCWKdiOD.ASgFG/9o/9%;L)yްuhr⳾wSNZ1KE`ңeFBь:u-]%#aS'Rt.)ިq{QqF̒βٓ5~>?8(m\R݇GcM F]j =j9So[;Phs(R=:ާWQ}BI܉N'}~`t;TD2yW:8VTCRdڷwJS+&]N|8WNQbsXWMx{->ݫhRjp V>5#]Zϝ~^ޞr斯_<ҨZq?}uw狧/:;:TLO'?rzW`M-ug$V?+NſWX4.ڲ%B"T*Rpc Kz"ȧ,Q̏ȓD7+vLM޾'NP|"c-5v.|Ό/7hqix͟򩢕U8#+E7Md7|ߩZGʷ~9͌E.,ohUI߹_w~Z䃑XC-R FE$3WFؖmĭ'%*Mq`04(% .`bXW) [Ҽ=Tj]zE=΅چk/,eS(XRGYQ?+޽^aIcR6UjR{mÒgޫNO7$ц\k&y/. mq,l{t_ ۞=yC}h/I)fD,-6N!HCho9|*q[,j"{?*K˥(@:WU %!B!JG#MHGtP:B#B(!JGtP:B#B(!JGtP:B#B(!J& B!JGtd$JkIENDB`images/googledrive_logo.png000064400000005712152214270100012044 0ustar00PNG  IHDR0 CPLTEuuuvPuuutvuuuuBuuu4S4Sc~uuu4S4SBBuuuuuuuuuuuurxtBuuu]+uuu?BuuuBuuuuuuC5BC5BuuuBK/BBB>BC5C5uuuA2?uuuC5uuuBuuuuuuBuuuBBC5uuuuuuBBBuuuuuuBC5A4C5BC5BuuuC5C5C4uuuBBBBuuuuuuC5C5B5C5uuuC5C5uuuBBBB5BuuuBBBC5C5uuuC5BuuuuuuuuuuuuBBC5uuuA4BC5uuuC5BuuuuuuBBuuuBC5uuuuuuuuuC5C5,TuuuA4uuuuuuC5C5uuuC5uuuC5uuuuuuC5C5uuuuuu4S4S-C54S4SBuuuC54S$CtRNSK#SB"5,u6޿PŪql[KF:(# ƣA4'ʸzuh^رbM>=% ha5.- ȼ}gZWNB:(!ӽo\VI0/,'ð|YU@̳v#D<-zIDAThgWA@_5(B0Ҥj)I*J,(޻ |&Q~$̝Wf, ,0wjaaN.- ,5#]" کWNZ )`-yx 3'm YNKXR*I=Rwjo2焰Vхs;w=KIa LG%y+ P @W(;plrR7Nn"#Zyp W&*r5ĘK} 0GN"oooBY6Mbm6|PD'4x`6"ib0f* 3Ldǜ9- 3^Iyp)xvaD,c'I"$ȟh&t9c 23&u|WWa6j"u p O[^8'4280:ųEj;Ϻ'D>vNgLqucU̗{m"sЃ70" @nN#%ć=!{K֭ⱚF4<^ "J!~-;-Ti+1Էfvbv$^vN˫ib '*U%źBbNI`u"NHW@x~+Zz&ۆ(/oぞ xeA?M9`F'H"do)މĖjZIDV'? b 39S(:q謩T2XK#rm} NxSo: AOFL7:ABNYT\SgC.LC"@%sQYH+pF\gaE~uGo&CCHzf[1e|Y'XppRIb| ^X^Q<D'?fF%XԂs-ڃ5ttà>#Yp0JaS> 8FTSԸz$°r}KC1ڡ1S/8XMwJq4|^դ+Sکǽkh_w$}aG*K1bHb0 4a9%Nqʲu;`\8 9K$Q]NDU+ms=kƈg2p`!Ͻ`.F-J'Բ1%Ѫt$V~_ wmIH"?/Y% :㙅Cgm/mk5`eŻ'؏[(15P\8] 6p$>I3,rBZʒ )?`̢-GuX׭-Su8}8m $+1r:X0ps'%TQ$۟/s KѓL,hMh|vFjZEt= PDJDj{n-@?IOQ+le"<&wc9;wؾ\Kح6$$aG#TJ[6ֳWDjw2>yc3]R1A;(;b3m[b}*'~.eBa 0a1i78t*bG-΄g_7 !8?-"c3,T;: ADVN%pS*)Ri{0eNhc5ׂ9GG=)m{o}ݦ;'B#M.ħFw, ~%&:Gf&$KA`bKuNѨP]C33y{$c)f5 S*(yi ٖ:ږ p`I1vKlce?R{bU*jC,tH\dD&엸;veę: =ԁӧ١/v/n7KV{ &``i7Ok^JNL9@_`' Jvkbn' 4M7'E 6@zgjfifO PIENDB`images/udp-logo-white.png000064400000020727152214270100011365 0ustar00PNG  IHDR6A+@PLTE*tRNS  "$&(*,.02468:<>@BDFHJLLNPRTVXZ\^`bdfhjlnprtvxzz|~<]IDATx][ו[B67x6.ơ ġ!. Yue ,%B%Ȋ*;|￶fF3sgF9-4t={9:fW4.l_ W }*6=2η? р%`th{qLRJDY P#ڷ5wh挟A|D3*Z>t!PgJ18.l;5tzL-e3nc(rn8QWjFAW*1-17&> E}R~=ߌ'bB£*xF`ӋyыG7mk5$A|ۉ:l(  {,ٺг鎚)&O&bICųDŽt&=Q3w @L6| P}ie|l,lP'1c1j/tN$s1E8 2~FW0UCulj.ȧ<\5"arij%1R3]yZY_Ԓ*k/<@0BػkBOP@v6'M#wQX0{DZ KOP pt}[d7e6|' }6כy4YvSPxseS>*v{i{!U%䄢f$_ .K֋ՕTR`ٛ՘-tSiKCI E&Jl);^i6NtT#([_IM 0 ! ء67/^]' 5$kmK0N +*;6(lzDםF_W>V+~m{M˃`& ڢ ]TԔT9&@.co7ı[;ܫELt4 lʜVqD?`j] 3g4XߓU<ξ@R#Fr[O(Q[O6T2BؓYjfZԅг|[dPVcƯt'@2J(/m`2 Su.Cڰ;*AtoϤbd TlؤǸ0ؐ]$IY2 \0I0 g##W)Λ*"S *[k%dl,l_IMkLlf`S^B>, FJl6)5{ЁBՒK cæPQxJS7JqT*J$5*-(]P6%[y8؆*!(;&l҅"aS8%6!H4*Wfc*W B°y_\.e lQ].ly8+rl8*ųgT8T͔]QFI*] ((aFx^'c,ZI?Ʉ-^mWMM9y1bۋ!/*S59||Inc^& !X6Jb™go [royo uP֣oǟq퐐CWSy%ǿJ7mR9^ RhN;<.m eL;~\< v")3. CϪU{ES) 9 * TZ|U*Lap֫|MiVj#->R-8=jِSꎾ1.l)%#c&ǃ?mhu>oA#UiKicYׂ[{b!}}6Æ]LIY~zdKFo=6!DY݅斖 ue'2 j =lSo)6̙f28֋w#u4i+Ћҝqqә!|Z{qӝZǣjMŅKxC i|iR C4M:(ף|%7_ Dk{ט6d;=jy4Rdi yB.ٿJr-/V#3~ 8ph~e ܼ+uH'ޥNi(pN9֟U"'jp-P#Ȣ5՞;JՁMWL@ߤR1{󀎈eWpb1+b pdPPx6iHşanMtri:F6-RHAR} y~:F\6 Fc];k.V28@)Y? ̄Vn2bHՀ2xnb,U֜oj05饢E qH|6#3k;713c7بIƀ<PbJ&nX ?wr9=֤鏳+^[(S΂;e"o9j q׮ғzq U|"N,7ܧ O,lzDg K_$J4O 4g!ٺ})g&wFJf j82dݶG6hiǨ7=)@o^1G+*^`zFҩUL8z~y#I֫Mo4[#J߆[-H]lQPi4d"ljJi2 W=p8D:4vCGrNeDŽewCAV<;_e#JzVCYBk?+Ǐ > /w $Ca7Ds$llqqGٗ6|TI7.9$qTtoNtRY$ma|bͭ6b^:aB,ޔ[wW6EV{6Wfݬ5uNOQPp>C-W F l!mH#4H#4H#4H#4H#4H#4H#4H#4H#4H#4H#4H#4H4C%:ZU|Sbf*ŇСԜw}W On}co]T8v}WD+DN^;[QՊ̃ws [vEag1)F0Bʷt\4> ~g~백o hҧAη{7o6x@زBl5?-' ՙe)DōI/,$ئ 6flTPRo Vcؾx&<3!;L؀l:szg8ؠmJ + tRam\)Il3W߆ Mv*$-mAT{a܃q@"P`{r24V6_+)+)8%-gT@$J ܡ;lYm`{Mgv-xIo;3z6Y:FIuF(tәl99Q$v\%UئGlߋ#TySsާOoV+ $ZF'>Qa*iFsseh/0eV6 ̌v_)*^_]c,S6W%T6`tvRElZ- %Ci]s3 U@o0)@xu{En4>Qa@msF(mwh J+ QO*l`)-|ĺE my6yD 2^dt d̻vG [cuX`R#ScdzX=IN`VR;4*<5AlAn^՟Y^l6QY: X7 Mg >va*&l ߹xOg|\ǖ6I`eyYu ӊLPlJ=]Á>uW[ucKi!"f<%f]侹jǩÖ.%]uPs-WV*6'lkETv/s9az YϔҔlyF$u " sfA`kf?eBwa,FE}Ws1hVD-o7r"ɟkj/@wbV˻yXDgA MpwkBeΙ8{.8c/2 %7&V1ҝ'菼}>ggyuJW@ܰ="`5qf{ݜUlQ=Rl a#κ[Q8~2b0myCm icoe cB4M2U-_4()ުcUF׸8Qb7 IVFyܭ [/ol==4@|[DfogڝgFƳk>{aϮyzP6'?qe[1J@6*?j郞xa!I$V(szMт,lA& !5?Ћ obl$g;zkOpE4 h%>؞%>O/#6\y*)3ih ]b$/ވ ?ѵpA- ~[dv0lQJtǏ\\|wX +VKy\Gf)ln~6 3W=o t,i#̝AɷM,aӵEG4e.5_Gv,N1~d4&$R]{/C-B?>?U!Ni#[Znj\ 4=@p^v,Mͬiln]E.lBL苺KhK]5XKϗ;,LY󥥥4 f^Zw(\l[3G"3wO01 ep*)OWT:YFZr-£;F5WE?Ց!cfwF{ٓ8{ƸeB`c alIƭm%&mlL>ӠФMMQ˗^E"dc+=gs%1IENDB`images/dreamobjects_logo-horiz-2013.png000064400000006155152214270100013716 0ustar00PNG  IHDR:DtEXtSoftwareAdobe ImageReadyqe< IDATx][dGpB:b\@ kd{t-" ;3/B`HfA__,z]#h<UN %!f 5uԹtaRU3F @ @ @ ,q" y,唿˻oQ39 /<Q7L[\Ga y< ĩ<ݼ65Q_98LF swUbfى[xUj@nj䞉' ~ ld̂zοͧkc_L@'~zK@_;X/NP@tz ."[v7-v&{L1h: 5>5}aЊ/&'/icч$W>ڿFo%3, d >&7dSB*nA+Y*noǠ ~X[=)3ɣTہʧ5NMi*|=+Řϻ`axǠ)Z8׉ӏ1Qk׮|>F E8[DDXU\M+Y`8HH.<< ]Rׯz?t)`6ӭÑ.>'x;T WS^0kbm>n@ٻ‘F]l #{4Q߸n)?3lvC.:jR`h^5RVyY8?C@ٹzf&v'O&{Wyٳ/>{\(Z&:A7FG<+Ib>n{GK7sQ8}znth|*:ّ%'xs25l7L;ׇ8 ~JN(.s sYԫ'M*G!w4{껩 UP7P%{0 `kw?<"#ֆʈo2ri] [BvPW#uğhsIH҅eW!Q%~W,Cj>~iRs%:8L釕t HgA ]<g vFlPeIR\4;M9-`eBD$wXÀ(_oEňrۊF V//H# At*EzC|."HȖ˔˺ET}5ŚUGC}dKSWs @҂'dbnM㞰+!.)8$J j:gKE|Vŵ6Gr{0*@y A0lCBhB($W9A[U> +Tmc[#x]\U'hp0~Si"`- w$.7s:ltziI+P;mGv\mNIK߯ hJcV8/exI1hg"=j:NG%7TrEXWW/wA#XB"9DNq~Yk4 ^& ə<Xط XfʮL&dSeA%mb9;v)#IYrN;/`TG֚;fۺl,6j|m N m5ߛ`so8wQ݋ MME[idYتLo,^V I.f d6k/{@U#X Dߍ.ȋ7IΌϮ?Sc$y`Zj_c(?!hp5 Y-rpוSy*Dِ$> != t\D?AKtNfbye!6aLn V~g$\Bj;cL" 2dPñUwG`#GbC!!L<\e^=o Y8?vR3)&b5soMLl~<k krX3 yj0wb{~5De9Ӯoqat`-@-@O+ xJPsp ߼`xśpC8TԢ@;WI]m@hf$VTwvƁ H& { No"$DS5X, We5*zQ`.杆pX<_ΉZ?HX'9qшyv+̢h{ &8 "%lԻ$9ֻ?a*f_r} q {O<8N7'y\)UU"i Lvzyn`At\WB-WsVЖ[7ߦSh3UH4<Š՘lxAw#6{ =@{\UIw6{V D ! Q kO¼q/B=v53:VϪZ^5&RIhBX@GTD(6SYa=y !.to;@@S82dhvU5jrAQ Fw)D;P,̫f!8Ha,QK3jˆ::Oט569a":{V eD %r3C32OJ ۉ$YHĘJk:GP}OcGR½v 6)߁یIeAJٱM\@ߊ'I:&*IL(϶7pzEA/^bo&,}C 0}~zR7ӳJ`}:UሡLU@D'M< YHIu'&oE,4!It1@N82ͅN [@0P*@ @ @  `RD@IENDB`images/updraft_cross.png000064400000002171152214270100011370 0ustar00PNG  IHDR;0sRGBgAMA a pHYsodtEXtSoftwarepaint.net 4.0.3PIDATHKc@+W2z {m6̴  w $suunRS.++WQTq`̙\Pi_?F|||0+)PcyVZUBpsRUR 3dPyZZZ @ "VVP (doarGy@"dj&A?l怰2G*++E]"5: ؂LX'(auUs2)|ڵb1Q8}rZl/Z[[[;5X} ҫvZ]][N8)!8Xcoo4'3 H614Ղlذw v80_*e{=vbZZ\SMccjJ&|>u5ꚓH vsq5t`gc31(TTTC GdrDr`ceՁ"dXRRZ2dlmaPr_ GƶV֯dZY> p /q+> ui aP+r ll`xCjq`Jϱ ege3t*V5 loˋlsIy{ P)#hgM-k?חl0re ` 􀰚#qrTҎv8-4",b>rV )\@ gG' ¡!J!:www`êM̙3':6 J%E%` Vlhh%@)bjjcDhHy8 &0E|x R@jRj.i9ױi'}=al c.(,Jf1P2Y bd(@,f1P2Y bd(@,f1P2Ybd%@,f1P2Ybd%@,Jf1Ybd%@,Jf1Y b%(ln 0p'&--xC g1P2̙)v&]2LusҤyd9-sm-uFUA?ޱʿhD~(쳹ҭS$[^}:K>>dtY(IGW-v=uM A+oHsoWS|ץۦ_='.HxP4F [& %y7 EEe[ՠm4ɋ)u1oDڲoKw̐|4Y'UfK(h qM~QD_$_Ez?iN +$=hhj.YG5'՜PupSg_y P|``!QH8q8qxœ,0C=7n*| % xN0R GJৠ-/!> v y9D s$z6W)dHުV}s B5lҞ#1s#aQ7J9wĖH{u1"07K <3؎K?{0E# \/Q-LLA$zOޫQX813>R͝ÕҜ *9^sȪjaAԫW+lB9gub["AS祕qtNBFTLRnN:d"ҘK7-\ P$kAˍiH6d}nQFy KC^ꞥ(:W s۪W؄r%UyIAAQy^l@pLn\pQ3JԙZLjU,__ؘ~w|>q%l!9Gy z%O"bbԫ8h\pM]ߤ"+ b86WPXXTRF1/"]rPE #Qg6#Z_iT ӵ9Tn0,}2K˔>1,$Ig$&a.ArO7:J.W*U8?>)** JS+J>{ FNOpY Hr}qab45V7W$H&S>uT/+tkvv&]D98kIt:׆?)JaJS @_BYRRє+UjVS{||p)`Y;c(- EU7T^D]D*Kt϶$,ޫޫ3n,&e'#T **uWP* Wk*҇SpDZZ4fW[Cg R%s(ŭP*GC7>#bl%Ҩ(.ɘpF slKOC@9p0! #$DA!քk6v;#[(%P JX鶩pR.L }G c6u -~#Q 1jC?G OٔjmʶB RZD *SBdyJwR N/>  )_?Q\Wf'*3_h26$$6U%~TbzFJA@D!!}9a3a`>AcCDKC5@FAmS 2#VUQCS ߼2\>-,.2(QH#PJ͌ / PP"Iܿf)X{ȹ䷎( RImϪzTzrv妈7(ej:%5dtKDkt'ůwIq;wJZ$%rr [eW5X$&eTj_yU ݋%]^'b:=\4RccJMM*NP)>cKY6Pba odkQEwCy쓙(6}J.,,2XHeyyə7,t0v!pF! OK-I냄")mcYYy %Mb"&qPCl"|"I  6;6rigplW 9 I/={#;~u#>x+MT&yBeI  eP Vb+ PIm!aOmԩ^|׳M_uϤm?*[Y[IF3%R PC9_ `@$ZXXĒOxNl"7 Yy%ܮE@|!$فl}7v: Nڬhh$q]Q8==36.$"DRRDR.K\A|rFf ; k!nYzZxH/(PE@ˑPk5IBbʣGyPY2yNJhl{ KZZ-E VPmhAq acW\r+:Mfb-,E<)9-7 -vgMw=q%TSv̵b78QKpTׇz66\J.rԹJzBBPA;t%'^=ÉKq"@"55ڝ8?X W `Σw\q!_@m#p 6yC*SsD}Um6PR[&`>sip2:wCiyob?H4ɭIkp)TS_NEOWCpPφOkrӡaWjhyu? !vR2:[JCԕgPˏY2xJD /EU#$h;`"RO:}-d'֮"@Q'DnxAAc۠T]h3e#]nA\)75֚zdD0d$h[}_/)k1אJ\ypSs*dۧ)յ:PШΖHQ.G6eCSck3VbQQY< JRT/F_}:Kg HYy{GRvf 3)xfY5+sfND4]CܛNdVUC)~/BQDݣAQZܿP 7MuEA#yړh QO›`'1 ʾ\alTu"*+hR@y޿guP̙c U\ &EDs3RyvK"P;eoJ^(ٿ4BT \+Jywe|V${鶈:!$|,.0sUVP':}QC ~dԈ[ꫨy=uv&8AMC- oPP@Pi8)V[4|֋iޣKCH~#r6?65c̯m{#o # uev5ahK[7PW偵!pI 3#%i`ԨmG%Ħ(RJ+qeQ°D7EäkbkmgOϸqPIV;2kģ#s YP cg;  i_[ʥ I[#Qg6$BѴwS b{k 5$br쯽ObSmdS h5T휓3*-{LXKq$pN ֔`{?6ol[zVc`{-aM5je/|oC$48"R2 "IY}ڏ;9tԯy_|媙, \> 0eM* h#; Oƛb;=~ PsSڗi8D&F@mu7~៎`km5ߒ]O Džh+ ,\m>%L\զK..,X&*bf{)ctb JOjl: w#kZ -Fz(cjn  aO{Fq%8=v :%8]_X@)ʢyj&u 2K 0(n(M,13T8ɨrccze]]}plflT4''7򂤛}./躦U :/D~"GͅҖ E^BVKTJ<0--'O.}ʼnIPՇ~T#KpeQ(@X?yk;DLJLd4?-^˝}-H.srzb'?m|@w\jFEhHOJjt>;sgM)0ǥ6BTe7<4u LLBGDzҮeB,v TVVv"#1'ܙHO@S\~hKB,mH,Աgui:|}&fEUFqIaIX+3A|bP=&;Cǝm!A Ssx1HSU>q6r.5g~:ٳuȗt7ZoBcYմKFLb:  EDcb~1p%KR}NRzzzgD6EOty:\]Rrw?139RK55 KKń%E).1!1)y}MiVHقSwI$-(m蛁~-'4u6( FhVC{lR, g]n,&y &TI.=ϳ"[[3w6ye::L, tȗZw yX5fEQ#v5'] JeRr9T J4z%@XzN$\D j4f'GSw5#A;H\p)/ e#>Bk58QZkM#q4gQuܹi%|*Z%&p_,n͜s9}p(q(:$Rl5(nu7""w7W0AU5K(J )#5ٍ)!4eO}5l753Z:P En+:  ~E ێKzƪ$naK(N`OELJ)Qc!4+F:Vw~,pg4.[CBBBPFݚlW}2J\^əҔݓf-]ic\~tOHÉGK-uRaٓy.w ecT"NQ|=UdM-/\IK& ݞ8u"uf Sһi8-~eۢ☪M6E"0 ZfDB׬=hN:#B, _2{Mw#%mVܥզD9cVMMӹ9T6Sc- Qkp wZ-cK:\e/u>`y -u-(@Nͥ#?tIy2W&T @6 d@[(ESoVGuGhW܎EN{suku'xH(G3s<~L<6.`h hv$;h 0ݥPNu!R-B˙mM6h~*x] K쉵V}ǠX{rP-,:O;]bA;M{q%a7rXl~rPB,˨/J(UB*0˥AIJ-uP@N%k7W8d%!R~ ".:۱(.AJ(4EnQ6n0G,+v*s K\Ej[4NQeFSyiM⫆Ֆ T|ՖuE(-hBk":0C [-D^>լrI|~[1Ѽ䂨OZWCiiHˍ[%vO]-K T \ܹ%wբbK$ oԘJBdڀkK?N=-wƀs9D93ZɥC$˧}1JA.$Z[vC{w,#v~빳9^7J\z<$ak%wVKEBCicWv>x9E.VX6ަz )<1!¥Bs9Cmͪ|C r^K n7F, ¸3_̐Fu;@Xǻ-)5efmK2.?ot~R'K)X^z;wgScc3RR3Ҧ&㓎Oyhm 4̢g;1V;-w!˚G(z! BKzsFBι@*<}k;BIM7m֕[y<}l2[֊ŬcH&KeϒD5FN꫔B׍Z*A%$1ge g Q eɶ,C=2B^YoMhDaf.6k80ӟ1h~^n]TCK-g (C-\ c;x9V:AXjB ^0 |5+ddxm\!*N%%JD7:"܁ ͺ>ROgNOɮOsILjpI:^^:+UE}CAKzYhyHC>vQ/B(c!d,niP%i9t(-²NGJ- ~#$_/=KS$*Z%)sSs~[}4yl x`av;+Wڸc'ҢѤI '0mD".ñ?7ڋM Hw!((Mw3@0 ne7~V5ZZ.W*UU%T>OGIJDiA-\.H<ӣIߠ#n~KtFI%͐ T!2}SȡR;儨htOPbrS뛐tT(TJhb qĬ3_X .ry kyPȻ~əYqIJqQHu<} O 3!:C_7ÉKQЬҬW:.%zSpx蘿A #r -5e|B2>3Ϗry߿M0.%P~.#1ǥ̐8^KQ9 5Uw&SC`!Tԩ%D&1HWXx v}8piwg(׋AYcUV+2mO:Kb\m=° P[,Eex~[r =%eZB xOFQbP"vע$Y@I#>2{_5anv1Kx~wN!; EŏB=-W4 zH ?  g/~5BdDLՙKƒƒc͢- gjw R <["A;,.%1."7<8c%:V<%%&jLV&y@{K 3Gű{(D^3o4>u:@*YLD=j֎| ܎z(0W"2!=`AbaYjB'}Trӈ)i=V*+ǕJJ^RiXc8 A,%|2 H6= &AR >x'e$*P1RVS233"($enr|%Hc^g޴2Jb\.-ұ: }( P1yٷ6l2lA_} 5eظV'](IUQ[.W%XLI$#㓔 JTK?W$MsX2(Nɋأ )wd""#[j`WwB2^vV^LjZ sV.!Uª+ ?D6nӗ::m^18t&ov\qp / AeC`.N( sǁZnkMYzXq/ \^w1.] J^ !XoL_u /NOTk%!)A/3YKWN[j #}{EHp"PW*Yb)'\n+~sի]nغqժ__|Y<#Bf?^n7D|P&Ƹtj(s.hs 4s.d%+.Y5mɪKW#"gӕG>[~glnf熒}NgS+zo V}cWr5F0'Ҷ0NCI̯˷ǹ ˃BZ ҅m<>Z. JBdrCڴ1X!`1ɠ$VR6Þh ;jji$4Sgml;M;@مfiJ:`(rQN%1%esdd;=A"^B"Qwh(x>pp!S2"\X,a䥃BI+hjhYbw?hu pPCJ;q#(JN^ubKQq {z%'fd2\:DF t8A@P0N CIںzh}k)`tD=:~ۗ%H{ըtܓ]s9P%uν!t!/!kp_3AI$č\>N޻К|*A\ݿFQ!lJv@tւ :F kPL W`3UOҵAr= 3 C*,z7 j:qRHLT6S\245A ){/]qם{)"h|0P*x=ڋ+9Y--oe8,b%(,Jf1P2Y bd(@,f1P2Y bd(@,f1P2YeLZ zIENDB`images/ud-logo.png000064400000015205152214270100010062 0ustar00PNG  IHDR<q OiCCPPhotoshop ICC profilexڝSgTS=BKKoR RB&*! J!QEEȠQ, !{kּ> H3Q5 B.@ $pd!s#~<<+"x M0B\t8K@zB@F&S`cbP-`'{[! eDh;VEX0fK9-0IWfH  0Q){`##xFW<+*x<$9E[-qWW.(I+6aa@.y24x6_-"bbϫp@t~,/;m%h^ uf@Wp~<5j>{-]cK'Xto(hw?G%fIq^D$.Tʳ?D*A, `6B$BB dr`)B(Ͱ*`/@4Qhp.U=pa( Aa!ڈbX#!H$ ɈQ"K5H1RT UH=r9\F;2G1Q= C7F dt1r=6Ыhڏ>C03l0.B8, c˱" VcϱwE 6wB aAHXLXNH $4 7 Q'"K&b21XH,#/{C7$C2'ITFnR#,4H#dk9, +ȅ3![ b@qS(RjJ4e2AURݨT5ZBRQ4u9̓IKhhitݕNWGw Ljg(gwLӋT071oUX**| J&*/Tު UUT^S}FU3S ԖUPSSg;goT?~YYLOCQ_ cx,!k u5&|v*=9C3J3WRf?qtN (~))4L1e\kXHQG6EYAJ'\'GgSSݧ M=:.kDwn^Loy}/TmG X $ <5qo</QC]@Caaᄑ.ȽJtq]zۯ6iܟ4)Y3sCQ? 0k߬~OCOg#/c/Wװwa>>r><72Y_7ȷOo_C#dz%gA[z|!?:eAAA!h쐭!ΑiP~aa~ 'W?pX15wCsDDDޛg1O9-J5*>.j<74?.fYXXIlK9.*6nl {/]py.,:@LN8A*%w% yg"/6шC\*NH*Mz쑼5y$3,幄'L Lݛ:v m2=:1qB!Mggfvˬen/kY- BTZ(*geWf͉9+̳ې7ᒶKW-X潬j9(xoʿܔĹdff-[n ڴ VE/(ۻCɾUUMfeI?m]Nmq#׹=TR+Gw- 6 U#pDy  :v{vg/jBFS[b[O>zG499?rCd&ˮ/~јѡ򗓿m|x31^VwwO| (hSЧc3-bKGD pHYs.#.#x?vtIME  l6eIDATx{_Eu?_rsC < 0N1#(BAWT]vJ|BKBʣU^T%=-4M$ycޛ}wkݕܛ=3sٳgUSI5wTUҦg)oIW6_UZ`fX~q[c $i/`O`5nf;A +cJgG{oсo 7o+m5VCA&cshWX lS 4͒҆$GפTڬh \MXf'ְ o ,*m~^w jT9K5';`fe]nX <\|+^Jhok̬X6lޅF~:uM} 3}E$MVXj6~D]<ѧ8:\Mkxju$L"`Mk+U>JJm%qtCGW|zGSW $VX@GQ `Ch|͎'q4lJc9wzXiWJ{^$.vPPHr!#|$$շ풠]8Sv2w6;:yW7$$-v PM< Bi)zbDg$q4hCpvCc#Go`fI5z9kG֙4BGBrя]:'$q գOcJ9#͖|;GDr^,7TZO2}'~FۛދS[8*s;;zgJfz6Τ |:eV-Jߦ$nsSߠ뻚v{|> Rkkn`ݝyp/a`+XϠ: {~ci`A#u 6P,XWP~:p՚D_5Y(q"QX)UX} K+d7!a# ֏w3,PD^,` G֗Y–nZGH_T1dVvB`mEj $Bo_6-YD,`m=U+5kf@X = P#EfW՚AWXiZ^X[B8>p=k`+Ih2Qy2e%(,/ zZy f+#<5ZBMz_+\ *x v 6䌬o<+$ X8X^"ؐO 9rjJABH)>$߶$ Tšڈ=#sW`2xz - ;z?2YwXoUYJYK3zP(xoI`m]Axk|M竦;%>/9 GA],4Nؓ]7Wgdmg$BpxKLY I$>"wxY˪J2SYہgYXigI&7ZPqG^Rdp"s).љ%6;6+Kj%0Cil(Xb* ٘RVCP܍Rd*V,NV`ɑZ`ą2WsI-t=2μ xfq.s&0KEBH-F o8{GGs? xAݣelL(mD y$>^V*Q >åVlѽfp͓ے8ڻJHbV}s5ߐ`+ x"_ &7+9+2x ٘UXa.dsN͂<ιXѱdJ\sj.Ϲb7O, 7Sy*mj.E>"ߩ=I}+{nxAP-*b)Uԛѻsj؍ ka,GY-،I³Ey:셂O>u<[%򸅆w7+B.V,.ͭ:!^[`I bnV؝ٳ np/i&q4:8Ճj4GQ=$sC%N5.{q`uWKsXJ[F=VW3Ö;zvl\%ϭ! ,PPHPIg8뽪\(gRd2gpj9qH tjHIFe&cL.m5RO򌶒K[s7"|}~xqviL.JcrzhkaO A,Rf 7 &EX{Դvw3MϮ((4[ޛIc֦CtVPKA нe2"V%J;Ѥ#*\Qm#;|5{ :CCyJG}f)5C-]a4 [ 2쵗}RlٵZݢ5KSKT˕b X5xҠtVbŅxl+._Gs\5 ]t0iQNQEai{ͷ/ڑ0fŽMC! ,OPH-H 8ɧ`t$%VD08 ,e g+rAȐU%UKW+\D9yjX4O2p]_s݌Ժ}|JGtxwjzK5J_N8LC3#yVKBoPɕΫCTُԭܤә"0rtsmlP`J PT`h 0 n4` [>];2 ;x.=ٸ'zHAD$b$oa6+]1QF KY$&o lqO,e⥺m,nŒWDy FO3( i'T馣n`Z RdzIŝ<{t.8^aS *{$zS>E *K`I* Nk5ꕥ@asҖ(tt7Djmqb%%! ,PPH.I%8M'hhk n]q<欞 (SҬr kͪ1dU؅ E/gw~P%625.Kt--p''#p+y-},4&u{Dk/(dIĹ(Z$­s[֡YNR᥿a[ھ^溘_HsNc 'n:|O]C(2,8b2,i$ cK/ mcʊܭ7q2jGҔ Lh#Q޼T랚9[גM8Ű.WFD+r5=յ̀ U};߶rd@ZOo yo>؉dFEX?787O._(t; ,6q |M#lT%Jy-.|P·ȾhVȸ&[RԨ`ҳ=ʗڹaDm %~8 1%sOݺdƕͰ}H8*h^Nj PE&O΂/9<iA#OΞ%AB|5U =эK]̈Ě*wz h"9v&TzZOqs|\[ҍҽ +`΄;6ƆbBHJNO2ӽܜE@bM} !_u+$ ! ,OOH0 89&hhv*?<:o bȢ$eJJ ,hJAdTd#um1mLʇEC}8=L?>>~S4S=78`B9$8/1w. 6'X.k-gT.q(-T¾ͪZYQbvYf`O^ WF JVMwp":]zpvEV\ʖ`z8FJ""'x$5SXdM[4QhODLָLMݬ#XjN( kXbv5Tl~| 5..'#nWmP@Zv &lP:\vZR7=yh…OBGNŮ/%y! ,PPH.I%8=E&hE*+?ߠ7D7 _DqyJ^P>vz< AmeՌ>$;8 ak,SST}wH r4@8O770u0zR+ m.-M# i"jLɆ%VӲ=k&ۭQMZRgKoTb  z-$B^'~2214xnC$9tۇ^`Qf>Rs2L KSQg"͟!/f<r*K\ Ҭæέ5r ! ` ,رJRh֫qm*fO=VnԺy+!+>5:$.G;;@*y姯<%'P1})w_ (ԉ9%! ,PPX/I&8뭦čXclt*uߤM+~qJ6P3Z$jG7]bUZT,M9r!8~5| zB:3J/4gOJ -@% 6/>yt&i;PnVu\)*Wp`x铇ܶ.J C+z@8M?dA<ƄcF$a`#-eCRɐș"5idU opgk#C 5<3^F" KWŸ%\ʂW9 '4uXX\[ 'Z\ZBhp!)=CDʻ͡/o=(x* >GJdh&EX;:ΧU~ ۔O$y4m5;/%,U<{ƘڬY 5KF_pÛ7)߾6IeTgC&fTt^d楄?s&%҆NJ! ,OOX*I8 `pdhjd+;o- ڼ:No fHU IDS(hq.Vg-ųmY֝qy%Ͼ'{|}t.BO6/GJ/w84ql5L.@ZryVm;NOb*/|zV &4#da"}E ͘ϪhYEPSaʕ>݋05X;(prJ!@ln؋(Qd*bAY@#&[P| 56(-髕NB? ʜY҄>Q1}I$OF'Q&jؤjX\-e1GEAN:%6&]WpZb"B(bCXrSam-kH! ,PPH/I8M'hd*,Q+,rV mFYl.m{ ԶTfFS-!7~6)qjzBa \P iODI3~'}c2(p,RJ; 1Ľ¾ʓ&UυԌҍ 8S : < !ѩ raEumgaC)g8±f*+zyM<) =g軦 M>9CT:Z=u֭\.ke#ˌ+R m۔=Q͙%ّ-{W&O Vq2f.F'ήpt֌Ix1ڜ&!,PPH.I'8k=E&hh{*_ޟ7:[1aXd4FK5a{HmkU<wUSt:~g|nx2)t.{I%mFc=6+V(~+hYaħ6]zoςӁW}զoۖjeɸ?wTg?>_;)R;Ȥ114X.ĉ!H/FO*2)QF\ ̼EBkINJnk(B6? K͚%a8vdQD5$t/*Y%߄wv skӱ pY+k/DV٠%ЎOkG),f ^L37b} )&weѭR۫Ds`X;images/updraft_tick.png000064400000001605152214270100011172 0ustar00PNG  IHDR$DSsRGBgAMA a pHYsodtEXtSoftwarepaint.net 4.0.3PIDATXGŗOA+$A#`4l " !(%FT 5~?AK[fmm*c,xi&*0#Nû~#ހ&&W֕ UIs4R:r|r̤ħ=Hɞ3t/{M$.@2bf+NQ6St?4/yͥrn6=U^sVU7S:+rGJj|ʈӳMMS:_]?5HVX)x?z! :B..})z@_ktu';4ZtYj}&sXx|’lf6A /y1w]1CS'עTKoѤN67L N3!x{BϿuژ_+IENDB`images/ud-logo-150.png000064400000022173152214270100010367 0ustar00PNG  IHDRKAtgAMA a :iCCPPhotoshop ICC profileHwTTϽwz0)C 7Da`(34!EDA"""` `QQy3Vt彗g}k=g}ֺtX 4Jc `23B=ÀH>nL"7w+7tI؂dPĩق }F1(1E";cX| v[="ޚ%qQ-["LqEVaf"+IĦ"&BD)+Rn|nbң2ޜT@`d0l[zZ ?KF\[fFf_nM{H? }_z=YQmv|c34 )[W%I Ȱ316rX7(ݝ ⺱SӅ|zfšyq_0sxpєqyv\7GSa؟8"Q>j1>s@7|8ՉŹ,߳e%9-$H*P*@#`l=p0VHiA>@ vjP @h'@8 .:n``a!2D UH 2!y@PAB&*: :]B=h~L2 p"΃ p\ u6<?g! DCJiA^&2L#PEGQި(j5jU:jGnFQ3Oh2Z mC#щlt݈nC_BF`0FcDa1k0Vy f 3bXl `{ǰCq[3yq<\ww7Zx;| ŗ]8~ M!8Ʉ*B !HT'\b8 q$C'bHBvay=+2Mv&G&Ec[ [bDDĐ I* Zc0&8(&iYH~Ho(%46h0װu wKDŽ7EGGDDōFG7FϮX{xULQ̝:+sV^]*uՙXXf8t\DѸ@f=s6'~_ ˍ̮`Oq8圉D]SINII\7n5ewrm\J`ᔅԈ4\Z\) /ד>aQ1n3|?~c&2S@L uYY5YoóOHrrsNy};_-cZuuk/\?kÑ)*0-(/x)bSWr±^$E[nEmnfmOk%%%JY׾1ꛅ ˬir]+wZiYYGgʿs{?T'U߮qiݧo۾C*זԾ?=xΫ^P֡ 2mjTl,ixwxHȑ&JG˚faԱc7sŨZr}wN>8(mP{nLGRHgT)S]]m?x3g]8wn| ƺc\x'ߥ+=/_u=wvWO]c\n}Ϫ'l:o\:xviMoܺ~{;˾;y/Ylx~XHQc?:b=rf}Icda)iDӤ)ϩV<|~W_}oοDΌ\«ï-_w>~f~#zGPQc'O%wu cHRMz&u0`:pQ<bKGD pHYs.#.#x?vIDATxyeõǿܴnn4Z5 :"Ӌ)2 #B"ĐePȄ$/ƗghAL4B 2nA辭}ںz;=sݿ|9{]{ժUV Zzxʺ{:>'ot5Jj]XjkFV~\0i{ʺyGsFD.91xTX^C쭽ChcHU -p0p20DYץD<7QVr *^SMD-U)+-?*o7'5ON-~Axl…)nr…y43j…=89- 7 !GH. :{ Pq~HWHkzFG"=s=P6|pCtqbaR)_y/n3 h g%ߓѺfu*'pc +rYΔIC.WzHܕMj;zb/?)1}y=:C{eGPֽT]e8h`wo{;>{ʩg`0-"e*2={ <  ,[!GgDJ= |#%TI;dt㌖JM>;. Len10Wv%J(^J5rVK6=ٚrʺw65 -8y.MYw@]UPꃂ:bixuV)oc4R1 +?+uZEG֛˸J)N~,xV.JU(Mͭ:yF>o5sY0v9tTZh*r!+6ʺӚ)ZB85u:,=lt/)ImyzMwG=53 )c FTF7 MǢ=P=~X:T0-הuc 0VVU֍+~ FOF|:kR[VYW^#5| ̍́s2g?{f<]7tUFGT{CYwp7zyBen2RQclV9zjTD urD%x7eQ~L.TSw{Yʺ/ hb ŧz QK޵`,Sۇih2&6dM95Z*"T3F )c̢[_hbϮ?^&q}l(n4g=bniڠu+b4cd)kb2/q#e۸{(3rĒgӏW^Y7Ct)׍H[2{IYfNw;g[YwcAֈ׫>Q*n;pkoojxVZiʺEY<0'GyW5cBlb%vX?GYw€1xw',6RAXkzRpV'ث=:D%Jh?VGd ;z3u'YʺU{1I?8vxק#ͽ /eݎH%+YפWLѕ$/U|.0T\Fq]%5)pB lzOW#ugMe~I:gsCы:E ‡Jqv3 >4U,$$U#]ugSѣNt+Gs%c7z:jt)}Oz;u#SǶS&tz4Nu/2+fe%Ku}F},!=ŶʺѼSYy )na[Vq7r!t`.񞼖Ҟ SkDp/Jݳp7:evFߧVxLFH$\O0h,K(QD%Jo{V"5^IBvR-H_7%e:.-"\?8 ?`1OL7W&jĄ߀OI7zA[+Zh#"12=-%ZY6o$o7 {Y)O{8N/Y,bjb@HA~&95X譐M-K(g g$B;δi~џlibyI1$Qd8OѲќ)ԳQ  m4֢D%7zkUZ5UuH Ҫڲg葭H3p8>F ,}`tHeߦ YS2ߊĺ.xVj/Y#@37#e[c1@Z 3_ӝ-Bn2;(뎩FtIXjF9㫼 ʺn1LAH{/p8]/T%ZCÕU+ |˸(`nY8 @BZP4PM!5N&(%Ԏ5.۶Gji%Hi *lSYv"7z7zl 5kPY^[0ps2C  AqlNPi;Rӓ`g'=^r$ۆ R֭Vӝ]CE5MUĊ֥[BomLP& W\o@<瀓uW}[YV.lB0"ք.BjKx,(QD%J(Q]$YDH(֑NXf_GY7S_6T=ۋ)ʺ2},V)7fX ijxHu٩,/ ;^ U%u}q AÉq-G9qPԐ8[N[QYw$!@s2AYw=a0W=rV"DN )ǧ+불{TBۮiRS1232;eued?ɿ^PegWyuKΏ7 eFRa:ukwoI3X 72=,>\2K6&l a' ߺcdpՔuk{'MyBVx=>IZ}8aU{QM2ma[F2 8&"NwzĪGVd)#TII{(SD{)S:w*}~Yo+qЎ:oCLNU`TSeT? &qkN5@ủϋ=[Y7Po1HSוh)81JZ1E@bE|#Je]ʺwu^*N;7N8{J%7zXɂBZ{/.X|rޯ#rbŠt-$"$ [!!s2zAe;]!d 'ߜzY l&KaA5ir^)\}k-/AD5J""_XA9\og+#oddi"֧sD~B)pكunAW}%J(QD%J(QD%J(1WaC`fx=t F#a\Z<9"$}!p1x2Șike73fE"4e]`aA'oofIB^'u*B zF IWBu\*Y +]gsXzK⍁'$evgc(cCoUڐ*+%+:7I`(Fڹ!?FBXR-V֭G7H=-yRjGF[^֒ nr)Oc|ppinhsqGM4"YAT?G*%VQImX6`dʃuDNJܕ*%VJx)mO&|ye% 1EtN%~ɰڲLuo 7ahjm7:Yˡ0 aOP%ćb%cXQcJYsX1(FLlުgX2} Ca~VLnl(+:-@]}ƒeX)[VY]_W6,%VN<_pV 8}s{kG4\R94KjLCW+e}.R=R$K[vVtqnUƺ;6uGj_L.=c%DŦNu[m;;D97`xYYǒ+㝄,Eӭ7z (뮗<4H?;XQ:/vmթm.頬GßчtaгH9ew13 y%v|40P=ݪmo,I7*~=bx*4=.}mQ[LH; >]Yww+m@[Cn Nc4p7H'OQS_]<`+d\sbM{H ' [ůuēVFyx7"D o|b/X#˔~ Ey_oh*|;m܎('VnBTֽ>+lOOz7[jz myF_Oa^mcՐ^P&=+E˄&״k\M˶\{bac пb%(N gYZu,pK6l66\x+@`LNj;ẁM9|!ÄpSzfA2v%J(QD%J(QD%J1>\$jxLY~֍bLpMyXY_0%ZT/d0UeMZf!:g^ear S8EY KOf{|~؆f u&!1m;{&BqeF-e݄!z'D_FHo _D*x'm:%2FʺG3up}EDekBM"$`[jÁkSr|oa*_H`'`s@I ܯW1rH?u6oфׅr|,5a v)HmS):X^WhKͼ c{#}S \J;5dEwkGvxQYU&lq!- Q>F7MbmF3B&a^ Bn1ut,B(ނS]BozSI= erTwFJJ#m_^v:5NgGyʺߧ)ʺ5y;|+Ҁqߊv^M1^mD*"V__$+NT=!%Re]EYwWYY|0N1_1VS`D%Уteql@i ݔu.yYYnfJ4VuE"naUow FERcE{g+&y!6̌aoEO{(-Sʺw:Ƙ[gf Sm 75% F{΄R\oI")z^W5&Xr]Lz$T+Gڑ#oغ-SEXAD*a[dBHH _!s#QOiO~RKS=_Y7VxÆFr1% {]f87z{ (l&+z? ]7 NTB jB;OI&mV\;+^.œeNF?9ܫL[-!f üwL;bJx}#p7'rE" -uCȱя=n Iʺ{e)^g79PxO(UF'Iֽ5yۣ)_ r>?xrG&JhPD%J(QD%Jh’GIENDB`images/onedrive.png000064400000016215152214270100010331 0ustar00PNG  IHDR@6@bKGDBIDATx{[Uǿs3dRBlRhEd&LY< PTtTPVtWQTaj$Ӗ*#+V⫀+-}Mr3IʽyLn&ɴsEjw*j:p;idʓIFU MR힯vG9ufB^*)_5UywЊ+E咭FS*VL/I/ۤE:-(Ӝ5jԘTllPUzZa7 =m*45UxN /=:5jԨRJzڱ2'sd>GMz5jԨ"d 0Bc0qu1k֨QJнr,r( bH7? ;t) Ǔou_FЦ Y ǖ潓-R%)t5u ]Lk@}c0oR),hS+Cyya猄THD6.C=; }!ojz]hzyŪ(Q+6{TE'ԕeΉ E,[lAJAu/ć |!B fK$ddΉs?)`~&#D$@O*/=Tv7kͭ \<)MN9D(o< LʀXesV 7 }Fx7ޭr‚qKlS {hp"C bD,= lRX}+::dD.z !¸vN\Ǭ Ow]VY:ugAr;85\-a#o3i4=kSeCuKo?H))LS}fopDL_X꼇"P# zOO# +ݿ9Re16#A?(?T~궅8>Q_)tpcL+0c`|V+{[)?nJݜlx4-47y㙻F齭c !x;I0"s8ǫ(>o~6 [fd! EH#ZݺE P[!_h6X/:.EFhpE֘u)t6 l'U㝿FnlpxQכn~i@HY-̌R}K-խR˩ gLHb+O|S" EGGbRf, :fXLJ~M`ZnW!!L 4^euUf5L-a7 yu()xo);$q3=3SH4Fے7tJX <a>@>-Cm*Gq{N"UĘV8`0S\ EwX"fXT zCK9w#yц9&ezH<4qS4{eЇѝnSa7'[ߵY|loxPZH*3U!׾fc=T!26't'R;Y(μG[oO,tTbB`\\ n/"ɉJP`9> s?2t{V-4SIt%범m]g}T@W3J*4;Hn뮨}wf1z֤tNΒMy:%ņ 4z}74)+;Tc'|W9(Jg`N<&`PqV!_QDKBNH*{V63}Ép/ojy 6v6he2j@uvW%%\de{y Xֻ-6LdmetZKCr2[ڙX~;:AϚP^8g{fQKL\&'"|Sk4ީ~m3:Xpe 3Rr->JO V$%|=naNf1put4vV2AYnV$rX5 *^u`_Z6zN̊kkzIı1|IdPvt$]}&g'"[3[]M]sTv =Ɯ{XLjuS("R:e8*iVPag39-vY=A&muQ<iYK{H!FX.L< 3֗k,-K]xgμಹW/g|p  R!v@B KR’_16ݿM 2K܋ d^>k{MHR4D}tt|~xB"E ǻ@_A]|]I(,uJPEܠX/ٞ,?{/Ms=Z*ς.VAT :)O8`yd;]&s8 g_3FUDgZE0QHljۥ_gyഖiC3pOز [7ه.)W|gu'_ލ'x k4B,vS(zN8/zs˽SɎ8B^. ,Mىa"q3}/#-aN:\.Alq)!qcf &&ݯj"`pL:^zXW|ڂroiޥ7 |oR*7ƹM9! taJ$Eq=*jtB)we pbm \B׏[a;<A_u?0Uir29i#;o&u9T)uH3F+V<2l?ٻu~4V-mN\QS9K Pp_֝ef:ոs5[L5;4r)V@ծc X^#"VB=LhF#(hTHbUFˉh࿊ؔtL (h)FVN+Mu$4wAWhN_yJ`\dyM\y dE"׶ŕwW:m&7t GvI;n(Y 1L5D%lT U.8Rut{Ѓ쬩B9+aC*Nb + SV~W5>pH)Η[-+d!S?%k _R}ڍvQUcgRZZ`vwת>qčYZŠ{ad$`)$?ˀ"c?Lsni}Ԝ-:ag뾇6׾0X4$IެgVY+]r5u-#!~ l$CUo d,ڈBc.;~,QzMVg@"x4|]kWM~r7>mnM,$MsLzH9eMZ s\^-g&Ap1x:@3?ttmOңL6N§ ``:>8َw&O;uAU6]:șCxgd& @kw >zht5szƔLG5d:[d@1etxԀq]fbнŸm6c/eν[Ww9-(x]Կ=«,#ΐ#A 90v:5CJYEu{eKN {v_&k x`Λ f½XX & ~D7"MAf|WO: 1&=bHflMhpš`(SsZKDZ7~X[3q,sp*0.,3V#.T# p_w۾zKT2s(,=:)=C܊2ĉBʂD$xhTB$IKgs>OG</6j(bn7V}G)g;G7YY/t;,5I@O^=q1G]aϲ(}Kv?VbPC5ToAc_qa Љzz< U*OnhIQR0 F^47Z$AMtfaпq?gv@Sz^;aU(}E WbTR)%p+h1!S7p:MtU/MuUJuƣpjݶ HzD0*-0a=ϬFnoPeO 8L2jrBw5jT c2Dh3 p2re'ِ%6nRa(~(„{`ըqRqo8W PĢG5jTk~<-{*g?IZ>t6UF*cBveH0sD]+a,)5Se A |h<&x^ #fnIDATx\ tTݻMIؼ !!@D(DK ՂJU|U= jKV=xڨIZ (!$GHB/n{Ifd6?;{ܹsgM?Wj8_@R&(0<^(յ+3bk*v?BJiU寭kv4]ё,뾕+W |b5X)JJ|& s5X--`cJtol_p Dt)1{^W3cuxp[OK]*k1qP8mK8Exh@|`6`iqqP;6oq[ˁJć%'۠qLnJ um 7!}ӈ Cs2)=] \H!81mp鳢4ۘ qMڦUqGB)N @G.b=m9Uj'e פo?/VKbK*`ncX 8֍'ٚ38%3F&)+yQ*t(9[!@7*п6$]}b_ߞ9_M^QL HZ<:Iᛜ2Եp쟁ġ\Ī`b:Z+o@EfggX$&Y!<:Cxp?*'-Zk,xH=iH@Qo '^+򧅻#|TdžcfCn@xaWqQcrUeՎbՅh6mic 0:\I``f5ը_&ZgcIN uK[?LJyc%˝OhfN&CȈ3C'(jX=h8v;+8❣Y+<}GZ"_" r*-86k-s|z.L7AB(/8?NTuo_ڻ ]bjz86j3<ۏv8Yb,K죹iHЯ!1V_l:kiq2iʢd=ZT Pcfw{d1 ׺:s+ukjfyɛr=ބ!4 wܷj/{;"}D_ybi)+"^1QXHYIH< 2OsD*}+aouf 5C$ኹ@ 88H הSC9=TYN0Gy3+>Y WyDiOS!IU{jm,ʦYT=FeT^AH&&l‹jĚvA_!V6vk{Zxmekk Iζ* FCwdex穲2qaHb֫I'$qR(b *S֪ƒ0pv@s%ij^UnuơVhH T;H1ߐ[&ָ%%rlpKG۠C[KlP&u͌Y&:u߁qzh6g}c9C8Uo Y픢1Ǽ'doaZ`M b r|'yGɵe9aAyO0Iw2myϋ_ALEq7 nx=:?uu{ =.ul AT*zqw W8Xp2 ,2铩zH'9>5ՆGaY:66PGU; sg/T#'M@]K(eq];+8.!ДT섍vh裞C Mfzq%j(]OMr>efUXZe~ϴݧ쫦GiAhRj8u5wErEXxZV @qVW/5٤: ?B?1t?z1yʰQ ]_ Qw7edC^bV:S3 kqwHj\Hia"6 IކdwhmPD$ )Oe[/Kd@כץf},֏v1 ( $j 1b0N0k6WJxhrdfoTFCK4D_DTKx*b.'QEӆVBj[Mc>5Fl~RmyƐM8o԰6iBBUBJ(Cȃy{$_b 2I[fӭ}j") [EȌ6_&Ƒ">#:h%J i|bP=Z6rPH(?$qո#R9-*/ǺO@+ʹH!3\3*&QCm`[}2UʬOQK7[l 3H Ar'E/A1; ]/D4}Mr+CaM0x-yF=I^H<'Yj/$/k5]}|^{{nÓe熀R\P'^o$]\|Ӣ-݌y5uHOUI?/Xے=' ri8iE͞ k{8W?jA+㺇io`0i_&I5Ԁ#sLk0 iS3Z|1 ) Ƹ`d؍DĨF*,Dl6Ұf1f0^א&'[9pbh.fP adIu S;GC&HÚ4YH>C]@@@@@@*fd f5iV(t}QBpwǼ/4PDa 4HsN0!id]oF4YWn6 `lP!mVw2 * `@aHPˉ\{V00.ZGځw#ݙlnO Xou0xSQ5K#}V7 "0>Tqjm(W hc*~&u"3U3\>0CntyC~ig6"0p(#0c95F3{|sFҵ+};>Ȍ ]X3|E&{ [КD)5`pccZǀ"0cLo74˨:JK%7 M@̬l d>HȀ"lhugWCo3ݵ}8Sh lzi2Z]_DO_ʌ0Nr\6>Cp>pBv i}CnCE/"n~[s3 M?PZo&"mws_gB-SllcQaUXsdAD~6! L?:< w Y󓴦O}w} F6>|vہ_φ`WG@0Ey'aB,DLxYgD^.ͅC|vKw7YKhv 0Y#"+G< \r!=mU_Ț-(p£ ERMfo :c,qh0w=p!0c;# 4{ 7h2zP4sQi>hDZ]͎a6(9vUM;Dl֟`Bt"x{um|?F@P hUvc8\!nKrss {=UQ3t"RcOĸ3'%pk۴ōm1g9+ڵ2_zjHډyPny[6 qNd{5}sRXà-@|=ߗA7ZgOn eXZ}Dv{QhCЦv သ \iA$Rݦ*"x.~|?MU59$~~GeB9=eg8 E^| pq pG_l ;Jkp 3:EM!"y~{3}f"BXh4jdsOkߴw&tj 0g:lscwbSo:Z89dDsQu^Acq.FXϻPR>=w rtC }Ƶy1PUj |(p3ZsIscGc'PɈ! ~}0Nt; }D ܽdsCbf!Ҟ"NB#j=A*[S1rYhDmhx"S$ ~8ڏhcm(4Uy?$"K^7:ߔy)Js %jE^\g t1 {'(Xݎ˴Չ~w4.8d2jصp;q~(V|ky# .~|Mgd= Rw 1h-H%#ݽ?c1!z:>EՇ 6mi3 >A \E N zfikQw}ȠB>Qam(Ҳa(q*`s%J3.f\D53ϥ<KbbE}ݸxqבbMï" mȇdu|L,sjYwЉ GPԆkFϠ-V )i܏4/5uI?xT] b`&NG3)ʕۋlsii0iL$IoDZLL>NQ1Zw~BQoːP(K7וH`_|1X!!hdzEyӏMYu=hƵӍ_{|l%2v )fE#L\z_5[R0~a{ Vdm]\N:f11?̍xBƮr#y3 kZAFE$?]"5N&ZfV"KhFD' ;qMDe۸"3 Os2os ">mB5 !HSZj/w&Xq7!b5I#M4 lI;bKMw2q?1$_DZ]"]=]?O~xp#21]|:Hi! (x提!1wߢ5MkE~<^>w" L6#%|҇b>aoFAHG4e2E@dZ3]G"A2dx=fwhGB2ty/T;*`9I7H/CHf`?F􄸙#GЙa N[U8;lG h_? c ٱ[_d2) 3&HNsQb_IקQ1_ߝMnʞ{J^7Q=X#c3.ا}K$[+ӵ*u<?H{9qb8 5]L6<& H04q{g1ABم^o&U#Fj}Ko>tӞ~m4&YD6?܈$0 2ؽ`7 ާ#ߜ];c@ґx^$%'Nbھ̘lfa-JNQBM{B%BmYH+.Z\Fug MGɬ8?6g~r1[WrQsfƏRD1A!,q_FBȊL67(Z`TϴfXd>p ɽ]FN?Zʬ7>둰w< ; 1]ɴ8xjP`grkG ,mgC)k{ ${}膑KDI)!Ǐ._!m6zO,=%skCH7fہ|KEMBc~81BRwf?+ͮ' ݵyȜv!pqhxC&rtYd\bc\eB 5'U߉nʙ5psm%{6@BG͘D@9FօljM6wٌoF!)7D@M joDBWSQݙlnL!ȇOѢ sE?:T (pfuqmiBGD ) {g؃ +=H?+ːb18FԭFY1ABD)oA W]m,j30>O=Gdk~| kÇ$xTZ#kC*i%>j.A4߳FqBi~RA8xHlVڗbs2'6 柳?$H1E}{;z7ھܒ6@Q-kq)w'ngtO|WZqE9W!#ʣq>{_{2C &-sKO@{VZAhahq!%x ގN)63]8I|=D j M n7qF+ԃ<}HڌjNĐ\EQޘd_@3:bןJZTcr5Ll)ʟ(#hM*NG:WҸ<40e ' izYN%.nAՕ dP=FiG[wV*/|1p<@u%h.KǶCd~oSCxMkID~͵P΃AuGzڐI&Fz< >ioF'2d"xl1i蚐ۓ?2țc&|9wZ4TEyq/qVzFăj U ڈ fg!_Ϫ46}UF[_Re $VҀZ'#Dw".GUihT\Z,Dm=$)z- T) d1UQ܌"} ͥsQX-y5 S`!qfKh́lD{f՛J(|*"F?姭$+E(ÛDjs{&{Uю?в(KME#xE<1{dor8'K@A-kC|%W(LjLDBi$c4 m pϣ(pNG"-w *ĈC}+q`0yy((ȦV?b?2NwHg:, z`;R9z^@h (tDTl|`_Bp|q4?LWT{z`ƣ0o a}DfuEyNf6j !`#{#R5\Mu',XA<o Fd߆JesgBlO#.6 ihD7Gz1{ܻ$BYa#C`m}p[4~B<}*t;ב:OEyGE$q7J7H5Wi3JBd zyh0yRb#n|-ip܋hhZR|P|E_W3W,.6Vv0'R\D>GvjlC ]߅3;ꠅzFE]vb!1qp: H}!VWg"sIΕ-D^^[ӘS b{"*hhqCuqWR8@o4]5|Db0&: z5Pypg7߽LlAs`qΏ_Zu3kB`dfAiՋJ ,~Gꪴ݂q$ Z茤*msѱLS@&!6WoGģ'E=HJzÈYZfw 2KO3n.>ќ=Ө6E<͟V]QJȶW!M;7sm-Dp1V޹UqՓ?_IRx R]7k3;#3VLss5l1TOŅ?f3: iK6Wwayy 3EpuaHiq6vo2-蜲'QL݃"la' ?'?f)ځHrck}cwӼs^B¦<oЉO!#?%pO" DL6ݬ>ۛFjm#@8݌y \et(mPzZ"x<%S ~L62S=:ܳ gH?܉$eFȚzt%!BDRf h]V.#ps7x{>SI#A0NB뻗р GDiNoG c/J a]fV"kD4 c|$4wRhs}KF=qo?{/a.B0K˶iJV,QvD8/B]{G#V6c͘b3 (3pԴ(WiDD fS8NKw*\-^%^[*\nCÈd|y@Tfed,5yI:M%0ڬ8 IS~kH $X;Q/^Ť}H gD{v%| u!hd+H懧#Zai0Tޝ? w;L~oBw IN$ ^|dN@{1͈h)i*=c]CT=Dޏ|O#i׵_@ZDUߺU6smy$6QNu:2].E,d@0 0UD5xkk"Z{LJaԫ/#!2AZrmC+,_*d=iD_Ff!qh]/CYyUy" 6BN6֠zJ,hl1d (0Q[&pᯐꣴL|ʵT 1Lc2}"Dl"b 1XY V f x1~tGte|Meھ_34o;Y HYvgG8#nw؉ *«HNVOL6˦@ڋ'b#H\Ouɽ0ˆ<6]-~ ڋDQ5L61~`ma {S}(9~Cl.:MNoCEla*N}ISqyd٦"n;}/ (C T41y,@RBw͛ks;̽rE0)0`oaB!xkG l{Abd?Ly뀀QhXԢDaPss 4Pذ; 4Zxqiav0/yu4blQ9}:!2 MqG<vXՙ7("F~<_M"hr(#KP&t!&a,Fo2Q*O* 8q0b0'V#ͭ5?)P||2׽/D|jL hޔ :BW&$D .*IENDB`images/updraftcentral_cloud.png000064400000006110152214270100012713 0ustar00PNG  IHDR,?tPLTEQfii&DZ^OdgG]`^D[_am,j(k)PehɰJ`cLbeg$dwx`ecBY\Xlnr䙥ZnqF㔡f!ǸͶkq2ﴒThkgM{@u7o.v}ZTx;лa׳rĪj|~˳w>UYy9PTꡬYU ̾ƽ:; IDATxIo0?K$-^,? m@}V$z@UsO Nʔi <.E<9999999999999999ԀWRk"xӸV=,o\_8;"o{s*K.P3)"V!8I\p(TAQrzQxr8yAXwiyӤJV{H&}-X1 5*!*xX걙g†w#?q]r@)9~Ga ]VjD𝹲|BNΈ\,ʎR rJNc4MXgQäp9!>[0 #|<Z%)9k/BKr'UaHdEt+sZA7*LÊ(?] vw?'] ? fCDXIB]N(,5'hm|<'EP} ru#WJnj&9)6(GMnZ<1#6@r s/ `fX(:IhOrCWj ~ĵ0$c9=aJӭMCa>ޘ80MeȼɌx:7O(Pyz}kПĵlɽsOgb?yM:Ξ.⯖fcO)UsǏ'2ÇI'BܵTqLiVFwӗt&TL36hFCEn%&џkpl&m\M&Ē?G^ n ᗔ PיAĶK Ե5vƣAƠnm16mc$.;ۆlץ춡PWhםyi}GC|<=3.d ͞x2Tr4AA*MT }`0lLt5oQ,7=Q@j 0˧YhMnlh5:u,R`p5-yjq4Nw%kJ髮Nr249sLq/QN1ښIPt`ނ_O)U8N){XER5JA>F:)Jch\ ĕ!* Ėg3 f4"㸙[?>.|B8^E/'.Źzkyw[7*p4O/ZOБ#`cxDqL!88888888888y#dFQ[Xc{A1mLsMmGH7eo? ,S!\x?!5)xTh"5`$`R>v[#BqM䱢Lh+~ >V Cs2"NY hܷ On]u G4LA<˾qR+Mɬ.5saiϸ88&5;`,]+X>ӹ8[0ge%zqġ9WW7*|gtç1Mqp`Q4rB5~\ZS3wuD=M[zf̄f(9הp_a W7YHq-W7|MKk ! [ɔ%Fԣ0[%&_ 'CZ*^T$,vOG;ۓ2#|:!QJCAAAAİIENDB`images/backblaze.png000064400000055511152214270100010436 0ustar00PNG  IHDR^1 pHYs  bKGDZIDATx}xTWpҾ}o_k)nBPF H;n Hl5b!`?swf7w[d aLCYaD=~vv.6lJG٫Vn=02{b{=rQR{ e\G(rGn#Xjooョހʢq#n0}v`}#&np}'OUF,Y\HŞ:ܾ9~!J, 3vF!rq\aol\R< }A~W܀!o(KGleLKKV[U;RJ_Th*ٲ3LPx&;عhfl} V2h۶+|^=?swvai6ŝ:ݖ.qg8wlIrw#̠sؠIrsr֊]7haZp1̞=7n3"Fi_Sm"DC*Q͙3gp UwG#`UNt0T!ك@*V/ţ{:Z'54iCFI:58fhfˈD4mX 1{[aHOOЛk_}Gyion_Y?%f:+H!K E=q,N t4Β+u4ܢTXk驳<6Bn6%{OmjY_ ;[ iJlPde "P \x,3T iLV<)@Ѷd4$(Gve b6 57Iy6B}C*Tn@/#!US4oq9ً RW(b %y`܀)E8/#wm-UڍM 7j!ͬ䃛NΜ%|8/MD ,Y\g|_cB<=7?;痸xxXͬ oV7-o"8;=Btt\wTL'&&vBn{7 X`AVf._Z!zCﱍZtXXXS[oZ7`]gh0+Ks9]P >M3|ǎ};` _ȶ 06FP۩~4iC ؽ{Rv1Yw֮jVK-4[/xwfUM 9E:G]qgmڰՍN5F'{,&K2`tCر& r/&PLgm{Ri}&,=u+mZbg6u}e$vhێYEB!XJc:|gg]m8439zRA޵[9{@3fN5c^ 4l8D$]㜜Z'Oq UO IS f4l6 %EfSäέ3ځFi .[H?Ƞ|'s64;i~=>=SL: atRM_A*S\.7iXlQ,[f#<ۂoB٪})J4Ϟj*{*؇L ?]JIʧtA@ܩ=N;;u _L0$Ҽ_mpf͞vQ1r0ڙ׮*IVHQftJKK;p;v cE)`1,\e˲ӂX r Tc|jcK"ݡ݆ceݾGjTuji{%C 08^Y5St,{@B I= ݮ5Ơh*fC3Mch]i"UR*nr[7HoիW-mo^i}GLUhW.gm4O,Ё9ٷj?.yd17s,/sܰ/,SCɓG~o-7-srrggvon|_1sUˤ$U.c*I I:eah]IJeje>WD,Zi!"փf R'x|a+вN15_dUL:u!qOB6cş0,wkUf:)'!1hnڸ*48;$RD#M5 ;ibV*n?9f0L,B}5d\|;:._ʨA9R>hnRƬ MI11Sqcڹdɚ3/AڸBc ~/$ó7F >F6$q$ʸ=^smj9U6Qg&",n $hNxЗaɽ1kɖQ̤ɍW

~4tkmG5v[_"Z'ސL\@ &Q OO_iR$U !{pI!$c#e )G'K+KZzγY&*f9la}t\E`"#,UfedZd\D#<922]WHé {)xDCGzs=i 'V֝;w=<'iL!RBu}" &[7?fhaayw|YA HGJϘ{>x^&!Y ^ޤE"Y~ DOQ:mf~gԈz')Iť p&xG3XfGҔK#͏0ɌdvSEr-Eqgj $SCyEH9'A2Yn n+gfvT(Wv}1oӻ3ΉP=gL"rIS:F2Ê2C)l=?-g>NX(4llU bi'-?0ɏ]vT>M#,ׯ&Gf6kXUPPSk$RR"ˠHP!RY#VTTA)'νZ)>|EA7i So3?dҡ+֐ޥ/TXuj"!*<DDh|ͷ8tb:o׵v\Ĥ\vUΆ1 Es;u09sqK`SuhoWƫ=da!U |31&a:mj~&uZOՍRy!$c!q@V-aڶR>,"zIw+OP0doA1urBhMߝIxtA$o)B8O҄DkݚRаD&^ }AI'^ ?o^e2e tl@3,>睈idhqR|?2jTU|2i󎏏7B -+WnF#c@+|Dd4G®={Qaaizݢ;{w䓖 ̻c9ظ~EjjknٙYx^]dW"1&&-Z"soA&3&RvynnI}i[wOE%%o,tg~~X)==̈́dqr+֚5'޹_9 XFQ75 ۥS@A(Bd#I8Ys1J^qƗ-8F=d۩O&@"J7 }/9iXCc;HRE /Hq%_/wyA췰[z 3dZk,7&<Ga|gC} zBfgx/8oaOہLx:Ҁ}G.AN.g5P6qD9$ЈxC(SH=!wl /C]B dBG&n*WxIΐ&$Hʸ+<x#Hth֌SewH?2C]I2Eҋdv@ǟ3SH٥T+=2+g^VSv "<)iTi S|C6jeY딶U\3##yVL23"\ R'd^[X$P6WxE q9r"OH{@Ѭo6@9E( d<` >^bĿ+D^ZWB٤( <#<e'Pط1߃PAO2[tC P0fZ"Y8&dΜ,yea\/ӱ#GkeLLlˤĦ֬EL pv*˯4Yԇtquwc1 dSm o%Ln+qbݬq'2q#ߍ M|2,ցwԤx('JBF=YFvB$;$Btn>g]ZYM6ͬ+FPжtFy.7n0y/]hyպi3&-Ӛgee jR[H*ݗHڅn֬Z1mvonrkO0OОU&4>CBa0}L8-wXN^ZHT/ȑcJS7Ҧ+4<" 盝}lL3H9*5< AY;a7_ID#+ع^NdBm|>n2S@nt裿ÇՈJ4*VkX݈ct)S;q<~ܥ&#S}CJV,[`C2Kz=qq81|ll5Suxb0}XS},9kQQ5T#ًT&\,Mi"g:E wg~ h>[O{GX,S.e[_ 'f!;+MʎieCH65f%zQzY2BCԟd8]t*;,{sG15B2¾Z5(0uz򵳦,\].,UltL֢i!חPp\8Sb&xTk+:Cs7J߰=?`FlҰ9']FMZX_,en9ֵ7CCi:0K̦dcwY=>ʄU(! I8!e=|X23(`t@$„H6sGudVzKoEXFO<7"LKbC(ƭdM>=F:d6!ѝۓHrd!;g~2z*:@IIeB$#3S-Y΍1\$u' Dd/?$ GzΝ@~!d#:Rc߯Zl F*ZD"a "D"-~ACܿ7ݿ?Sʹi\+5밚? |G =,~ r Hҳg6e1u"pcO(Sָ8]7=$,o޸sUC20FVA202+c} YzzG_(Rbb"՚S  щy*҇d 1d[ӂKn̞X mE8' >Umۭ vjbO\\M.OE0ùsߘ5s^"3&N^f* +ɖ,] eߨ/.Bl#>;s17ٳS֐"3j.TXhH6ad<&Oj0-]O%dv#/(%[F˔ a@eIbwk$>ڠ{>'͞]xS v8 )Xfu=!&P3'_}PN/uJ5s*P~4m<$WGcݺkiOںRe&jeKyaވTlmI2C2vH_C1c='Z@2 r%ȡ+!ͮ=H9&i&B{wk$cS{ΤCklҸa#<6n#ws]jty$ ڴs$+;l-޷nҔ)… f#Y; e&i3!/Ю왋Njn>8JNDHVL8y{b+Dރ ސ =(,(-%du\Id0Q, A6kMomɨkDY)0ap*+pb|B1֯_SϠ@#VNJ8 /߲. 9<<{Q$lZ _ʏ/,I5B8;, 0ǙU7b8 zO? ]c{""4!ݰ quStj'sxSHBj& ؽb5dFhUw(LLzPPgHFN'GqGd޽zݞlXf~֑Dd溦dX߮uټe˖ ei۴|vQ<3f>>{8"F9k#71g츓WPk$s'7$X7eWa<T!%d7~b=q2>$9k.̟_Ԟ`Ia&u7\|ί);%N qd;4vfT'8{Mr4i [(XM}jodϞ> L@DSu޷hš֗p lڬrP}-*(Z_*|\ds7flU=bV0 5Gƍ)mڼZ!aԙU  #,͛#Y*|.[xx}ݙ˪T 7OO_*/*>ˏR$Ju΃{6r<J_4wY,]Jeī\\$[zCBTX -|}ulGW\kWk$S6s#c˨U٢ tSe HWhp/7c4l3sѩdx8rúmŀP9"lVIfϘ9;qmC͢5IVz>s`"2,M$]P{s$'·pmlz",W"c9}wxlFOns{$ Q-ED Q& 4ӓ|&Plm߰l*gY•TE2BD^#H7*٭b'H3Q.n V]u§k5ơuĦ '!kyAOD+n|u=fϙH6+HGYU6B#/R28*Em?my%HFW~**C2im2ÆiμUmgdԐ\M"[}o7oނ61_C>,D9Q:zsِFR;7Z4֙LJAk)vf(BYiv^C*jEJv>_הRqeo}3$&uWуtS ٳ,1ȣc7rH+W4mXEOW^}5y T.5mrL';<}ʕGN#voeek&Qvaŋ^Gb9+C|yĩ[!MQ՛AA!kDD(l"YQQ4705V&v2eadJlZ{y-'lάE/GLd'Z@|dah}6m>+kk{&7nz. 53~.]UOaCd!? ]i;QߢN;n9azZ3@sj\nXrKRw h& z,Wn:"%݃Ckdf͞âd~ 6Ֆ2jѦLw$+] oxhSm A2Ũ9I9S,rrrzizSvfs%P/^JKI-'yy2<3=JsrSӘ&f|tzV)Ci措WqɣX9i~{7Ym'}%%-nSJ/L#h$)OLL.ͽ]W3oL/vEEwz)0-ecjO~~]&yfv=tg2 t76 y!=ܽ8MoR[7ȟ8rOcǎNw")ɮeb<0%C{F"Gt𺰰( $dx`lbȰ:ft"v7 +h2~at+Ax4b5߻<@~'$;aS8QP- %7jJnuiz@=HbspRKgyw%E/ƍOi )A2Tϛv EjEX| ; o6L@;NJ?lJvptBդl:۹XJ{LES'~S4qdg.Ɉ|N Q9(rGO{:d {_q#-#<<فӌ0#;۽ySg<ßHA x퇼i3d}J$ [CJOw&<<4!A̅𶮐c;G%̉N< E9 XJ+HΛ\A)]^ȴ/^x]lP0i&$:1[P*S@`t|O{xZCxFݗ7yUE΄`9A PHt%Pb{"yի:9 ,aiQFh rQk !1yxlx Qߘ_N!CD3ض ֐,leI@!OeJ|Ɲ,:x*+|ȉ/r4 (ocd|d"1nj <CѲ51PHfդ섇a^<ͿqPQ#ȵ߸DL8zCƭxWxhXc h* H d̊I ϿeK>Y.O=Hxp::q똾3gi ͇5V֤R-[ fΘ-wϘQ͛N1&)z~N^J ޵&s5=Y/{O =8H"sȪqdL|ڄ 4,?ZMØ4k2EU1}¶a&M`nOBB []Xx8pF[7n0^j/@&t7h@a ҳ,xds '#RY2z$"gC;[kg%d#Ztd06Ѣ46)gYGwI R +{Fi/dn?0ڹc'nfbHQbat mH9:tD}qT-!7~xu]LƌmI:KBrŬyMZƆVkglC $ u g+\uwH AEojmϟWOV%c~wBFs.ȤC5̔ .No'J<"$7_.]4 dK7zVM vD:諯hх!H"~R>]B"F?ᢗ.] .]q)-}!dQ Pah;01FNM"m0U" “[JyLbWHuڽ۷I4&R$"Ѱ 0r K%D-E 'ig'd a0H%pH7]gDݱ zDh VD"2F肌?_ V\CäXQKa`FϞ3 c]飇%'[9J $XB#EF42a=zsNWivhԁFkfO2M"d'`5 5jOv{j@ZfwO}Y!Å ;bUY iiLJOd \[+P&j\GaApiHd^1]APP%`2p">cw@0?v ?z~m*׺J˖&8#F%թ'NTkB6/|I? \KD‡!!#˟8M"LQg -HHR_%f ) f 2V|pHy!7JB?+!߯Ruy%&&UM}-1CԼ<aëkygV֭}M*(Po!]|WWgi_P,Y ~bBƍÇ! ]@.;B:3^=@J /r*cPHu]-IJ'c,r&< Yd $T箝}W,cP/g> #{8q¬lڰ1]`emPّ͆$R!عc3Oz5׈CmMYI.u=CX q-h{d(umapj "Ǝ9*jc^A᜽0ǯn~/'dyJ:4 먖4uTBc ;w#ڵm'dy.]VسY"F,f<(9{޸quΘ1BD1X Ue)>/%Bզ{^QiLm(GfFOe) ⭛߻3y:ȬURV۹1Q`2+(wS>ifɓc*Ԓcը(hCgΚ._iP25(777ֆ&x9K+2m ]d6-Rs JYF !pHM ɍzVu% 9?m&d\l3k.7Ͻ>Æ^=?CG =4\KI~Pء#hћ֟^GK:%a)k7ɘP]ʞ>nj1ޭ[Y`q=g)Ccf{oB^{)zGب:|`EwvٳⷑJ5NCDeluVRwF]( RQB RRp&Ҙ &υ8`&L9w;-+i^|+ rZB*B|;[R[&p}4{'}˧Ԙ)! >"e$)٠1pthn$j"e8p۷m+}0}̋VKې1ųꅲ>baQ%Gh͵­\8IJw?vVV dyyuٲBC"> 'M.Ϩ#?h<N>S'swQtڗ]~Ae:]MؖtԄ0*7R,YgNi9C^AT'!Pn 2DP$D"9 l/(˜gW-? 0s_B(noNjߴ9<=m5߿ OqQ]-5x`OxS4{mƒ/zz`01W~#4[#"AU-GO.,o2Hȴ7gsB㟑%%lٲ" 0pP"||M2n||Ϥ)}֬CSq%9]!LAmƌgx(ƺ,LP͛,XNy%pR;g!s1sI*}|Tqqq{*+IVh :gL@]Xn<+{aSB6vDzgϞqOH*-}>51=ѣ'1[#)NaNE@eLj_lFe.\7 nCF ͽ[R7_W<|9A} 92yr+Eᦝ#ՙDV r Y ^BVsdٙYZzVMr=|X7iڰvԉJb "12ܙ-T_nmmRӡt3jȴvU{d\{!9 b91zKaW}C7y2*-?չj6Ο?oqv)Sgh&3y*!rõV{;7QH\""GŽ;wS'OJ=n0V Bu舱pk,B6sd {4BOH91k6%+6(oxSI?ހ=LK: w3B&`ڂԦ#d?|sjȶ*dﵡٻoS)[,F5>VB7]k'½"JjT% JCG͵| xP}.=A Am緉1l6b;.Y2IJJ #ET륣 U3bbMII3XףG3ן~ڦ5J!$nmGeP{h:Afƒi@޸%ѳB~*f-7  .(R7աDlvPvK8͆_win[DN_VQ_swU OvG /FD ?ʄiaca;*m  U6mM11w@OoǎFPE(L7\rzMa3DiF3f`{Щ/BV1NHH<5|A/t_r-dddv!BqO+" nj@lӈQPZZ:[OMT9 =uZh9ܹ]u~w&U+Hr@sy46$f Nܰ%H:Azˎ =2C^hH4*^F2SƌR~ du +Xyq /m%d P qS'OO8);uZ1<~B|`+t"ƻ5Tvvx4i6n'FCNڽ-)S+d򬴔lrV&'I3RR9ډG|(>hYi\"kl͘+;6|u+;[9ͿzPcTz*,$5nZjhМ %H=!dmKRO+%c1⵾&ż$h=¸R/m*C}an+W~5%dQ`C1tI=v \@áE+:)Z 4k2  x$"B7Ibg&lK^VKGnΠ&覂Q>mDH$F-U|﹦H`OڻZ+wob2fh(/`\mvhi,ɳo>w 2 u$)}ذ=?C_}Є;C+>1;, ]^IDrAD7E=Fժ B`$qcQex)+{nUV i(N9է1Ձ;)B,/\a3w]e?{~Jd22HfϞ[+B>c67?3zja^ 5Țb<יd [NO_4(+Qo؛tesd)Onfޠ@SQdZ$ Ć&eYSf?f6rw1GF5Ż`n(V,qNзWJZoVWQ"gw.]ĻQzzzKLߖ,ͫrlݴjŲ<whG_nKBD\YG hMn_ 6< 4ւ(XWLL޾69gbpT![MT*eo}M׀ؾægg׃ 0/̳f<%~޵[& ߷OF=Ƴ_303V,_CK%6miWZ6.Y ~a( :af m D̕^[.E&v)4Kޘ]nGtwj '·?BU0k~ OxxЕxdW!޳H^bI$+7DDB E՝ds-YD7Hېzҿ /Gx觭jV,(wd\ 6uk4`,1G2uFȘQ*tE3Gt[㧞b<&zt!P㻌L^hNDjE[-@٭+dvɯ@L˫yx6k\am5|~G쁂C uΝ@F$d[wb;!oxxHm$A<<nL"7w+7tI؂dPĩق }F1(1E";cX| v[="ޚ%qQ-["LqEVaf"+IĦ"&BD)+Rn|nbң2ޜT@`d0l[zZ ?KF\[fFf_nM{H? }_z=YQmv|c34 )[W%I Ȱ316rX7(ݝ ⺱SӅ|zfšyq_0sxpєqyv\7GSa؟8"Q>j1>s@7|8ՉŹ,߳e%9-$H*P*@#`l=p0VHiA>@ vjP @h'@8 .:n``a!2D UH 2!y@PAB&*: :]B=h~L2 p"΃ p\ u6<?g! DCJiA^&2L#PEGQި(j5jU:jGnFQ3Oh2Z mC#щlt݈nC_BF`0FcDa1k0Vy f 3bXl `{ǰCq[3yq<\ww7Zx;| ŗ]8~ M!8Ʉ*B !HT'\b8 q$C'bHBvay=+2Mv&G&Ec[ [bDDĐ I* Zc0&8(&iYH~Ho(%46h0װu wKDŽ7EGGDDōFG7FϮX{xULQ̝:+sV^]*uՙXXf8t\DѸ@f=s6'~_ ˍ̮`Oq8圉D]SINII\7n5ewrm\J`ᔅԈ4\Z\) /ד>aQ1n3|?~c&2S@L uYY5YoóOHrrsNy};_-cZuuk/\?kÑ)*0-(/x)bSWr±^$E[nEmnfmOk%%%JY׾1ꛅ ˬir]+wZiYYGgʿs{?T'U߮qiݧo۾C*זԾ?=xΫ^P֡ 2mjTl,ixwxHȑ&JG˚faԱc7sŨZr}wN>8(mP{nLGRHgT)S]]m?x3g]8wn| ƺc\x'ߥ+=/_u=wvWO]c\n}Ϫ'l:o\:xviMoܺ~{;˾;y/Ylx~XHQc?:b=rf}Icda)iDӤ)ϩV<|~W_}oοDΌ\«ï-_w>~f~#zGPQc'OVe cHRMz&u0`:pQ<bKGD pHYs.#.#x?vIDAT8˭=hQ9 _pd < ;+)gU0 \p(ЊyhE*Fu+H;o. `-2+R d1끍?*[vx]}eL 'or @&j_\5@Sp9'p ?ym>ps)༨Řb/:]H_0tzO5g$aQ{r>=3J#}hڇq3M[Q EZa U{Oy}vl翈 } >p Dm)eL/vL"K9o'u*.4)b IENDB`images/padlock-150.png000064400000050625152214270100010441 0ustar00PNG  IHDRKAt pHYs^bKGDQ5IDATxZ}lTY?s޼NgveٸP(m&V"D\J׬_Q7q51&FpMt5 " PbE- (%Ж~>sg-3iix뼙w{ι߽ $8q;;;u]ܸq5mCb_ܳx;800Et~|;26<Ѳv]GmG(4dMCISB!B&zhCCòTsS/^<߲,v#1;wZ<+g_hn=w_d޹s8{5k#GpŊ٪U$ɓFG )8k>cBSSSJ++z {3k' }"1HHRv%T pj鑹ɥ3X WNkse[Ô2HV'wR6a(WqE%RBf70 ;^jD3w|@TIǃՇJgM~p}F+Q@M#=ɉUunƟ'f.xvf_5@UAXTPR* H"kRVets$)1Mc ٢l.弢FFd *^J\6n:upp;そRв%t WFy!((+Oy^rWFi&՘Aiwp,[ .\,ꬤf1WKK01JZ_VH1L%8P-C9m~%8<^Zz,kҥKLq+jŸ|\[[*%K\C( /ŋqͳ{{{Kc{7n,("8y2?.իW.\555rJi P+Lϥf ,+a.Z'ѵMTQmQU}džus#z@z5:s Ѧ,JȎ ڗ~dj>`<}zl(fx}ކt?H-њd mkBM"^80v1 9\KdRHnSE.%zBQٖ[ĦgMv#V㼱 BDN"J>$C0?O-賗Q}1'm ;EעJ4N\x'GݒF"ND0{VΪgG)hSiŘK# Ȉ=>Sl ֕e^LLmnO@+DrtH#1ZN80Lӫ&UOg'BFw pO})8p z$Vߤ#6x45Kd){Q1i $545.t`"xZFfF#Q,yP"P)P˂!b ׵PB5m6̙3:_h*DZ#,T @Yxd$I8LEfi0 ETx:FEx0M) 466V9/_v V8Z'5FqQhs*)葢򝾗;d@j}4{ir!d_3h6mڴ }v8vKs:A" 3Ǐ-!Ϳy!qĺ:{+)O X  >h0 fm=zf>usC±7Wyeڼ#Bxlٲeh |}RSQM ?IԬ"?} _4]r;m=z7{Y}6.%uH͌9=p`ߺu 45'X>?cPT}Ҭ zx޾~%ݺu$-9w܌ÀɚgDSB'|bĩvJ\&D"Oc'T1 sx/Ϧ9SƢfPO}t,ޜ'u,T$PrK;)dAA @\/N[D0iӞvϟO&H6ɨP:n"Ar,`j8$W+| TR7Iȥ7YOc9Mb"@\9=`D^@yy9Dpe5UH˲PsYI~@P>p]RI&l7}Pȣz6V"f0J%"ϗtHIب*~ofZZJQF),)51npaÓ(Qy#0$_ECxh֘"aWE@wС;߽n]R7tfzΟι5,KYSY@IM6 .k f8nsu N~aļ,`w]pI_|lP"1qS9tX,o+Vf'HoCҼP-&4S~C*XBA /6>0VwB;9h*fS V"zM+ n Bo7qa}@WB1e =ɍM*KG0k%' KaC p6XLV ~P4G'3:+Cۣ 9|SJ g̡:Y'Gښ>0?>.J" сf9hȕ j i.TK4X.M->O^ 0t,y$~N+M6%<43kg*3U`번hZ$;02Ì!yC[h)G MӬ;Xj YX#l pADx~GI},5"@pu-kή"Z*`XZ YATs9<6~q/^{?eS H25I4!m"eŠJ 1/պ+T›*,Hl?.{%s?| -gz,w'a)4% Iw'T؇\eƈЬRyqMem5 0 A#g iDڱ:zL IݖxZe~Ŗf>Z5'ëW@,˪RZ$MVA';wLN>'ڵk{8^U6~{z(lvޭ兊=ql@݃T#ˍ72-'N&&&>%JY[n=y3m*V:&w$ +:\Wsy H[@T!+?Q>:496ٳgȑ#߾vڷZe8p  ",2vMi20yQJ;rw6?Nso~ :|Ty d|5?ίmgJyz 2c m٢cСCM(oS{N9sf~s|uOHzoR7G+Wu?KwV_}I߾}[/.kehؾ}/ɈΧݷdvg~]"s;Ti.\˱cǖM[͢'Oک)ׯ_/{O o}ܿW^? b1D"*+R3;wN^=~BϽ{##,FRQ0*sV;u6*' ˹m۶Ǐ[D׮](=FJ t钾PV~󋌌X4ڙ|AAڲP+!HD;y^vQl', QU]1u5Ep0.M(r9b~*yɕŖiє<듐iQLqȴ-Ob`)յAW{.Mڽ{ }҈~HGsd+īPNT,BzGăֆW#zW-{F|LlvɊ9%5b9):M1yز _z+5*9LXQV "w(Xޞۺ'I%Q(2`GV m(gPZ5:rz>7 gΠȍ nh`bvl_J25.B $/su9Yr\4)8&⶛>\rH^^k+JcEg@$c 8 @W i%ҞVMɲ榚*/̓CBy[Lё&WB CR5I~ JJN( 7Dߺİ#41N6"ReKb3x"zIVK[:H{zRw&h5%C'rEBs/DvGm" +Ϋҩ-H>܌2HZX.`Z* ^嶔#kLs-tF"W + D H[ 6,Ё\ bD]Q:|'/K+""<q-)6gWkbS1i[;s lsefUE'MRB!H =ehgj^y:?7q9+=A *ґ]4)"z]6(bqYBLLaØFM ŲAQaqZJiYKˣ/vf̽sfa:f=w;}G = d@#Al VVbQ][g q%dB ْ 7?AEF;-yY&DiL@Hd8Y:1M\[*U!2LfH=[0ٚ? ʢ҉VnB =a`-RL='!TT,*zaY +T+ZZ[A*(c_"m$P<g!vG,iH)VhJc3x;|ႜ YOz5%Ѿ $ZwW ZEE0fi[ϊ(X|DCK$R]Nl(OwsXQSr}Rv/=2g x%ɑTb"AհuleA ,"ů [S2u$j)5>tEL[cs,+#C<5Y2T^ij5b( f%jwK YIV%)˚>rOOE^&3 :K#|uPY'M򠤡8e f+0J>%49AsqR~C-:JJBbE%a4HbY\zSlgp, ( |+-, ?0tO`5TLW&:^ʬZ%|t6C@Q) kTQ5AA8Kmy԰>t5Dd[t'PYQ'gjj*F!޹pBIao ɳ.=lB>A Bl%,C!}ں)G?k񣩟 V 6 K c,ڒmpr|3CkO1ßEv=y߇fHeț_E,Y,繧˹!Jkٲe+W,e)li 6oLtjmm!|(bzl_޶m544d!x[[[&\f-+@ϝ;G--- [n}yǎJȳ@@gȈZ#PWWG ,s"aO8AxJ[޽{\@Odvw޿. )=)*ࣀ#"N/]H1-Z**++x,?jj,7JW˖ӳȰ SGPTAwOMG&5~ov59sе?a^}g Kfe ]v5 ~DžwhzFx:n8ꊧ홌MxܥɤRl^ȉl_l(< aY7:.IcWGqchnw֭[3X0vH#ѻ=GtЕIzo=£m*;s 9*5g ;6lP?|1ҥnLxyիWdžc.KG!OcCX9\GG,T䧹HE:Ò:K wW/^,;o nq[(  ڵk,4RkϜ9#sV.zX#ojjBgX@? E֜ЦѠD9Z*Jì6%x|MX:CU3G`c9h%)WU\`-9Ku/8y$V} U ?sT"eh,ma>UUN[ё.~^`ifJ~*p a ̫t',kԿyVdғcn7%k۔Uo餳ݦ^>cš΢ee `c|:fQ~hSVl}VM}ׁoܯ]VKVa(=pHS)܀G= IZ"*{KjU沖ΌR5Jߡ0rjY2ӠUTAB6lu+e BQ2EZ{3EEl~U&(6`ykh:ӢݸlgEy${RoSzFIMnb o|PݢK)Ul>OO'SZ%!ρbC앒B g;6\P|*[AJ%T;ϹN3} ?`0)R)Toթ]Sc|jIJ*R@%n@=a00TPeԿVGk(H9 ET[Z5O׀Rrٛӻ"h@Ŀii lSjf;Q\:=~ |xv!,@Ӿ$ŖLEA!I+񥯕 J'0xinқXJт&ˈ33<GW 3K-HuHR-/0#|"PzX- IVx! Vq0VL2NVbuY_^ڦЄ`=K(lljTM'47>K,w.=RmUgsȍHbȘHL ΝiG0" CWUյ}jR]@ʩGSUgk[wsn4gÈH]l0WTX=w4]|Ҋ5իBk`?3'3^X[+MK{ W׼"]4*UU'"W7x<.vsg$/t3‡k׌O/=Cnjsr0nhS-L MQC ?E hfvu@V01˿`NPJ{%ñ}Cotkϲ6+ӽl$>)Q`8Y G:h165 f[B% V5e>A(6CKdyd8й#֫e+HL[ mQ뉐5 q܁ǹCxу+Pͺy˲!`qSOZ>Rlcu,ۋn{Y&{oM6+g"SIBOw%?|%lTYvt׽[*II3aG̀ێ:<AsxZ'?+mlQ~V^pN{-i֖`]Uר75qNh]N=].zYI$2lhxD(+GrfJ0rx77̖3ƳH0hR+:ȼ~\^i/p}#e1ƣcɕkQEp(Ĉ'TT]QX.EU [`X1z9çd`!p v!c.T)W,ڀ);TƸ LPߌklUIFk" b0`\+In)Щ^F+עYNj|!Ċv!Z °M5LJD+dð(+!h,Gj[{f1@5)lId-"n !֎n 6 ^g>U͢WK+VE~X%aZYl ,!b -Z-9ײ37 AVeYf݆QI g>]N^4@U9}qZ䃅 3XF[jA(f%u;uN8y)JVo>Rne6BR\!4G"۬"F%aE,BucTiH\enG^bh#‚F0SH+RM),j}^(rJ5 >Ƒo;xmLy\Es> bzd- C4iͦ17DrO,yFxIP2c:;hi۠9hSHnAΜ9jG, _K53cԖuM?le њU3攗62p҈?/(`bU C_$l ^= | E?JymHGNUk ֚ZEiż! R5޲Lh ~OWKЉ-'\uL~cs5~w|TJfZ*T/s؃.gTLN26 Epn/Ig.R:{<d,$ V/ɦYBRp!ǝNO%AŪ:cD/x~Z e"Lq0-fE,iILw üamsf3<[FMcr{J_|?D@~4tj0T5jHVbBY}iqn l37X8㬪K YaF hmtNHoj T W-%Cx^~{  ͛ݻo߂7:RU-V7qMf[AKUOШ4RApҢlW/p~(-wg=Ʌ݅G<;(-.\ɓ')" ֭[ҥKCm0d$ ocܳ_ΩA WjHQX}`kO0VJ|oDF)K3=mky]pkxak2Iܝ>M;x{|vkBXS9FQݼ{58AD=g!Iׂnۉ:y>m+_# >DvvfiiRV?F<ףhT\Qt@[<@Xm3lwwwQ#Y1=|0}HK.Qex@{QiI: DSlC²#TDu?o~%}I/8}k׮:HQc+*!/*%&OE_&䳝"@оsN( g}ֲxG,:i\sdcF-wgq2 \~0ϟ?'`B?KSyO s:73{wX. *T*BFXlsJմP6PO-6g!;zh-]]]7=a}ʍ /8p |)+}]);p (fPH/Bf|bǠI]|`\= eo6@$q Ex P4YCZJ.u7{cە+/^H?::\"焰6m{dd(z;oMQQ.4U@胸vy,_b_n nuLA#TeXBVU.6uuu70EgΜǏ>yZڽ{w4Z (Lө u4*Uk Maׯs[O6GeNqEiQAב?mmmA >0o?tCkGGG3[n= D  tC*o31J sZփ^\濺7m O,.a(T-_!NS`vdhVsKnK^Cq̉l>%gʪ/&s+DRj %2755x&C_96n0>7E03L-`uG7{{6cvsT'(Y~E&@T`&ҪU{{{Hnʞ,m۶MB  Xi6]p_n2 m|:;;Ϟ=+XXXwЈ+5 -Ŀ;qEOքz 5R?v{vpo+Wj 9YN!; ą!}v{-kxR H>ǹ{Nq>b( Ο?_zͷL۽{FGIRԚX8GL&0V oT{RSwYP!tToB@=+l}-Y ԑrvd 6 !&kƍbY/x" eʕ+Ekf ZV;:6C"ΈG޸ :TP;H (K=7BRbcc+l^DFFd}zOX5a gowt"X8@r#pّ ,̦ qV{{;zZ,⓴0t##nB)ϱ2c嵙tga! _OqnB>-tX^{8%nX'7wB;D RФn0 ˁzzr Ϟz)β'-N1cن^{rtcf}ƫ 92"0ԩ+8)9ʤ3®gHوiɤ4V RW#O-13-eBHOxSx39AQ}iDiغaӗmF.A4{u+}K,SӃ ^8mGY)4Tdn7'^Yri WA0.OEG@5HQxaFPX S@e.`)`Sq_/!gB,ef<-RzԔo$iv閪 zݛ5eljQ%eLjqST8?"'392c`+oE%~+,)Qh:W-` SYf@EiX}Z yK"tV8_a(lT繲㕄JI&*:dAѴY|YP,aU3pΆ} ."#\CP ?n{"[m/zl_/J}u5l)7pI_7Hㆮ^s>~LQV!E9s $HTS| kj(}J Xy-,x9V: ,`.K`.tbabVK*Ohg)C4(šdf {"MSt2u]5]7%&]QB$;x:KW " Qܩ(\ PF[QI ~?!Y45,Ŗ4☓C/ Z;@sMB:+ ' kQD8+(% 1%]]s# $9#>'JoL]./iHn]*݃k%[3hLG0H?'ڝ\DWVav2}`"liQEi S jWt՞ؖ6MYW1pX&G"PuOfon^=SB0:5mI;{Ñzf!kddaC6^dx}>A7 V77X{e;Y 4GwzH1~؂p\h4}MtRIt!Hڢ=xM”&enoYer_%`g w]/TB)Y c"+pee^V7Չ>t`===s|yIK^v\y8x*LJWinR ;ߏ%HbVqg>Il(Oz_P 1}'|=~4@W\ y|5IN`xLځsl՜ L8qP*,Xx7F'׫4KkT&N*ppdoG6[ThhfwNj'#-/Îc9VI߭ w& J+~`!ym(%,w>BGNKbny_`Q* |1 ?8{7OJ:50OĪN`ȁ.zᬏYya uǻwXD:\5d AHvyg0 p`:2 sr]V<bH4NqUF# 2-47Bsh&y?ìMx|IRV4 wvZc6#) 0ưyaZ_ ެ R`hgiFs!<`mg 䤄zҮen8 Zbmw;Z~MG @'Y!۲L $9ec n)L>;9IMdY*[9\vKtю&?=y/T礐0`Đ+|Ek:m2+z(5Ԝ;ȾEedĬl{"b-+qVcP{bGNajQ$"Zy.F盦ՃB+nPvMWo1CNڅvk4~r+OD -Q f|R!N"`v:BcLiZ:KS,S.ZB炬96cTFSiJf%K8,I]0HEokLUExjA{Қ>($>Se1j17 |*NYXUv bgi@φ|ur+dXanLxKbq獴㒼V ԥ&Lѯ"&Ff"KHKA=A·Ujλ OQN+LoF+uh$mxLkL2M<`wT\#AUq& AWd/hPum'QNy UFhYH?n ^}}X,KrV)Vk~=Th̵@%7nHQ;v6ުn*Ԝo%zl:qӭ?7mxͧ}gvm{;?ӤJhgQ&¨ Q ]-wXcPx}}= >GB" X,bJI><+&|3ҟy%|+<~^z^v1hyEIm-tm ! T]EN= r5d~-U, q_ߒL亗2Gy|}=;kkhc[xe+>y2%HBJ% / ,ҋʞ bњH<9<Ljoa|?>K>`@#$$ʟK_q .u=@*QM\{<^uߦ Ŗ#umDXR[dG;z@qw>$u543b " pf}E|CrAg Ym}:puu'H.C)H0?B8s8Ölq "߈m*.* ג6Ŏ+O*(Q'|H2D `ׇF;?Yp(丂%۾(0>m惁6\Ag}ƻFAsqoMSغEKfflH))Y i"p$&iSlN-77ђ`f9!Fo%̷ܬlWDwKB"eY~o^{H>ª |= rٳk3m*=M1ߏ.]:Cx矱OսketѭC@x~ԖoirNU=F`<ݻȾ(x0(HjGP pZ]tNods@ʾv8s!sط(Nǀ[66l$eضmK׭Y՝=k6য়~á4ds"RtSFܔ3٬ ?DJB"k*aI0sŲسk7&^xʲnZ#9$ , f$&qN>%[7:rZtD9  O<۷ N&M% 4^mSKжoA!MkD^,}%$ *ucABTvVrʡ( rEJbY8`IN k[ÿu)?{jk[bՎ;{Xf5w/gcN[-CoUd$|Ι%~oiIsf{ԤD_8By_xgOI#e/ CvZ8„hޮ;8SX mInü6:qyGĥP؁IiP׿/LȔ$9 "H"7\q|[(A!d 1ܺyΟ/Dtt,Nd(xjtmX{1ځ:y W_~ ݻusog }/*<x{ᖹa27^nƚJEAMM _,GakY3q@ !@}Gȶqgw\)`>$B!2ssc۴D3I-ٜ@ՆB!)f"|}=JE`w>1T:)I,//Džb׻X\\?#37[11kkׯGREڕ!IBсR]$ l &2 H]K5Z!C$,ukPCףx8.Hq0@b\۷nE!=*z⋘5k&$B%!Zh @BD@yuqe0GRoF߾}SԱM'36&Ng]QZ2Ų1@#yIM(L } N@S>'4p)nX^z 9l`@i}H5kJѥ3ͱ1zMG8F޻pެ/roQAʶi-if0}.><~%[xð.F>0˙Ieee۷mQЩl5VUt$QSU$/^m\G9H"IʟgfsZSN$VKQߵ?}/O;FXxwmߦfNg$۫=8PS7]z*IȲl!Gbcx]ciK[KLa<ȰPzy_pNѐ(3&b_lb ꮽ9 ͎ds_ {`H΀fFgV :_7ĭk? /hr26>FP>GL'*yI9GĠ$ ABU:I Rwxyj ͉د$5Րes* ` `IgLT@[6'';nI!LHXf$IBnV&tE{O?HYxI@'<eFDYE(+- A;o%@~}`;Ak7lо(jZ6o&)$#G֓օ$ "24n Idvy͸ƃ$6o&$j6(V@c)GDc]wP0m@\'3O+(+EQPRRN*8BLxa]t p3 rswuDŚE```=/cn-\2HbW.%%IBUE%z! `.#v;|kBz, to/t:ЦUK !!:6 ~~!CϿ`eeu]{vQQ3O?Iaˆ/ѷ,&YZS Y$ﵢ8t8SؐeOMj",q^7:uqL>̉ ذy42`Yư>gvVƍ3g)CJK/R$&p $QUU !4v@#L̳\t)HBXƉ| 2ΈyKIT jtx݄u ^lCS,)-id5ff慎[G46"WgvٵNxil*Q\|ƛ7k¨PΛ%;zdn]䣏 bGأG,l֒w#GHoNC0;;?3S|g٧QĒ$֬YE/}{[F~vr&O?2ײp5=ahT=ǗѸUB.? 'N$.T V(5HРb=70** Z~t1'O|$c'E?#""`NǀuNt:N=+3L-9|pPUVcqӈ[}6 ÇyԷ$$PtTWcʟ"YSZV(_ZR2+#EQh"h̙࣏?$I5ݒccij9gaۂB;&YҒjJkt:z{ O5#yy9޹,c݈3m+ӎw݁tHnV& n{yvَ3gc uط}zFPө5jBW)ݩS\v-H 55)E|tz-Z >gi+H*l?Vp:${_8l,c]B,n ڵ(XnzySߩ #}i)S2uj3 Jiǜ6jDhI+sۈ"FErƒ!2):I1 jݓ'3*,a!F9pkז}{`=ԟLEE3h)Ȉ0~H^(:5kV9t 0?~̣8__4CS߻7C4WsfkuoƘZ\c3xc`EsUW;Gpi͛fcwӫ;uؠnЧwOBh 62´͸ Q=0յ?:<7 'OzܟW][lG;ǎaq=^=/(,\BQˑu1/st/Z?5OVi-4)%1 ggNi.G&I9[tQ||g7[5o}wqώ팉gNi .;=go-7PQpm 6Ӹ{6Mp㺵eN8 _ݹD6pO?2B2ne$g|C~"+PZk5N$!g rvߦu+:SN!'N;z1cUEŒgygdxkuoy .Q eFΟ7x] |ysgԩ3K;g8Ʊ͂!IX=\GMAAխ+ɔD3 f\T$zp##Bأ|~u[ܳ>I7cL~q6IJeȳgriNb9ޱ wOf0"}7lq^]{Gy<Lb)p p G#B{E@/C 4Aڵ"+ڻt:^өQwW@+Xk>~E*$N~[| EdxM|Rx)NTeC26:e㶹xbh#ŭ[Y/ػbJb<- 4bqi#Z\9lEٴ~p$Y#9zoIfdRVD]Mm)na<.T;]^~O7vN2 (SX-n'@:U_!yM6p.+/y'>T> j$ڵm׈=S1B悀bIr.*O閛[6odXXӶ? HO+h֢e#F\ 9Ė <"WZ=w}Ѡ f󕟹l $e>] O>oLn.76 IDATbm7'gm6Xk!C8xtMm͛IIׯ"##lqgΜּys6l޽{ѱcG 87۽fj:tio3gT kW4ImP';;6l@yy9:w={^B=gԝ{B Lp"9o6HShUv,v t.ocbt:q4/[ѣ/\$`^|GHhZW^>Ԡ #`,I/!#3[<4n<ׯ] (--cGoV?w߅$ H@Jj*V]'͙yAˁ$I\;Z|♧ಥ8fc Bҥ2ڽ ͚7jNtPOE ֮YŻ %cyU^{~~|W wϡl 75dZD|o Eb u5@ rx{{UW1p@@m 00^ ?]Pc03ˠۚ@V*KOߧM׭)SI$xyyaubo𕿽Ex?~Bs? D`@G`msoXhzRbH~~~^ϬڷC#((PAN':t8&[8b{ǎmȐ֞Ϧ? Bi>)u07ơCG~U*UT\ ^}5Bs6|8Fr +]>$NG3>D`pk #^y%9x`CI&;"l< ɚ4kn[Y햛IPUSNG@Uu5^{uxQU] KJʿXY] c+)5WJK5/ v;?f=F(_ӾKJ 8%IUh٪%_^ݺR :\k׭՛#be9z@ ==y xC?m+q0X7MRbM=Xkkʈ7&޾#|t1""B9qݻv@`¸'R$$qh|{4XzKKJa0xC{=HI!($)w[7(Xa}jp[$Im *2 ⹭x]j,{ xɔmvMBŋ+/"##=GYQqWَi߮Ŏ՗j!I k߾{|( rss=oݺ5f~EK/_]=p@)dYY!2l6,\VmhhI-ҴELY{U"3;RCP` Ic0u4 j up}u̓njf8z!:2:F:]ob'N?-`ǫW~j 7Eۿ?YD=WVVj[kӦM=rl!pQXF㕥s]B/nݺwAVN(<_t9|N%:q7xd/H>$e[,׊EQrʫN޽^;H+*eB)P^V(81B($׸ӦKɈ uuM^&>R]}EDhƨɲOGDG ! Ʊbt1b7s)P^2pWx !P]F= Ѥie}(a^CHz̟7wSOTݻ-܂.֢ D6cI(++=uj_c޽YVV-"BBB&NSkhjE >ж͎oYP> +Z*4OIFjL{!;Ռw9Z۶3*2#(X2[H+y:˿]Z#hHjPsER9{{MJ54j/"<2W#!&Y>8qңGyzsK)KH*{}x;y-`0\QzR{?W/ BY={*GCiMӱtw.M 50]Yԭ텗_BUU=㏹l6 -Y'cO<)k,>_ZcyȲ NsТiS:L5bsNMදq/n7~f5JKJ+_\jNM%S@g~762G@@ .B ti*Zd)Ƚ?ZSc Uuݻ&ylA 8s~iԸVNᅬH:r߻w{Kr=np#3>!̙=55T922v75%U+s<#\T;[wݰIfb޼yСcGUS!B!0@wEWk{_\H6nބ_]FYYnf9r7o}åKt 97fKaINBuay1qi(//GyEJJK8aّMO4UzEj4i L<H(-+GEUZm="/7G<;9XVWV *\lٺMK},㔘7.|(Ee(++O=ϨI? ֲ%L&>c}RZa$fOdb w>DyH|'V.0-% IQp#ZHmLUT41:w6M cع3CX.ahæ=vq1ؾc )MS  R4Ÿ 9F?54?ug󵿽Fp~-I(/Kp1Z5S뗫 ~9|5.O?=ߟq,:WQyq۶ln}Wf,i܅:6mejΞǴG"Ι3p28:w;};{&'OcJ~;X GBaq{Ν/dEyYzIu.;|)Є/r ܸv Ӛ6S'١}[>y6ob]y\i=mۺa|qL2s$`?&8a8qܵm+C֔7ĒwMի{1%{XvԑC\@ʲl͛Kk8!4$3LS=d.7a`>cLftx3N֥}Gc}XҪy3Λ;2h$I<6a0'4#L!L2y*㢣XtxfuCsŊ$_{G7 [@qqqܰa_~ ϘC8}:/ܹC_zvyF 6 .]⥊,łǟzJSI&F)c JKSbΝh 9pZj}qv>.]R6x"~hp4i (8z(bb=nmC4-ՙgF3~:xڛ6n@Xx8v;S`#vήݺ)SDmm-z̟?7 _l9z4`̙X<رGS :\ٙ"5խ+Ib]$[GՋ/bbl 'Pw;m*Sޥ{I;gx~tFEF$"gDN컥#oafM9{Li͞E7puCپu+Zx͚}6L$1Е?|=cɇƍc|t76i}{wL^=pI" #a݇H}{GZk55m¬ֵ3O:JGEV[;iJV󘓝IhݬCMp/vsܷ.mC &}\PdB?G:h ߟ.3Oe4]zL.-\s\;nўv!ej$V\9*/Tp<}\mݲkxfWXrúi$qF%GFFbEHLNi$$CZ‰% ~1:D@$ PvBR] `PK>pBNH(!2j$C`21ذyxbᏀ9fjGxҜ),hybK ]?t>A!us~2 J$ ^W7BAIJ߲On0\zCA~!ڴl9s̜eǀ ފ K@V=o'ou–q 7Բ5{:'=_E]cdQUR APx8}9NbIŘFh Uvs $x!*z" PpHN a߾^@5pXHw^,NVP#RމǟEa9n(/"(ȨrS?g,նZHMM4B#4QzD$:PAPr0N*Qt[D0>y > M rX:`3^#N~=b38t">>wj$_:뉽Nj’_W?V$@BBR%$g Mi/h*_ 7LȲfD%,nKoS5")+ bexP@!\XxI7`л7bds"S͉l Wǰqλhۺ N/tW0!A:"~W1Nǀ3_N g0j۞=0> g;!ϴ:yY۫}LƝ8ؾ};Fvk, 9|ǎG@%:vXѺuAjO<9zoo>BrUC*'΄oO B>Prl08cG!ztGжG"q >!~ց8vԏ:W AlvEV:wmF}ģfF  a DY!%p@Axp`a*HBX^Q_eqsB~N)$qۋtFD7_tQQzFmG͎,^8԰: ԝ>A6 Oݏm-Yg n0ةoݿo/CLO%LKILI4G&hU 62.2ӛ|9xvԙa 62*,1LetDCFDFqqn}|ؾuF1<0DD2:<P3hd֭¯rrs%6rsZDvݿFF11.qqL%!Iq4[o;,\(,Ǟ]02,ThG062a43&,lߺ #f a)Qaጉbb˦͸aګ~ܹN&iמPx{txCL6'򹧟ffd 4,&T|@'?TUU.:m*BC_}oq9֯fGp^#6aׯ^yNc( BL&PQ냎#<.ɓ9uk U=1|/ocYXwz ???X@ c#HlVrd2Q~{1ge^kE%m֕boތn60lHKׯGPPk;Ɯ^jEHHMmm-""`ԨIG8yΆ`@` 'nCuu5t0M92 ob !q0_%r8s L&|}+nܾ! A If7֩Cґ#0d5GuǓKspaZԛ߅dv_{'N/|ylUi!F 諩P۪7@FQЦݵ6ݵYWz @@ĉ8u$EqB"  BRWH?;ǍgVqN#(V8!sC :$a0h@@VF:ݙGsʊBWT@(TL&|f뛀>ve?h( ¿̆:y$jl5^WʲaK ϝӧl6x C]VVDGG읷ٵK7'Nmm-GbæyE";@|g0U@*ȜV+WsǎkRQA_`dffC!BfNÏ>>j;p\:;<~¸3z4JKKy !PQQMb"'/_0 Ήcv:Æ CZ/fIp'M{v#5=Ci"5=Cye.4$]~套xO^*tERʪJ,X.\"P܂B1ꑿA8iiXeo|54NBccW˘g;vz6 6 {+ڠ>{AA!4^͜$Î|axm0*\iAr `b<Μ1+V@DD8dYVJ͆?<7mX!r}cٲe qURM.7\ZE}eO +2 t.,^ׯ5oC)@LlS\x1t:/cH(**ڼy;?Z֣l' ϟÅ )o6oR4oqMp铨\%ٖ^9ڬƎ}\$ym@yy{q \dFbx,4SlX] !$l*)@'O& ~ fyUUNM{݆M[aՈ)LiSƍ&TdԞ={nHY@TUVЁê0% ))i( (+ߴiS=Ǭ[m3Qk7lȺ޲e SPJPP<CGlwU@\ͽ1xGO?7nDhh\!*X++#ndLI9gCstw'T[Oo>u'*<_EEZn֬An]oXw˸VI&u ^ziVN!JHB '+j5^aUÁPeغeE;w.N͛7oURWscS6Vk*+*Q^^r(???U˯o@qI /~-th˪\猩K\P !JR0|)F6l4y3XM`7I 4i uf5$AbM-$I@VdD5űD@P*ܱ꣠/#FMt^6BBH­rNHNѩn88t0 S 6[5"8YAA!._5IiY쁙f޲i~GZ Eq8},F3H)Z+ٳgp#^ (6H$TYXQUUylou?F$ vZİ#.IhUMm ]؝[б#v3nw kE"..^{NL{TWWCMJ B^{ϼx{=vݎ 1qXhG{$IBJJ .+9().]^7dsa F;uBIEh֢MXZN_pjjj0 5OޭzQ4so߾uW蛖q}xṭس?,dfC```=-GeDFFb޼yⷷG!j{RWWW#,, zAVflޢnu%22ww&.]FnnꋨZ4iuM:ÉX,FC?E@|^7-~F\L,6*ةuvܼ;{O=$h^<?΋/sӽ+ |͛7 o#33;w n&  ={nլ.EQШQ#q^J PoAiiFJ 6 Em[9}֝E>10]TUQ.77įk5\ VVVra^ky%wl8$Y4IJivh W_QNܘ*.١GF͘EN?kx\*$a8x ^-1ܫ8th0.G/fMȄVxVFnTP @T믾իt\ 88\5ՠ sT)ǑIr %'+*ѺmmC<]uk FΜ>Eo.@rr h۾vq __ Eq@QBq ǂ n23<,;XZ@lL|lA*P(ZONgUǭ,!$"7?_y M5.Cx,$cVq&Lv}d 33epZ-]¡`v.~͒v ?/o33DjzpHMO2Ejz# JE~q8|B̙3WDD4%>@dT[NGqc T $uUn7LIIx;68pgϜ" :웄޽F򮫆%!᫯_DPp-uXQ[znb`21tЛM\& 99T-I@ ǏAPVD4ls7D`PP}Mb7cysЍtq.;]n. h4KPmr't N?;pϞ=6 qqqhޢ= i4hn+WĬ/T]m]cVDG@PH`q8tp˳_!7ˏ>L=Pe"\-(ER HHZ|_?;{VwKzf|xWd_dN\;`bg߶͟+IaCBuZ#2z_i۶nÇ!$$:0}(UUU0u&Rxn55V 1 #ܹتcaX`6Q[[RWL$I“O?f?ḡ`\DE3f#cF{˸ͅrmYmCQQs_Fè(;@4Z=Yf0MHOKڵ --M]β++ХG7,Y3k62UUU àA`4O?!55:N"SY]UACԾ.Y?^ʹu*i=G5D1UqB7><FKEQP^^PFİZ0L(,)ĪUG3O\kQP7ij Z111sF[C^^;ft:0`@?>bv;>c}Un/Ͽ9 H h't1 ωa6B=ѣX2Λ7^^^c梷@3gz1эvfL0'N@ee%`6;wRSSzQeDYh=v=H'rss1G0{ˈh)V~BFsɄr|;cOrjD^^!O^|aJ˝q޵z[5kf3v5j<5O]mYףw{<|b裏`ZksQ_ o$ :NS!!!׺5&$$IFVVd2!I TSSpBgT,c4i6m؀& <ζ4 EL@֩}h;cq7p)⎪j D=ߊu<%KpG 5=#6PU#//[6o dg$P<gcHYS&~޽ UU@*n H ?V^AjeHZ 8>ʨFFS{|ZX ,] t|$IFq9XEq Х{wkNJ<B*@H 4@vhsC:Ϙ5KL8EEP B a0xChQmuÝiH%Y$<‹(V> #ŕLMf$$ݷ+Zn 5UT  d@;JʋWA*fϝ+񧟉X o6j?BQZ^ ڻ:ux24 ݻ73mtq.2z8w2eȐceoQTT!C#$ZTph8~w(-۠ VI[(24ʊ DFV G ܹ;vD~~|-UThqÛjE TᒎB#nШ:֢>jƏ #WOq]ZF81B,+~oMKWsr輼81Z_Kպ ӋQkhaa 9 v"壼BHChh0Gߴ{e%4B|':bl^p%h$7hwt$Wsr,K`Fttc忒J,,,, GPP Dzd1'7eP&~ DHX*sXPX͚{^ܳG>)x_/mBjϞݻw?v ǏGvN6*+`@faa!hٲ%۴A|||ɺrӕ.P"wJ_- 0$8&cQAm[oeq:h h0ׇ۴Çؿ__i1k21<8/͘;w ?0!Aӫ3K?hϟ~rӶKi݊f|gaD0.Y%ʧN셋뮻Γ}Ŷmcv~cfxH01U߾4 ! ̭CDžoΧ!C}v_v@? ^:>(.Uh*|V@?Ξ9yu.>, &uZ-mZ~ӊm|,Z8jV|r$'blLc꽴iإs'=lݪ%~%tFB6hWQɓ'٭[WZ|}J4$6_#SOMa]E  F48lV[ge ]p_=Foϥ¥ui[Ʀ1Ѽc˗yu /`qA~إs'Ő2*26_ϘHnzed񙧦[e{a<2| ٮuk^0gzZޮ;xg۶ k/!Iz1YV\DwH BŋR\0>:x Ϟ=]G'& /TϰRp`2;3I}E-n:ȡC̺ɁA#qhJ9GW}964GsΪy| ۷iKVӞgAz}vZF6yI|*n=Iby&ѾoA8qVVo-\H g^Nvpk!k8'W|pPd]-٠1b4Eq2afzLM߮՟26*ǒ}i;ю7c$xoFEGy$ڊ{[6m!ut8yW]p+H>`tÆ^ Ev 2g<|ϜfxH0zŵjW^yAǒăe;dG-d m'ΞF ™s%IGؤqc4cRxIDAT'&qЮ^:~نf7O:Q;۶.Vw#w?[co#I=l7mx'&cB{H~Æ\["38?ITv0X0ѵ & ̆a0זּVQVZŎ-CCy.CiSk=nh/\ϧGק~֯[-$2}'9(we(d\$ݻ1K^ RA~N6GEF1F1/'̝C {11ѩiH>{{C:}n];SwߦT*/ǘƐ''߰/O`||~UQ [5 gO3q_++Al{rQ6n.>3_|۵auۖ͛ ȘF\ j5#1* z>0?Ϟ9uSf5#2ׇ~f}lKũO=I^)&9}>fY| Ȅ^=yP7zr'0(lӧNpl׊Q~55fKJ3,5پm<ؼɣ'Lŗ~Z|1d0;oO R{%3N? ,446p Ёn:?ڶF i{1Q׮矛J_BVݺkQ۸8>TZU ~;lӫ/{9w,D7fj*Muk٢I6fÈpj5۶iS'NTıcI.]? &>>-6,1t8A~t1?O~ݡ##o~w p9l@>#߱ʋҔ>HB%-?%*lz;>Fǣ!Qb3(.Txi*V'cCd!m(0*s5hw':5)/M^i]-/p}0P&O4 SV@GK0XYH9S4*y`j@ m_>d'!MnA#~;,SWj-Fbg@xMF|-Jd,p7[(h/]lc>acSV"+du1mmi J@"ЇSn$)*MeE$p.#c 6y]Hlhl3 J}mðk'??images/updraft_premv.png000064400000024011152214270100011365 0ustar00PNG  IHDRxgAMA a pHYs(JtEXtSoftwarepaint.net 4.0.3P'IDATx^}UafVw״]O$IFɊD $9! S3 s uέn[nZtS]F75迩yo(Ba9 *MNOVIPeјU"Yf4Y/`Oqp贛JIaիY6NB IfUj * YVUΪeGV4,YU SFǦ|0LY Qs6л!wk %RhD/j:://ˢ1e = ٵ.~Ǥx}::~N!'Փ\[R< Łh;X$mA:}_jMiW oml&t}>E";>rQQL3RNNYu]BX1/Ioo~ZgGGߤA WrBNtЛX賷NλWty|sKdL*xKR-~Ge" ) I?v!…-3t:JCE4FI{#Il1ɴvӟi o^UuRZm42Y\(Wѱn,{gS>ń~^\ōqH=X3hElC'\O#Z=^p  z&=&qO?# +Bgc}ӋW* GEՓ 8D ;:We{R_<dX9ޘ:ƦVcpL3ӜVy~͗3Wwij5u / ~<+XV{~}7W ~_|:KQí#s_Uݱ؄_˽F5VsK7yR3)yOE8)B_bqu\t j{ow"qXdžMXGɊ5vpK.۰?+* Y"`-\EZu؏_dsT5FYk#x&*.O?M URgF *KA\?Qi'T&z=ʲ|67. ~-Dr00$\C>? yO:y/+D3y*Zׄik]_Dg\  Dj(/TVO&B>\ F>Hq WC~(-oUa`cbI;~dG~MgRA? ϊRgV< +@s6mk?y戳.na-hh&FmY_:P (ŤdAḿ0 }mT`Tj:4LUg[P*VѫYUPWt69bG&zM2Yv㬚ЖIVȄ[߮~שlTRUѝ٬^V?g fU`YIRXVWo<lc؍J1椔UhC&Ns Zt8޾=9.Ge>^Y 3ȎѰTc!l(M&ʃ֋@)pEZ~U.X-,@Hd*N۷1StГIE4gu nSF0HׂpYY8&eDk*KMͤ28e#SNrh]m[T=*z5k bp5ύmd4y2XVsL,}}"a\Mx,|Nh+}Xe" X)&ImuXlr*le> ADJTC S/1V<@NbyW"04jDS&gQ : YPe fm`jj VϬ"W%gdP&ݿD3y-wE r0#h+[P6ξ+Y%Z}_ԧK ox'aNp a)s_ 5v,kDYJ1Ij#bPe{K?z`WTְIE[&Y)+>FC 㛳ZJZg=U7dYU X)&Imkږ `q7 ԄLBȢ1epVHiNm׊Һl E1o6((ؤBʚ`@HV8el5Gd$قڕ5H :7p= SRR샔,kDYJ1Ij#p83T]디 e@<%DRLn1 UG:%eA->HY/OɲF6[3CQ4&S(t GpO;}VvU *d*[Nw@T VUA޹;Yɽ`QUq0`o'ty*DJHB>7"G9{b?"0MEC ?~'~D^m o[(oj&|'$WAbi|\TeӶ{#xsH_-ӚV+Pݵ>~d{  xg#rbwIҡ U5d1;L1]G~%o8'+y#DΤlM"gIL/"Mn\ ζ4mR_@9) $NX~i9؜]@gEd@YlD0@4P^ ;ii*LVzeq(~0M4oWXD.JtulL:pzQ~"<3^pg|TIZ=D+}{rTS I= \!R`&?AnW*)mQ F[j@mv<גΓoۻ``FOgM ~4B;KD~?5y`/gBގ-ݽ;\v˷62^l6}nhW@<X5 k#Ouc-KVDŽ~N?;8knmȝRD*J\cvM+b*uSё-o ­`IGB[u(VL4b.]*8t:چ͟wTN9>;cۈAVGPtקhHQ4n_84xӏ3 lVPG#>/>A?zB0}sg(e6TK [a*[Eu*k}dĩ7vp{#ƮPѨQ *=' &2/]Ѐ#:g|Q#f2RDU)qGAGݓw=yi>OPog3):B!P$ud 4}0~solƤ3T[n<Dolr/sCR;޴qeÀ2GyO~y&U ^ϡ_B?" )pY_\W޼ u”%Lr*63#^Sr~^dЏ1gtaKɚLbYďvyQ+}5[tx=৳-!w|9ƅX=Rȶ6-J @xb'>N_ڦ5WRpGܛhCVB?Onð#,Mzjo&"ڵϐOw{\҆oq9P^~.{>nzg(oF ~j?FVtlq;'|-/ o\ǡ"U&vZ5dK 8ď?ɡ_x@tU]=黤kCd*tsV6W?v4ߪnWnt+jϯ~0ފ_8S%0V[qտ;W?rr | LV7.QF%TUy&=?/錟7D??HՏ ;7"u7gJ9y%tKYW?3c' ȷ [\dLLoݩ+}k)Ӈqs'MگU?~L* %q:CʄuɋRg<j(&3(XL[꫿VV`q~h}_S88/3rQ:[jʭBsqA0LB#:l]E,ו)O}RH3_=ol 7~؁o4şZ2t<) b\";[PAk9p`V *1suq_H4L2[/k 7zx~OM(yU"߼Gq.zg;>\bD?3M֗C&"߭39 6kuoosSqc9D?w p<1 xZVdǚ я:ڏY'޴]6z"?};t0&ɿlsqQԳIY>7 [28[G\Caǜy7q2k/?'L'VmQ$⇶R)@_BͲipڐb72FWɃЕ~^K+B]qýVy)ě>_8'j/g9w1W&E;wnо я%d?UTy{gwȉZ-9{DTtNyf؀6oEPkHn5d#~Giw#cU3):qCsԇ+i%zc$]g|@, o^I&b6ӏm!WV_RQ,eÔjƔ.$iO Rʽ_6c`j5fb;11c*E`c7хPg(%~~9qOD?ZOWO JE0*)sW볟Ž@2|U6_Rb̏o.(9t |8:8ݷ.~ُ+qJEEvP#z2(׉ԃ)<lϾwkJQ~%I^ЪTWYB4kNҚ~4 Jh=~lѷ֫D0[+|BSA>=+"cKbR?6s=IO6.Iy|8gox{#t3ä{?unS!FH G5u>M݁F$@/p =i-G!Lj'R!w~5Q;w';ժsWT؏?SH_~rԌ)Կ6smݽs^ږ x҉8mpFlkJ ey7/ wz?Ly'5,]Qbl]58jA@O%N@U $]@{Vo^yp)0 a s%7{m0~(u0k "&Q! /~4w 'q!rU=A;;78Rg}"@{ӞϸF=+K\#?zJ"CY"=EeM'GL |8;ympH⺁ጴ^'C>_pJ+j70t<@N0zҿ3h0\|R&dbY>,0eVd嬠FpvCi:pǽܣ5k3N:[vx{=&C;G._a}㳇7_p%}y」҅5a1;yO]ny`2Ctr[ׂLv|T &{dx? q0fIŃLkot 1M:&s{Z1A<䬻S\9+}*|o|m=ZMDs3;W-_nz7wPY݊Ͷ7VӉj|!kIǨ*Ey{M+ת!;]5**#`@$yb*rĘ(nkyK!*O Bdp1S.^@KgFlH 0"Dá)[7OZZ!"em"Ԣ4duq߱ [Ngc'v]rҥ3j9ĆܒMK-dя'cBC) xscn~7~3_C@*́sL ΢NҹF4a7! ZSzmq(MSD?=;>KRO[/oB߾]L@48GVᆕןk=q[Ha%Nw.`18In[Xc\L 5)%f!gӻ?Aĥ(ֿR߯ 8%ޒM'S/6iBKX-@$ ,>4x 9(xDt~KkOxecf<4A/_p2XZ"x BЃgA%b"! /FLxRtpE~~l, gbhG۱3"Ճ=C%8!31ºxDGG|ƱrU#ڱp*C0Mmr Ѐ Gw.#[9?;O6ܶsp,A/5rٖ=cAT ~xLJRZ4:sh3.*~ҏroT;9 hN|caGlep̜ܲta`ȔCWM:q%^:&cQUŪM_kJG2S_.V8^S?ҏ9c)I#,أcweCTseIy&>G1":߰?D`m ~"׈{\4*߅'ɛNa.{x LtUuЏu5tT0B?"8$@= Lz4?0Yk:UXMe8MཽЏ &=b"t#"~4GP~;[3eT=`6 I=cWM?-1[DŽ@}l'}#.HBHOZĔڹKnAE ֨ ܪBtôJGpts]jŵӯ u!.*0:luX6+sd-t#H5G)hfJ9S+Ƌ.|! *GN?Y%+nV+p?f> lԘyNnU5 ~h#Wx|'TjC-لXNU4es 琻й_zqSc8pTIWtfqƞK W.o&G?.M骍hi"7ŮY r,49h)S8gTad +#7cF騺z XNW,V?ZgSaA'aE|lz֌`)أc鵥~-RX]~dd{> <-bUz)\@t77hT`_;%]6P@@EW{V`K)<#=RUo} q-F~!u/q VV; TѻԊ]D ]F75迩EM.ojtS?}rw IENDB`images/updraft_freev.png000064400000012703152214270100011350 0ustar00PNG  IHDRxgAMA a pHYs(JtEXtSoftwarepaint.net 4.0.3PAIDATx^]{E޿$ .*+|\wuw]pȍ@ADQ9!rd3US$D=LUuwU_}U]:AaЯkAaЯkAaЯkl6O?iG̞59dz^藳鴥1t'-^S:/58û;dytП_!R^Rl n {YNMC7?}Ht;b@Yb5 ݌RΣ*;SM R*J" c=5)IݱEg跍?㺎{pY_9`h ?mZhvLQ>Cz!}0 zj4/iOELEQ&^YpQ$d* Akw-#X,y2P{ab!ۘ)7Aa*eYΤ;4)M|t=&muxׇ,lӟU7-/q*A?@KC6=_[4%hڡ?~jS臃a vn!T!mwiiP;Vyw">=yUZXZχ_/'ߪQ,B9&=.5,6YZχ'#E< `  hPJ҅S뚘Jz>C`T'UkD ?HfAAV:.)ei=ڡ?f'H KSkt0j"3<|+DgX&>sXZg0x6x)2TA.Gwm_Leiv臫wL~B>Q)fy9gq=rBnĆ,9xC* COυ2$F?|:o!y!>t謧v8]n*,h~qtYcv??E!)O T3"%"Xc" m~qHQu0ؾ-ʹ8 XA#1 tF< E<-B* Ar*ٻ! ޻̔v\a5 O!q{O`PplJC/sșTʏC[P X;#p2 =AwaЯkAaЯk$sQkap0m@t$zd]-]v7Nv~7:_ 6AtՆ<[WF}4 m tDOf׉xJ=.g31p#{a!Of BrL%t5~9,7sQ`9/w+=L+TCyWDzMU bvm5@xMՖlxώZFM7q035~Od'ylb۝J`We!pѣ_ZF =Z\ ;n6OD/0mvGTy$.}GFN5@oO9iiGۧ=$|GʹLQTWO`Lwpۄu^D͖ fcM '#֋(DCk؉֌˅܈{VJ0f.`&ul 0l6bhlPO7/lD '#>I ONS_M7VV!:~rN[CH!mb?`j:vhdg[8{?& Gz}S0RYZǍC~RD\p/7;KFYY~4ip]o ৽MڙJ:tw;S"iJJ:v C:  e߷%F鏝4iS / 8Yԍ3fE?iOL3q1j2A%5zSַO_4#t ke7q^EitT3d˨D}/hO5TZpkQ͍υv.v\I.E`޽$*BJr_x*ȣpotM;`. A]Bo#+.2: CPT/]/d9I%GgPF$LI~='a qyxeٽMZ*uXD!KÑIYPcLt DվQ]BXYnRbN,w%j$%P"JԒO>P=jqnTt& O{QngKG!el&)s#KЏEo=бcgO$c8ĹK˕ioHR*Z3F}L>mJO~T w mR7m_[V߂WAdZYv 7p/wDAA=F#*dmUxjG cǷp}]E? G~ɗ%)F>ms;U_e7P@+ K"F@i؂&̕(V\b'.~ܿTo yt 2m\s^n)y6prr*δ%1s߻bX>"#*u *~ jwڑ ?{>[0#ϲ];R>T9VyWN/:!ӶD~=RV%\C?; 6up1LUӏٚ8ӅXG߇hx@cs~m#5c݋yT@\Zp1BOOFI\ֻbX`S4 OP~@%jIr B{?"هp;R7ζlGYjou!R[0Clɫ'D2)5 )DM5p=~ԁ]ArJ!+b<%Xm0W@?zDlЕ أ? $po̢4ʢH[.`&桷OKq*=ˇh@inp% 碇dCn}qH~n/:Vp|8z#> p!!Ȯ]P>Ne:åNW \\S\W0" \RjAE?yl'?YèYb.qso6 ?n5Hh"nP%,Od [O`B Ea[承= A}SBuhBz^FMKfTװ74??IU|!lrF`9Z7skhP?~F~~]à_05 u ҟx1S 4p렂aЯkAaЯkAaЯkAM>}9*ɒ+8Ku ݋$by ؉m'G]7Z.UJ"z0Zz&뵰@d8yb9~s],HU#JCo'a>O {Cz9f*!ks!POA7AHw%PJ=*"%"wԐiԧu}W{ >KE|C[Nų>k9ꋋU i+ߞmwkQ'@Džb}:Yx?2掫KtPS-R9%h@EF!PZ O4#qΥ0,3AV2zr~䂕:n~_J:fXFݣ\dAIԍ3($vbkIiFulWᷧ?~vawPoww:܋ߌ?h TY_'. XA!A±j]I 8`2=8Y<`tc 8o(j*ߧc-#X{s.@ lSGǡRi+DEnjphh@$EV0enĹwp˼7Fr#93,咺v Id+6:m+|lG dE[]zxJ{v!ˠ|7țfR߲/NBBdQJ ?[GP~#N.2^eĝ5~8b H`7_[e{珶Ix$Q=KZ9޽ʌF9~BLM.+o Τ%Y[T9/+SbQӰ~Gj_rUH?E*M |4T\mwo ?6x?v v/Dl+P@@YSɾYU#X0g}6-Ōxʏ((eӗY@DRPSȮs^&-82D3桽1ISЎENGh Umώ[ZJ{\@s$H{z!GE9$qMBcBQQ;3MJ7]m)oodꅒV  GM ;.Zh1f9n~x0:!gtq"b"!@A %P<ܯ}@prۏg\Cz"y'?auo ]ĔxRWTd{x{9U0BsO?9) {a'#b@87Z~G# d`:miD'4탐.I0XtJb4Ge(*t 8gy.~/KY8'\ t^EFݕSH?wa#d!RVw-mЏZΦᓑJ$[˘jD*ۤV! r&<"nhB@,a,( SL? &ߍ9=fSh~ u4ِ#s!OoGf! osu|-ESm wmΡU[r.j:|Dd7Ckqm獟 vyNc2Hԍ8Y?.`1XGH!ݵM5aЯkAaЯkA< G MIENDB`images/aws_logo.png000064400000003652152214270100010331 0ustar00PNG  IHDR8>;PLTEfff333OOO%%% BBBXXX?& }}}`:0````@@@ppptVN.IIIW4 C(ևEEE[www)))~b\\\TTT,,,MÑzzznnn===܄j}K-ttt999(XPqDj?qnRuFc;p{fzJ8" QQQ^Wm*IDATXiw@_dB$B"-J[h]}p\Q>B,'8w&f3;f&Xs$ɋt &o־Os-,׏7<Ʋ_PugsoqYU~-o

k!Tʆ74 Ͷܔ0fsA'#™>XR\x{G(F)D}5v  |B_P`cyw™ qT*3oNSg H%uc(Ry 엃W(3p^Eל?A7qlSRr]V1@޴8"jV ED)@DkXU}tUmĺmQs@h,?s!_L]+ `~ͅ~Zp6D14)7m4ڟY=t/_z< x5H:}$2uIR#뺮~&ʮAԴS?dWQH}iCT{~^Շj=пs7)yr3/ v;K@Ћ!/oY@1E8nVU+/8I #͙ YĤ~A58o7]fvʿ =3~(M:9=ëUgkb>̖ Lx~1OŚ*(gRU.CzQ 𨽺^toM6La[T'ON-c1[]PdnƤhLZS.E9͇Ft|QaWgDdzIQ{SuI!;4`o)#\kR~^6 ZBt8(PH{|3MPlE}3љx~i]7[ t r]uP%>4~ƍAO!:3&E^Y[2!Kh<ys6Y zT.6W]83@>Mѥ&RM(M@f=AAU+8eJ8N1񪿡IENDB`images/pcloud-logo.png000064400000035326152214270100010746 0ustar00PNG  IHDR+SPLTE#'08\#ǣ+P?jyrDJюUc׻DHtRNSDU{ n#w֤)ci=77#JD2-Oَ·\pN-U`ƁgyW 8IDATx`@TUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU}{M8ђ%obCX\jR $KO5RC4@-\zc?_K>+>0]7°W@wQsrêf۶ mkaɪy#)~U25WP[3%QGRh~SD=׫SssQZdFϋ`o-?lX GS]*#;佊Fo!P^Q$ǯnA7sj'7-{ ir)(J G''g`)N>`AfZ#O v"UM6I(iRDz(hkz;FjV E v;?Z~EL/OvT\-}T9ʚ,XlF[ f9&%JmUFME[#ۢ8yqkǃ?6HEwogjڻ>>>/ZbȘV?9:]]vS|;7Gݵ€\Ъls nu4Sj'_ӣ9|@F$n|rvj=qxMJ@FZHۧ%U~K f dB+j?>zo_Rz\EA^}OgQ Ozib@f1<)\.`ujt`DXX{Vǽil:YQRW~oI/4}] 6G ?>^Z&g '8ZA 6Fi-)0}qg^/tu<'S,nh HԲcO@y$2Oo*͞N.Ч/%r#@7]|}dPUwrw{Os:L t_g.-=/y^EI@,Z0';6^8K]*%]BGMgo.Z~I$˷>]Hv$kYMZɵf 6` a=-='>< cE_rwx%3xy2-^J#/Y> eSx4Q=k&u%͞_9 > :ng 0.:+;F}@|WۖӔ?sΓ/'ߡ $:wmYs J2)bcf/z>]PD }u6 >tpuW=rH pwmZB|.u"My@;"o=5/e(! 'Z~?̐kW."WΌ`']i#vt= [(a"Buyo/ PN', LyZ6'j,p,.M(znd?Һ<@Nw`<ѱm_o:H9=J*7eK`ғMj[F5@ @AT|% ~yJZг &urs#E!EC1 @Fԉj,QUW!Ɠѹ%tvgOܬc?G9zT@l=) C p 0M9%LS?VoBi$j<ѻ`-t'2gV Tp 'o0 y98@ݜ;\d Y4w\M1y'x *r B뚴jU*ղ~fW"@ pt |\ t_]3k(t PqY?wXUTSۀfI-%ǀ"[b#D 0<"zwKaR~Fg)'fg: @M]gM@rdpbQ;Ee"Jb/Z|Mw]g,s0;H!)cO_B#4fE'e>Xy~C0u:=A?N9D/ '}.$p u, U=ZJ e)$g1_87w@͸\3e,mlNps-ϽgVV[@$ .gxZ5IMVӺ )b{hjD9f?穴@ׯ3iGz:&枂` sl??B %fǗ7h",:j8E̥qPA'QQ(  סj w[ټQqЁW2A=nMم,˦f "!!^^CUjtaA: :-ЌC27&z 99Q(`p,!J'M$ Җ&VRiܹ͊Q-*[Ȓs=p|@?;cC3k)PDpx&'|x_Xt DA;;R骈ɷ,-͂iO4"Qh[խX(w`2{H6>K#Xd2@x(v; Zy1U6? FEH?z V|EݪBH^&p5֟GCrN3 7S8w'UcU 9hO/.Th5')rߏ<ݲYm@ov~ ;DWy =R,VV/biЉ$>$/=!44@eby@gEp{[8l$(Nftۗ)9eA:4O/J`Hu% $!u>>>=J:5I"!iPBڎG(iCLn ys=0Sҋ -xޣ/B3.zx|L6*`211W\ƪ/.{lC(B#sV ySt)@:^ 꿁uZ@Gm.WX :vV*s9u/k0Wo?.CT(ՔZInRWFc3hw mq3*aCD<*qyfTSbK/'g%zy;{0@ յR-' ɒV7ʝs-5EmՆj@R9) 2=~4b k+\}{ B.Y!Gm+ln|>b{m^SKiFcj*Ss 0:r0yZz|rmpihn:̡{ͪ\"Q' Ux"1Y[04Tx/+@p\@d4fMd"!b$H Y ԛc3j=BWz W'zc}]@,jDž534@nWDS"G6%.ysg1#:۟OŒu;k<6ykL~^ȅOy7U0ny q`lx\q`n@jDeA$|˓5(@屙dXS,+Du YbY#w@xp[~ۼ?CȊ/#$G|Gr; 햗9 @g%he ק4yn*m`y Qaa~$`' շƑJ Gjs^`mDwVvW-Bt)hRgQF̉YЛ>d#9O @@.V+A0`VwVgp:4촇28{w F .M-Q~(ҋ6H2Sx ;)dI'Dz@g`vpӀ\rTEfsn:D("I#VNdmdjlȸA#@%k0ᄃC6hQ#33GJGu0G4 k Fʈ NExrI3ܜkEφ;-u޾ F'" Spy@ $%~7i'.42H s^Yi^cp7sK_V1s{=#X դ_k1~B2I*De#^ɂ TM,G |G?DOm6[>>O+YSR7Ǒ2x *qB@&`zp7=;}=w6X&{>p `<Γ_ʁc.F[J=y{4S0r,#ҭa]]^Jy;`)m2@j㶅@~+~<8>a?pvXr8g/44?-/"g l W3{utGgVOA#{.(gƘ`$[dQh  Jbg$0+FR+ApA;^ ?Ϳ: OaI㫋󏠧Rs$jbZj!G9qC A05@a\w\Яi;e }>\v@6-]vҁ>V.b6b F -bkojy iy UE, g,yW@EJٻ7}2 5.j5ĉA).0$T C?`ƾu8P*[X(1@ȍi@ƏS'׻iD#7${0IV@6'i[*oo㳫#qլ3KG%mՌjvxBј,e Gγp5 7l857}?/O>p#P"I5,J IwkR ٭_nB%@ΰ`n;Fyu*OPv`7 =n=q<0GVGud%XN@dJ=O+OS;/v7YnҞR?TtmlNmErYNՇ`7er^(x& @xN jW&8i-y/S}rɚ | #ƾ0}.*JCly&M B,z~Sg½1v :Hb!N J9[@I|*@p icn5@BBvR.NgƁjt4]!x0pT'@ZQN@Iz/Dst)'Z0M>‘HIk[L %%#'_i!7v;89 g \@`v0[@=Q~W3@䷈SC*o9 *͒R^[!r$h^1d%4R{]pi(˶n@s'қ 7E`a K~qN6 F9&ՋUL@.C }"\ C@MG!"e s:+Y&&a{d:yHN{Fͱ@kw֐+`$54+he2==O~^ =FI$.# 00 ph28I?uV0s^Qu~@\RpeԴMXʄUr3F+&_\HSAm!1j61cYCm(?x h pö![;, PZ0$+ ɒ≨bpL(v LvO7{4dbلW(pójkEVmժOko IvO?dR7wcFYrHptTWb7y "hcHM`ۭIk6 t@?@0 3q"?+_$ K`Sp3YD^Q`c`22BD`!P* em=oIY2#&Vp jtnua;%Ab@rmˤ/ h]%gpHCO@㤒.Dta\p(H$9QT(B..Z0\yWǃoК^y=.ݱH{7)@$wbܴ`Y1֐bD+ig~*r*zdؖ' C>tÃ"Fg7;[䙭9Gg3H [Mh8CFjɑ`ٰLqJ>H;,4XRU2!VJw <-H"$1q \~{AbtOꏬ>@kp;#H?_"UYPH,!؜+j`S&]%< :[\H<R"ul!E\D^tϠGw|܁M;?n/hr'T*%Qx1T%ɕB{"z%Hﺎ!S%تJFNcKerkEp1 Kٍ 7-Y޻aݗ&?=kA~1!÷=/_;.wi jM(ʍ,k'/+^ؤ \竆U 4=/wpju3Ԁ/: KDv'eBω0hf+|ZKo[/xmK4rcІ܄e8|a TY*@]e&bn]\,z} 77=kQɻ-6Wܤ)*vDy;lRr\ vV\՟* 8/o8\ !=Kz%Z/>_ϗ*pȵrl٦A#=+H (?A7?9T#As'TG`e= Gf ˱Ul).2kjsF/OTٞ6d໮  Z)֛acҲ/.C1vNb(^\<x5*Y |w 4လ3`c98$I l#@j hـ'#U%xp]`_qN#]> `y̸):b @:CCTvgZ'_+ |CX{tŠL͌ ?'ںtZ-Tl0`bz*gXeWW h @[z<ȺV^<3!>9Ou?zeW9] BY-,ps˱ 6oKjZVeΤ  kE U0"$Ɩ/ S8|K[zgۋ@*5ǿ@*jJq 6ݷ7iuU_O8)M_εcf%%Jɦ f(]J KTѡ7r9){C]K $_i2iy,OvˠNwsvΫ#j+CO@p_`jz<".+q<*r#0Ε8P=@%Ln $|ag%yK4s)b4?>iɇ1yvg7mlWv"&X&,Q-7 f<eDn)%'\M rUw;Y7+j,ejXy)˙W p$2و$d)}ϗmGw͠NoxܞY<;RtΎC( <3hJd-T] Ѓ䑒o&jF4 ī%ej-"gcZ!j\V볣ONW0L1㛛N/J^sMɀ]IreS꧗l+P\JDUy緍) Q~@Kr§stNŒ 6Gtg^k,pR{ ( #](N$y<124|#bok蜔?[ͬtF>d ɴ@n O&1?4SonqnݚȻՂ]WܽO_ NaF?M;|4 ph2< t{S=?a~rK/۝7p$}p3w7w^K.W*;" x|Jn88]ǑkpE mh܀xtTo2/_7i(UQq>b:;QkflB4q57MS*`Е[j9[%\b: $&u"ruڰmKⲟl?ED x aZTD)Wo5߮Bn>3cb) 0 "rkAPiZ=@Hr_tCxM:cZRcTY(_ᠴH@Q3_֟$ڦEMl̏ 0,F:$Q%<,mJgTMJ@jq%{accountId = $accountId; $this->applicationKey = $applicationKey; $this->singleBucketKeyId = $singleBucketKeyId; if (isset($options['ssl_verify'])) $this->sslVerify = $options['ssl_verify']; if (isset($options['ssl_ca_certs'])) $this->useCACerts = $options['ssl_ca_certs']; $this->authorizeAccount(); } protected function request($method = 'GET', $uri = '', array $options = array(), $as_json = true) { $session = curl_init($uri); $headers = array(); if (isset($options['auth'])) { $account_id = empty($this->singleBucketKeyId) ? $this->accountId : $this->singleBucketKeyId; $headers[] = 'Authorization: Basic ' . base64_encode($account_id . ':' . $this->applicationKey); } if (isset($options['headers'])) { foreach ($options['headers'] as $key => $header) { $headers[] = $key . ': ' . $header; } } if ($this->sslVerify) { curl_setopt($session, CURLOPT_SSL_VERIFYPEER, true); curl_setopt($session, CURLOPT_SSL_VERIFYHOST, 2); } else { curl_setopt($session, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($session, CURLOPT_SSL_VERIFYHOST, 0); } if ($this->useCACerts) { curl_setopt($session, CURLOPT_CAINFO, $this->useCACerts); } if ('GET' == $method) { curl_setopt($session, CURLOPT_HTTPGET, true); } else { $data = array(); if (isset($options['json'])) { $headers[] = "Accept: application/json"; $data = json_encode($options['json']); } if (isset($options['body'])) { $data = $options['body']; } curl_setopt($session, CURLOPT_POSTFIELDS, $data); curl_setopt($session, CURLOPT_POST, true); } curl_setopt($session, CURLOPT_HTTPHEADER, $headers); curl_setopt($session, CURLOPT_RETURNTRANSFER, true); if (isset($options['sink'])) { $sink = fopen($options['sink'], 'w+'); curl_setopt($session, CURLOPT_FILE, $sink); curl_setopt($session, CURLOPT_FOLLOWLOCATION, true); } if (isset($options['session'])) { return $session; } $response = curl_exec($session); if (0 != ($curl_error = curl_errno($session))) { throw new Exception("Curl error ($curl_error): ".curl_error($session), $curl_error); } $decode_response = json_decode($response, true); if (isset($decode_response['status']) && 200 !== $decode_response['status']) { throw new Exception($decode_response['message'], $decode_response['status']); } curl_close($session); if (!empty($sink)) @fclose($sink); if ($as_json) return $decode_response; return $response; } public function uploadLargeStart($options) { // Request body parameters if ('/' === substr($options['FileName'], 0, 1)) { $options['FileName'] = ltrim($options['FileName'], '/'); } if (!isset($options['BucketId']) && isset($options['BucketName'])) { $options['BucketId'] = $this->getBucketIdFromName($options['BucketName']); } if (!isset($options['FileContentType'])) { $options['FileContentType'] = 'b2/x-auto'; } // Request start large file upload $response = $this->request('POST', $this->apiUrl . '/b2_start_large_file', array( 'headers' => array( 'Authorization' => $this->authToken, ), 'json' => array( 'bucketId' => $options['BucketId'], 'fileName' => $options['FileName'], 'contentType' => $options['FileContentType'], ), )); /* * fileId * fileName * accountId * bucketId * contentType * fileInfo * uploadTimestamp */ return $response; } public function uploadLargeUrl($options) { if (!isset($options['FileId'])) { throw new Exception('FileId required'); } $response = $this->request('POST', $this->apiUrl . '/b2_get_upload_part_url', array( 'headers' => array( 'Authorization' => $this->authToken, ), 'json' => array( 'fileId' => $options['FileId'], ), )); /* * authorizationToken * fileId * uploadUrl */ return $response; } public function uploadLargePart($options) { if (!isset($options['AuthorizationToken'])) { throw new Exception('AuthorizationToken required'); } if (!isset($options['FilePartNo'])) { throw new Exception('FilePartNo required'); } if (!isset($options['UploadUrl'])) { throw new Exception('UploadUrl required'); } if (!isset($options['Body'])) { throw new Exception('Body required'); } if (is_resource($options['Body'])) { // We need to calculate the file's hash incrementally from the stream. $context = hash_init('sha1'); hash_update_stream($context, $options['Body']); $hash = hash_final($context); // Similarly, we have to use fstat to get the size of the stream. $fstat = fstat($options['Body']); $size = $fstat['size']; // Rewind the stream before passing it to the HTTP client. rewind($options['Body']); } else { // We've been given a simple string body, it's super simple to calculate the hash and size. $hash = sha1($options['Body']); $size = mb_strlen($options['Body'], '8bit'); } $response = $this->request('POST', $options['UploadUrl'], array( 'headers' => array( 'Authorization' => $options['AuthorizationToken'], 'X-Bz-Part-Number' => $options['FilePartNo'], 'Content-Length' => $size, 'X-Bz-Content-Sha1' => $hash, ), 'body' => $options['Body'], )); /* * fileId * partNumber * contentLength * contentSha1 */ return $response; } public function uploadLargeFinish($options) { if (!isset($options['FileId'])) { throw new Exception('FileId required'); } if (!isset($options['FilePartSha1Array'])) { throw new Exception('FilePartSha1Array required'); } if (!is_array($options['FilePartSha1Array'])) { throw new Exception("FilePartSha1Array must be an array"); } $response = $this->request('POST', $this->apiUrl . '/b2_finish_large_file', array( 'headers' => array( 'Authorization' => $this->authToken, ), 'json' => array( 'fileId' => (string) $options['FileId'], 'partSha1Array' => $options['FilePartSha1Array'], ), )); if (empty($response['contentLength'])) { throw new Exception('B2: uploadLargeFinish error: contentLength returned was empty ('.serialize($response).')'); } return new UpdraftPlus_Backblaze_File( $response['fileId'], $response['fileName'], $response['contentSha1'], $response['contentLength'], $response['contentType'], $response['fileInfo'] ); } protected function authorizeAccount() { $response = $this->request("GET", 'https://api.backblazeb2.com/b2api/v1/b2_authorize_account', array( 'auth' => array($this->accountId, $this->applicationKey), )); $this->authToken = $response['authorizationToken']; $this->apiUrl = $response['apiUrl'] . '/b2api/v1'; $this->downloadUrl = $response['downloadUrl']; } public function listBuckets() { $buckets = array(); $response = $this->request('POST', $this->apiUrl . '/b2_list_buckets', array( 'headers' => array( 'Authorization' => $this->authToken, ), 'json' => array( 'accountId' => $this->accountId, ), )); if (!isset($response['buckets'])) throw new Exception('Failed to list buckets: '.serialize($response)); foreach ($response['buckets'] as $bucket) { $buckets[] = new UpdraftPlus_Backblaze_Bucket($bucket['bucketId'], $bucket['bucketName'], $bucket['bucketType']); } return $buckets; } protected function getBucketIdFromName($name) { $buckets = $this->listBuckets(); foreach ($buckets as $bucket) { if ($bucket->getName() === $name) { return $bucket->getId(); } } return null; } protected function getBucketNameFromId($id) { $buckets = $this->listBuckets(); foreach ($buckets as $bucket) { if ($bucket->getId() === $id) { return $bucket->getName(); } } return null; } protected function getFileIdFromBucketAndFileName($bucketName, $fileName) { $files = $this->listFiles(array( 'BucketName' => $bucketName, 'FileName' => $fileName, )); foreach ($files as $file) { if ($file->getName() === $fileName) { return $file->getId(); } } return null; } public function listFiles($options) { // if FileName is set, we only attempt to retrieve information about that single file. $fileName = !empty($options['FileName']) ? $options['FileName'] : null; $nextFileName = null; $maxFileCount = 1000; $files = array(); if (!isset($options['BucketId']) && isset($options['BucketName'])) { $options['BucketId'] = $this->getBucketIdFromName($options['BucketName']); } if ($fileName) { $nextFileName = $fileName; $maxFileCount = 1; } $json = array( 'bucketId' => $options['BucketId'], 'startFileName' => $nextFileName, 'maxFileCount' => $maxFileCount, ); if (!empty($options['Prefix'])) $json['prefix'] = $options['Prefix']; // B2 returns, at most, 1000 files per "page". Loop through the pages and compile an array of File objects. while (true) { $response = $this->request('POST', $this->apiUrl . '/b2_list_file_names', array( 'headers' => array( 'Authorization' => $this->authToken, ), 'json' => $json )); if (!isset($response['files'])) throw new Exception('Failed to list files. '.serialize($files)); foreach ($response['files'] as $file) { // if we have a file name set, only retrieve information if the file name matches if (!$fileName || ($fileName === $file['fileName'])) { $files[] = new UpdraftPlus_Backblaze_File($file['fileId'], $file['fileName'], null, $file['size']); } } if ($fileName || $response['nextFileName'] === null) { // We've got all the files - break out of loop. break; } $json['startFileName'] = $response['nextFileName']; } return $files; } public function upload($options) { // Clean the path if it starts with /. if (substr($options['FileName'], 0, 1) === '/') { $options['FileName'] = ltrim($options['FileName'], '/'); } if (!isset($options['BucketId']) && isset($options['BucketName'])) { $options['BucketId'] = $this->getBucketIdFromName($options['BucketName']); } // Retrieve the URL that we should be uploading to. $response = $this->request('POST', $this->apiUrl . '/b2_get_upload_url', array( 'headers' => array( 'Authorization' => $this->authToken, ), 'json' => array( 'bucketId' => $options['BucketId'], ), )); $uploadEndpoint = $response['uploadUrl']; $uploadAuthToken = $response['authorizationToken']; if (is_resource($options['Body'])) { // We need to calculate the file's hash incrementally from the stream. $context = hash_init('sha1'); hash_update_stream($context, $options['Body']); $hash = hash_final($context); // Similarly, we have to use fstat to get the size of the stream. $fstat = fstat($options['Body']); $size = $fstat['size']; // Rewind the stream before passing it to the HTTP client. rewind($options['Body']); } else { // We've been given a simple string body, it's super simple to calculate the hash and size. $hash = sha1($options['Body']); $size = mb_strlen($options['Body'], '8bit'); } if (!isset($options['FileLastModified'])) { $options['FileLastModified'] = round(microtime(true) * 1000); } if (!isset($options['FileContentType'])) { $options['FileContentType'] = 'b2/x-auto'; } $response = $this->request('POST', $uploadEndpoint, array( 'headers' => array( 'Authorization' => $uploadAuthToken, 'Content-Type' => $options['FileContentType'], 'Content-Length' => $size, 'X-Bz-File-Name' => $options['FileName'], 'X-Bz-Content-Sha1' => $hash, 'X-Bz-Info-src_last_modified_millis' => $options['FileLastModified'], ), 'body' => $options['Body'], )); return new UpdraftPlus_Backblaze_File( $response['fileId'], $response['fileName'], $response['contentSha1'], $response['contentLength'], $response['contentType'], $response['fileInfo'] ); } public function download($options) { $requestUrl = null; $requestOptions = array( 'headers' => array( 'Authorization' => $this->authToken, ), 'sink' => isset($options['SaveAs']) ? $options['SaveAs'] : null, ); if (isset($options['FileId'])) { $requestOptions['query'] = array('fileId' => $options['FileId']); $requestUrl = $this->downloadUrl . '/b2api/v1/b2_download_file_by_id'; } else { if (!isset($options['BucketName']) && isset($options['BucketId'])) { $options['BucketName'] = $this->getBucketNameFromId($options['BucketId']); } $requestUrl = sprintf('%s/file/%s/%s', $this->downloadUrl, $options['BucketName'], $options['FileName']); } if (isset($options['headers'])) { $requestOptions['headers'] = array_merge($requestOptions['headers'], $options['headers']); } $response = $this->request('GET', $requestUrl, $requestOptions, false); return isset($options['SaveAs']) ? true : $response; } public function getFile($options) { if (!isset($options['FileId']) && isset($options['BucketName']) && isset($options['FileName'])) { $options['FileId'] = $this->getFileIdFromBucketAndFileName($options['BucketName'], $options['FileName']); if (!$options['FileId']) { throw new UpdraftPlus_Backblaze_NotFoundException(); } } $response = $this->request('POST', $this->apiUrl . '/b2_get_file_info', array( 'headers' => array( 'Authorization' => $this->authToken, ), 'json' => array( 'fileId' => $options['FileId'], ), )); return new UpdraftPlus_Backblaze_File( $response['fileId'], $response['fileName'], $response['contentSha1'], $response['contentLength'], $response['contentType'], $response['fileInfo'], $response['bucketId'], $response['action'], $response['uploadTimestamp'] ); } /** * Delete a file * * @param Array $options - possible keys are FileName, FileId, BucketName * * @return Boolean. Can also throw an exception; including UpdraftPlus_Backblaze_NotFoundException if the file was not found. */ public function deleteFile($options) { if (!isset($options['FileName'])) { $file = $this->getFile($options); $options['FileName'] = $file->getName(); } if (!isset($options['FileId']) && isset($options['BucketName']) && isset($options['FileName'])) { $file = $this->getFile($options); $options['FileId'] = $file->getId(); } $delete_result = $this->request('POST', $this->apiUrl . '/b2_delete_file_version', array( 'headers' => array( 'Authorization' => $this->authToken, ), 'json' => array( 'fileName' => $options['FileName'], 'fileId' => $options['FileId'], ), )); return (is_array($delete_result) && !empty($delete_result['fileId'])) ? true : false; } /** * Delete multiple files * * @param Array $files_to_delete - array of possible files to delete; sub-keys are FileName, FileId, BucketName * @param String $bucket_name - the bucket that files are being deleted from * @param String|Null - path prefix (to prevent unnecessary scanning of other paths) * * @return Array|Boolean */ public function deleteMultipleFiles($files_to_delete, $bucket_name, $path_prefix = null) { if (count($files_to_delete) == 0) { return false; } $active = null; $sessions = []; $result = []; $bulk_session = curl_multi_init(); $list_options = array( 'BucketName' => $bucket_name ); if (is_string($path_prefix) && '' !== $path_prefix) $list_options['Prefix'] = $path_prefix; $files = $this->listFiles($list_options); $files_lookup = array(); foreach ($files as $file_object) { $file_name = $file_object->getName(); $file_id = $file_object->getId(); $files_lookup[$file_name] = $file_id; } foreach ($files_to_delete as $file_identification) { try { if (!isset($file_identification['FileName'])) { // We should not enter here as we always pass a file name but just in case $file = $this->getFile($file_identification); $file_identification['FileName'] = $file->getName(); $file_identification['FileId'] = $file->getId(); } elseif (!isset($file_identification['FileId'])) { if (isset($files_lookup[$file_identification['FileName']])) { $file_identification['FileId'] = $files_lookup[$file_identification['FileName']]; } else { // We should not enter here as all the files should be in the same bucket but just in case $file = $this->getFile($file_identification); $file_identification['FileId'] = $file->getId(); } } } catch (UpdraftPlus_Backblaze_NotFoundException $e) { array_push($sessions, true); continue; } $session = $this->request('POST', $this->apiUrl . '/b2_delete_file_version', array( 'headers' => array( 'Authorization' => $this->authToken, ), 'json' => array( 'fileName' => $file_identification['FileName'], 'fileId' => $file_identification['FileId'], ), 'session' => true )); array_push($sessions, $session); curl_multi_add_handle($bulk_session, $session); } do { $status = curl_multi_exec($bulk_session, $active); if ($active) { curl_multi_select($bulk_session); } } while ($active && $status == CURLM_OK); foreach ($sessions as $session) { if (is_bool($session)) { array_push($result, $session); continue; } $response = curl_multi_getcontent($session); array_push($result, $response); curl_multi_remove_handle($bulk_session, $session); } curl_multi_close($bulk_session); return (is_array($result) && !empty($result)) ? $result : false; } /** * Create a private bucket with the given name. * * @param String $bucket_name - valid bucket name * @throws Exception * * @return boolean - If bucket created successfully, it returns true otherwise false. */ public function createPrivateBucket($bucket_name) { try { $response = $this->request('POST', $this->apiUrl.'/b2_create_bucket', array( 'headers' => array( 'Authorization' => $this->authToken, ), 'json' => array( 'accountId' => $this->accountId, 'bucketName' => $bucket_name, 'bucketType' => 'allPrivate' ) ) ); } catch (Exception $e) { if (400 == $e->getCode()) { throw new Exception("Bucket can't be created because Bucket name is already in use.", $e->getCode()); } else { throw $e; } return false; } if (isset($response['bucketId']) && isset($response['bucketName']) && isset($response['bucketType'])) { return true; } return false; } } final class UpdraftPlus_Backblaze_Bucket { const TYPE_PUBLIC = 'allPublic'; const TYPE_PRIVATE = 'allPrivate'; protected $id; protected $name; protected $type; /** * Bucket constructor. * * @param $id * @param $name * @param $type */ public function __construct($id, $name, $type) { $this->id = $id; $this->name = $name; $this->type = $type; } public function getId() { return $this->id; } public function getName() { return $this->name; } public function getType() { return $this->type; } } final class UpdraftPlus_Backblaze_File { protected $id; protected $name; protected $hash; protected $size; protected $type; protected $info; protected $bucketId; protected $action; protected $uploadTimestamp; /** * File constructor. * * @param $id * @param $name * @param $hash * @param $size * @param $type * @param $info * @param $bucketId * @param $action * @param $uploadTimestamp */ public function __construct($id, $name, $hash = null, $size = null, $type = null, $info = null, $bucketId = null, $action = null, $uploadTimestamp = null) { $this->id = $id; $this->name = $name; $this->hash = $hash; $this->size = $size; $this->type = $type; $this->info = $info; $this->bucketId = $bucketId; $this->action = $action; $this->uploadTimestamp = $uploadTimestamp; } /** * @return string */ public function getId() { return $this->id; } /** * @return string */ public function getName() { return $this->name; } /** * @return string */ public function getHash() { return $this->hash; } /** * @return int */ public function getSize() { return $this->size; } /** * @return string */ public function getType() { return $this->type; } /** * @return array */ public function getInfo() { return $this->info; } /** * @return string */ public function getBucketId() { return $this->bucketId; } /** * @return string */ public function getAction() { return $this->action; } /** * @return string */ public function getUploadTimestamp() { return $this->uploadTimestamp; } } class UpdraftPlus_Backblaze_NotFoundException extends Exception { } includes/Dropbox2/OAuth/Consumer/ConsumerAbstract.php000064400000055071152214270100016656 0ustar00 * @link https://github.com/benthedesigner/dropbox * @package Dropbox\OAuth * @subpackage Consumer */ abstract class Dropbox_ConsumerAbstract { // Dropbox web endpoint. v2 API has just dropped the 1/ suffix to the below. const WEB_URL = 'https://www.dropbox.com/'; // OAuth flow methods const AUTHORISE_METHOD = 'oauth2/authorize'; // Beware - the documentation in one place says oauth2/token/revoke, but that appears to be wrong const DEAUTHORISE_METHOD = '2/auth/token/revoke'; const ACCESS_TOKEN_METHOD = 'oauth2/token'; // The next endpoint only exists with APIv1 const OAUTH_UPGRADE = 'oauth2/token_from_oauth1'; private $scopes = array( 'account_info.read', 'files.content.write', 'files.content.read', 'files.metadata.read', ); /** * Signature method, either PLAINTEXT or HMAC-SHA1 * @var string */ private $sigMethod = 'PLAINTEXT'; /** * Output file handle * @var null|resource */ protected $outFile = null; /** * Input file handle * @var null|resource */ protected $inFile = null; /** * Authenticate using 3-legged OAuth flow, firstly * checking we don't already have tokens to use * @return void */ protected function authenticate() { global $updraftplus; $access_token = $this->storage->get('access_token'); //Check if the new token type is set if not they need to be upgraded to OAuth2 if (!empty($access_token) && isset($access_token->oauth_token) && !isset($access_token->token_type)) { $updraftplus->log('OAuth v1 token found: upgrading to v2'); $this->upgradeOAuth(); $updraftplus->log('OAuth token upgrade successful'); } if (!empty($access_token) && isset($access_token->refresh_token) && isset($access_token->expires_in)) { if ($access_token->expires_in < time()) $this->refreshAccessToken(); } if (empty($access_token) || !isset($access_token->oauth_token)) { try { $this->getAccessToken(); } catch(Exception $e) { $excep_class = get_class($e); // 04-Sep-2015 - Dropbox started throwing a 400, which caused a Dropbox_BadRequestException which previously wasn't being caught if ('Dropbox_BadRequestException' == $excep_class || 'Dropbox_Exception' == $excep_class) { global $updraftplus; $updraftplus->log($e->getMessage().' - need to reauthenticate this site with Dropbox (if this fails, then you can also try wiping your settings from the Expert Settings section)'); //$this->getRequestToken(); $this->authorise(); } else { throw $e; } } } } /** * Upgrade the user's OAuth1 token to a OAuth2 token * @return void */ private function upgradeOAuth() { // N.B. This call only exists under API v1 - i.e. there is no APIv2 equivalent. Hence the APIv1 endpoint (API_URL) is used, and not the v2 (API_URL_V2) $url = 'https://api.dropbox.com/1/' . self::OAUTH_UPGRADE; $response = $this->fetch('POST', $url, ''); $token = new stdClass(); /* oauth token secret and oauth token were needed by oauth1 these are replaced in oauth2 with an access token currently they are still there just in case a method somewhere is expecting them to both be set as far as I can tell only the oauth token is used after more testing token secret can be removed. */ $token->oauth_token_secret = $response['body']->access_token; $token->oauth_token = $response['body']->access_token; $token->token_type = $response['body']->token_type; $this->storage->set($token, 'access_token'); $this->storage->set('true','upgraded'); $this->storage->do_unset('request_token'); } /** * Obtain user authorisation * The user will be redirected to Dropbox' web endpoint * @link http://tools.ietf.org/html/rfc5849#section-2.2 * @return void */ private function authorise() { // Only redirect if not using CLI if (PHP_SAPI !== 'cli' && (!defined('DOING_CRON') || !DOING_CRON) && (!defined('DOING_AJAX') || !DOING_AJAX)) { $url = $this->getAuthoriseUrl(); if (!headers_sent()) { header('Location: ' . $url); exit; } else { throw new Dropbox_Exception(sprintf(__('The %s authentication could not go ahead, because something else on your site is breaking it. Try disabling your other plugins and switching to a default theme. (Specifically, you are looking for the component that sends output (most likely PHP warnings/errors) before the page begins. Turning off any debugging settings may also help).', 'updraftplus'), 'Dropbox')); } ?>log('Dropbox reauthorisation needed; but we are running from cron, AJAX or the CLI, so this is not possible'); $this->storage->do_unset('access_token'); throw new Dropbox_Exception(sprintf(__('You need to re-authenticate with %s, as your existing credentials are not working.', 'updraftplus'), 'Dropbox')); #$updraftplus->log(sprintf(__('You need to re-authenticate with %s, as your existing credentials are not working.', 'updraftplus'), 'Dropbox'), 'error'); return false; } /** * Build the user authorisation URL * @return string */ public function getAuthoriseUrl() { /* Generate a random key to be passed to Dropbox and stored in session to be checked to prevent CSRF Uses OpenSSL or Mcrypt or defaults to pure PHP implementaion if neither are available. */ global $updraftplus; if (!function_exists('crypt_random_string')) $updraftplus->ensure_phpseclib('Crypt_Random'); $CSRF = base64_encode(crypt_random_string(16)); $this->storage->set($CSRF,'CSRF'); // Prepare request parameters /* For OAuth v2 Dropbox needs to use a authorisation url that matches one that is set inside the Dropbox developer console. In order to check this it needs the client ID for the OAuth v2 app This will use the default one unless the user is using their own Dropbox App For users that use their own Dropbox App there is also no need to provide the callbackhome as part of the CSRF as there is no need to go to auth.updraftplus.com also the redirect uri can then be set to the home as default Check if the key has dropbox: if so then remove it to stop the request from being invalid */ $appkey = $this->storage->get('appkey'); if (!empty($appkey) && 'dropbox:' == substr($appkey, 0, 8)) { $key = substr($appkey, 8); } else if (!empty($appkey)) { $key = $appkey; } if ('' != $this->instance_id) $this->instance_id = ':'.$this->instance_id; $params = array( 'client_id' => empty($key) ? $this->oauth2_id : $key, 'response_type' => 'code', 'redirect_uri' => empty($key) ? $this->callback : $this->callbackhome, 'state' => empty($key) ? "POST:".$CSRF.$this->instance_id.$this->callbackhome : $CSRF.$this->instance_id, 'scope' => implode(' ', $this->scopes), 'token_access_type' => 'offline' ); // Build the URL and redirect the user $query = '?' . http_build_query($params, '', '&'); $url = self::WEB_URL . self::AUTHORISE_METHOD . $query; return $url; } protected function deauthenticate() { $url = UpdraftPlus_Dropbox_API::API_URL_V2 . self::DEAUTHORISE_METHOD; $response = $this->fetch('POST', $url, '', array('api_v2' => true)); $this->storage->delete(); } /** * Acquire an access token * Tokens acquired at this point should be stored to * prevent having to request new tokens for each API call * @link http://tools.ietf.org/html/rfc5849#section-2.3 */ public function getAccessToken() { // If this is non-empty, then we just received a code. It is stored in 'code' - our next job is to put it into the proper place. $code = $this->storage->get('code'); /* Checks to see if the user is using their own Dropbox App if so then they need to get a request token. If they are using our App then we just need to save these details */ if (!empty($code)){ $appkey = $this->storage->get('appkey'); if (!empty($appkey)){ // Get the signed request URL $url = UpdraftPlus_Dropbox_API::API_URL_V2 . self::ACCESS_TOKEN_METHOD; $params = array( 'code' => $code, 'grant_type' => 'authorization_code', 'redirect_uri' => $this->callbackhome, 'client_id' => $this->consumerKey, 'client_secret' => $this->consumerSecret, ); $response = $this->fetch('POST', $url, '' , $params); $code = json_decode(json_encode($response['body']),true); } else { $code = base64_decode($code); $code = json_decode($code, true); } /* Again oauth token secret and oauth token were needed by oauth1 these are replaced in oauth2 with an access token currently they are still there just in case a method somewhere is expecting them to both be set as far as I can tell only the oauth token is used after more testing token secret can be removed. */ $token = new stdClass(); $token->oauth_token_secret = $code['access_token']; $token->oauth_token = $code['access_token']; $token->account_id = $code['account_id']; $token->token_type = $code['token_type']; $token->uid = $code['uid']; $token->refresh_token = $code['refresh_token']; $token->expires_in = time() + $code['expires_in'] - 30; $this->storage->set($token, 'access_token'); $this->storage->do_unset('upgraded'); //reset code $this->storage->do_unset('code'); } else { throw new Dropbox_BadRequestException("No Dropbox Code found, will try to get one now", 400); } } /** * This function will make a request to the auth server sending the users refresh token to get a new access token * * @return void */ public function refreshAccessToken() { global $updraftplus; $access_token = $this->storage->get('access_token'); if ($this->callback == $this->callbackhome) { $url = UpdraftPlus_Dropbox_API::API_URL_V2 . self::ACCESS_TOKEN_METHOD; $params = array( 'grant_type' => 'refresh_token', 'refresh_token' => $access_token->refresh_token, 'client_id' => $this->consumerKey, 'client_secret' => $this->consumerSecret, ); } else { $url = $this->callback; $params = array( 'code' => 'ud_dropbox_code', 'refresh_token' => $access_token->refresh_token, 'headers' => apply_filters('updraftplus_auth_headers', ''), ); } $response = $this->fetch('POST', $url, '' , $params); if ("200" != $response['code']) { $updraftplus->log('Failed to refresh access token error code: '.$response['code']); return; } if (empty($response['body'])) { $updraftplus->log('Failed to refresh access token empty response body'); return; } // If the request comes from the auth server (master app refreshing a token) then we need to decode the response into an object before we can use it. $body = is_object($response['body']) ? $response['body'] : json_decode(base64_decode($response['body'])); if (isset($body->access_token) && isset($body->expires_in)) { $access_token->oauth_token_secret = $body->access_token; $access_token->oauth_token = $body->access_token; $access_token->expires_in = time() + $body->expires_in - 30; $this->storage->set($access_token, 'access_token'); $updraftplus->log('Successfully updated and refreshed the access token'); } else { $updraftplus->log('Failed to refresh access token missing token and expiry: '.json_encode($body)); return; } } /** * Get the request/access token * This will return the access/request token depending on * which stage we are at in the OAuth flow, or a dummy object * if we have not yet started the authentication process * @return object stdClass */ private function getToken() { if (!$token = $this->storage->get('access_token')) { if (!$token = $this->storage->get('request_token')) { $token = new stdClass(); $token->oauth_token = null; $token->oauth_token_secret = null; } } return $token; } /** * Generate signed request URL * See inline comments for description * @link http://tools.ietf.org/html/rfc5849#section-3.4 * @param string $method HTTP request method * @param string $url API endpoint to send the request to * @param string $call API call to send * @param array $additional Additional parameters as an associative array * @return array */ protected function getSignedRequest($method, $url, $call, array $additional = array()) { // Get the request/access token $token = $this->getToken(); // Prepare the standard request parameters differently for OAuth1 and OAuth2; we still need OAuth1 to make the request to the upgrade token endpoint if (isset($token->token_type)) { $params = array( 'access_token' => $token->oauth_token, ); /* To keep this API backwards compatible with the API v1 endpoints all v2 endpoints will also send to this method a api_v2 parameter this will then return just the access token as the signed request is not needed for any calls. */ if (isset($additional['api_v2']) && $additional['api_v2'] == true) { unset($additional['api_v2']); if (isset($additional['timeout'])) unset($additional['timeout']); if (isset($additional['content_download']) && $additional['content_download'] == true) { unset($additional['content_download']); $extra_headers = array(); if (isset($additional['headers'])) { foreach ($additional['headers'] as $key => $header) { $extra_headers[] = $header; } unset($additional['headers']); } $headers = array( 'Authorization: Bearer '.$params['access_token'], 'Content-Type:', 'Dropbox-API-Arg: '.json_encode($additional), ); $headers = array_merge($headers, $extra_headers); $additional = ''; } else if (isset($additional['content_upload']) && $additional['content_upload'] == true) { unset($additional['content_upload']); $headers = array( 'Authorization: Bearer '.$params['access_token'], 'Content-Type: application/octet-stream', 'Dropbox-API-Arg: '.json_encode($additional), ); $additional = ''; } else { $headers = array( 'Authorization: Bearer '.$params['access_token'], 'Content-Type: application/json', ); } return array( 'url' => $url . $call, 'postfields' => $additional, 'headers' => $headers, ); } elseif (isset($additional['code']) && isset($additional['refresh_token'])) { $extra_headers = array(); if (isset($additional['headers']) && !empty($additional['headers'])) { foreach ($additional['headers'] as $key => $header) { $extra_headers[] = $key.': '.$header; } unset($additional['headers']); } $headers = array(); $headers = array_merge($headers, $extra_headers); return array( 'url' => $url . $call, 'postfields' => $additional, 'headers' => $headers, ); } // if grant_type is set and it's value is refresh_token, then this is a custom app trying to get a new access token using their refresh token. So we don't want to send an access token and break the request. if (isset($additional['grant_type']) && 'refresh_token' == $additional['grant_type']) unset($params['access_token']); } else { // Generate a random string for the request $nonce = md5(microtime(true) . uniqid('', true)); $params = array( 'oauth_consumer_key' => $this->consumerKey, 'oauth_token' => $token->oauth_token, 'oauth_signature_method' => $this->sigMethod, 'oauth_version' => '1.0', // Generate nonce and timestamp if signature method is HMAC-SHA1 'oauth_timestamp' => ($this->sigMethod == 'HMAC-SHA1') ? time() : null, 'oauth_nonce' => ($this->sigMethod == 'HMAC-SHA1') ? $nonce : null, ); } // Merge with the additional request parameters $params = array_merge($params, $additional); ksort($params); // URL encode each parameter to RFC3986 for use in the base string $encoded = array(); foreach($params as $param => $value) { if ($value !== null) { // If the value is a file upload (prefixed with @), replace it with // the destination filename, the file path will be sent in POSTFIELDS if (isset($value[0]) && $value[0] === '@') $value = $params['filename']; # Prevent spurious PHP warning by only doing non-arrays if (!is_array($value)) $encoded[] = $this->encode($param) . '=' . $this->encode($value); } else { unset($params[$param]); } } // Build the first part of the string $base = $method . '&' . $this->encode($url . $call) . '&'; // Re-encode the encoded parameter string and append to $base $base .= $this->encode(implode('&', $encoded)); // Concatenate the secrets with an ampersand $key = $this->consumerSecret . '&' . $token->oauth_token_secret; // Get the signature string based on signature method $signature = $this->getSignature($base, $key); $params['oauth_signature'] = $signature; // Build the signed request URL $query = '?' . http_build_query($params, '', '&'); return array( 'url' => $url . $call . $query, 'postfields' => $params, ); } /** * Generate the oauth_signature for a request * @param string $base Signature base string, used by HMAC-SHA1 * @param string $key Concatenated consumer and token secrets */ private function getSignature($base, $key) { switch ($this->sigMethod) { case 'PLAINTEXT': $signature = $key; break; case 'HMAC-SHA1': $signature = base64_encode(hash_hmac('sha1', $base, $key, true)); break; } return $signature; } /** * Set the OAuth signature method * @param string $method Either PLAINTEXT or HMAC-SHA1 * @return void */ public function setSignatureMethod($method) { $method = strtoupper($method); switch ($method) { case 'PLAINTEXT': case 'HMAC-SHA1': $this->sigMethod = $method; break; default: throw new Dropbox_Exception('Unsupported signature method ' . $method); } } /** * Set the output file * @param resource Resource to stream response data to * @return void */ public function setOutFile($handle) { if (!is_resource($handle) || get_resource_type($handle) != 'stream') { throw new Dropbox_Exception('Outfile must be a stream resource'); } $this->outFile = $handle; } /** * Set the input file * @param resource Resource to read data from * @return void */ public function setInFile($handle) { $this->inFile = $handle; } /** * Parse response parameters for a token into an object * Dropbox returns tokens in the response parameters, and * not a JSON encoded object as per other API requests * @link http://oauth.net/core/1.0/#response_parameters * @param string $response * @return object stdClass */ private function parseTokenString($response) { $parts = explode('&', $response); $token = new stdClass(); foreach ($parts as $part) { list($k, $v) = explode('=', $part, 2); $k = strtolower($k); $token->$k = $v; } return $token; } /** * Encode a value to RFC3986 * This is a convenience method to decode ~ symbols encoded * by rawurldecode. This will encode all characters except * the unreserved set, ALPHA, DIGIT, '-', '.', '_', '~' * @link http://tools.ietf.org/html/rfc5849#section-3.6 * @param mixed $value */ private function encode($value) { return str_replace('%7E', '~', rawurlencode($value)); } } includes/Dropbox2/OAuth/Consumer/WordPress.php000064400000005630152214270100015323 0ustar00 * @link https://github.com/DavidAnderson684/Dropbox * @package Dropbox\OAuth * @subpackage Consumer */ class Dropbox_ConsumerWordPress extends Dropbox_ConsumerAbstract { /** * Set properties and begin authentication * @param string $key * @param string $secret * @param \Dropbox\OAuth\Consumer\StorageInterface $storage * @param string $callback */ public function __construct($key, $secret, Dropbox_StorageInterface $storage, $callback = null) { // Check we are in a WordPress environment if (!defined('ABSPATH')) { throw new Dropbox_Exception('The WordPress OAuth consumer requires a WordPress environment'); } $this->consumerKey = $key; $this->consumerSecret = $secret; $this->storage = $storage; $this->callback = $callback; $this->authenticate(); } /** * Execute an API call * @param string $method The HTTP method * @param string $url The API endpoint * @param string $call The API method to call * @param array $additional Additional parameters * @return array */ public function fetch($method, $url, $call, array $additional = array()) { // Get the signed request URL $request = $this->getSignedRequest($method, $url, $call, $additional); if ($method == 'GET') { $args = array ( ); $response = wp_remote_get($request['url'], $args); $this->outFile = null; } elseif ($method == 'POST') { $args = array( 'body' => $request['postfields'] ); $response = wp_remote_post($request['url'], $args ); } elseif ($method == 'PUT' && $this->inFile) { return new WP_Error('unsupported', "WordPress does not have a native HTTP PUT function"); } // If the response body is not a JSON encoded string // we'll return the entire response body // Important to do this first, as the next section relies on the decoding having taken place if (!$body = json_decode(wp_remote_retrieve_body($response))) { $body = wp_remote_retrieve_body($response); } // Check if an error occurred and throw an Exception. This is part of the authentication process - don't modify. if (!empty($body->error)) { $message = $body->error . ' (Status Code: ' . wp_remote_retrieve_response_code($response) . ')'; throw new Dropbox_Exception($message); } if (is_wp_error($response)) { $message = $response->get_error_message(); throw new Dropbox_Exception($message); } $results = array ( 'body' => $body, 'code' => wp_remote_retrieve_response_code($response), 'headers' => $response['headers'] ); return $results; } } includes/Dropbox2/OAuth/Consumer/Curl.php000064400000034123152214270100014277 0ustar00 * @link https://github.com/benthedesigner/dropbox * @package Dropbox\OAuth * @subpackage Consumer */ class Dropbox_Curl extends Dropbox_ConsumerAbstract { /** * Dropbox consumer key * @var String */ protected $consumerKey; /** * Dropbox oauth2_id * @var String */ protected $oauth2_id; /** * Dropbox consumer secret * @var String */ protected $consumerSecret; /** * Dropbox storage object * @var \Dropbox\OAuth\Consumer\StorageInterface|Dropbox_StorageInterface */ protected $storage; /** * Not used anywhere but it is set * @var Callable|Null */ protected $callback; /** * Callback URL * @var String|null */ protected $callbackhome; /** * Dropbox storage instance id * @var String */ protected $instance_id; /** * Default cURL options * @var array */ protected $defaultOptions = array( CURLOPT_VERBOSE => true, CURLOPT_HEADER => true, CURLINFO_HEADER_OUT => false, CURLOPT_RETURNTRANSFER => true, CURLOPT_FOLLOWLOCATION => false, ); /** * Store the last response form the API * @var mixed */ protected $lastResponse = null; /** * Set properties and begin authentication * @param string $key * @param string $secret * @param \Dropbox\OAuth\Consumer\StorageInterface $storage * @param string $callback */ public function __construct($key, $oauth2_id, $secret, Dropbox_StorageInterface $storage, $callback = null, $callbackhome = null, $deauthenticate = false, $instance_id = '') { // Check the cURL extension is loaded if (!extension_loaded('curl')) { throw new Dropbox_Exception('The cURL OAuth consumer requires the cURL extension. Please speak to your web hosting provider so that this missing PHP component can be installed.'); } $this->consumerKey = $key; $this->oauth2_id = $oauth2_id; $this->consumerSecret = $secret; $this->storage = $storage; $this->callback = $callback; $this->callbackhome = $callbackhome; $this->instance_id = $instance_id; if ($deauthenticate) { $this->deauthenticate(); } else { $this->authenticate(); } } /** * Execute an API call * @todo Improve error handling * @param string $method The HTTP method * @param string $url The API endpoint * @param string $call The API method to call * @param array $additional Additional parameters * @return string|object stdClass */ public function fetch($method, $url, $call, array $additional = array(), $retry_with_header = false) { // Get the signed request URL $request = $this->getSignedRequest($method, $url, $call, $additional); // Initialise and execute a cURL request $handle = curl_init($request['url']); // Get the default options array $options = $this->defaultOptions; if (!UpdraftPlus_Options::get_updraft_option('updraft_ssl_useservercerts')) { $options[CURLOPT_CAINFO] = UPDRAFTPLUS_DIR.'/includes/cacert.pem'; } if (UpdraftPlus_Options::get_updraft_option('updraft_ssl_disableverify')) { $options[CURLOPT_SSL_VERIFYPEER] = false; } else { $options[CURLOPT_SSL_VERIFYPEER] = true; } if (!class_exists('WP_HTTP_Proxy')) require_once(ABSPATH.WPINC.'/class-http.php'); $proxy = new WP_HTTP_Proxy(); if ($proxy->is_enabled()) { # WP_HTTP_Proxy returns empty strings if nothing is set $user = $proxy->username(); $pass = $proxy->password(); $host = $proxy->host(); $port = (int)$proxy->port(); if (empty($port)) $port = 8080; if (!empty($host) && $proxy->send_through_proxy($request['url'])) { $options[CURLOPT_PROXY] = $host; $options[CURLOPT_PROXYTYPE] = CURLPROXY_HTTP; $options[CURLOPT_PROXYPORT] = $port; if (!empty($user) && !empty($pass)) { $options[CURLOPT_PROXYAUTH] = CURLAUTH_ANY; $options[CURLOPT_PROXYUSERPWD] = sprintf('%s:%s', $user, $pass); } } } /* Add check to see if it's an API v2 call if so then json encode the contents. This is so that it is backwards compatible with API v1 endpoints. */ if (isset($additional['api_v2']) && !empty($request['postfields'])) { $request['postfields'] = json_encode($request['postfields']); } if (isset($request['headers']) && !empty($request['headers'])) $options[CURLOPT_HTTPHEADER] = $request['headers']; if ($method == 'GET' && $this->outFile) { // GET $options[CURLOPT_RETURNTRANSFER] = false; $options[CURLOPT_HEADER] = false; $options[CURLOPT_FILE] = $this->outFile; $options[CURLOPT_BINARYTRANSFER] = true; $options[CURLOPT_FAILONERROR] = true; $this->outFile = null; } elseif ($method == 'POST' && $this->outFile) { // POST $options[CURLOPT_POST] = true; $options[CURLOPT_RETURNTRANSFER] = false; $options[CURLOPT_HEADER] = false; $options[CURLOPT_FILE] = $this->outFile; $options[CURLOPT_BINARYTRANSFER] = true; $options[CURLOPT_FAILONERROR] = true; $this->outFile = null; } elseif ($method == 'POST' && $this->inFile) { // POST $options[CURLOPT_POST] = true; $options[CURLOPT_POSTFIELDS] = $this->inFile; } elseif ($method == 'POST') { // POST $options[CURLOPT_POST] = true; if (!empty($request['postfields'])) { $options[CURLOPT_POSTFIELDS] = $request['postfields']; } elseif (empty($additional['content_upload'])) { // JSON representation of nullity $options[CURLOPT_POSTFIELDS] = 'null'; } elseif ($retry_with_header) { // It's a content upload, and there's no data. Versions of php-curl differ as to whether they add a Content-Length header automatically or not. Dropbox complains if it's not there. Here we have had a Dropbox 400 bad request returned so we try again with the header $options[CURLOPT_HTTPHEADER] = array_merge($options[CURLOPT_HTTPHEADER], array('Content-Length: 0')); } } elseif ($method == 'PUT' && $this->inFile) { // PUT $options[CURLOPT_PUT] = true; $options[CURLOPT_INFILE] = $this->inFile; // @todo Update so the data is not loaded into memory to get its size $options[CURLOPT_INFILESIZE] = strlen(stream_get_contents($this->inFile)); fseek($this->inFile, 0); $this->inFile = null; } if (isset($additional['timeout'])) { $options[CURLOPT_TIMEOUT] = $additional['timeout']; } if (function_exists('apply_filters')) $options = apply_filters('updraftplus_dropbox_fetch_curl_options', $options, $method, $url, $call, $additional); // Set the cURL options at once curl_setopt_array($handle, $options); // Execute, get any error and close $response = curl_exec($handle); $error = curl_error($handle); $getinfo = curl_getinfo($handle); curl_close($handle); //Check if a cURL error has occured if ($response === false) { throw new Dropbox_CurlException($error); } else { // Parse the response if it is a string if (is_string($response)) { $response = $this->parse($response); } // Set the last response $this->lastResponse = $response; $code = (!empty($response['code'])) ? $response['code'] : $getinfo['http_code']; // The API doesn't return an error message for the 304 status code... // 304's are only returned when the path supplied during metadata calls has not been modified if ($code == 304) { $response['body'] = new stdClass; $response['body']->error = 'The folder contents have not changed'; } // Check if an error occurred and throw an Exception if (!empty($response['body']->error) || $code >= 400) { // Dropbox returns error messages inconsistently... if (!empty($response['body']->error) && $response['body']->error instanceof stdClass) { $array = array_values((array) $response['body']->error); // Dropbox API v2 only throws 409 errors if this error is a incorrect_offset then we need the entire error array not just the message. PHP Exception messages have to be a string so JSON encode the array. $extract_message = (is_object($array[0]) && isset($array[0]->{'.tag'})) ? $array[0]->{'.tag'} : $array[0]; if (strpos($extract_message, 'incorrect_offset') !== false) { $message = json_encode($array); } elseif (strpos($extract_message, 'lookup_failed') !== false ) { // re-structure the array so it is correctly formatted for API // Note: Dropbox v2 returns different errors at different stages hence this fix $correctOffset = array( '0' => $array[1]->{'.tag'}, ); // the lookup_failed response doesn't always return a correct_offset this happens when the lookup fails because the session has been closed e.g the file has already been uploaded but the response didn't make it back to the client so we try again if (isset($array[1]->correct_offset)) $correctOffset['1'] = $array[1]->correct_offset; $message = json_encode($correctOffset); } else { $message = $extract_message; } } elseif (!empty($response['body']->error)) { $message = $response['body']->error; } elseif (is_string($response['body'])) { // 31 Mar 2017 - This case has been found to exist; though the docs imply that there's always an 'error' property and that what is returned in JSON, we found a case of this being returned just as a simple string, but detectable via an HTTP 400: Error in call to API function "files/upload_session/append_v2": HTTP header "Dropbox-API-Arg": cursor.offset: expected integer, got string $message = $response['body']; } else { $message = "HTTP bad response code: $code"; } // Throw an Exception with the appropriate with the appropriate message and code switch ($code) { case 304: throw new Dropbox_NotModifiedException($message, 304); case 400: if (!$retry_with_header) return $this->fetch($method, $url, $call, $additional, true); throw new Dropbox_BadRequestException($message, 400); case 404: throw new Dropbox_NotFoundException($message, 404); case 406: throw new Dropbox_NotAcceptableException($message, 406); case 415: throw new Dropbox_UnsupportedMediaTypeException($message, 415); case 401: //401 means oauth token is expired continue to manually handle the exception depending on the situation break; case 409: //409 in API V2 every error will return with a 409 to find out what the error is the error description should be checked. throw new Dropbox_Exception($message, $code); default: throw new Dropbox_Exception($message, $code); } } return $response; } } /** * Parse a cURL response * @param string $response * @return array */ private function parse($response) { // Explode the response into headers and body parts (separated by double EOL) list($headers, $response) = explode("\r\n\r\n", $response, 2); // Explode response headers $lines = explode("\r\n", $headers); // If the status code is 100, the API server must send a final response // We need to explode the response again to get the actual response if (preg_match('#^HTTP/[\.\d]+ 100#i', $lines[0])) { list($headers, $response) = explode("\r\n\r\n", $response, 2); $lines = explode("\r\n", $headers); } // Get the HTTP response code from the first line $first = array_shift($lines); $pattern = '#^HTTP/[\.\d]+ ([0-9]{3})#i'; preg_match($pattern, $first, $matches); $code = $matches[1]; // Parse the remaining headers into an associative array $headers = array(); foreach ($lines as $line) { list($k, $v) = explode(': ', $line, 2); $headers[strtolower($k)] = $v; } // If the response body is not a JSON encoded string // we'll return the entire response body if (!$body = json_decode($response)) { $body = $response; } if (is_string($body)) { $body_lines = explode("\r\n", $body); if (preg_match('#^HTTP/[\.\d]+ 100#i', $body_lines[0]) && preg_match('#^HTTP/\d#i', $body_lines[2])) { return $this->parse($body); } } return array('code' => $code, 'body' => $body, 'headers' => $headers); } /** * Return the response for the last API request * @return mixed */ public function getlastResponse() { return $this->lastResponse; } } includes/Dropbox2/OAuth/Storage/Encrypter.php000064400000011176152214270100015161 0ustar00 * @link https://github.com/benthedesigner/dropbox * @package Dropbox\Oauth * @subpackage Storage */ /* UpdraftPlus notes Using this was fairly pointless (it encrypts storage credentials at rest). But, it's implemented now, so needs supporting. Investigation shows that mcrypt and phpseclib native encryption using different padding schemes. As a result, that which is encrypted by phpseclib native can be decrypted by mcrypt, but not vice-versa. Each can (as you'd expect) decrypt the results of their own encryption. As a consequence, it makes sense to always encrypt with phpseclib native, and prefer decrypting with with mcrypt if it is available and otherwise fall back to phpseclib. We could deliberately re-encrypt all loaded information with phpseclib native, but there seems little need for that yet. There can only be a problem if mcrypt is disabled - which pre-July-2015 meant that Dropbox wouldn't work at all. Now, it will force a re-authorisation. */ class Dropbox_Encrypter { // Encryption settings - default settings yield encryption to AES (256-bit) standard // @todo Provide PHPDOC for each class constant const KEY_SIZE = 32; const IV_SIZE = 16; /** * Encryption key * @var null|string */ private $key = null; /** * Check Mcrypt is loaded and set the encryption key * @param string $key * @return void */ public function __construct($key) { if (preg_match('/^[A-Za-z0-9]+$/', $key) && $length = strlen($key) === self::KEY_SIZE) { # Short-cut so that the mbstring extension is not required $this->key = $key; } elseif (($length = mb_strlen($key, '8bit')) !== self::KEY_SIZE) { throw new Dropbox_Exception('Expecting a ' . self::KEY_SIZE . ' byte key, got ' . $length); } else { // Set the encryption key $this->key = $key; } } /** * Encrypt the OAuth token * @param \stdClass $token Serialized token object * @return string */ public function encrypt($token) { // Encryption: we always use phpseclib for this global $updraftplus; $ensure_phpseclib = $updraftplus->ensure_phpseclib('Crypt_AES'); if (is_wp_error($ensure_phpseclib)) { $updraftplus->log("Failed to load phpseclib classes (".$ensure_phpseclib->get_error_code()."): ".$ensure_phpseclib->get_error_message()); $updraftplus->log("Failed to load phpseclib classes (".$ensure_phpseclib->get_error_code()."): ".$ensure_phpseclib->get_error_message(), 'error'); return false; } $updraftplus->ensure_phpseclib('Crypt_Rijndael'); if (!function_exists('crypt_random_string')) updraft_try_include_file('vendor/phpseclib/phpseclib/phpseclib/Crypt/Random.php', 'require_once'); $iv = crypt_random_string(self::IV_SIZE); // Defaults to CBC mode $rijndael = new Crypt_Rijndael(); $rijndael->setKey($this->key); $rijndael->setIV($iv); $cipherText = $rijndael->encrypt($token); return base64_encode($iv . $cipherText); } /** * Decrypt the ciphertext * @param string $cipherText * @return object \stdClass Unserialized token */ public function decrypt($cipherText) { // Decryption: prefer mcrypt, if available (since it can decrypt data encrypted by either mcrypt or phpseclib) $cipherText = base64_decode($cipherText); $iv = substr($cipherText, 0, self::IV_SIZE); $cipherText = substr($cipherText, self::IV_SIZE); $decrypted = false; if (function_exists('mcrypt_decrypt')) { // @codingStandardsIgnoreLine $token = @mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $this->key, $cipherText, MCRYPT_MODE_CBC, $iv); // Some plugins provide their own version of mcrypt_* functions and they don't provide the functionality that the original method has, so try and detect if the decryption has failed and if so try rijndael if (false != $token) $decrypted = true; } if (!$decrypted) { global $updraftplus; $updraftplus->ensure_phpseclib('Crypt_Rijndael'); $rijndael = new Crypt_Rijndael(); $rijndael->setKey($this->key); $rijndael->setIV($iv); $token = $rijndael->decrypt($cipherText); } return $token; } } includes/Dropbox2/OAuth/Storage/StorageInterface.php000064400000001204152214270100016422 0ustar00 * @link https://github.com/benthedesigner/dropbox * @package Dropbox\OAuth * @subpackage Storage */ interface Dropbox_StorageInterface { /** * Get a token by type * @param string $type Token type to retrieve */ public function get($type); /** * Set a token by type * @param \stdClass $token Token object to set * @param string $type Token type */ public function set($token, $type); /** * Delete tokens for the current session/user */ public function delete(); } includes/Dropbox2/OAuth/Storage/WordPress.php000064400000013423152214270100015133 0ustar00 * @link https://updraftplus.com * @package Dropbox\Oauth * @subpackage Storage */ class Dropbox_WordPress implements Dropbox_StorageInterface { /** * Option name * @var string */ protected $option_name_prefix = 'dropbox_token'; /** * Option name (array storage) * @var string */ protected $option_array = ''; /** * Encyption object * @var Encrypter|null */ protected $encrypter = null; /** * Backup module object * @var Backup_module_object|null */ protected $backup_module_object = null; /** * Check if an instance of the encrypter is passed, set the encryption object * @return void */ public function __construct(Dropbox_Encrypter $encrypter = null, $option_name_prefix = 'dropbox_token', $option_array = 'dropbox', $backup_module_object = null) { if ($encrypter instanceof Dropbox_Encrypter) { $this->encrypter = $encrypter; } if ($backup_module_object instanceof UpdraftPlus_BackupModule) { $this->backup_module_object = $backup_module_object; } $this->option_name_prefix = $option_name_prefix; $this->option_array = $option_array; } /** * Get an entry from the Dropbox options in the database * If the encryption object is set then decrypt the token before returning * @param string $type is the key to retrieve * @return array|bool */ public function get($type) { if ($type != 'request_token' && $type != 'access_token' && $type != 'appkey' && $type != 'CSRF' && $type != 'code') { throw new Dropbox_Exception("Expected a type of either 'request_token', 'access_token', 'CSRF' or 'code', got '$type'"); } else { if (false !== ($opts = $this->backup_module_object->get_options())) { if ($type == 'request_token' || $type == 'access_token'){ if (!empty($opts[$this->option_name_prefix.$type])) { $gettoken = $opts[$this->option_name_prefix.$type]; $token = $this->decrypt($gettoken); return $token; } } else { if (!empty($opts[$type])) { return $opts[$type]; } } } return false; } } /** * Set a value in the database by type * If the value is a token and the encryption object is set then encrypt the token before storing * @param \stdClass Token object to set * @param string $type Token type * @return void */ public function set($token, $type) { if ($type != 'request_token' && $type != 'access_token' && $type != 'upgraded' && $type != 'CSRF' && $type != 'code') { throw new Dropbox_Exception("Expected a type of either 'request_token', 'access_token', 'CSRF', 'upgraded' or 'code', got '$type'"); } else { $opts = $this->backup_module_object->get_options(); if ($type == 'access_token'){ $token = $this->encrypt($token); $opts[$this->option_name_prefix.$type] = $token; } else if ($type == 'request_token' ) { $opts[$this->option_name_prefix.$type] = $token; } else { $opts[$type] = $token; } $this->backup_module_object->set_options($opts, true); } } /** * Remove a value in the database by type rather than setting to null / empty * set the value to null here so that when it gets to the options filter it will * unset the value there, this avoids a bug where if the value is not set then * the option filter will take the value from the database and save that version back. * * N.B. Before PHP 7.0, you can't call a method name unset() * * @param string $type Token type * @return void */ public function do_unset($type) { if ($type != 'request_token' && $type != 'access_token' && $type != 'upgraded' && $type != 'CSRF' && $type != 'code') { throw new Dropbox_Exception("Expected a type of either 'request_token', 'access_token', 'CSRF', 'upgraded' or 'code', got '$type'"); } else { $opts = $this->backup_module_object->get_options(); if ($type == 'access_token' || $type == 'request_token'){ $opts[$this->option_name_prefix.$type] = null; } else { $opts[$type] = null; } $this->backup_module_object->set_options($opts, true); } } /** * Delete the request and access tokens currently stored in the database * @return bool */ public function delete() { $opts = $this->backup_module_object->get_options(); $opts[$this->option_name_prefix.'request_token'] = null; $opts[$this->option_name_prefix.'access_token'] = null; unset($opts['ownername']); unset($opts['upgraded']); $this->backup_module_object->set_options($opts, true); return true; } /** * Use the Encrypter to encrypt a token and return it * If there is not encrypter object, return just the * serialized token object for storage * @param stdClass $token OAuth token to encrypt * @return stdClass|string */ protected function encrypt($token) { // Serialize the token object $token = serialize($token); // Encrypt the token if there is an Encrypter instance if ($this->encrypter instanceof Dropbox_Encrypter) { $token = $this->encrypter->encrypt($token); } // Return the token return $token; } /** * Decrypt a token using the Encrypter object and return it * If there is no Encrypter object, assume the token was stored * serialized and return the unserialized token object * @param stdClass $token OAuth token to encrypt * @return stdClass|string */ protected function decrypt($token) { // Decrypt the token if there is an Encrypter instance if ($this->encrypter instanceof Dropbox_Encrypter) { $token = $this->encrypter->decrypt($token); } // Return the unserialized token return @unserialize($token); } } includes/Dropbox2/API.php000064400000035701152214270100011173 0ustar00 * @link https://github.com/benthedesigner/dropbox * @link https://www.dropbox.com/developers * @link https://status.dropbox.com Dropbox status * @package Dropbox */ class UpdraftPlus_Dropbox_API { // API Endpoints const API_URL_V2 = 'https://api.dropboxapi.com/'; const CONTENT_URL_V2 = 'https://content.dropboxapi.com/2/'; /** * OAuth consumer object * @var null|OAuth\Consumer */ private $OAuth; /** * The root level for file paths * Either `dropbox` or `sandbox` (preferred) * @var null|string */ private $root; /** * JSONP callback * @var string */ private $callback = 'dropboxCallback'; /** * Chunk size used for chunked uploads * @see \Dropbox\API::chunkedUpload() */ private $chunkSize = 4194304; /** * Set the OAuth consumer object * See 'General Notes' at the link below for information on access type * @link https://www.dropbox.com/developers/reference/api * @param OAuth\Consumer\ConsumerAbstract $OAuth * @param string $root Dropbox app access type */ public function __construct(Dropbox_ConsumerAbstract $OAuth, $root = 'sandbox') { $this->OAuth = $OAuth; $this->setRoot($root); } /** * Set the root level * @param mixed $root * @throws Exception * @return void */ public function setRoot($root) { if ($root !== 'sandbox' && $root !== 'dropbox') { throw new Exception("Expected a root of either 'dropbox' or 'sandbox', got '$root'"); } else { $this->root = $root; } } /** * This function will make a request to refresh the access token * * @return void */ public function refreshAccessToken() { $this->OAuth->refreshAccessToken(); } /** * Retrieves information about the user's account * @return object stdClass */ public function accountInfo() { $call = '2/users/get_current_account'; $params = array('api_v2' => true); $response = $this->fetch('POST', self::API_URL_V2, $call, $params); return $response; } /** * Retrieves information about the user's quota * @param array $options - valid keys are 'timeout' * @return object stdClass */ public function quotaInfo($options = array()) { $call = '2/users/get_space_usage'; // Cases have been seen (Apr 2019) where a response came back (HTTP/2.0 response header - suspected outgoing web hosting proxy, as everyone else seems to get HTTP/1.0 and I'm not aware that current Curl versions would do HTTP/2.0 without specifically being told to) after 180 seconds; a valid response, but took a long time. $params = array( 'api_v2' => true, 'timeout' => isset($options['timeout']) ? $options['timeout'] : 20 ); $response = $this->fetch('POST', self::API_URL_V2, $call, $params); return $response; } /** * Uploads large files to Dropbox in mulitple chunks * @param string $file Absolute path to the file to be uploaded * @param string|bool $filename The destination filename of the uploaded file * @param string $path Path to upload the file to, relative to root * @param boolean $overwrite Should the file be overwritten? (Default: true) * @param integer $offset position to seek to when opening the file * @param string $uploadID existing upload_id to resume an upload * @param string|array function to call back to upon each chunk * @return stdClass */ public function chunkedUpload($file, $filename = false, $path = '', $overwrite = true, $offset = 0, $uploadID = null, $callback = null) { if (file_exists($file)) { if ($handle = @fopen($file, 'r')) { // Set initial upload ID and offset if ($offset > 0) { fseek($handle, $offset); } /* Set firstCommit to true so that the upload session start endpoint is called. */ $firstCommit = (0 == $offset); // Read from the file handle until EOF, uploading each chunk while ($data = fread($handle, $this->chunkSize)) { // Set the file, request parameters and send the request $this->OAuth->setInFile($data); if ($firstCommit) { $params = array( 'close' => false, 'api_v2' => true, 'content_upload' => true ); $response = $this->fetch('POST', self::CONTENT_URL_V2, 'files/upload_session/start', $params); $firstCommit = false; } else { $params = array( 'cursor' => array( 'session_id' => $uploadID, // If you send it as a string, Dropbox will be unhappy 'offset' => (int)$offset ), 'api_v2' => true, 'content_upload' => true ); $response = $this->append_upload($params, false); } // On subsequent chunks, use the upload ID returned by the previous request if (isset($response['body']->session_id)) { $uploadID = $response['body']->session_id; } /* API v2 no longer returns the offset, we need to manually work this out. So check that there are no errors and update the offset as well as calling the callback method. */ if (!isset($response['body']->error)) { $offset = ftell($handle); if ($callback) { call_user_func($callback, $offset, $uploadID, $file); } $this->OAuth->setInFile(null); } } // Complete the chunked upload $filename = (is_string($filename)) ? $filename : basename($file); $params = array( 'cursor' => array( 'session_id' => $uploadID, 'offset' => $offset ), 'commit' => array( 'path' => '/' . $this->encodePath($path . $filename), 'mode' => 'add' ), 'api_v2' => true, 'content_upload' => true ); $response = $this->append_upload($params, true); return $response; } else { throw new Exception('Could not open ' . $file . ' for reading'); } } // Throw an Exception if the file does not exist throw new Exception('Local file ' . $file . ' does not exist'); } private function append_upload($params, $last_call) { try { if ($last_call){ $response = $this->fetch('POST', self::CONTENT_URL_V2, 'files/upload_session/finish', $params); } else { $response = $this->fetch('POST', self::CONTENT_URL_V2, 'files/upload_session/append_v2', $params); } } catch (Exception $e) { $responseCheck = json_decode($e->getMessage()); if (empty($responseCheck)) { throw $e; } else { $extract_message = (is_object($responseCheck[0]) && isset($responseCheck[0]->{'.tag'})) ? $responseCheck[0]->{'.tag'} : $responseCheck[0]; if (strpos($extract_message, 'incorrect_offset') !== false) { $expected_offset = $responseCheck[1]; throw new Exception('Submitted input out of alignment: got ['.$params['cursor']['offset'].'] expected ['.$expected_offset.']'); // $params['cursor']['offset'] = $responseCheck[1]; // $response = $this->append_upload($params, $last_call); } elseif (strpos($extract_message, 'closed') !== false) { throw new Exception("Upload with upload_id {$params['cursor']['session_id']} already completed"); } elseif (strpos($extract_message, 'too_many_requests') !== false) { throw new Exception("Dropbox API error: too_many_requests"); } } } return $response; } /** * Chunked downloads a file from Dropbox, it will return false if a file handle is not passed and will return true if the call was successful. * * @param string $file Path - to file, relative to root, including path * @param resource $outFile - the local file handle * @param array $options - any extra options to be passed e.g headers * @return boolean - a boolean to indicate success or failure */ public function download($file, $outFile = null, $options = array()) { if ($outFile) { $this->OAuth->setOutFile($outFile); $params = array('path' => '/' . $file, 'api_v2' => true, 'content_download' => true); if (isset($options['headers'])) { foreach ($options['headers'] as $key => $header) { $headers[] = $key . ': ' . $header; } $params['headers'] = $headers; } $file = $this->encodePath($file); $call = 'files/download'; $response = $this->fetch('GET', self::CONTENT_URL_V2, $call, $params); fclose($outFile); return true; } else { return false; } } /** * Calls the relevant method to return metadata for all files and folders that match the search query * @param mixed $query The search string. Must be at least 3 characters long * @param string [$path=''] The path to the folder you want to search in * @param integer [$limit=1000] Maximum number of results to return (1-1000) * @param integer [$cursor=''] A Dropbox ID to start the search from * @return array */ public function search($query, $path = '', $limit = 1000, $cursor = '') { if (empty($cursor)) { return $this->start_search($query, $path, $limit); } else { return $this->continue_search($cursor); } } /** * This method will start a search for all files and folders that match the search query * * @param mixed $query - the search string, must be at least 3 characters long * @param string $path - the path to the folder you want to search in * @param integer $limit - maximum number of results to return (1-1000) * * @return array - an array of search results */ private function start_search($query, $path, $limit) { $call = '2/files/search_v2'; $path = $this->encodePath($path); // APIv2 requires that the path match this regex: String(pattern="(/(.|[\r\n])*)?|(ns:[0-9]+(/.*)?)") if ($path && '/' != substr($path, 0, 1)) $path = "/$path"; $params = array( 'query' => $query, 'options' => array( 'path' => $path, 'max_results' => ($limit < 1) ? 1 : (($limit > 1000) ? 1000 : (int) $limit), ), 'api_v2' => true, ); $response = $this->fetch('POST', self::API_URL_V2, $call, $params); return $response; } /** * This method will continue a previous search for all files and folders that match the previous search query * * @param string $cursor - a Dropbox ID to continue the search * * @return array - an array of search results */ private function continue_search($cursor) { $call = '2/files/search/continue_v2'; $params = array( 'cursor' => $cursor, 'api_v2' => true, ); $response = $this->fetch('POST', self::API_URL_V2, $call, $params); return $response; } /** * Deletes a file or folder * @param string $path The path to the file or folder to be deleted * @return object stdClass */ public function delete($path) { $call = '2/files/delete_v2'; $params = array('path' => '/' . $this->normalisePath($path), 'api_v2' => true); $response = $this->fetch('POST', self::API_URL_V2, $call, $params); return $response; } /** * Intermediate fetch function * @param string $method The HTTP method * @param string $url The API endpoint * @param string $call The API method to call * @param array $params Additional parameters * @return mixed */ private function fetch($method, $url, $call, array $params = array()) { // Make the API call via the consumer return $this->OAuth->fetch($method, $url, $call, $params); } /** * Set the chunk size for chunked uploads * If $chunkSize is empty, set to 4194304 bytes (4 MB) * @see \Dropbox\API\chunkedUpload() */ public function setChunkSize($chunkSize = 4194304) { if (!is_int($chunkSize)) { throw new Exception('Expecting chunk size to be an integer, got ' . gettype($chunkSize)); } elseif ($chunkSize > 157286400) { throw new Exception('Chunk size must not exceed 157286400 bytes, got ' . $chunkSize); } else { $this->chunkSize = $chunkSize; } } /** * Set the JSONP callback function * @param string $function * @return void */ public function setCallback($function) { $this->callback = $function; } /** * Get the mime type of downloaded file * If the Fileinfo extension is not loaded, return false * @param string $data File contents as a string or filename * @param string $isFilename Is $data a filename? * @return boolean|string Mime type and encoding of the file */ private function getMimeType($data, $isFilename = false) { if (extension_loaded('fileinfo')) { $finfo = new finfo(FILEINFO_MIME); if ($isFilename !== false) { return $finfo->file($data); } return $finfo->buffer($data); } return false; } /** * Trim the path of forward slashes and replace * consecutive forward slashes with a single slash * @param string $path The path to normalise * @return string */ private function normalisePath($path) { $path = preg_replace('#/+#', '/', trim($path, '/')); return $path; } /** * Encode the path, then replace encoded slashes * with literal forward slash characters * @param string $path The path to encode * @return string */ private function encodePath($path) { // in APIv1, encoding was needed because parameters were passed as part of the URL; this is no longer done in our APIv2 SDK; hence, all that we now do here is normalise. return $this->normalisePath($path); } } includes/Dropbox2/Exception.php000064400000001056152214270100012514 0ustar00 * @link https://github.com/benthedesigner/dropbox * @package Dropbox */ class Dropbox_Exception extends Exception { } class Dropbox_BadRequestException extends Exception { } class Dropbox_CurlException extends Exception { } class Dropbox_NotAcceptableException extends Exception { } class Dropbox_NotFoundException extends Exception { } class Dropbox_NotModifiedException extends Exception { } class Dropbox_UnsupportedMediaTypeException extends Exception { } includes/Google/Auth/Simple.php000064400000003723152214270100012430 0ustar00client = $client; } /** * Perform an authenticated / signed apiHttpRequest. * This function takes the apiHttpRequest, calls apiAuth->sign on it * (which can modify the request in what ever way fits the auth mechanism) * and then calls apiCurlIO::makeRequest on the signed request * * @param Google_Http_Request $request * @return Google_Http_Request The resulting HTTP response including the * responseHttpCode, responseHeaders and responseBody. */ public function authenticatedRequest(UDP_Google_Http_Request $request) { $request = $this->sign($request); return $this->io->makeRequest($request); } public function sign(UDP_Google_Http_Request $request) { $key = $this->client->getClassConfig($this, 'developer_key'); if ($key) { $this->client->getLogger()->debug( 'Simple API Access developer key authentication' ); $request->setQueryParam('key', $key); } return $request; } } includes/Google/Auth/AssertionCredentials.php000064400000007436152214270100015331 0ustar00serviceAccountName = $serviceAccountName; $this->scopes = is_string($scopes) ? $scopes : implode(' ', $scopes); $this->privateKey = $privateKey; $this->privateKeyPassword = $privateKeyPassword; $this->assertionType = $assertionType; $this->sub = $sub; $this->prn = $sub; $this->useCache = $useCache; } /** * Generate a unique key to represent this credential. * @return string */ public function getCacheKey() { if (!$this->useCache) { return false; } $h = $this->sub; $h .= $this->assertionType; $h .= $this->privateKey; $h .= $this->scopes; $h .= $this->serviceAccountName; return md5($h); } public function generateAssertion() { $now = time(); $jwtParams = array( 'aud' => Google_Auth_OAuth2::OAUTH2_TOKEN_URI, 'scope' => $this->scopes, 'iat' => $now, 'exp' => $now + self::MAX_TOKEN_LIFETIME_SECS, 'iss' => $this->serviceAccountName, ); if ($this->sub !== false) { $jwtParams['sub'] = $this->sub; } else if ($this->prn !== false) { $jwtParams['prn'] = $this->prn; } return $this->makeSignedJwt($jwtParams); } /** * Creates a signed JWT. * @param array $payload * @return string The signed JWT. */ private function makeSignedJwt($payload) { $header = array('typ' => 'JWT', 'alg' => 'RS256'); $payload = json_encode($payload); // Handle some overzealous escaping in PHP json that seemed to cause some errors // with claimsets. $payload = str_replace('\/', '/', $payload); $segments = array( Google_Utils::urlSafeB64Encode(json_encode($header)), Google_Utils::urlSafeB64Encode($payload) ); $signingInput = implode('.', $segments); $signer = new Google_Signer_P12($this->privateKey, $this->privateKeyPassword); $signature = $signer->sign($signingInput); $segments[] = Google_Utils::urlSafeB64Encode($signature); return implode(".", $segments); } } includes/Google/Auth/Abstract.php000064400000002406152214270100012737 0ustar00 * */ abstract class Google_Auth_Abstract { /** * An utility function that first calls $this->auth->sign($request) and then * executes makeRequest() on that signed request. Used for when a request * should be authenticated * @param Google_Http_Request $request * @return Google_Http_Request $request */ abstract public function authenticatedRequest(UDP_Google_Http_Request $request); abstract public function sign(UDP_Google_Http_Request $request); } includes/Google/Auth/ComputeEngine.php000064400000010254152214270100013736 0ustar00 */ class Google_Auth_ComputeEngine extends Google_Auth_Abstract { const METADATA_AUTH_URL = 'http://metadata/computeMetadata/v1/instance/service-accounts/default/token'; private $client; private $token; public function __construct(UDP_Google_Client $client, $config = null) { $this->client = $client; } /** * Perform an authenticated / signed apiHttpRequest. * This function takes the apiHttpRequest, calls apiAuth->sign on it * (which can modify the request in what ever way fits the auth mechanism) * and then calls apiCurlIO::makeRequest on the signed request * * @param Google_Http_Request $request * @return Google_Http_Request The resulting HTTP response including the * responseHttpCode, responseHeaders and responseBody. */ public function authenticatedRequest(UDP_Google_Http_Request $request) { $request = $this->sign($request); return $this->client->getIo()->makeRequest($request); } /** * @param string $token * @throws Google_Auth_Exception */ public function setAccessToken($token) { $token = json_decode($token, true); if ($token == null) { throw new Google_Auth_Exception('Could not json decode the token'); } if (! isset($token['access_token'])) { throw new Google_Auth_Exception("Invalid token format"); } $token['created'] = time(); $this->token = $token; } public function getAccessToken() { return json_encode($this->token); } /** * Acquires a new access token from the compute engine metadata server. * @throws Google_Auth_Exception */ public function acquireAccessToken() { $request = new UDP_Google_Http_Request( self::METADATA_AUTH_URL, 'GET', array( 'Metadata-Flavor' => 'Google' ) ); $request->disableGzip(); $response = $this->client->getIo()->makeRequest($request); if ($response->getResponseHttpCode() == 200) { $this->setAccessToken($response->getResponseBody()); $this->token['created'] = time(); return $this->getAccessToken(); } else { throw new Google_Auth_Exception( sprintf( "Error fetching service account access token, message: '%s'", $response->getResponseBody() ), $response->getResponseHttpCode() ); } } /** * Include an accessToken in a given apiHttpRequest. * @param Google_Http_Request $request * @return Google_Http_Request * @throws Google_Auth_Exception */ public function sign(UDP_Google_Http_Request $request) { if ($this->isAccessTokenExpired()) { $this->acquireAccessToken(); } $this->client->getLogger()->debug('Compute engine service account authentication'); $request->setRequestHeaders( array('Authorization' => 'Bearer ' . $this->token['access_token']) ); return $request; } /** * Returns if the access_token is expired. * @return bool Returns True if the access_token is expired. */ public function isAccessTokenExpired() { if (!$this->token || !isset($this->token['created'])) { return true; } // If the token is set to expire in the next 30 seconds. $expired = ($this->token['created'] + ($this->token['expires_in'] - 30)) < time(); return $expired; } } includes/Google/Auth/OAuth2.php000064400000045327152214270100012307 0ustar00client = $client; } /** * Perform an authenticated / signed apiHttpRequest. * This function takes the apiHttpRequest, calls apiAuth->sign on it * (which can modify the request in what ever way fits the auth mechanism) * and then calls apiCurlIO::makeRequest on the signed request * * @param Google_Http_Request $request * @return Google_Http_Request The resulting HTTP response including the * responseHttpCode, responseHeaders and responseBody. */ public function authenticatedRequest(UDP_Google_Http_Request $request) { $request = $this->sign($request); return $this->client->getIo()->makeRequest($request); } /** * @param string $code * @throws Google_Auth_Exception * @return string */ public function authenticate($code) { if (strlen($code) == 0) { throw new Google_Auth_Exception("Invalid code"); } // We got here from the redirect from a successful authorization grant, // fetch the access token $request = new UDP_Google_Http_Request( self::OAUTH2_TOKEN_URI, 'POST', array(), array( 'code' => $code, 'grant_type' => 'authorization_code', 'redirect_uri' => $this->client->getClassConfig($this, 'redirect_uri'), 'client_id' => $this->client->getClassConfig($this, 'client_id'), 'client_secret' => $this->client->getClassConfig($this, 'client_secret') ) ); $request->disableGzip(); $response = $this->client->getIo()->makeRequest($request); if ($response->getResponseHttpCode() == 200) { $this->setAccessToken($response->getResponseBody()); $this->token['created'] = time(); return $this->getAccessToken(); } else { $decodedResponse = json_decode($response->getResponseBody(), true); if ($decodedResponse != null && $decodedResponse['error']) { $errorText = $decodedResponse['error']; if (isset($decodedResponse['error_description'])) { $errorText .= ": " . $decodedResponse['error_description']; } } throw new Google_Auth_Exception( sprintf( "Error fetching OAuth2 access token, message: '%s'", $errorText ), $response->getResponseHttpCode() ); } } /** * Create a URL to obtain user authorization. * The authorization endpoint allows the user to first * authenticate, and then grant/deny the access request. * @param string $scope The scope is expressed as a list of space-delimited strings. * @return string */ public function createAuthUrl($scope) { $params = array( 'response_type' => 'code', 'redirect_uri' => $this->client->getClassConfig($this, 'redirect_uri'), 'client_id' => $this->client->getClassConfig($this, 'client_id'), 'scope' => $scope, 'access_type' => $this->client->getClassConfig($this, 'access_type'), ); // Prefer prompt to approval prompt. if ($this->client->getClassConfig($this, 'prompt')) { $params = $this->maybeAddParam($params, 'prompt'); } else { $params = $this->maybeAddParam($params, 'approval_prompt'); } $params = $this->maybeAddParam($params, 'login_hint'); $params = $this->maybeAddParam($params, 'hd'); $params = $this->maybeAddParam($params, 'openid.realm'); $params = $this->maybeAddParam($params, 'include_granted_scopes'); // If the list of scopes contains plus.login, add request_visible_actions // to auth URL. $rva = $this->client->getClassConfig($this, 'request_visible_actions'); if (strpos($scope, 'plus.login') && strlen($rva) > 0) { $params['request_visible_actions'] = $rva; } if (isset($this->state)) { $params['state'] = $this->state; } return self::OAUTH2_AUTH_URL . "?" . http_build_query($params, '', '&'); } /** * @param string $token * @throws Google_Auth_Exception */ public function setAccessToken($token) { $token = json_decode($token, true); if ($token == null) { throw new Google_Auth_Exception('Could not json decode the token'); } if (! isset($token['access_token'])) { throw new Google_Auth_Exception("Invalid token format"); } $this->token = $token; } public function getAccessToken() { return json_encode($this->token); } public function getRefreshToken() { if (array_key_exists('refresh_token', $this->token)) { return $this->token['refresh_token']; } else { return null; } } public function setState($state) { $this->state = $state; } public function setAssertionCredentials(Google_Auth_AssertionCredentials $creds) { $this->assertionCredentials = $creds; } /** * Include an accessToken in a given apiHttpRequest. * @param Google_Http_Request $request * @return Google_Http_Request * @throws Google_Auth_Exception */ public function sign(UDP_Google_Http_Request $request) { // add the developer key to the request before signing it if ($this->client->getClassConfig($this, 'developer_key')) { $request->setQueryParam('key', $this->client->getClassConfig($this, 'developer_key')); } // Cannot sign the request without an OAuth access token. if (null == $this->token && null == $this->assertionCredentials) { return $request; } // Check if the token is set to expire in the next 30 seconds // (or has already expired). if ($this->isAccessTokenExpired()) { if ($this->assertionCredentials) { $this->refreshTokenWithAssertion(); } else { $this->client->getLogger()->debug('OAuth2 access token expired'); if (! array_key_exists('refresh_token', $this->token)) { $error = "The OAuth 2.0 access token has expired," ." and a refresh token is not available. Refresh tokens" ." are not returned for responses that were auto-approved."; $this->client->getLogger()->error($error); throw new Google_Auth_Exception($error); } $this->refreshToken($this->token['refresh_token']); } } $this->client->getLogger()->debug('OAuth2 authentication'); // Add the OAuth2 header to the request $request->setRequestHeaders( array('Authorization' => 'Bearer ' . $this->token['access_token']) ); return $request; } /** * Fetches a fresh access token with the given refresh token. * @param string $refreshToken * @return void */ public function refreshToken($refreshToken) { $this->refreshTokenRequest( array( 'client_id' => $this->client->getClassConfig($this, 'client_id'), 'client_secret' => $this->client->getClassConfig($this, 'client_secret'), 'refresh_token' => $refreshToken, 'grant_type' => 'refresh_token' ) ); } /** * Fetches a fresh access token with a given assertion token. * @param Google_Auth_AssertionCredentials $assertionCredentials optional. * @return void */ public function refreshTokenWithAssertion($assertionCredentials = null) { if (!$assertionCredentials) { $assertionCredentials = $this->assertionCredentials; } $cacheKey = $assertionCredentials->getCacheKey(); if ($cacheKey) { // We can check whether we have a token available in the // cache. If it is expired, we can retrieve a new one from // the assertion. $token = $this->client->getCache()->get($cacheKey); if ($token) { $this->setAccessToken($token); } if (!$this->isAccessTokenExpired()) { return; } } $this->client->getLogger()->debug('OAuth2 access token expired'); $this->refreshTokenRequest( array( 'grant_type' => 'assertion', 'assertion_type' => $assertionCredentials->assertionType, 'assertion' => $assertionCredentials->generateAssertion(), ) ); if ($cacheKey) { // Attempt to cache the token. $this->client->getCache()->set( $cacheKey, $this->getAccessToken() ); } } private function refreshTokenRequest($params) { if (isset($params['assertion'])) { $this->client->getLogger()->info( 'OAuth2 access token refresh with Signed JWT assertion grants.' ); } else { $this->client->getLogger()->info('OAuth2 access token refresh'); } $http = new UDP_Google_Http_Request( self::OAUTH2_TOKEN_URI, 'POST', array(), $params ); $http->disableGzip(); $request = $this->client->getIo()->makeRequest($http); $code = $request->getResponseHttpCode(); $body = $request->getResponseBody(); if (200 == $code) { $token = json_decode($body, true); if ($token == null) { throw new Google_Auth_Exception("Could not json decode the access token"); } if (! isset($token['access_token']) || ! isset($token['expires_in'])) { throw new Google_Auth_Exception("Invalid token format"); } if (isset($token['id_token'])) { $this->token['id_token'] = $token['id_token']; } $this->token['access_token'] = $token['access_token']; $this->token['expires_in'] = $token['expires_in']; $this->token['created'] = time(); } else { throw new Google_Auth_Exception("Error refreshing the OAuth2 token, message: '$body'", $code); } } /** * Revoke an OAuth2 access token or refresh token. This method will revoke the current access * token, if a token isn't provided. * @throws Google_Auth_Exception * @param string|null $token The token (access token or a refresh token) that should be revoked. * @return boolean Returns True if the revocation was successful, otherwise False. */ public function revokeToken($token = null) { if (!$token) { if (!$this->token) { // Not initialized, no token to actually revoke return false; } elseif (array_key_exists('refresh_token', $this->token)) { $token = $this->token['refresh_token']; } else { $token = $this->token['access_token']; } } $request = new UDP_Google_Http_Request( self::OAUTH2_REVOKE_URI, 'POST', array(), "token=$token" ); $request->disableGzip(); $response = $this->client->getIo()->makeRequest($request); $code = $response->getResponseHttpCode(); if ($code == 200) { $this->token = null; return true; } return false; } /** * Returns if the access_token is expired. * @return bool Returns True if the access_token is expired. */ public function isAccessTokenExpired() { if (!$this->token || !isset($this->token['created'])) { return true; } // If the token is set to expire in the next 30 seconds. $expired = ($this->token['created'] + ($this->token['expires_in'] - 30)) < time(); return $expired; } // Gets federated sign-on certificates to use for verifying identity tokens. // Returns certs as array structure, where keys are key ids, and values // are PEM encoded certificates. private function getFederatedSignOnCerts() { return $this->retrieveCertsFromLocation( $this->client->getClassConfig($this, 'federated_signon_certs_url') ); } /** * Retrieve and cache a certificates file. * * @param $url string location * @throws Google_Auth_Exception * @return array certificates */ public function retrieveCertsFromLocation($url) { // If we're retrieving a local file, just grab it. if ("http" != substr($url, 0, 4)) { $file = file_get_contents($url); if ($file) { return json_decode($file, true); } else { throw new Google_Auth_Exception( "Failed to retrieve verification certificates: '" . $url . "'." ); } } // This relies on makeRequest caching certificate responses. $request = $this->client->getIo()->makeRequest( new UDP_Google_Http_Request( $url ) ); if ($request->getResponseHttpCode() == 200) { $certs = json_decode($request->getResponseBody(), true); if ($certs) { return $certs; } } throw new Google_Auth_Exception( "Failed to retrieve verification certificates: '" . $request->getResponseBody() . "'.", $request->getResponseHttpCode() ); } /** * Verifies an id token and returns the authenticated apiLoginTicket. * Throws an exception if the id token is not valid. * The audience parameter can be used to control which id tokens are * accepted. By default, the id token must have been issued to this OAuth2 client. * * @param $id_token * @param $audience * @return Google_Auth_LoginTicket */ public function verifyIdToken($id_token = null, $audience = null) { if (!$id_token) { $id_token = $this->token['id_token']; } $certs = $this->getFederatedSignonCerts(); if (!$audience) { $audience = $this->client->getClassConfig($this, 'client_id'); } return $this->verifySignedJwtWithCerts($id_token, $certs, $audience, self::OAUTH2_ISSUER); } /** * Verifies the id token, returns the verified token contents. * * @param $jwt string the token * @param $certs array of certificates * @param $required_audience string the expected consumer of the token * @param [$issuer] the expected issues, defaults to Google * @param [$max_expiry] the max lifetime of a token, defaults to MAX_TOKEN_LIFETIME_SECS * @throws Google_Auth_Exception * @return mixed token information if valid, false if not */ public function verifySignedJwtWithCerts( $jwt, $certs, $required_audience, $issuer = null, $max_expiry = null ) { if (!$max_expiry) { // Set the maximum time we will accept a token for. $max_expiry = self::MAX_TOKEN_LIFETIME_SECS; } $segments = explode(".", $jwt); if (count($segments) != 3) { throw new Google_Auth_Exception("Wrong number of segments in token: $jwt"); } $signed = $segments[0] . "." . $segments[1]; $signature = Google_Utils::urlSafeB64Decode($segments[2]); // Parse envelope. $envelope = json_decode(Google_Utils::urlSafeB64Decode($segments[0]), true); if (!$envelope) { throw new Google_Auth_Exception("Can't parse token envelope: " . $segments[0]); } // Parse token $json_body = Google_Utils::urlSafeB64Decode($segments[1]); $payload = json_decode($json_body, true); if (!$payload) { throw new Google_Auth_Exception("Can't parse token payload: " . $segments[1]); } // Check signature $verified = false; foreach ($certs as $keyName => $pem) { $public_key = new Google_Verifier_Pem($pem); if ($public_key->verify($signed, $signature)) { $verified = true; break; } } if (!$verified) { throw new Google_Auth_Exception("Invalid token signature: $jwt"); } // Check issued-at timestamp $iat = 0; if (array_key_exists("iat", $payload)) { $iat = $payload["iat"]; } if (!$iat) { throw new Google_Auth_Exception("No issue time in token: $json_body"); } $earliest = $iat - self::CLOCK_SKEW_SECS; // Check expiration timestamp $now = time(); $exp = 0; if (array_key_exists("exp", $payload)) { $exp = $payload["exp"]; } if (!$exp) { throw new Google_Auth_Exception("No expiration time in token: $json_body"); } if ($exp >= $now + $max_expiry) { throw new Google_Auth_Exception( sprintf("Expiration time too far in future: %s", $json_body) ); } $latest = $exp + self::CLOCK_SKEW_SECS; if ($now < $earliest) { throw new Google_Auth_Exception( sprintf( "Token used too early, %s < %s: %s", $now, $earliest, $json_body ) ); } if ($now > $latest) { throw new Google_Auth_Exception( sprintf( "Token used too late, %s > %s: %s", $now, $latest, $json_body ) ); } $iss = $payload['iss']; if ($issuer && $iss != $issuer) { throw new Google_Auth_Exception( sprintf( "Invalid issuer, %s != %s: %s", $iss, $issuer, $json_body ) ); } // Check audience $aud = $payload["aud"]; if ($aud != $required_audience) { throw new Google_Auth_Exception( sprintf( "Wrong recipient, %s != %s:", $aud, $required_audience, $json_body ) ); } // All good. return new Google_Auth_LoginTicket($envelope, $payload); } /** * Add a parameter to the auth params if not empty string. */ private function maybeAddParam($params, $name) { $param = $this->client->getClassConfig($this, $name); if ($param != '') { $params[$name] = $param; } return $params; } } includes/Google/Auth/Exception.php000064400000001367152214270100013137 0ustar00client = $client; } /** * Retrieve an access token for the scopes supplied. */ public function authenticateForScope($scopes) { if ($this->token && $this->tokenScopes == $scopes) { return $this->token; } $cacheKey = self::CACHE_PREFIX; if (is_string($scopes)) { $cacheKey .= $scopes; } else if (is_array($scopes)) { $cacheKey .= implode(":", $scopes); } $this->token = $this->client->getCache()->get($cacheKey); if (!$this->token) { $this->retrieveToken($scopes, $cacheKey); } else if ($this->token['expiration_time'] < time()) { $this->client->getCache()->delete($cacheKey); $this->retrieveToken($scopes, $cacheKey); } $this->tokenScopes = $scopes; return $this->token; } /** * Retrieve a new access token and store it in cache * @param mixed $scopes * @param string $cacheKey */ private function retrieveToken($scopes, $cacheKey) { $this->token = AppIdentityService::getAccessToken($scopes); if ($this->token) { $this->client->getCache()->set( $cacheKey, $this->token ); } } /** * Perform an authenticated / signed apiHttpRequest. * This function takes the apiHttpRequest, calls apiAuth->sign on it * (which can modify the request in what ever way fits the auth mechanism) * and then calls apiCurlIO::makeRequest on the signed request * * @param Google_Http_Request $request * @return Google_Http_Request The resulting HTTP response including the * responseHttpCode, responseHeaders and responseBody. */ public function authenticatedRequest(UDP_Google_Http_Request $request) { $request = $this->sign($request); return $this->client->getIo()->makeRequest($request); } public function sign(UDP_Google_Http_Request $request) { if (!$this->token) { // No token, so nothing to do. return $request; } $this->client->getLogger()->debug('App Identity authentication'); // Add the OAuth2 header to the request $request->setRequestHeaders( array('Authorization' => 'Bearer ' . $this->token['access_token']) ); return $request; } } includes/Google/Auth/LoginTicket.php000064400000003612152214270100013410 0ustar00 */ class Google_Auth_LoginTicket { const USER_ATTR = "sub"; // Information from id token envelope. private $envelope; // Information from id token payload. private $payload; /** * Creates a user based on the supplied token. * * @param string $envelope Header from a verified authentication token. * @param string $payload Information from a verified authentication token. */ public function __construct($envelope, $payload) { $this->envelope = $envelope; $this->payload = $payload; } /** * Returns the numeric identifier for the user. * @throws Google_Auth_Exception * @return */ public function getUserId() { if (array_key_exists(self::USER_ATTR, $this->payload)) { return $this->payload[self::USER_ATTR]; } throw new Google_Auth_Exception("No user_id in token"); } /** * Returns attributes from the login ticket. This can contain * various information about the user session. * @return array */ public function getAttributes() { return array("envelope" => $this->envelope, "payload" => $this->payload); } } includes/Google/Cache/Null.php000064400000002261152214270100012207 0ustar00 */ abstract class Google_Cache_Abstract { abstract public function __construct(UDP_Google_Client $client); /** * Retrieves the data for the given key, or false if they * key is unknown or expired * * @param String $key The key who's data to retrieve * @param boolean|int $expiration Expiration time in seconds * */ abstract public function get($key, $expiration = false); /** * Store the key => $value set. The $value is serialized * by this function so can be of any type * * @param string $key Key of the data * @param string $value data */ abstract public function set($key, $value); /** * Removes the key/data pair for the given $key * * @param String $key */ abstract public function delete($key); } includes/Google/Cache/Memcache.php000064400000011332152214270100012776 0ustar00 */ class Google_Cache_Memcache extends Google_Cache_Abstract { private $connection = false; private $mc = false; private $host; private $port; /** * @var Google_Client the current client */ private $client; public function __construct(UDP_Google_Client $client) { if (!function_exists('memcache_connect') && !class_exists("Memcached")) { $error = "Memcache functions not available"; $client->getLogger()->error($error); throw new Google_Cache_Exception($error); } $this->client = $client; if ($client->isAppEngine()) { // No credentials needed for GAE. $this->mc = new Memcached(); $this->connection = true; } else { $this->host = $client->getClassConfig($this, 'host'); $this->port = $client->getClassConfig($this, 'port'); if (empty($this->host) || (empty($this->port) && (string) $this->port != "0")) { $error = "You need to supply a valid memcache host and port"; $client->getLogger()->error($error); throw new Google_Cache_Exception($error); } } } /** * @inheritDoc */ public function get($key, $expiration = false) { $this->connect(); $ret = false; if ($this->mc) { $ret = $this->mc->get($key); } else { $ret = memcache_get($this->connection, $key); } if ($ret === false) { $this->client->getLogger()->debug( 'Memcache cache miss', array('key' => $key) ); return false; } if (is_numeric($expiration) && (time() - $ret['time'] > $expiration)) { $this->client->getLogger()->debug( 'Memcache cache miss (expired)', array('key' => $key, 'var' => $ret) ); $this->delete($key); return false; } $this->client->getLogger()->debug( 'Memcache cache hit', array('key' => $key, 'var' => $ret) ); return $ret['data']; } /** * @inheritDoc * @param string $key * @param string $value * @throws Google_Cache_Exception */ public function set($key, $value) { $this->connect(); // we store it with the cache_time default expiration so objects will at // least get cleaned eventually. $data = array('time' => time(), 'data' => $value); $rc = false; if ($this->mc) { $rc = $this->mc->set($key, $data); } else { $rc = memcache_set($this->connection, $key, $data, false); } if ($rc == false) { $this->client->getLogger()->error( 'Memcache cache set failed', array('key' => $key, 'var' => $data) ); throw new Google_Cache_Exception("Couldn't store data in cache"); } $this->client->getLogger()->debug( 'Memcache cache set', array('key' => $key, 'var' => $data) ); } /** * @inheritDoc * @param String $key */ public function delete($key) { $this->connect(); if ($this->mc) { $this->mc->delete($key, 0); } else { memcache_delete($this->connection, $key, 0); } $this->client->getLogger()->debug( 'Memcache cache delete', array('key' => $key) ); } /** * Lazy initialiser for memcache connection. Uses pconnect for to take * advantage of the persistence pool where possible. */ private function connect() { if ($this->connection) { return; } if (class_exists("Memcached")) { $this->mc = new Memcached(); $this->mc->addServer($this->host, $this->port); $this->connection = true; } else { $this->connection = memcache_pconnect($this->host, $this->port); } if (! $this->connection) { $error = "Couldn't connect to memcache server"; $this->client->getLogger()->error($error); throw new Google_Cache_Exception($error); } } } includes/Google/Cache/Apc.php000064400000005417152214270100012006 0ustar00 */ class Google_Cache_Apc extends Google_Cache_Abstract { /** * @var Google_Client the current client */ private $client; public function __construct(UDP_Google_Client $client) { if (! function_exists('apc_add') ) { $error = "Apc functions not available"; $client->getLogger()->error($error); throw new Google_Cache_Exception($error); } $this->client = $client; } /** * @inheritDoc */ public function get($key, $expiration = false) { $ret = apc_fetch($key); if ($ret === false) { $this->client->getLogger()->debug( 'APC cache miss', array('key' => $key) ); return false; } if (is_numeric($expiration) && (time() - $ret['time'] > $expiration)) { $this->client->getLogger()->debug( 'APC cache miss (expired)', array('key' => $key, 'var' => $ret) ); $this->delete($key); return false; } $this->client->getLogger()->debug( 'APC cache hit', array('key' => $key, 'var' => $ret) ); return $ret['data']; } /** * @inheritDoc */ public function set($key, $value) { $var = array('time' => time(), 'data' => $value); $rc = apc_store($key, $var); if ($rc == false) { $this->client->getLogger()->error( 'APC cache set failed', array('key' => $key, 'var' => $var) ); throw new Google_Cache_Exception("Couldn't store data"); } $this->client->getLogger()->debug( 'APC cache set', array('key' => $key, 'var' => $var) ); } /** * @inheritDoc * @param String $key */ public function delete($key) { $this->client->getLogger()->debug( 'APC cache delete', array('key' => $key) ); apc_delete($key); } } includes/Google/Cache/File.php000064400000013141152214270100012153 0ustar00 */ class Google_Cache_File extends Google_Cache_Abstract { const MAX_LOCK_RETRIES = 10; private $path; private $fh; /** * @var Google_Client the current client */ private $client; public function __construct(UDP_Google_Client $client) { $this->client = $client; $this->path = $this->client->getClassConfig($this, 'directory'); } public function get($key, $expiration = false) { $storageFile = $this->getCacheFile($key); $data = false; if (!file_exists($storageFile)) { $this->client->getLogger()->debug( 'File cache miss', array('key' => $key, 'file' => $storageFile) ); return false; } if ($expiration) { $mtime = filemtime($storageFile); if ((time() - $mtime) >= $expiration) { $this->client->getLogger()->debug( 'File cache miss (expired)', array('key' => $key, 'file' => $storageFile) ); $this->delete($key); return false; } } if ($this->acquireReadLock($storageFile)) { if (filesize($storageFile) > 0) { $data = fread($this->fh, filesize($storageFile)); $data = unserialize($data); } else { $this->client->getLogger()->debug( 'Cache file was empty', array('file' => $storageFile) ); } $this->unlock($storageFile); } $this->client->getLogger()->debug( 'File cache hit', array('key' => $key, 'file' => $storageFile, 'var' => $data) ); return $data; } public function set($key, $value) { $storageFile = $this->getWriteableCacheFile($key); if ($this->acquireWriteLock($storageFile)) { // We serialize the whole request object, since we don't only want the // responseContent but also the postBody used, headers, size, etc. $data = serialize($value); $result = fwrite($this->fh, $data); $this->unlock($storageFile); $this->client->getLogger()->debug( 'File cache set', array('key' => $key, 'file' => $storageFile, 'var' => $value) ); } else { $this->client->getLogger()->notice( 'File cache set failed', array('key' => $key, 'file' => $storageFile) ); } } public function delete($key) { $file = $this->getCacheFile($key); if (file_exists($file) && !unlink($file)) { $this->client->getLogger()->error( 'File cache delete failed', array('key' => $key, 'file' => $file) ); throw new Google_Cache_Exception("Cache file could not be deleted"); } $this->client->getLogger()->debug( 'File cache delete', array('key' => $key, 'file' => $file) ); } private function getWriteableCacheFile($file) { return $this->getCacheFile($file, true); } private function getCacheFile($file, $forWrite = false) { return $this->getCacheDir($file, $forWrite) . '/' . md5($file); } private function getCacheDir($file, $forWrite) { // use the first 2 characters of the hash as a directory prefix // this should prevent slowdowns due to huge directory listings // and thus give some basic amount of scalability $storageDir = $this->path . '/' . substr(md5($file), 0, 2); if ($forWrite && ! is_dir($storageDir)) { if (! mkdir($storageDir, 0755, true)) { $this->client->getLogger()->error( 'File cache creation failed', array('dir' => $storageDir) ); throw new Google_Cache_Exception("Could not create storage directory: $storageDir"); } } return $storageDir; } private function acquireReadLock($storageFile) { return $this->acquireLock(LOCK_SH, $storageFile); } private function acquireWriteLock($storageFile) { $rc = $this->acquireLock(LOCK_EX, $storageFile); if (!$rc) { $this->client->getLogger()->notice( 'File cache write lock failed', array('file' => $storageFile) ); $this->delete($storageFile); } return $rc; } private function acquireLock($type, $storageFile) { $mode = $type == LOCK_EX ? "w" : "r"; $this->fh = fopen($storageFile, $mode); if (!$this->fh) { $this->client->getLogger()->error( 'Failed to open file during lock acquisition', array('file' => $storageFile) ); return false; } $count = 0; while (!flock($this->fh, $type | LOCK_NB)) { // Sleep for 10ms. usleep(10000); if (++$count < self::MAX_LOCK_RETRIES) { return false; } } return true; } public function unlock($storageFile) { if ($this->fh) { flock($this->fh, LOCK_UN); } } } includes/Google/Cache/Exception.php000064400000001370152214270100013233 0ustar00getRequestMethod(), $req->getUrl()), array(get_class(), 'doExecute'), array($client, $req) ); return $runner->run(); } /** * Executes a Google_Http_Request * * @param UDP_Google_Client $client * @param Google_Http_Request $req * @return array decoded result * @throws UDP_Google_Service_Exception on server side error (ie: not authenticated, * invalid or malformed post body, invalid url) */ public static function doExecute(UDP_Google_Client $client, UDP_Google_Http_Request $req) { $httpRequest = $client->getIo()->makeRequest($req); $httpRequest->setExpectedClass($req->getExpectedClass()); return self::decodeHttpResponse($httpRequest, $client); } /** * Decode an HTTP Response. * @static * @throws UDP_Google_Service_Exception * @param Google_Http_Request $response The http response to be decoded. * @param UDP_Google_Client $client * @return mixed|null */ public static function decodeHttpResponse($response, UDP_Google_Client $client = null) { $code = $response->getResponseHttpCode(); $body = $response->getResponseBody(); $decoded = null; if ((intVal($code)) >= 300) { $decoded = json_decode($body, true); $err = 'Error calling ' . $response->getRequestMethod() . ' ' . $response->getUrl(); if (isset($decoded['error']) && isset($decoded['error']['message']) && isset($decoded['error']['code'])) { // if we're getting a json encoded error definition, use that instead of the raw response // body for improved readability $err .= ": ({$decoded['error']['code']}) {$decoded['error']['message']}"; } else { $err .= ": ($code) $body"; } $errors = null; // Specific check for APIs which don't return error details, such as Blogger. if (isset($decoded['error']) && isset($decoded['error']['errors'])) { $errors = $decoded['error']['errors']; } $map = null; if ($client) { $client->getLogger()->error( $err, array('code' => $code, 'errors' => $errors) ); $map = $client->getClassConfig( 'UDP_Google_Service_Exception', 'retry_map' ); } throw new UDP_Google_Service_Exception($err, $code, null, $errors, $map); } // Only attempt to decode the response, if the response code wasn't (204) 'no content' if ($code != '204') { if ($response->getExpectedRaw()) { return $body; } $decoded = json_decode($body, true); if ($decoded === null || $decoded === "") { # UpdraftPlus patch $error = "Invalid json in service response ($code): $body"; if ($client) { $client->getLogger()->error($error); } throw new UDP_Google_Service_Exception($error); } if ($response->getExpectedClass()) { $class = $response->getExpectedClass(); $decoded = new $class($decoded); } } return $decoded; } /** * Parse/expand request parameters and create a fully qualified * request uri. * @static * @param string $servicePath * @param string $restPath * @param array $params * @return string $requestUrl */ public static function createRequestUri($servicePath, $restPath, $params) { $requestUrl = $servicePath . $restPath; $uriTemplateVars = array(); $queryVars = array(); foreach ($params as $paramName => $paramSpec) { if ($paramSpec['type'] == 'boolean') { $paramSpec['value'] = ($paramSpec['value']) ? 'true' : 'false'; } if ($paramSpec['location'] == 'path') { $uriTemplateVars[$paramName] = $paramSpec['value']; } else if ($paramSpec['location'] == 'query') { if (isset($paramSpec['repeated']) && is_array($paramSpec['value'])) { foreach ($paramSpec['value'] as $value) { $queryVars[] = $paramName . '=' . rawurlencode(rawurldecode($value)); } } else { $queryVars[] = $paramName . '=' . rawurlencode(rawurldecode($paramSpec['value'])); } } } if (count($uriTemplateVars)) { $uriTemplateParser = new Google_Utils_URITemplate(); $requestUrl = $uriTemplateParser->parse($requestUrl, $uriTemplateVars); } if (count($queryVars)) { $requestUrl .= '?' . implode('&', $queryVars); } return $requestUrl; } } includes/Google/Http/MediaFileUpload.php000064400000020232152214270100014173 0ustar00client = $client; $this->request = $request; $this->mimeType = $mimeType; $this->data = $data; $this->size = strlen($this->data); $this->resumable = $resumable; if (!$chunkSize) { $chunkSize = 256 * 1024; } $this->chunkSize = $chunkSize; $this->progress = 0; $this->boundary = $boundary; // Process Media Request $this->process(); } /** * Set the size of the file that is being uploaded. * @param $size - int file size in bytes */ public function setFileSize($size) { $this->size = $size; } /** * Return the progress on the upload * @return int progress in bytes uploaded. */ public function getProgress() { return $this->progress; } /** * Return the HTTP result code from the last call made. * @return int code */ public function getHttpResultCode() { return $this->httpResultCode; } /** * Send the next part of the file to upload. * @param [$chunk] the next set of bytes to send. If false will used $data passed * at construct time. */ public function nextChunk($chunk = false) { if (false == $this->resumeUri) { $this->resumeUri = $this->getResumeUri(); } if (false == $chunk) { $chunk = substr($this->data, $this->progress, $this->chunkSize); } $lastBytePos = $this->progress + strlen($chunk) - 1; $headers = array( 'content-range' => "bytes $this->progress-$lastBytePos/$this->size", 'content-type' => $this->request->getRequestHeader('content-type'), 'content-length' => $this->chunkSize, 'expect' => '', ); $httpRequest = new UDP_Google_Http_Request( $this->resumeUri, 'PUT', $headers, $chunk ); if ($this->client->getClassConfig("UDP_Google_Http_Request", "enable_gzip_for_uploads")) { $httpRequest->enableGzip(); } else { $httpRequest->disableGzip(); } $response = $this->client->getIo()->makeRequest($httpRequest); $response->setExpectedClass($this->request->getExpectedClass()); $code = $response->getResponseHttpCode(); $this->httpResultCode = $code; if (308 == $code) { // Track the amount uploaded. $range = explode('-', $response->getResponseHeader('range')); $this->progress = $range[1] + 1; // Allow for changing upload URLs. $location = $response->getResponseHeader('location'); if ($location) { $this->resumeUri = $location; } // No problems, but upload not complete. return false; } else { return UDP_Google_Http_REST::decodeHttpResponse($response, $this->client); } } /** * @param $meta * @param $params * @return array|bool * @visible for testing */ private function process() { $postBody = false; $contentType = false; $meta = $this->request->getPostBody(); $meta = is_string($meta) ? json_decode($meta, true) : $meta; $uploadType = $this->getUploadType($meta); $this->request->setQueryParam('uploadType', $uploadType); $this->transformToUploadUrl(); $mimeType = $this->mimeType ? $this->mimeType : $this->request->getRequestHeader('content-type'); if (self::UPLOAD_RESUMABLE_TYPE == $uploadType) { $contentType = $mimeType; $postBody = is_string($meta) ? $meta : json_encode($meta); } else if (self::UPLOAD_MEDIA_TYPE == $uploadType) { $contentType = $mimeType; $postBody = $this->data; } else if (self::UPLOAD_MULTIPART_TYPE == $uploadType) { // This is a multipart/related upload. $boundary = $this->boundary ? $this->boundary : mt_rand(); $boundary = str_replace('"', '', $boundary); $contentType = 'multipart/related; boundary=' . $boundary; $related = "--$boundary\r\n"; $related .= "Content-Type: application/json; charset=UTF-8\r\n"; $related .= "\r\n" . json_encode($meta) . "\r\n"; $related .= "--$boundary\r\n"; $related .= "Content-Type: $mimeType\r\n"; $related .= "Content-Transfer-Encoding: base64\r\n"; $related .= "\r\n" . base64_encode($this->data) . "\r\n"; $related .= "--$boundary--"; $postBody = $related; } $this->request->setPostBody($postBody); if (isset($contentType) && $contentType) { $contentTypeHeader['content-type'] = $contentType; $this->request->setRequestHeaders($contentTypeHeader); } } private function transformToUploadUrl() { $base = $this->request->getBaseComponent(); $this->request->setBaseComponent($base . '/upload'); } /** * Valid upload types: * - resumable (UPLOAD_RESUMABLE_TYPE) * - media (UPLOAD_MEDIA_TYPE) * - multipart (UPLOAD_MULTIPART_TYPE) * @param $meta * @return string * @visible for testing */ public function getUploadType($meta) { if ($this->resumable) { return self::UPLOAD_RESUMABLE_TYPE; } if (false == $meta && $this->data) { return self::UPLOAD_MEDIA_TYPE; } return self::UPLOAD_MULTIPART_TYPE; } private function getResumeUri() { $result = null; $body = $this->request->getPostBody(); if ($body) { $headers = array( 'content-type' => 'application/json; charset=UTF-8', 'content-length' => Google_Utils::getStrLen($body), 'x-upload-content-type' => $this->mimeType, 'x-upload-content-length' => $this->size, 'expect' => '', ); $this->request->setRequestHeaders($headers); } $response = $this->client->getIo()->makeRequest($this->request); $location = $response->getResponseHeader('location'); $code = $response->getResponseHttpCode(); if (200 == $code && true == $location) { return $location; } $message = $code; $body = @json_decode($response->getResponseBody()); if (!empty( $body->error->errors ) ) { $message .= ': '; foreach ($body->error->errors as $error) { $message .= "{$error->domain}, {$error->message};"; } $message = rtrim($message, ';'); } $error = "Failed to start the resumable upload (HTTP {$message})"; $this->client->getLogger()->error($error); throw new Google_Exception($error); } } includes/Google/Http/Request.php000064400000027525152214270100012653 0ustar00 * @author Chirag Shah * */ class UDP_Google_Http_Request { const GZIP_UA = " (gzip)"; private $batchHeaders = array( 'Content-Type' => 'application/http', 'Content-Transfer-Encoding' => 'binary', 'MIME-Version' => '1.0', ); protected $queryParams; protected $requestMethod; protected $requestHeaders; protected $baseComponent = null; protected $path; protected $postBody; // UpdraftPlus tweak: added default value to prevent type notices protected $userAgent = ''; protected $canGzip = null; protected $responseHttpCode; protected $responseHeaders; protected $responseBody; protected $expectedClass; protected $expectedRaw = false; public $accessKey; public function __construct( $url, $method = 'GET', $headers = array(), $postBody = null ) { $this->setUrl($url); $this->setRequestMethod($method); $this->setRequestHeaders($headers); $this->setPostBody($postBody); } /** * Misc function that returns the base url component of the $url * used by the OAuth signing class to calculate the base string * @return string The base url component of the $url. */ public function getBaseComponent() { return $this->baseComponent; } /** * Set the base URL that path and query parameters will be added to. * @param $baseComponent string */ public function setBaseComponent($baseComponent) { $this->baseComponent = $baseComponent; } /** * Enable support for gzipped responses with this request. */ public function enableGzip() { $this->setRequestHeaders(array("Accept-Encoding" => "gzip")); $this->canGzip = true; $this->setUserAgent($this->userAgent); } /** * Disable support for gzip responses with this request. */ public function disableGzip() { if ( isset($this->requestHeaders['accept-encoding']) && $this->requestHeaders['accept-encoding'] == "gzip" ) { unset($this->requestHeaders['accept-encoding']); } $this->canGzip = false; $this->userAgent = str_replace(self::GZIP_UA, "", $this->userAgent); } /** * Can this request accept a gzip response? * @return bool */ public function canGzip() { return $this->canGzip; } /** * Misc function that returns an array of the query parameters of the current * url used by the OAuth signing class to calculate the signature * @return array Query parameters in the query string. */ public function getQueryParams() { return $this->queryParams; } /** * Set a new query parameter. * @param $key - string to set, does not need to be URL encoded * @param $value - string to set, does not need to be URL encoded */ public function setQueryParam($key, $value) { $this->queryParams[$key] = $value; } /** * @return string HTTP Response Code. */ public function getResponseHttpCode() { return (int) $this->responseHttpCode; } /** * @param int $responseHttpCode HTTP Response Code. */ public function setResponseHttpCode($responseHttpCode) { $this->responseHttpCode = $responseHttpCode; } /** * @return $responseHeaders (array) HTTP Response Headers. */ public function getResponseHeaders() { return $this->responseHeaders; } /** * @return string HTTP Response Body */ public function getResponseBody() { return $this->responseBody; } /** * Set the class the response to this request should expect. * * @param $class string the class name */ public function setExpectedClass($class) { $this->expectedClass = $class; } /** * Retrieve the expected class the response should expect. * @return string class name */ public function getExpectedClass() { return $this->expectedClass; } /** * Enable expected raw response */ public function enableExpectedRaw() { $this->expectedRaw = true; } /** * Disable expected raw response */ public function disableExpectedRaw() { $this->expectedRaw = false; } /** * Expected raw response or not. * @return boolean expected raw response */ public function getExpectedRaw() { return $this->expectedRaw; } /** * @param array $headers The HTTP response headers * to be normalized. */ public function setResponseHeaders($headers) { $headers = Google_Utils::normalize($headers); if ($this->responseHeaders) { $headers = array_merge($this->responseHeaders, $headers); } $this->responseHeaders = $headers; } /** * @param string $key * @return array|boolean Returns the requested HTTP header or * false if unavailable. */ public function getResponseHeader($key) { return isset($this->responseHeaders[$key]) ? $this->responseHeaders[$key] : false; } /** * @param string $responseBody The HTTP response body. */ public function setResponseBody($responseBody) { $this->responseBody = $responseBody; } /** * @return string $url The request URL. */ public function getUrl() { return $this->baseComponent . $this->path . (count($this->queryParams) ? "?" . $this->buildQuery($this->queryParams) : ''); } /** * @return string $method HTTP Request Method. */ public function getRequestMethod() { return $this->requestMethod; } /** * @return array $headers HTTP Request Headers. */ public function getRequestHeaders() { return $this->requestHeaders; } /** * @param string $key * @return array|boolean Returns the requested HTTP header or * false if unavailable. */ public function getRequestHeader($key) { return isset($this->requestHeaders[$key]) ? $this->requestHeaders[$key] : false; } /** * @return string $postBody HTTP Request Body. */ public function getPostBody() { return $this->postBody; } /** * @param string $url the url to set */ public function setUrl($url) { if (substr($url, 0, 4) != 'http') { // Force the path become relative. if (substr($url, 0, 1) !== '/') { $url = '/' . $url; } } $parts = parse_url($url); if (isset($parts['host'])) { $this->baseComponent = sprintf( "%s%s%s", isset($parts['scheme']) ? $parts['scheme'] . "://" : '', isset($parts['host']) ? $parts['host'] : '', isset($parts['port']) ? ":" . $parts['port'] : '' ); } $this->path = isset($parts['path']) ? $parts['path'] : ''; $this->queryParams = array(); if (isset($parts['query'])) { $this->queryParams = $this->parseQuery($parts['query']); } } /** * @param string $method Set he HTTP Method and normalize * it to upper-case, as required by HTTP. * */ public function setRequestMethod($method) { $this->requestMethod = strtoupper($method); } /** * @param array $headers The HTTP request headers * to be set and normalized. */ public function setRequestHeaders($headers) { $headers = Google_Utils::normalize($headers); if ($this->requestHeaders) { $headers = array_merge($this->requestHeaders, $headers); } $this->requestHeaders = $headers; } /** * @param string $postBody the postBody to set */ public function setPostBody($postBody) { $this->postBody = $postBody; } /** * Set the User-Agent Header. * @param string $userAgent The User-Agent. */ public function setUserAgent($userAgent) { $this->userAgent = $userAgent; if ($this->canGzip) { $this->userAgent = $userAgent . self::GZIP_UA; } } /** * @return string The User-Agent. */ public function getUserAgent() { return $this->userAgent; } /** * Returns a cache key depending on if this was an OAuth signed request * in which case it will use the non-signed url and access key to make this * cache key unique per authenticated user, else use the plain request url * @return string The md5 hash of the request cache key. */ public function getCacheKey() { $key = $this->getUrl(); if (isset($this->accessKey)) { $key .= $this->accessKey; } if (isset($this->requestHeaders['authorization'])) { $key .= $this->requestHeaders['authorization']; } return md5($key); } public function getParsedCacheControl() { $parsed = array(); $rawCacheControl = $this->getResponseHeader('cache-control'); if ($rawCacheControl) { $rawCacheControl = str_replace(', ', '&', $rawCacheControl); parse_str($rawCacheControl, $parsed); } return $parsed; } /** * @param string $id * @return string A string representation of the HTTP Request. */ public function toBatchString($id) { $str = ''; $path = parse_url($this->getUrl(), PHP_URL_PATH) . "?" . http_build_query($this->queryParams); $str .= $this->getRequestMethod() . ' ' . $path . " HTTP/1.1\n"; foreach ($this->getRequestHeaders() as $key => $val) { $str .= $key . ': ' . $val . "\n"; } if ($this->getPostBody()) { $str .= "\n"; $str .= $this->getPostBody(); } $headers = ''; foreach ($this->batchHeaders as $key => $val) { $headers .= $key . ': ' . $val . "\n"; } $headers .= "Content-ID: $id\n"; $str = $headers . "\n" . $str; return $str; } /** * Our own version of parse_str that allows for multiple variables * with the same name. * @param $string - the query string to parse */ private function parseQuery($string) { $return = array(); $parts = explode("&", $string); foreach ($parts as $part) { list($key, $value) = explode('=', $part, 2); $value = urldecode($value); if (isset($return[$key])) { if (!is_array($return[$key])) { $return[$key] = array($return[$key]); } $return[$key][] = $value; } else { $return[$key] = $value; } } return $return; } /** * A version of build query that allows for multiple * duplicate keys. * @param $parts array of key value pairs */ private function buildQuery($parts) { $return = array(); foreach ($parts as $key => $value) { if (is_array($value)) { foreach ($value as $v) { $return[] = urlencode($key) . "=" . urlencode($v); } } else { $return[] = urlencode($key) . "=" . urlencode($value); } } return implode('&', $return); } /** * If we're POSTing and have no body to send, we can send the query * parameters in there, which avoids length issues with longer query * params. */ public function maybeMoveParametersToBody() { if ($this->getRequestMethod() == "POST" && empty($this->postBody)) { $this->setRequestHeaders( array( "content-type" => "application/x-www-form-urlencoded; charset=UTF-8" ) ); $this->setPostBody($this->buildQuery($this->queryParams)); $this->queryParams = array(); } } } includes/Google/Http/CacheParser.php000064400000014071152214270100013373 0ustar00getRequestMethod(); if (! in_array($method, self::$CACHEABLE_HTTP_METHODS)) { return false; } // Don't cache authorized requests/responses. // [rfc2616-14.8] When a shared cache receives a request containing an // Authorization field, it MUST NOT return the corresponding response // as a reply to any other request... if ($resp->getRequestHeader("authorization")) { return false; } return true; } /** * Check if an HTTP response can be cached by a private local cache. * * @static * @param Google_Http_Request $resp * @return bool True if the response is cacheable. * False if the response is un-cacheable. */ public static function isResponseCacheable(UDP_Google_Http_Request $resp) { // First, check if the HTTP request was cacheable before inspecting the // HTTP response. if (false == self::isRequestCacheable($resp)) { return false; } $code = $resp->getResponseHttpCode(); if (! in_array($code, self::$CACHEABLE_STATUS_CODES)) { return false; } // The resource is uncacheable if the resource is already expired and // the resource doesn't have an ETag for revalidation. $etag = $resp->getResponseHeader("etag"); if (self::isExpired($resp) && $etag == false) { return false; } // [rfc2616-14.9.2] If [no-store is] sent in a response, a cache MUST NOT // store any part of either this response or the request that elicited it. $cacheControl = $resp->getParsedCacheControl(); if (isset($cacheControl['no-store'])) { return false; } // Pragma: no-cache is an http request directive, but is occasionally // used as a response header incorrectly. $pragma = $resp->getResponseHeader('pragma'); if ($pragma == 'no-cache' || strpos($pragma, 'no-cache') !== false) { return false; } // [rfc2616-14.44] Vary: * is extremely difficult to cache. "It implies that // a cache cannot determine from the request headers of a subsequent request // whether this response is the appropriate representation." // Given this, we deem responses with the Vary header as uncacheable. $vary = $resp->getResponseHeader('vary'); if ($vary) { return false; } return true; } /** * @static * @param Google_Http_Request $resp * @return bool True if the HTTP response is considered to be expired. * False if it is considered to be fresh. */ public static function isExpired(UDP_Google_Http_Request $resp) { // HTTP/1.1 clients and caches MUST treat other invalid date formats, // especially including the value “0”, as in the past. $parsedExpires = false; $responseHeaders = $resp->getResponseHeaders(); if (isset($responseHeaders['expires'])) { $rawExpires = $responseHeaders['expires']; // Check for a malformed expires header first. if (empty($rawExpires) || (is_numeric($rawExpires) && $rawExpires <= 0)) { return true; } // See if we can parse the expires header. $parsedExpires = strtotime($rawExpires); if (false == $parsedExpires || $parsedExpires <= 0) { return true; } } // Calculate the freshness of an http response. $freshnessLifetime = false; $cacheControl = $resp->getParsedCacheControl(); if (isset($cacheControl['max-age'])) { $freshnessLifetime = $cacheControl['max-age']; } $rawDate = $resp->getResponseHeader('date'); $parsedDate = strtotime($rawDate); if (empty($rawDate) || false == $parsedDate) { // We can't default this to now, as that means future cache reads // will always pass with the logic below, so we will require a // date be injected if not supplied. throw new Google_Exception("All cacheable requests must have creation dates."); } if (false == $freshnessLifetime && isset($responseHeaders['expires'])) { $freshnessLifetime = $parsedExpires - $parsedDate; } if (false == $freshnessLifetime) { return true; } // Calculate the age of an http response. $age = max(0, time() - $parsedDate); if (isset($responseHeaders['age'])) { $age = max($age, strtotime($responseHeaders['age'])); } return $freshnessLifetime <= $age; } /** * Determine if a cache entry should be revalidated with by the origin. * * @param Google_Http_Request $response * @return bool True if the entry is expired, else return false. */ public static function mustRevalidate(UDP_Google_Http_Request $response) { // [13.3] When a cache has a stale entry that it would like to use as a // response to a client's request, it first has to check with the origin // server to see if its cached entry is still usable. return self::isExpired($response); } } includes/Google/Http/Batch.php000064400000010360152214270100012231 0ustar00client = $client; $this->base_path = $this->client->getBasePath(); $this->expected_classes = array(); $boundary = (false == $boundary) ? mt_rand() : $boundary; $this->boundary = str_replace('"', '', $boundary); } public function add(UDP_Google_Http_Request $request, $key = false) { if (false == $key) { $key = mt_rand(); } $this->requests[$key] = $request; } public function execute() { $body = ''; /** @var Google_Http_Request $req */ foreach ($this->requests as $key => $req) { $body .= "--{$this->boundary}\n"; $body .= $req->toBatchString($key) . "\n"; $this->expected_classes["response-" . $key] = $req->getExpectedClass(); } $body = rtrim($body); $body .= "\n--{$this->boundary}--"; $url = $this->base_path . '/batch'; $httpRequest = new UDP_Google_Http_Request($url, 'POST'); $httpRequest->setRequestHeaders( array('Content-Type' => 'multipart/mixed; boundary=' . $this->boundary) ); $httpRequest->setPostBody($body); $response = $this->client->getIo()->makeRequest($httpRequest); return $this->parseResponse($response); } public function parseResponse(UDP_Google_Http_Request $response) { $contentType = $response->getResponseHeader('content-type'); $contentType = explode(';', $contentType); $boundary = false; foreach ($contentType as $part) { $part = (explode('=', $part, 2)); if (isset($part[0]) && 'boundary' == trim($part[0])) { $boundary = $part[1]; } } $body = $response->getResponseBody(); if ($body) { $body = str_replace("--$boundary--", "--$boundary", $body); $parts = explode("--$boundary", $body); $responses = array(); foreach ($parts as $part) { $part = trim($part); if (!empty($part)) { list($metaHeaders, $part) = explode("\r\n\r\n", $part, 2); $metaHeaders = $this->client->getIo()->getHttpResponseHeaders($metaHeaders); $status = substr($part, 0, strpos($part, "\n")); $status = explode(" ", $status); $status = $status[1]; list($partHeaders, $partBody) = $this->client->getIo()->ParseHttpResponse($part, false); $response = new UDP_Google_Http_Request(""); $response->setResponseHttpCode($status); $response->setResponseHeaders($partHeaders); $response->setResponseBody($partBody); // Need content id. $key = $metaHeaders['content-id']; if (isset($this->expected_classes[$key]) && strlen($this->expected_classes[$key]) > 0) { $class = $this->expected_classes[$key]; $response->setExpectedClass($class); } try { $response = UDP_Google_Http_REST::decodeHttpResponse($response, $this->client); $responses[$key] = $response; } catch (UDP_Google_Service_Exception $e) { // Store the exception as the response, so successful responses // can be processed. $responses[$key] = $e; } } } return $responses; } return null; } } includes/Google/IO/cacerts.pem000064400000407316152214270100012231 0ustar00# Issuer: CN=GTE CyberTrust Global Root O=GTE Corporation OU=GTE CyberTrust Solutions, Inc. # Subject: CN=GTE CyberTrust Global Root O=GTE Corporation OU=GTE CyberTrust Solutions, Inc. # Label: "GTE CyberTrust Global Root" # Serial: 421 # MD5 Fingerprint: ca:3d:d3:68:f1:03:5c:d0:32:fa:b8:2b:59:e8:5a:db # SHA1 Fingerprint: 97:81:79:50:d8:1c:96:70:cc:34:d8:09:cf:79:44:31:36:7e:f4:74 # SHA256 Fingerprint: a5:31:25:18:8d:21:10:aa:96:4b:02:c7:b7:c6:da:32:03:17:08:94:e5:fb:71:ff:fb:66:67:d5:e6:81:0a:36 -----BEGIN CERTIFICATE----- MIICWjCCAcMCAgGlMA0GCSqGSIb3DQEBBAUAMHUxCzAJBgNVBAYTAlVTMRgwFgYD VQQKEw9HVEUgQ29ycG9yYXRpb24xJzAlBgNVBAsTHkdURSBDeWJlclRydXN0IFNv bHV0aW9ucywgSW5jLjEjMCEGA1UEAxMaR1RFIEN5YmVyVHJ1c3QgR2xvYmFsIFJv b3QwHhcNOTgwODEzMDAyOTAwWhcNMTgwODEzMjM1OTAwWjB1MQswCQYDVQQGEwJV UzEYMBYGA1UEChMPR1RFIENvcnBvcmF0aW9uMScwJQYDVQQLEx5HVEUgQ3liZXJU cnVzdCBTb2x1dGlvbnMsIEluYy4xIzAhBgNVBAMTGkdURSBDeWJlclRydXN0IEds b2JhbCBSb290MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCVD6C28FCc6HrH iM3dFw4usJTQGz0O9pTAipTHBsiQl8i4ZBp6fmw8U+E3KHNgf7KXUwefU/ltWJTS r41tiGeA5u2ylc9yMcqlHHK6XALnZELn+aks1joNrI1CqiQBOeacPwGFVw1Yh0X4 04Wqk2kmhXBIgD8SFcd5tB8FLztimQIDAQABMA0GCSqGSIb3DQEBBAUAA4GBAG3r GwnpXtlR22ciYaQqPEh346B8pt5zohQDhT37qw4wxYMWM4ETCJ57NE7fQMh017l9 3PR2VX2bY1QY6fDq81yx2YtCHrnAlU66+tXifPVoYb+O7AWXX1uw16OFNMQkpw0P lZPvy5TYnh+dXIVtx6quTx8itc2VrbqnzPmrC3p/ -----END CERTIFICATE----- # Issuer: CN=Thawte Server CA O=Thawte Consulting cc OU=Certification Services Division # Subject: CN=Thawte Server CA O=Thawte Consulting cc OU=Certification Services Division # Label: "Thawte Server CA" # Serial: 1 # MD5 Fingerprint: c5:70:c4:a2:ed:53:78:0c:c8:10:53:81:64:cb:d0:1d # SHA1 Fingerprint: 23:e5:94:94:51:95:f2:41:48:03:b4:d5:64:d2:a3:a3:f5:d8:8b:8c # SHA256 Fingerprint: b4:41:0b:73:e2:e6:ea:ca:47:fb:c4:2f:8f:a4:01:8a:f4:38:1d:c5:4c:fa:a8:44:50:46:1e:ed:09:45:4d:e9 -----BEGIN CERTIFICATE----- MIIDEzCCAnygAwIBAgIBATANBgkqhkiG9w0BAQQFADCBxDELMAkGA1UEBhMCWkEx FTATBgNVBAgTDFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMR0wGwYD VQQKExRUaGF3dGUgQ29uc3VsdGluZyBjYzEoMCYGA1UECxMfQ2VydGlmaWNhdGlv biBTZXJ2aWNlcyBEaXZpc2lvbjEZMBcGA1UEAxMQVGhhd3RlIFNlcnZlciBDQTEm MCQGCSqGSIb3DQEJARYXc2VydmVyLWNlcnRzQHRoYXd0ZS5jb20wHhcNOTYwODAx MDAwMDAwWhcNMjAxMjMxMjM1OTU5WjCBxDELMAkGA1UEBhMCWkExFTATBgNVBAgT DFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMR0wGwYDVQQKExRUaGF3 dGUgQ29uc3VsdGluZyBjYzEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNl cyBEaXZpc2lvbjEZMBcGA1UEAxMQVGhhd3RlIFNlcnZlciBDQTEmMCQGCSqGSIb3 DQEJARYXc2VydmVyLWNlcnRzQHRoYXd0ZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQAD gY0AMIGJAoGBANOkUG7I/1Zr5s9dtuoMaHVHoqrC2oQl/Kj0R1HahbUgdJSGHg91 yekIYfUGbTBuFRkC6VLAYttNmZ7iagxEOM3+vuNkCXDF/rFrKbYvScg71CcEJRCX L+eQbcAoQpnXTEPew/UhbVSfXcNY4cDk2VuwuNy0e982OsK1ZiIS1ocNAgMBAAGj EzARMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEEBQADgYEAB/pMaVz7lcxG 7oWDTSEwjsrZqG9JGubaUeNgcGyEYRGhGshIPllDfU+VPaGLtwtimHp1it2ITk6e QNuozDJ0uW8NxuOzRAvZim+aKZuZGCg70eNAKJpaPNW15yAbi8qkq43pUdniTCxZ qdq5snUb9kLy78fyGPmJvKP/iiMucEc= -----END CERTIFICATE----- # Issuer: CN=Thawte Premium Server CA O=Thawte Consulting cc OU=Certification Services Division # Subject: CN=Thawte Premium Server CA O=Thawte Consulting cc OU=Certification Services Division # Label: "Thawte Premium Server CA" # Serial: 1 # MD5 Fingerprint: 06:9f:69:79:16:66:90:02:1b:8c:8c:a2:c3:07:6f:3a # SHA1 Fingerprint: 62:7f:8d:78:27:65:63:99:d2:7d:7f:90:44:c9:fe:b3:f3:3e:fa:9a # SHA256 Fingerprint: ab:70:36:36:5c:71:54:aa:29:c2:c2:9f:5d:41:91:16:3b:16:2a:22:25:01:13:57:d5:6d:07:ff:a7:bc:1f:72 -----BEGIN CERTIFICATE----- MIIDJzCCApCgAwIBAgIBATANBgkqhkiG9w0BAQQFADCBzjELMAkGA1UEBhMCWkEx FTATBgNVBAgTDFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMR0wGwYD VQQKExRUaGF3dGUgQ29uc3VsdGluZyBjYzEoMCYGA1UECxMfQ2VydGlmaWNhdGlv biBTZXJ2aWNlcyBEaXZpc2lvbjEhMB8GA1UEAxMYVGhhd3RlIFByZW1pdW0gU2Vy dmVyIENBMSgwJgYJKoZIhvcNAQkBFhlwcmVtaXVtLXNlcnZlckB0aGF3dGUuY29t MB4XDTk2MDgwMTAwMDAwMFoXDTIwMTIzMTIzNTk1OVowgc4xCzAJBgNVBAYTAlpB MRUwEwYDVQQIEwxXZXN0ZXJuIENhcGUxEjAQBgNVBAcTCUNhcGUgVG93bjEdMBsG A1UEChMUVGhhd3RlIENvbnN1bHRpbmcgY2MxKDAmBgNVBAsTH0NlcnRpZmljYXRp b24gU2VydmljZXMgRGl2aXNpb24xITAfBgNVBAMTGFRoYXd0ZSBQcmVtaXVtIFNl cnZlciBDQTEoMCYGCSqGSIb3DQEJARYZcHJlbWl1bS1zZXJ2ZXJAdGhhd3RlLmNv bTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA0jY2aovXwlue2oFBYo847kkE VdbQ7xwblRZH7xhINTpS9CtqBo87L+pW46+GjZ4X9560ZXUCTe/LCaIhUdib0GfQ ug2SBhRz1JPLlyoAnFxODLz6FVL88kRu2hFKbgifLy3j+ao6hnO2RlNYyIkFvYMR uHM/qgeN9EJN50CdHDcCAwEAAaMTMBEwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG 9w0BAQQFAAOBgQAmSCwWwlj66BZ0DKqqX1Q/8tfJeGBeXm43YyJ3Nn6yF8Q0ufUI hfzJATj/Tb7yFkJD57taRvvBxhEf8UqwKEbJw8RCfbz6q1lu1bdRiBHjpIUZa4JM pAwSremkrj/xw0llmozFyD4lt5SZu5IycQfwhl7tUCemDaYj+bvLpgcUQg== -----END CERTIFICATE----- # Issuer: O=Equifax OU=Equifax Secure Certificate Authority # Subject: O=Equifax OU=Equifax Secure Certificate Authority # Label: "Equifax Secure CA" # Serial: 903804111 # MD5 Fingerprint: 67:cb:9d:c0:13:24:8a:82:9b:b2:17:1e:d1:1b:ec:d4 # SHA1 Fingerprint: d2:32:09:ad:23:d3:14:23:21:74:e4:0d:7f:9d:62:13:97:86:63:3a # SHA256 Fingerprint: 08:29:7a:40:47:db:a2:36:80:c7:31:db:6e:31:76:53:ca:78:48:e1:be:bd:3a:0b:01:79:a7:07:f9:2c:f1:78 -----BEGIN CERTIFICATE----- MIIDIDCCAomgAwIBAgIENd70zzANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQGEwJV UzEQMA4GA1UEChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUgQ2Vy dGlmaWNhdGUgQXV0aG9yaXR5MB4XDTk4MDgyMjE2NDE1MVoXDTE4MDgyMjE2NDE1 MVowTjELMAkGA1UEBhMCVVMxEDAOBgNVBAoTB0VxdWlmYXgxLTArBgNVBAsTJEVx dWlmYXggU2VjdXJlIENlcnRpZmljYXRlIEF1dGhvcml0eTCBnzANBgkqhkiG9w0B AQEFAAOBjQAwgYkCgYEAwV2xWGcIYu6gmi0fCG2RFGiYCh7+2gRvE4RiIcPRfM6f BeC4AfBONOziipUEZKzxa1NfBbPLZ4C/QgKO/t0BCezhABRP/PvwDN1Dulsr4R+A cJkVV5MW8Q+XarfCaCMczE1ZMKxRHjuvK9buY0V7xdlfUNLjUA86iOe/FP3gx7kC AwEAAaOCAQkwggEFMHAGA1UdHwRpMGcwZaBjoGGkXzBdMQswCQYDVQQGEwJVUzEQ MA4GA1UEChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUgQ2VydGlm aWNhdGUgQXV0aG9yaXR5MQ0wCwYDVQQDEwRDUkwxMBoGA1UdEAQTMBGBDzIwMTgw ODIyMTY0MTUxWjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAUSOZo+SvSspXXR9gj IBBPM5iQn9QwHQYDVR0OBBYEFEjmaPkr0rKV10fYIyAQTzOYkJ/UMAwGA1UdEwQF MAMBAf8wGgYJKoZIhvZ9B0EABA0wCxsFVjMuMGMDAgbAMA0GCSqGSIb3DQEBBQUA A4GBAFjOKer89961zgK5F7WF0bnj4JXMJTENAKaSbn+2kmOeUJXRmm/kEd5jhW6Y 7qj/WsjTVbJmcVfewCHrPSqnI0kBBIZCe/zuf6IWUrVnZ9NA2zsmWLIodz2uFHdh 1voqZiegDfqnc1zqcPGUIWVEX/r87yloqaKHee9570+sB3c4 -----END CERTIFICATE----- # Issuer: O=VeriSign, Inc. OU=Class 3 Public Primary Certification Authority # Subject: O=VeriSign, Inc. OU=Class 3 Public Primary Certification Authority # Label: "Verisign Class 3 Public Primary Certification Authority" # Serial: 149843929435818692848040365716851702463 # MD5 Fingerprint: 10:fc:63:5d:f6:26:3e:0d:f3:25:be:5f:79:cd:67:67 # SHA1 Fingerprint: 74:2c:31:92:e6:07:e4:24:eb:45:49:54:2b:e1:bb:c5:3e:61:74:e2 # SHA256 Fingerprint: e7:68:56:34:ef:ac:f6:9a:ce:93:9a:6b:25:5b:7b:4f:ab:ef:42:93:5b:50:a2:65:ac:b5:cb:60:27:e4:4e:70 -----BEGIN CERTIFICATE----- MIICPDCCAaUCEHC65B0Q2Sk0tjjKewPMur8wDQYJKoZIhvcNAQECBQAwXzELMAkG A1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFz cyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTk2 MDEyOTAwMDAwMFoXDTI4MDgwMTIzNTk1OVowXzELMAkGA1UEBhMCVVMxFzAVBgNV BAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAzIFB1YmxpYyBQcmlt YXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGfMA0GCSqGSIb3DQEBAQUAA4GN ADCBiQKBgQDJXFme8huKARS0EN8EQNvjV69qRUCPhAwL0TPZ2RHP7gJYHyX3KqhE BarsAx94f56TuZoAqiN91qyFomNFx3InzPRMxnVx0jnvT0Lwdd8KkMaOIG+YD/is I19wKTakyYbnsZogy1Olhec9vn2a/iRFM9x2Fe0PonFkTGUugWhFpwIDAQABMA0G CSqGSIb3DQEBAgUAA4GBALtMEivPLCYATxQT3ab7/AoRhIzzKBxnki98tsX63/Do lbwdj2wsqFHMc9ikwFPwTtYmwHYBV4GSXiHx0bH/59AhWM1pF+NEHJwZRDmJXNyc AA9WjQKZ7aKQRUzkuxCkPfAyAw7xzvjoyVGM5mKf5p/AfbdynMk2OmufTqj/ZA1k -----END CERTIFICATE----- # Issuer: O=VeriSign, Inc. OU=Class 3 Public Primary Certification Authority - G2/(c) 1998 VeriSign, Inc. - For authorized use only/VeriSign Trust Network # Subject: O=VeriSign, Inc. OU=Class 3 Public Primary Certification Authority - G2/(c) 1998 VeriSign, Inc. - For authorized use only/VeriSign Trust Network # Label: "Verisign Class 3 Public Primary Certification Authority - G2" # Serial: 167285380242319648451154478808036881606 # MD5 Fingerprint: a2:33:9b:4c:74:78:73:d4:6c:e7:c1:f3:8d:cb:5c:e9 # SHA1 Fingerprint: 85:37:1c:a6:e5:50:14:3d:ce:28:03:47:1b:de:3a:09:e8:f8:77:0f # SHA256 Fingerprint: 83:ce:3c:12:29:68:8a:59:3d:48:5f:81:97:3c:0f:91:95:43:1e:da:37:cc:5e:36:43:0e:79:c7:a8:88:63:8b -----BEGIN CERTIFICATE----- MIIDAjCCAmsCEH3Z/gfPqB63EHln+6eJNMYwDQYJKoZIhvcNAQEFBQAwgcExCzAJ BgNVBAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xh c3MgMyBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcy MTowOAYDVQQLEzEoYykgMTk5OCBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3Jp emVkIHVzZSBvbmx5MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMB4X DTk4MDUxODAwMDAwMFoXDTI4MDgwMTIzNTk1OVowgcExCzAJBgNVBAYTAlVTMRcw FQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xhc3MgMyBQdWJsaWMg UHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyMTowOAYDVQQLEzEo YykgMTk5OCBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5 MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMIGfMA0GCSqGSIb3DQEB AQUAA4GNADCBiQKBgQDMXtERXVxp0KvTuWpMmR9ZmDCOFoUgRm1HP9SFIIThbbP4 pO0M8RcPO/mn+SXXwc+EY/J8Y8+iR/LGWzOOZEAEaMGAuWQcRXfH2G71lSk8UOg0 13gfqLptQ5GVj0VXXn7F+8qkBOvqlzdUMG+7AUcyM83cV5tkaWH4mx0ciU9cZwID AQABMA0GCSqGSIb3DQEBBQUAA4GBAFFNzb5cy5gZnBWyATl4Lk0PZ3BwmcYQWpSk U01UbSuvDV1Ai2TT1+7eVmGSX6bEHRBhNtMsJzzoKQm5EWR0zLVznxxIqbxhAe7i F6YM40AIOw7n60RzKprxaZLvcRTDOaxxp5EJb+RxBrO6WVcmeQD2+A2iMzAo1KpY oJ2daZH9 -----END CERTIFICATE----- # Issuer: CN=GlobalSign Root CA O=GlobalSign nv-sa OU=Root CA # Subject: CN=GlobalSign Root CA O=GlobalSign nv-sa OU=Root CA # Label: "GlobalSign Root CA" # Serial: 4835703278459707669005204 # MD5 Fingerprint: 3e:45:52:15:09:51:92:e1:b7:5d:37:9f:b1:87:29:8a # SHA1 Fingerprint: b1:bc:96:8b:d4:f4:9d:62:2a:a8:9a:81:f2:15:01:52:a4:1d:82:9c # SHA256 Fingerprint: eb:d4:10:40:e4:bb:3e:c7:42:c9:e3:81:d3:1e:f2:a4:1a:48:b6:68:5c:96:e7:ce:f3:c1:df:6c:d4:33:1c:99 -----BEGIN CERTIFICATE----- MIIDdTCCAl2gAwIBAgILBAAAAAABFUtaw5QwDQYJKoZIhvcNAQEFBQAwVzELMAkG A1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jv b3QgQ0ExGzAZBgNVBAMTEkdsb2JhbFNpZ24gUm9vdCBDQTAeFw05ODA5MDExMjAw MDBaFw0yODAxMjgxMjAwMDBaMFcxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9i YWxTaWduIG52LXNhMRAwDgYDVQQLEwdSb290IENBMRswGQYDVQQDExJHbG9iYWxT aWduIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDaDuaZ jc6j40+Kfvvxi4Mla+pIH/EqsLmVEQS98GPR4mdmzxzdzxtIK+6NiY6arymAZavp xy0Sy6scTHAHoT0KMM0VjU/43dSMUBUc71DuxC73/OlS8pF94G3VNTCOXkNz8kHp 1Wrjsok6Vjk4bwY8iGlbKk3Fp1S4bInMm/k8yuX9ifUSPJJ4ltbcdG6TRGHRjcdG snUOhugZitVtbNV4FpWi6cgKOOvyJBNPc1STE4U6G7weNLWLBYy5d4ux2x8gkasJ U26Qzns3dLlwR5EiUWMWea6xrkEmCMgZK9FGqkjWZCrXgzT/LCrBbBlDSgeF59N8 9iFo7+ryUp9/k5DPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8E BTADAQH/MB0GA1UdDgQWBBRge2YaRQ2XyolQL30EzTSo//z9SzANBgkqhkiG9w0B AQUFAAOCAQEA1nPnfE920I2/7LqivjTFKDK1fPxsnCwrvQmeU79rXqoRSLblCKOz yj1hTdNGCbM+w6DjY1Ub8rrvrTnhQ7k4o+YviiY776BQVvnGCv04zcQLcFGUl5gE 38NflNUVyRRBnMRddWQVDf9VMOyGj/8N7yy5Y0b2qvzfvGn9LhJIZJrglfCm7ymP AbEVtQwdpf5pLGkkeB6zpxxxYu7KyJesF12KwvhHhm4qxFYxldBniYUr+WymXUad DKqC5JlR3XC321Y9YeRq4VzW9v493kHMB65jUr9TU/Qr6cf9tveCX4XSQRjbgbME HMUfpIBvFSDJ3gyICh3WZlXi/EjJKSZp4A== -----END CERTIFICATE----- # Issuer: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R2 # Subject: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R2 # Label: "GlobalSign Root CA - R2" # Serial: 4835703278459682885658125 # MD5 Fingerprint: 94:14:77:7e:3e:5e:fd:8f:30:bd:41:b0:cf:e7:d0:30 # SHA1 Fingerprint: 75:e0:ab:b6:13:85:12:27:1c:04:f8:5f:dd:de:38:e4:b7:24:2e:fe # SHA256 Fingerprint: ca:42:dd:41:74:5f:d0:b8:1e:b9:02:36:2c:f9:d8:bf:71:9d:a1:bd:1b:1e:fc:94:6f:5b:4c:99:f4:2c:1b:9e -----BEGIN CERTIFICATE----- MIIDujCCAqKgAwIBAgILBAAAAAABD4Ym5g0wDQYJKoZIhvcNAQEFBQAwTDEgMB4G A1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjIxEzARBgNVBAoTCkdsb2JhbFNp Z24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDYxMjE1MDgwMDAwWhcNMjExMjE1 MDgwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMjETMBEG A1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCASIwDQYJKoZI hvcNAQEBBQADggEPADCCAQoCggEBAKbPJA6+Lm8omUVCxKs+IVSbC9N/hHD6ErPL v4dfxn+G07IwXNb9rfF73OX4YJYJkhD10FPe+3t+c4isUoh7SqbKSaZeqKeMWhG8 eoLrvozps6yWJQeXSpkqBy+0Hne/ig+1AnwblrjFuTosvNYSuetZfeLQBoZfXklq tTleiDTsvHgMCJiEbKjNS7SgfQx5TfC4LcshytVsW33hoCmEofnTlEnLJGKRILzd C9XZzPnqJworc5HGnRusyMvo4KD0L5CLTfuwNhv2GXqF4G3yYROIXJ/gkwpRl4pa zq+r1feqCapgvdzZX99yqWATXgAByUr6P6TqBwMhAo6CygPCm48CAwEAAaOBnDCB mTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUm+IH V2ccHsBqBt5ZtJot39wZhi4wNgYDVR0fBC8wLTAroCmgJ4YlaHR0cDovL2NybC5n bG9iYWxzaWduLm5ldC9yb290LXIyLmNybDAfBgNVHSMEGDAWgBSb4gdXZxwewGoG 3lm0mi3f3BmGLjANBgkqhkiG9w0BAQUFAAOCAQEAmYFThxxol4aR7OBKuEQLq4Gs J0/WwbgcQ3izDJr86iw8bmEbTUsp9Z8FHSbBuOmDAGJFtqkIk7mpM0sYmsL4h4hO 291xNBrBVNpGP+DTKqttVCL1OmLNIG+6KYnX3ZHu01yiPqFbQfXf5WRDLenVOavS ot+3i9DAgBkcRcAtjOj4LaR0VknFBbVPFd5uRHg5h6h+u/N5GJG79G+dwfCMNYxd AfvDbbnvRG15RjF+Cv6pgsH/76tuIMRQyV+dTZsXjAzlAcmgQWpzU/qlULRuJQ/7 TBj0/VLZjmmx6BEP3ojY+x1J96relc8geMJgEtslQIxq/H5COEBkEveegeGTLg== -----END CERTIFICATE----- # Issuer: CN=http://www.valicert.com/ O=ValiCert, Inc. OU=ValiCert Class 1 Policy Validation Authority # Subject: CN=http://www.valicert.com/ O=ValiCert, Inc. OU=ValiCert Class 1 Policy Validation Authority # Label: "ValiCert Class 1 VA" # Serial: 1 # MD5 Fingerprint: 65:58:ab:15:ad:57:6c:1e:a8:a7:b5:69:ac:bf:ff:eb # SHA1 Fingerprint: e5:df:74:3c:b6:01:c4:9b:98:43:dc:ab:8c:e8:6a:81:10:9f:e4:8e # SHA256 Fingerprint: f4:c1:49:55:1a:30:13:a3:5b:c7:bf:fe:17:a7:f3:44:9b:c1:ab:5b:5a:0a:e7:4b:06:c2:3b:90:00:4c:01:04 -----BEGIN CERTIFICATE----- MIIC5zCCAlACAQEwDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0 IFZhbGlkYXRpb24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAz BgNVBAsTLFZhbGlDZXJ0IENsYXNzIDEgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9y aXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAeBgkqhkiG 9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMB4XDTk5MDYyNTIyMjM0OFoXDTE5MDYy NTIyMjM0OFowgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRpb24gTmV0d29y azEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENs YXNzIDEgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRw Oi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNl cnQuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDYWYJ6ibiWuqYvaG9Y LqdUHAZu9OqNSLwxlBfw8068srg1knaw0KWlAdcAAxIiGQj4/xEjm84H9b9pGib+ TunRf50sQB1ZaG6m+FiwnRqP0z/x3BkGgagO4DrdyFNFCQbmD3DD+kCmDuJWBQ8Y TfwggtFzVXSNdnKgHZ0dwN0/cQIDAQABMA0GCSqGSIb3DQEBBQUAA4GBAFBoPUn0 LBwGlN+VYH+Wexf+T3GtZMjdd9LvWVXoP+iOBSoh8gfStadS/pyxtuJbdxdA6nLW I8sogTLDAHkY7FkXicnGah5xyf23dKUlRWnFSKsZ4UWKJWsZ7uW7EvV/96aNUcPw nXS3qT6gpf+2SQMT2iLM7XGCK5nPOrf1LXLI -----END CERTIFICATE----- # Issuer: CN=http://www.valicert.com/ O=ValiCert, Inc. OU=ValiCert Class 2 Policy Validation Authority # Subject: CN=http://www.valicert.com/ O=ValiCert, Inc. OU=ValiCert Class 2 Policy Validation Authority # Label: "ValiCert Class 2 VA" # Serial: 1 # MD5 Fingerprint: a9:23:75:9b:ba:49:36:6e:31:c2:db:f2:e7:66:ba:87 # SHA1 Fingerprint: 31:7a:2a:d0:7f:2b:33:5e:f5:a1:c3:4e:4b:57:e8:b7:d8:f1:fc:a6 # SHA256 Fingerprint: 58:d0:17:27:9c:d4:dc:63:ab:dd:b1:96:a6:c9:90:6c:30:c4:e0:87:83:ea:e8:c1:60:99:54:d6:93:55:59:6b -----BEGIN CERTIFICATE----- MIIC5zCCAlACAQEwDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0 IFZhbGlkYXRpb24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAz BgNVBAsTLFZhbGlDZXJ0IENsYXNzIDIgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9y aXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAeBgkqhkiG 9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMB4XDTk5MDYyNjAwMTk1NFoXDTE5MDYy NjAwMTk1NFowgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRpb24gTmV0d29y azEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENs YXNzIDIgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRw Oi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNl cnQuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDOOnHK5avIWZJV16vY dA757tn2VUdZZUcOBVXc65g2PFxTXdMwzzjsvUGJ7SVCCSRrCl6zfN1SLUzm1NZ9 WlmpZdRJEy0kTRxQb7XBhVQ7/nHk01xC+YDgkRoKWzk2Z/M/VXwbP7RfZHM047QS v4dk+NoS/zcnwbNDu+97bi5p9wIDAQABMA0GCSqGSIb3DQEBBQUAA4GBADt/UG9v UJSZSWI4OB9L+KXIPqeCgfYrx+jFzug6EILLGACOTb2oWH+heQC1u+mNr0HZDzTu IYEZoDJJKPTEjlbVUjP9UNV+mWwD5MlM/Mtsq2azSiGM5bUMMj4QssxsodyamEwC W/POuZ6lcg5Ktz885hZo+L7tdEy8W9ViH0Pd -----END CERTIFICATE----- # Issuer: CN=http://www.valicert.com/ O=ValiCert, Inc. OU=ValiCert Class 3 Policy Validation Authority # Subject: CN=http://www.valicert.com/ O=ValiCert, Inc. OU=ValiCert Class 3 Policy Validation Authority # Label: "RSA Root Certificate 1" # Serial: 1 # MD5 Fingerprint: a2:6f:53:b7:ee:40:db:4a:68:e7:fa:18:d9:10:4b:72 # SHA1 Fingerprint: 69:bd:8c:f4:9c:d3:00:fb:59:2e:17:93:ca:55:6a:f3:ec:aa:35:fb # SHA256 Fingerprint: bc:23:f9:8a:31:3c:b9:2d:e3:bb:fc:3a:5a:9f:44:61:ac:39:49:4c:4a:e1:5a:9e:9d:f1:31:e9:9b:73:01:9a -----BEGIN CERTIFICATE----- MIIC5zCCAlACAQEwDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0 IFZhbGlkYXRpb24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAz BgNVBAsTLFZhbGlDZXJ0IENsYXNzIDMgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9y aXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAeBgkqhkiG 9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMB4XDTk5MDYyNjAwMjIzM1oXDTE5MDYy NjAwMjIzM1owgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRpb24gTmV0d29y azEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENs YXNzIDMgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRw Oi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNl cnQuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDjmFGWHOjVsQaBalfD cnWTq8+epvzzFlLWLU2fNUSoLgRNB0mKOCn1dzfnt6td3zZxFJmP3MKS8edgkpfs 2Ejcv8ECIMYkpChMMFp2bbFc893enhBxoYjHW5tBbcqwuI4V7q0zK89HBFx1cQqY JJgpp0lZpd34t0NiYfPT4tBVPwIDAQABMA0GCSqGSIb3DQEBBQUAA4GBAFa7AliE Zwgs3x/be0kz9dNnnfS0ChCzycUs4pJqcXgn8nCDQtM+z6lU9PHYkhaM0QTLS6vJ n0WuPIqpsHEzXcjFV9+vqDWzf4mH6eglkrh/hXqu1rweN1gqZ8mRzyqBPu3GOd/A PhmcGcwTTYJBtYze4D1gCCAPRX5ron+jjBXu -----END CERTIFICATE----- # Issuer: CN=VeriSign Class 3 Public Primary Certification Authority - G3 O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 1999 VeriSign, Inc. - For authorized use only # Subject: CN=VeriSign Class 3 Public Primary Certification Authority - G3 O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 1999 VeriSign, Inc. - For authorized use only # Label: "Verisign Class 3 Public Primary Certification Authority - G3" # Serial: 206684696279472310254277870180966723415 # MD5 Fingerprint: cd:68:b6:a7:c7:c4:ce:75:e0:1d:4f:57:44:61:92:09 # SHA1 Fingerprint: 13:2d:0d:45:53:4b:69:97:cd:b2:d5:c3:39:e2:55:76:60:9b:5c:c6 # SHA256 Fingerprint: eb:04:cf:5e:b1:f3:9a:fa:76:2f:2b:b1:20:f2:96:cb:a5:20:c1:b9:7d:b1:58:95:65:b8:1c:b9:a1:7b:72:44 -----BEGIN CERTIFICATE----- MIIEGjCCAwICEQCbfgZJoz5iudXukEhxKe9XMA0GCSqGSIb3DQEBBQUAMIHKMQsw CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZl cmlTaWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWdu LCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlT aWduIENsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3Jp dHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMIHKMQswCQYD VQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlT aWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJ bmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWdu IENsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkg LSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMu6nFL8eB8aHm8b N3O9+MlrlBIwT/A2R/XQkQr1F8ilYcEWQE37imGQ5XYgwREGfassbqb1EUGO+i2t KmFZpGcmTNDovFJbcCAEWNF6yaRpvIMXZK0Fi7zQWM6NjPXr8EJJC52XJ2cybuGu kxUccLwgTS8Y3pKI6GyFVxEa6X7jJhFUokWWVYPKMIno3Nij7SqAP395ZVc+FSBm CC+Vk7+qRy+oRpfwEuL+wgorUeZ25rdGt+INpsyow0xZVYnm6FNcHOqd8GIWC6fJ Xwzw3sJ2zq/3avL6QaaiMxTJ5Xpj055iN9WFZZ4O5lMkdBteHRJTW8cs54NJOxWu imi5V5cCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAERSWwauSCPc/L8my/uRan2Te 2yFPhpk0djZX3dAVL8WtfxUfN2JzPtTnX84XA9s1+ivbrmAJXx5fj267Cz3qWhMe DGBvtcC1IyIuBwvLqXTLR7sdwdela8wv0kL9Sd2nic9TutoAWii/gt/4uhMdUIaC /Y4wjylGsB49Ndo4YhYYSq3mtlFs3q9i6wHQHiT+eo8SGhJouPtmmRQURVyu565p F4ErWjfJXir0xuKhXFSbplQAz/DxwceYMBo7Nhbbo27q/a2ywtrvAkcTisDxszGt TxzhT5yvDwyd93gN2PQ1VoDat20Xj50egWTh/sVFuq1ruQp6Tk9LhO5L8X3dEQ== -----END CERTIFICATE----- # Issuer: CN=VeriSign Class 4 Public Primary Certification Authority - G3 O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 1999 VeriSign, Inc. - For authorized use only # Subject: CN=VeriSign Class 4 Public Primary Certification Authority - G3 O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 1999 VeriSign, Inc. - For authorized use only # Label: "Verisign Class 4 Public Primary Certification Authority - G3" # Serial: 314531972711909413743075096039378935511 # MD5 Fingerprint: db:c8:f2:27:2e:b1:ea:6a:29:23:5d:fe:56:3e:33:df # SHA1 Fingerprint: c8:ec:8c:87:92:69:cb:4b:ab:39:e9:8d:7e:57:67:f3:14:95:73:9d # SHA256 Fingerprint: e3:89:36:0d:0f:db:ae:b3:d2:50:58:4b:47:30:31:4e:22:2f:39:c1:56:a0:20:14:4e:8d:96:05:61:79:15:06 -----BEGIN CERTIFICATE----- MIIEGjCCAwICEQDsoKeLbnVqAc/EfMwvlF7XMA0GCSqGSIb3DQEBBQUAMIHKMQsw CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZl cmlTaWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWdu LCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlT aWduIENsYXNzIDQgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3Jp dHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMIHKMQswCQYD VQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlT aWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJ bmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWdu IENsYXNzIDQgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkg LSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAK3LpRFpxlmr8Y+1 GQ9Wzsy1HyDkniYlS+BzZYlZ3tCD5PUPtbut8XzoIfzk6AzufEUiGXaStBO3IFsJ +mGuqPKljYXCKtbeZjbSmwL0qJJgfJxptI8kHtCGUvYynEFYHiK9zUVilQhu0Gbd U6LM8BDcVHOLBKFGMzNcF0C5nk3T875Vg+ixiY5afJqWIpA7iCXy0lOIAgwLePLm NxdLMEYH5IBtptiWLugs+BGzOA1mppvqySNb247i8xOOGlktqgLw7KSHZtzBP/XY ufTsgsbSPZUd5cBPhMnZo0QoBmrXRazwa2rvTl/4EYIeOGM0ZlDUPpNz+jDDZq3/ ky2X7wMCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAj/ola09b5KROJ1WrIhVZPMq1 CtRK26vdoV9TxaBXOcLORyu+OshWv8LZJxA6sQU8wHcxuzrTBXttmhwwjIDLk5Mq g6sFUYICABFna/OIYUdfA5PVWw3g8dShMjWFsjrbsIKr0csKvE+MW8VLADsfKoKm fjaF3H48ZwC15DtS4KjrXRX5xm3wrR0OhbepmnMUWluPQSjA1egtTaRezarZ7c7c 2NU8Qh0XwRJdRTjDOPP8hS6DRkiy1yBfkjaP53kPmF6Z6PDQpLv1U70qzlmwr25/ bLvSHgCwIe34QWKCudiyxLtGUPMxxY8BqHTr9Xgn2uf3ZkPznoM+IKrDNWCRzg== -----END CERTIFICATE----- # Issuer: CN=Entrust.net Secure Server Certification Authority O=Entrust.net OU=www.entrust.net/CPS incorp. by ref. (limits liab.)/(c) 1999 Entrust.net Limited # Subject: CN=Entrust.net Secure Server Certification Authority O=Entrust.net OU=www.entrust.net/CPS incorp. by ref. (limits liab.)/(c) 1999 Entrust.net Limited # Label: "Entrust.net Secure Server CA" # Serial: 927650371 # MD5 Fingerprint: df:f2:80:73:cc:f1:e6:61:73:fc:f5:42:e9:c5:7c:ee # SHA1 Fingerprint: 99:a6:9b:e6:1a:fe:88:6b:4d:2b:82:00:7c:b8:54:fc:31:7e:15:39 # SHA256 Fingerprint: 62:f2:40:27:8c:56:4c:4d:d8:bf:7d:9d:4f:6f:36:6e:a8:94:d2:2f:5f:34:d9:89:a9:83:ac:ec:2f:ff:ed:50 -----BEGIN CERTIFICATE----- MIIE2DCCBEGgAwIBAgIEN0rSQzANBgkqhkiG9w0BAQUFADCBwzELMAkGA1UEBhMC VVMxFDASBgNVBAoTC0VudHJ1c3QubmV0MTswOQYDVQQLEzJ3d3cuZW50cnVzdC5u ZXQvQ1BTIGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxpYWIuKTElMCMGA1UECxMc KGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDE6MDgGA1UEAxMxRW50cnVzdC5u ZXQgU2VjdXJlIFNlcnZlciBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw05OTA1 MjUxNjA5NDBaFw0xOTA1MjUxNjM5NDBaMIHDMQswCQYDVQQGEwJVUzEUMBIGA1UE ChMLRW50cnVzdC5uZXQxOzA5BgNVBAsTMnd3dy5lbnRydXN0Lm5ldC9DUFMgaW5j b3JwLiBieSByZWYuIChsaW1pdHMgbGlhYi4pMSUwIwYDVQQLExwoYykgMTk5OSBF bnRydXN0Lm5ldCBMaW1pdGVkMTowOAYDVQQDEzFFbnRydXN0Lm5ldCBTZWN1cmUg U2VydmVyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGdMA0GCSqGSIb3DQEBAQUA A4GLADCBhwKBgQDNKIM0VBuJ8w+vN5Ex/68xYMmo6LIQaO2f55M28Qpku0f1BBc/ I0dNxScZgSYMVHINiC3ZH5oSn7yzcdOAGT9HZnuMNSjSuQrfJNqc1lB5gXpa0zf3 wkrYKZImZNHkmGw6AIr1NJtl+O3jEP/9uElY3KDegjlrgbEWGWG5VLbmQwIBA6OC AdcwggHTMBEGCWCGSAGG+EIBAQQEAwIABzCCARkGA1UdHwSCARAwggEMMIHeoIHb oIHYpIHVMIHSMQswCQYDVQQGEwJVUzEUMBIGA1UEChMLRW50cnVzdC5uZXQxOzA5 BgNVBAsTMnd3dy5lbnRydXN0Lm5ldC9DUFMgaW5jb3JwLiBieSByZWYuIChsaW1p dHMgbGlhYi4pMSUwIwYDVQQLExwoYykgMTk5OSBFbnRydXN0Lm5ldCBMaW1pdGVk MTowOAYDVQQDEzFFbnRydXN0Lm5ldCBTZWN1cmUgU2VydmVyIENlcnRpZmljYXRp b24gQXV0aG9yaXR5MQ0wCwYDVQQDEwRDUkwxMCmgJ6AlhiNodHRwOi8vd3d3LmVu dHJ1c3QubmV0L0NSTC9uZXQxLmNybDArBgNVHRAEJDAigA8xOTk5MDUyNTE2MDk0 MFqBDzIwMTkwNTI1MTYwOTQwWjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAU8Bdi E1U9s/8KAGv7UISX8+1i0BowHQYDVR0OBBYEFPAXYhNVPbP/CgBr+1CEl/PtYtAa MAwGA1UdEwQFMAMBAf8wGQYJKoZIhvZ9B0EABAwwChsEVjQuMAMCBJAwDQYJKoZI hvcNAQEFBQADgYEAkNwwAvpkdMKnCqV8IY00F6j7Rw7/JXyNEwr75Ji174z4xRAN 95K+8cPV1ZVqBLssziY2ZcgxxufuP+NXdYR6Ee9GTxj005i7qIcyunL2POI9n9cd 2cNgQ4xYDiKWL2KjLB+6rQXvqzJ4h6BUcxm1XAX5Uj5tLUUL9wqT6u0G+bI= -----END CERTIFICATE----- # Issuer: CN=Entrust.net Certification Authority (2048) O=Entrust.net OU=www.entrust.net/CPS_2048 incorp. by ref. (limits liab.)/(c) 1999 Entrust.net Limited # Subject: CN=Entrust.net Certification Authority (2048) O=Entrust.net OU=www.entrust.net/CPS_2048 incorp. by ref. (limits liab.)/(c) 1999 Entrust.net Limited # Label: "Entrust.net Premium 2048 Secure Server CA" # Serial: 946059622 # MD5 Fingerprint: ba:21:ea:20:d6:dd:db:8f:c1:57:8b:40:ad:a1:fc:fc # SHA1 Fingerprint: 80:1d:62:d0:7b:44:9d:5c:5c:03:5c:98:ea:61:fa:44:3c:2a:58:fe # SHA256 Fingerprint: d1:c3:39:ea:27:84:eb:87:0f:93:4f:c5:63:4e:4a:a9:ad:55:05:01:64:01:f2:64:65:d3:7a:57:46:63:35:9f -----BEGIN CERTIFICATE----- MIIEXDCCA0SgAwIBAgIEOGO5ZjANBgkqhkiG9w0BAQUFADCBtDEUMBIGA1UEChML RW50cnVzdC5uZXQxQDA+BgNVBAsUN3d3dy5lbnRydXN0Lm5ldC9DUFNfMjA0OCBp bmNvcnAuIGJ5IHJlZi4gKGxpbWl0cyBsaWFiLikxJTAjBgNVBAsTHChjKSAxOTk5 IEVudHJ1c3QubmV0IExpbWl0ZWQxMzAxBgNVBAMTKkVudHJ1c3QubmV0IENlcnRp ZmljYXRpb24gQXV0aG9yaXR5ICgyMDQ4KTAeFw05OTEyMjQxNzUwNTFaFw0xOTEy MjQxODIwNTFaMIG0MRQwEgYDVQQKEwtFbnRydXN0Lm5ldDFAMD4GA1UECxQ3d3d3 LmVudHJ1c3QubmV0L0NQU18yMDQ4IGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxp YWIuKTElMCMGA1UECxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDEzMDEG A1UEAxMqRW50cnVzdC5uZXQgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgKDIwNDgp MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArU1LqRKGsuqjIAcVFmQq K0vRvwtKTY7tgHalZ7d4QMBzQshowNtTK91euHaYNZOLGp18EzoOH1u3Hs/lJBQe sYGpjX24zGtLA/ECDNyrpUAkAH90lKGdCCmziAv1h3edVc3kw37XamSrhRSGlVuX MlBvPci6Zgzj/L24ScF2iUkZ/cCovYmjZy/Gn7xxGWC4LeksyZB2ZnuU4q941mVT XTzWnLLPKQP5L6RQstRIzgUyVYr9smRMDuSYB3Xbf9+5CFVghTAp+XtIpGmG4zU/ HoZdenoVve8AjhUiVBcAkCaTvA5JaJG/+EfTnZVCwQ5N328mz8MYIWJmQ3DW1cAH 4QIDAQABo3QwcjARBglghkgBhvhCAQEEBAMCAAcwHwYDVR0jBBgwFoAUVeSB0RGA vtiJuQijMfmhJAkWuXAwHQYDVR0OBBYEFFXkgdERgL7YibkIozH5oSQJFrlwMB0G CSqGSIb2fQdBAAQQMA4bCFY1LjA6NC4wAwIEkDANBgkqhkiG9w0BAQUFAAOCAQEA WUesIYSKF8mciVMeuoCFGsY8Tj6xnLZ8xpJdGGQC49MGCBFhfGPjK50xA3B20qMo oPS7mmNz7W3lKtvtFKkrxjYR0CvrB4ul2p5cGZ1WEvVUKcgF7bISKo30Axv/55IQ h7A6tcOdBTcSo8f0FbnVpDkWm1M6I5HxqIKiaohowXkCIryqptau37AUX7iH0N18 f3v/rxzP5tsHrV7bhZ3QKw0z2wTR5klAEyt2+z7pnIkPFc4YsIV4IU9rTw76NmfN B/L/CNDi3tm/Kq+4h4YhPATKt5Rof8886ZjXOP/swNlQ8C5LWK5Gb9Auw2DaclVy vUxFnmG6v4SBkgPR0ml8xQ== -----END CERTIFICATE----- # Issuer: CN=Baltimore CyberTrust Root O=Baltimore OU=CyberTrust # Subject: CN=Baltimore CyberTrust Root O=Baltimore OU=CyberTrust # Label: "Baltimore CyberTrust Root" # Serial: 33554617 # MD5 Fingerprint: ac:b6:94:a5:9c:17:e0:d7:91:52:9b:b1:97:06:a6:e4 # SHA1 Fingerprint: d4:de:20:d0:5e:66:fc:53:fe:1a:50:88:2c:78:db:28:52:ca:e4:74 # SHA256 Fingerprint: 16:af:57:a9:f6:76:b0:ab:12:60:95:aa:5e:ba:de:f2:2a:b3:11:19:d6:44:ac:95:cd:4b:93:db:f3:f2:6a:eb -----BEGIN CERTIFICATE----- MIIDdzCCAl+gAwIBAgIEAgAAuTANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJJ RTESMBAGA1UEChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYD VQQDExlCYWx0aW1vcmUgQ3liZXJUcnVzdCBSb290MB4XDTAwMDUxMjE4NDYwMFoX DTI1MDUxMjIzNTkwMFowWjELMAkGA1UEBhMCSUUxEjAQBgNVBAoTCUJhbHRpbW9y ZTETMBEGA1UECxMKQ3liZXJUcnVzdDEiMCAGA1UEAxMZQmFsdGltb3JlIEN5YmVy VHJ1c3QgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKMEuyKr mD1X6CZymrV51Cni4eiVgLGw41uOKymaZN+hXe2wCQVt2yguzmKiYv60iNoS6zjr IZ3AQSsBUnuId9Mcj8e6uYi1agnnc+gRQKfRzMpijS3ljwumUNKoUMMo6vWrJYeK mpYcqWe4PwzV9/lSEy/CG9VwcPCPwBLKBsua4dnKM3p31vjsufFoREJIE9LAwqSu XmD+tqYF/LTdB1kC1FkYmGP1pWPgkAx9XbIGevOF6uvUA65ehD5f/xXtabz5OTZy dc93Uk3zyZAsuT3lySNTPx8kmCFcB5kpvcY67Oduhjprl3RjM71oGDHweI12v/ye jl0qhqdNkNwnGjkCAwEAAaNFMEMwHQYDVR0OBBYEFOWdWTCCR1jMrPoIVDaGezq1 BE3wMBIGA1UdEwEB/wQIMAYBAf8CAQMwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3 DQEBBQUAA4IBAQCFDF2O5G9RaEIFoN27TyclhAO992T9Ldcw46QQF+vaKSm2eT92 9hkTI7gQCvlYpNRhcL0EYWoSihfVCr3FvDB81ukMJY2GQE/szKN+OMY3EU/t3Wgx jkzSswF07r51XgdIGn9w/xZchMB5hbgF/X++ZRGjD8ACtPhSNzkE1akxehi/oCr0 Epn3o0WC4zxe9Z2etciefC7IpJ5OCBRLbf1wbWsaY71k5h+3zvDyny67G7fyUIhz ksLi4xaNmjICq44Y3ekQEe5+NauQrz4wlHrQMz2nZQ/1/I6eYs9HRCwBXbsdtTLS R9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp -----END CERTIFICATE----- # Issuer: CN=Equifax Secure Global eBusiness CA-1 O=Equifax Secure Inc. # Subject: CN=Equifax Secure Global eBusiness CA-1 O=Equifax Secure Inc. # Label: "Equifax Secure Global eBusiness CA" # Serial: 1 # MD5 Fingerprint: 8f:5d:77:06:27:c4:98:3c:5b:93:78:e7:d7:7d:9b:cc # SHA1 Fingerprint: 7e:78:4a:10:1c:82:65:cc:2d:e1:f1:6d:47:b4:40:ca:d9:0a:19:45 # SHA256 Fingerprint: 5f:0b:62:ea:b5:e3:53:ea:65:21:65:16:58:fb:b6:53:59:f4:43:28:0a:4a:fb:d1:04:d7:7d:10:f9:f0:4c:07 -----BEGIN CERTIFICATE----- MIICkDCCAfmgAwIBAgIBATANBgkqhkiG9w0BAQQFADBaMQswCQYDVQQGEwJVUzEc MBoGA1UEChMTRXF1aWZheCBTZWN1cmUgSW5jLjEtMCsGA1UEAxMkRXF1aWZheCBT ZWN1cmUgR2xvYmFsIGVCdXNpbmVzcyBDQS0xMB4XDTk5MDYyMTA0MDAwMFoXDTIw MDYyMTA0MDAwMFowWjELMAkGA1UEBhMCVVMxHDAaBgNVBAoTE0VxdWlmYXggU2Vj dXJlIEluYy4xLTArBgNVBAMTJEVxdWlmYXggU2VjdXJlIEdsb2JhbCBlQnVzaW5l c3MgQ0EtMTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAuucXkAJlsTRVPEnC UdXfp9E3j9HngXNBUmCbnaEXJnitx7HoJpQytd4zjTov2/KaelpzmKNc6fuKcxtc 58O/gGzNqfTWK8D3+ZmqY6KxRwIP1ORROhI8bIpaVIRw28HFkM9yRcuoWcDNM50/ o5brhTMhHD4ePmBudpxnhcXIw2ECAwEAAaNmMGQwEQYJYIZIAYb4QgEBBAQDAgAH MA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUvqigdHJQa0S3ySPY+6j/s1dr aGwwHQYDVR0OBBYEFL6ooHRyUGtEt8kj2Puo/7NXa2hsMA0GCSqGSIb3DQEBBAUA A4GBADDiAVGqx+pf2rnQZQ8w1j7aDRRJbpGTJxQx78T3LUX47Me/okENI7SS+RkA Z70Br83gcfxaz2TE4JaY0KNA4gGK7ycH8WUBikQtBmV1UsCGECAhX2xrD2yuCRyv 8qIYNMR1pHMc8Y3c7635s3a0kr/clRAevsvIO1qEYBlWlKlV -----END CERTIFICATE----- # Issuer: CN=Equifax Secure eBusiness CA-1 O=Equifax Secure Inc. # Subject: CN=Equifax Secure eBusiness CA-1 O=Equifax Secure Inc. # Label: "Equifax Secure eBusiness CA 1" # Serial: 4 # MD5 Fingerprint: 64:9c:ef:2e:44:fc:c6:8f:52:07:d0:51:73:8f:cb:3d # SHA1 Fingerprint: da:40:18:8b:91:89:a3:ed:ee:ae:da:97:fe:2f:9d:f5:b7:d1:8a:41 # SHA256 Fingerprint: cf:56:ff:46:a4:a1:86:10:9d:d9:65:84:b5:ee:b5:8a:51:0c:42:75:b0:e5:f9:4f:40:bb:ae:86:5e:19:f6:73 -----BEGIN CERTIFICATE----- MIICgjCCAeugAwIBAgIBBDANBgkqhkiG9w0BAQQFADBTMQswCQYDVQQGEwJVUzEc MBoGA1UEChMTRXF1aWZheCBTZWN1cmUgSW5jLjEmMCQGA1UEAxMdRXF1aWZheCBT ZWN1cmUgZUJ1c2luZXNzIENBLTEwHhcNOTkwNjIxMDQwMDAwWhcNMjAwNjIxMDQw MDAwWjBTMQswCQYDVQQGEwJVUzEcMBoGA1UEChMTRXF1aWZheCBTZWN1cmUgSW5j LjEmMCQGA1UEAxMdRXF1aWZheCBTZWN1cmUgZUJ1c2luZXNzIENBLTEwgZ8wDQYJ KoZIhvcNAQEBBQADgY0AMIGJAoGBAM4vGbwXt3fek6lfWg0XTzQaDJj0ItlZ1MRo RvC0NcWFAyDGr0WlIVFFQesWWDYyb+JQYmT5/VGcqiTZ9J2DKocKIdMSODRsjQBu WqDZQu4aIZX5UkxVWsUPOE9G+m34LjXWHXzr4vCwdYDIqROsvojvOm6rXyo4YgKw Env+j6YDAgMBAAGjZjBkMBEGCWCGSAGG+EIBAQQEAwIABzAPBgNVHRMBAf8EBTAD AQH/MB8GA1UdIwQYMBaAFEp4MlIR21kWNl7fwRQ2QGpHfEyhMB0GA1UdDgQWBBRK eDJSEdtZFjZe38EUNkBqR3xMoTANBgkqhkiG9w0BAQQFAAOBgQB1W6ibAxHm6VZM zfmpTMANmvPMZWnmJXbMWbfWVMMdzZmsGd20hdXgPfxiIKeES1hl8eL5lSE/9dR+ WB5Hh1Q+WKG1tfgq73HnvMP2sUlG4tega+VWeponmHxGYhTnyfxuAxJ5gDgdSIKN /Bf+KpYrtWKmpj29f5JZzVoqgrI3eQ== -----END CERTIFICATE----- # Issuer: O=Equifax Secure OU=Equifax Secure eBusiness CA-2 # Subject: O=Equifax Secure OU=Equifax Secure eBusiness CA-2 # Label: "Equifax Secure eBusiness CA 2" # Serial: 930140085 # MD5 Fingerprint: aa:bf:bf:64:97:da:98:1d:6f:c6:08:3a:95:70:33:ca # SHA1 Fingerprint: 39:4f:f6:85:0b:06:be:52:e5:18:56:cc:10:e1:80:e8:82:b3:85:cc # SHA256 Fingerprint: 2f:27:4e:48:ab:a4:ac:7b:76:59:33:10:17:75:50:6d:c3:0e:e3:8e:f6:ac:d5:c0:49:32:cf:e0:41:23:42:20 -----BEGIN CERTIFICATE----- MIIDIDCCAomgAwIBAgIEN3DPtTANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQGEwJV UzEXMBUGA1UEChMORXF1aWZheCBTZWN1cmUxJjAkBgNVBAsTHUVxdWlmYXggU2Vj dXJlIGVCdXNpbmVzcyBDQS0yMB4XDTk5MDYyMzEyMTQ0NVoXDTE5MDYyMzEyMTQ0 NVowTjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDkVxdWlmYXggU2VjdXJlMSYwJAYD VQQLEx1FcXVpZmF4IFNlY3VyZSBlQnVzaW5lc3MgQ0EtMjCBnzANBgkqhkiG9w0B AQEFAAOBjQAwgYkCgYEA5Dk5kx5SBhsoNviyoynF7Y6yEb3+6+e0dMKP/wXn2Z0G vxLIPw7y1tEkshHe0XMJitSxLJgJDR5QRrKDpkWNYmi7hRsgcDKqQM2mll/EcTc/ BPO3QSQ5BxoeLmFYoBIL5aXfxavqN3HMHMg3OrmXUqesxWoklE6ce8/AatbfIb0C AwEAAaOCAQkwggEFMHAGA1UdHwRpMGcwZaBjoGGkXzBdMQswCQYDVQQGEwJVUzEX MBUGA1UEChMORXF1aWZheCBTZWN1cmUxJjAkBgNVBAsTHUVxdWlmYXggU2VjdXJl IGVCdXNpbmVzcyBDQS0yMQ0wCwYDVQQDEwRDUkwxMBoGA1UdEAQTMBGBDzIwMTkw NjIzMTIxNDQ1WjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAUUJ4L6q9euSBIplBq y/3YIHqngnYwHQYDVR0OBBYEFFCeC+qvXrkgSKZQasv92CB6p4J2MAwGA1UdEwQF MAMBAf8wGgYJKoZIhvZ9B0EABA0wCxsFVjMuMGMDAgbAMA0GCSqGSIb3DQEBBQUA A4GBAAyGgq3oThr1jokn4jVYPSm0B482UJW/bsGe68SQsoWou7dC4A8HOd/7npCy 0cE+U58DRLB+S/Rv5Hwf5+Kx5Lia78O9zt4LMjTZ3ijtM2vE1Nc9ElirfQkty3D1 E4qUoSek1nDFbZS1yX2doNLGCEnZZpum0/QL3MUmV+GRMOrN -----END CERTIFICATE----- # Issuer: CN=AddTrust Class 1 CA Root O=AddTrust AB OU=AddTrust TTP Network # Subject: CN=AddTrust Class 1 CA Root O=AddTrust AB OU=AddTrust TTP Network # Label: "AddTrust Low-Value Services Root" # Serial: 1 # MD5 Fingerprint: 1e:42:95:02:33:92:6b:b9:5f:c0:7f:da:d6:b2:4b:fc # SHA1 Fingerprint: cc:ab:0e:a0:4c:23:01:d6:69:7b:dd:37:9f:cd:12:eb:24:e3:94:9d # SHA256 Fingerprint: 8c:72:09:27:9a:c0:4e:27:5e:16:d0:7f:d3:b7:75:e8:01:54:b5:96:80:46:e3:1f:52:dd:25:76:63:24:e9:a7 -----BEGIN CERTIFICATE----- MIIEGDCCAwCgAwIBAgIBATANBgkqhkiG9w0BAQUFADBlMQswCQYDVQQGEwJTRTEU MBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3 b3JrMSEwHwYDVQQDExhBZGRUcnVzdCBDbGFzcyAxIENBIFJvb3QwHhcNMDAwNTMw MTAzODMxWhcNMjAwNTMwMTAzODMxWjBlMQswCQYDVQQGEwJTRTEUMBIGA1UEChML QWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3b3JrMSEwHwYD VQQDExhBZGRUcnVzdCBDbGFzcyAxIENBIFJvb3QwggEiMA0GCSqGSIb3DQEBAQUA A4IBDwAwggEKAoIBAQCWltQhSWDia+hBBwzexODcEyPNwTXH+9ZOEQpnXvUGW2ul CDtbKRY654eyNAbFvAWlA3yCyykQruGIgb3WntP+LVbBFc7jJp0VLhD7Bo8wBN6n tGO0/7Gcrjyvd7ZWxbWroulpOj0OM3kyP3CCkplhbY0wCI9xP6ZIVxn4JdxLZlyl dI+Yrsj5wAYi56xz36Uu+1LcsRVlIPo1Zmne3yzxbrww2ywkEtvrNTVokMsAsJch PXQhI2U0K7t4WaPW4XY5mqRJjox0r26kmqPZm9I4XJuiGMx1I4S+6+JNM3GOGvDC +Mcdoq0Dlyz4zyXG9rgkMbFjXZJ/Y/AlyVMuH79NAgMBAAGjgdIwgc8wHQYDVR0O BBYEFJWxtPCUtr3H2tERCSG+wa9J/RB7MAsGA1UdDwQEAwIBBjAPBgNVHRMBAf8E BTADAQH/MIGPBgNVHSMEgYcwgYSAFJWxtPCUtr3H2tERCSG+wa9J/RB7oWmkZzBl MQswCQYDVQQGEwJTRTEUMBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFk ZFRydXN0IFRUUCBOZXR3b3JrMSEwHwYDVQQDExhBZGRUcnVzdCBDbGFzcyAxIENB IFJvb3SCAQEwDQYJKoZIhvcNAQEFBQADggEBACxtZBsfzQ3duQH6lmM0MkhHma6X 7f1yFqZzR1r0693p9db7RcwpiURdv0Y5PejuvE1Uhh4dbOMXJ0PhiVYrqW9yTkkz 43J8KiOavD7/KCrto/8cI7pDVwlnTUtiBi34/2ydYB7YHEt9tTEv2dB8Xfjea4MY eDdXL+gzB2ffHsdrKpV2ro9Xo/D0UrSpUwjP4E/TelOL/bscVjby/rK25Xa71SJl pz/+0WatC7xrmYbvP33zGDLKe8bjq2RGlfgmadlVg3sslgf/WSxEo8bl6ancoWOA WiFeIc9TVPC6b4nbqKqVz4vjccweGyBECMB6tkD9xOQ14R0WHNC8K47Wcdk= -----END CERTIFICATE----- # Issuer: CN=AddTrust External CA Root O=AddTrust AB OU=AddTrust External TTP Network # Subject: CN=AddTrust External CA Root O=AddTrust AB OU=AddTrust External TTP Network # Label: "AddTrust External Root" # Serial: 1 # MD5 Fingerprint: 1d:35:54:04:85:78:b0:3f:42:42:4d:bf:20:73:0a:3f # SHA1 Fingerprint: 02:fa:f3:e2:91:43:54:68:60:78:57:69:4d:f5:e4:5b:68:85:18:68 # SHA256 Fingerprint: 68:7f:a4:51:38:22:78:ff:f0:c8:b1:1f:8d:43:d5:76:67:1c:6e:b2:bc:ea:b4:13:fb:83:d9:65:d0:6d:2f:f2 -----BEGIN CERTIFICATE----- MIIENjCCAx6gAwIBAgIBATANBgkqhkiG9w0BAQUFADBvMQswCQYDVQQGEwJTRTEU MBIGA1UEChMLQWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFkZFRydXN0IEV4dGVybmFs IFRUUCBOZXR3b3JrMSIwIAYDVQQDExlBZGRUcnVzdCBFeHRlcm5hbCBDQSBSb290 MB4XDTAwMDUzMDEwNDgzOFoXDTIwMDUzMDEwNDgzOFowbzELMAkGA1UEBhMCU0Ux FDASBgNVBAoTC0FkZFRydXN0IEFCMSYwJAYDVQQLEx1BZGRUcnVzdCBFeHRlcm5h bCBUVFAgTmV0d29yazEiMCAGA1UEAxMZQWRkVHJ1c3QgRXh0ZXJuYWwgQ0EgUm9v dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALf3GjPm8gAELTngTlvt H7xsD821+iO2zt6bETOXpClMfZOfvUq8k+0DGuOPz+VtUFrWlymUWoCwSXrbLpX9 uMq/NzgtHj6RQa1wVsfwTz/oMp50ysiQVOnGXw94nZpAPA6sYapeFI+eh6FqUNzX mk6vBbOmcZSccbNQYArHE504B4YCqOmoaSYYkKtMsE8jqzpPhNjfzp/haW+710LX a0Tkx63ubUFfclpxCDezeWWkWaCUN/cALw3CknLa0Dhy2xSoRcRdKn23tNbE7qzN E0S3ySvdQwAl+mG5aWpYIxG3pzOPVnVZ9c0p10a3CitlttNCbxWyuHv77+ldU9U0 WicCAwEAAaOB3DCB2TAdBgNVHQ4EFgQUrb2YejS0Jvf6xCZU7wO94CTLVBowCwYD VR0PBAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wgZkGA1UdIwSBkTCBjoAUrb2YejS0 Jvf6xCZU7wO94CTLVBqhc6RxMG8xCzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRU cnVzdCBBQjEmMCQGA1UECxMdQWRkVHJ1c3QgRXh0ZXJuYWwgVFRQIE5ldHdvcmsx IjAgBgNVBAMTGUFkZFRydXN0IEV4dGVybmFsIENBIFJvb3SCAQEwDQYJKoZIhvcN AQEFBQADggEBALCb4IUlwtYj4g+WBpKdQZic2YR5gdkeWxQHIzZlj7DYd7usQWxH YINRsPkyPef89iYTx4AWpb9a/IfPeHmJIZriTAcKhjW88t5RxNKWt9x+Tu5w/Rw5 6wwCURQtjr0W4MHfRnXnJK3s9EK0hZNwEGe6nQY1ShjTK3rMUUKhemPR5ruhxSvC Nr4TDea9Y355e6cJDUCrat2PisP29owaQgVR1EX1n6diIWgVIEM8med8vSTYqZEX c4g/VhsxOBi0cQ+azcgOno4uG+GMmIPLHzHxREzGBHNJdmAPx/i9F4BrLunMTA5a mnkPIAou1Z5jJh5VkpTYghdae9C8x49OhgQ= -----END CERTIFICATE----- # Issuer: CN=AddTrust Public CA Root O=AddTrust AB OU=AddTrust TTP Network # Subject: CN=AddTrust Public CA Root O=AddTrust AB OU=AddTrust TTP Network # Label: "AddTrust Public Services Root" # Serial: 1 # MD5 Fingerprint: c1:62:3e:23:c5:82:73:9c:03:59:4b:2b:e9:77:49:7f # SHA1 Fingerprint: 2a:b6:28:48:5e:78:fb:f3:ad:9e:79:10:dd:6b:df:99:72:2c:96:e5 # SHA256 Fingerprint: 07:91:ca:07:49:b2:07:82:aa:d3:c7:d7:bd:0c:df:c9:48:58:35:84:3e:b2:d7:99:60:09:ce:43:ab:6c:69:27 -----BEGIN CERTIFICATE----- MIIEFTCCAv2gAwIBAgIBATANBgkqhkiG9w0BAQUFADBkMQswCQYDVQQGEwJTRTEU MBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3 b3JrMSAwHgYDVQQDExdBZGRUcnVzdCBQdWJsaWMgQ0EgUm9vdDAeFw0wMDA1MzAx MDQxNTBaFw0yMDA1MzAxMDQxNTBaMGQxCzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtB ZGRUcnVzdCBBQjEdMBsGA1UECxMUQWRkVHJ1c3QgVFRQIE5ldHdvcmsxIDAeBgNV BAMTF0FkZFRydXN0IFB1YmxpYyBDQSBSb290MIIBIjANBgkqhkiG9w0BAQEFAAOC AQ8AMIIBCgKCAQEA6Rowj4OIFMEg2Dybjxt+A3S72mnTRqX4jsIMEZBRpS9mVEBV 6tsfSlbunyNu9DnLoblv8n75XYcmYZ4c+OLspoH4IcUkzBEMP9smcnrHAZcHF/nX GCwwfQ56HmIexkvA/X1id9NEHif2P0tEs7c42TkfYNVRknMDtABp4/MUTu7R3AnP dzRGULD4EfL+OHn3Bzn+UZKXC1sIXzSGAa2Il+tmzV7R/9x98oTaunet3IAIx6eH 1lWfl2royBFkuucZKT8Rs3iQhCBSWxHveNCD9tVIkNAwHM+A+WD+eeSI8t0A65RF 62WUaUC6wNW0uLp9BBGo6zEFlpROWCGOn9Bg/QIDAQABo4HRMIHOMB0GA1UdDgQW BBSBPjfYkrAfd59ctKtzquf2NGAv+jALBgNVHQ8EBAMCAQYwDwYDVR0TAQH/BAUw AwEB/zCBjgYDVR0jBIGGMIGDgBSBPjfYkrAfd59ctKtzquf2NGAv+qFopGYwZDEL MAkGA1UEBhMCU0UxFDASBgNVBAoTC0FkZFRydXN0IEFCMR0wGwYDVQQLExRBZGRU cnVzdCBUVFAgTmV0d29yazEgMB4GA1UEAxMXQWRkVHJ1c3QgUHVibGljIENBIFJv b3SCAQEwDQYJKoZIhvcNAQEFBQADggEBAAP3FUr4JNojVhaTdt02KLmuG7jD8WS6 IBh4lSknVwW8fCr0uVFV2ocC3g8WFzH4qnkuCRO7r7IgGRLlk/lL+YPoRNWyQSW/ iHVv/xD8SlTQX/D67zZzfRs2RcYhbbQVuE7PnFylPVoAjgbjPGsye/Kf8Lb93/Ao GEjwxrzQvzSAlsJKsW2Ox5BF3i9nrEUEo3rcVZLJR2bYGozH7ZxOmuASu7VqTITh 4SINhwBk/ox9Yjllpu9CtoAlEmEBqCQTcAARJl/6NVDFSMwGR+gn2HCNX2TmoUQm XiLsks3/QppEIW1cxeMiHV9HEufOX1362KqxMy3ZdvJOOjMMK7MtkAY= -----END CERTIFICATE----- # Issuer: CN=AddTrust Qualified CA Root O=AddTrust AB OU=AddTrust TTP Network # Subject: CN=AddTrust Qualified CA Root O=AddTrust AB OU=AddTrust TTP Network # Label: "AddTrust Qualified Certificates Root" # Serial: 1 # MD5 Fingerprint: 27:ec:39:47:cd:da:5a:af:e2:9a:01:65:21:a9:4c:bb # SHA1 Fingerprint: 4d:23:78:ec:91:95:39:b5:00:7f:75:8f:03:3b:21:1e:c5:4d:8b:cf # SHA256 Fingerprint: 80:95:21:08:05:db:4b:bc:35:5e:44:28:d8:fd:6e:c2:cd:e3:ab:5f:b9:7a:99:42:98:8e:b8:f4:dc:d0:60:16 -----BEGIN CERTIFICATE----- MIIEHjCCAwagAwIBAgIBATANBgkqhkiG9w0BAQUFADBnMQswCQYDVQQGEwJTRTEU MBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3 b3JrMSMwIQYDVQQDExpBZGRUcnVzdCBRdWFsaWZpZWQgQ0EgUm9vdDAeFw0wMDA1 MzAxMDQ0NTBaFw0yMDA1MzAxMDQ0NTBaMGcxCzAJBgNVBAYTAlNFMRQwEgYDVQQK EwtBZGRUcnVzdCBBQjEdMBsGA1UECxMUQWRkVHJ1c3QgVFRQIE5ldHdvcmsxIzAh BgNVBAMTGkFkZFRydXN0IFF1YWxpZmllZCBDQSBSb290MIIBIjANBgkqhkiG9w0B AQEFAAOCAQ8AMIIBCgKCAQEA5B6a/twJWoekn0e+EV+vhDTbYjx5eLfpMLXsDBwq xBb/4Oxx64r1EW7tTw2R0hIYLUkVAcKkIhPHEWT/IhKauY5cLwjPcWqzZwFZ8V1G 87B4pfYOQnrjfxvM0PC3KP0q6p6zsLkEqv32x7SxuCqg+1jxGaBvcCV+PmlKfw8i 2O+tCBGaKZnhqkRFmhJePp1tUvznoD1oL/BLcHwTOK28FSXx1s6rosAx1i+f4P8U WfyEk9mHfExUE+uf0S0R+Bg6Ot4l2ffTQO2kBhLEO+GRwVY18BTcZTYJbqukB8c1 0cIDMzZbdSZtQvESa0NvS3GU+jQd7RNuyoB/mC9suWXY6QIDAQABo4HUMIHRMB0G A1UdDgQWBBQ5lYtii1zJ1IC6WA+XPxUIQ8yYpzALBgNVHQ8EBAMCAQYwDwYDVR0T AQH/BAUwAwEB/zCBkQYDVR0jBIGJMIGGgBQ5lYtii1zJ1IC6WA+XPxUIQ8yYp6Fr pGkwZzELMAkGA1UEBhMCU0UxFDASBgNVBAoTC0FkZFRydXN0IEFCMR0wGwYDVQQL ExRBZGRUcnVzdCBUVFAgTmV0d29yazEjMCEGA1UEAxMaQWRkVHJ1c3QgUXVhbGlm aWVkIENBIFJvb3SCAQEwDQYJKoZIhvcNAQEFBQADggEBABmrder4i2VhlRO6aQTv hsoToMeqT2QbPxj2qC0sVY8FtzDqQmodwCVRLae/DLPt7wh/bDxGGuoYQ992zPlm hpwsaPXpF/gxsxjE1kh9I0xowX67ARRvxdlu3rsEQmr49lx95dr6h+sNNVJn0J6X dgWTP5XHAeZpVTh/EGGZyeNfpso+gmNIquIISD6q8rKFYqa0p9m9N5xotS1WfbC3 P6CxB9bpT9zeRXEwMn8bLgn5v1Kh7sKAPgZcLlVAwRv1cEWw3F369nJad9Jjzc9Y iQBCYz95OdBEsIJuQRno3eDBiFrRHnGTHyQwdOUeqN48Jzd/g66ed8/wMLH/S5no xqE= -----END CERTIFICATE----- # Issuer: CN=Entrust Root Certification Authority O=Entrust, Inc. OU=www.entrust.net/CPS is incorporated by reference/(c) 2006 Entrust, Inc. # Subject: CN=Entrust Root Certification Authority O=Entrust, Inc. OU=www.entrust.net/CPS is incorporated by reference/(c) 2006 Entrust, Inc. # Label: "Entrust Root Certification Authority" # Serial: 1164660820 # MD5 Fingerprint: d6:a5:c3:ed:5d:dd:3e:00:c1:3d:87:92:1f:1d:3f:e4 # SHA1 Fingerprint: b3:1e:b1:b7:40:e3:6c:84:02:da:dc:37:d4:4d:f5:d4:67:49:52:f9 # SHA256 Fingerprint: 73:c1:76:43:4f:1b:c6:d5:ad:f4:5b:0e:76:e7:27:28:7c:8d:e5:76:16:c1:e6:e6:14:1a:2b:2c:bc:7d:8e:4c -----BEGIN CERTIFICATE----- MIIEkTCCA3mgAwIBAgIERWtQVDANBgkqhkiG9w0BAQUFADCBsDELMAkGA1UEBhMC VVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xOTA3BgNVBAsTMHd3dy5lbnRydXN0 Lm5ldC9DUFMgaXMgaW5jb3Jwb3JhdGVkIGJ5IHJlZmVyZW5jZTEfMB0GA1UECxMW KGMpIDIwMDYgRW50cnVzdCwgSW5jLjEtMCsGA1UEAxMkRW50cnVzdCBSb290IENl cnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA2MTEyNzIwMjM0MloXDTI2MTEyNzIw NTM0MlowgbAxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMTkw NwYDVQQLEzB3d3cuZW50cnVzdC5uZXQvQ1BTIGlzIGluY29ycG9yYXRlZCBieSBy ZWZlcmVuY2UxHzAdBgNVBAsTFihjKSAyMDA2IEVudHJ1c3QsIEluYy4xLTArBgNV BAMTJEVudHJ1c3QgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASIwDQYJ KoZIhvcNAQEBBQADggEPADCCAQoCggEBALaVtkNC+sZtKm9I35RMOVcF7sN5EUFo Nu3s/poBj6E4KPz3EEZmLk0eGrEaTsbRwJWIsMn/MYszA9u3g3s+IIRe7bJWKKf4 4LlAcTfFy0cOlypowCKVYhXbR9n10Cv/gkvJrT7eTNuQgFA/CYqEAOwwCj0Yzfv9 KlmaI5UXLEWeH25DeW0MXJj+SKfFI0dcXv1u5x609mhF0YaDW6KKjbHjKYD+JXGI rb68j6xSlkuqUY3kEzEZ6E5Nn9uss2rVvDlUccp6en+Q3X0dgNmBu1kmwhH+5pPi 94DkZfs0Nw4pgHBNrziGLp5/V6+eF67rHMsoIV+2HNjnogQi+dPa2MsCAwEAAaOB sDCBrTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zArBgNVHRAEJDAi gA8yMDA2MTEyNzIwMjM0MlqBDzIwMjYxMTI3MjA1MzQyWjAfBgNVHSMEGDAWgBRo kORnpKZTgMeGZqTx90tD+4S9bTAdBgNVHQ4EFgQUaJDkZ6SmU4DHhmak8fdLQ/uE vW0wHQYJKoZIhvZ9B0EABBAwDhsIVjcuMTo0LjADAgSQMA0GCSqGSIb3DQEBBQUA A4IBAQCT1DCw1wMgKtD5Y+iRDAUgqV8ZyntyTtSx29CW+1RaGSwMCPeyvIWonX9t O1KzKtvn1ISMY/YPyyYBkVBs9F8U4pN0wBOeMDpQ47RgxRzwIkSNcUesyBrJ6Zua AGAT/3B+XxFNSRuzFVJ7yVTav52Vr2ua2J7p8eRDjeIRRDq/r72DQnNSi6q7pynP 9WQcCk3RvKqsnyrQ/39/2n3qse0wJcGE2jTSW3iDVuycNsMm4hH2Z0kdkquM++v/ eu6FSqdQgPCnXEqULl8FmTxSQeDNtGPPAUO6nIPcj2A781q0tHuu2guQOHXvgR1m 0vdXcDazv/wor3ElhVsT/h5/WrQ8 -----END CERTIFICATE----- # Issuer: CN=GeoTrust Global CA O=GeoTrust Inc. # Subject: CN=GeoTrust Global CA O=GeoTrust Inc. # Label: "GeoTrust Global CA" # Serial: 144470 # MD5 Fingerprint: f7:75:ab:29:fb:51:4e:b7:77:5e:ff:05:3c:99:8e:f5 # SHA1 Fingerprint: de:28:f4:a4:ff:e5:b9:2f:a3:c5:03:d1:a3:49:a7:f9:96:2a:82:12 # SHA256 Fingerprint: ff:85:6a:2d:25:1d:cd:88:d3:66:56:f4:50:12:67:98:cf:ab:aa:de:40:79:9c:72:2d:e4:d2:b5:db:36:a7:3a -----BEGIN CERTIFICATE----- MIIDVDCCAjygAwIBAgIDAjRWMA0GCSqGSIb3DQEBBQUAMEIxCzAJBgNVBAYTAlVT MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i YWwgQ0EwHhcNMDIwNTIxMDQwMDAwWhcNMjIwNTIxMDQwMDAwWjBCMQswCQYDVQQG EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEbMBkGA1UEAxMSR2VvVHJ1c3Qg R2xvYmFsIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2swYYzD9 9BcjGlZ+W988bDjkcbd4kdS8odhM+KhDtgPpTSEHCIjaWC9mOSm9BXiLnTjoBbdq fnGk5sRgprDvgOSJKA+eJdbtg/OtppHHmMlCGDUUna2YRpIuT8rxh0PBFpVXLVDv iS2Aelet8u5fa9IAjbkU+BQVNdnARqN7csiRv8lVK83Qlz6cJmTM386DGXHKTubU 1XupGc1V3sjs0l44U+VcT4wt/lAjNvxm5suOpDkZALeVAjmRCw7+OC7RHQWa9k0+ bw8HHa8sHo9gOeL6NlMTOdReJivbPagUvTLrGAMoUgRx5aszPeE4uwc2hGKceeoW MPRfwCvocWvk+QIDAQABo1MwUTAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTA ephojYn7qwVkDBF9qn1luMrMTjAfBgNVHSMEGDAWgBTAephojYn7qwVkDBF9qn1l uMrMTjANBgkqhkiG9w0BAQUFAAOCAQEANeMpauUvXVSOKVCUn5kaFOSPeCpilKIn Z57QzxpeR+nBsqTP3UEaBU6bS+5Kb1VSsyShNwrrZHYqLizz/Tt1kL/6cdjHPTfS tQWVYrmm3ok9Nns4d0iXrKYgjy6myQzCsplFAMfOEVEiIuCl6rYVSAlk6l5PdPcF PseKUgzbFbS9bZvlxrFUaKnjaZC2mqUPuLk/IH2uSrW4nOQdtqvmlKXBx4Ot2/Un hw4EbNX/3aBd7YdStysVAq45pmp06drE57xNNB6pXE0zX5IJL4hmXXeXxx12E6nV 5fEWCRE11azbJHFwLJhWC9kXtNHjUStedejV0NxPNO3CBWaAocvmMw== -----END CERTIFICATE----- # Issuer: CN=GeoTrust Global CA 2 O=GeoTrust Inc. # Subject: CN=GeoTrust Global CA 2 O=GeoTrust Inc. # Label: "GeoTrust Global CA 2" # Serial: 1 # MD5 Fingerprint: 0e:40:a7:6c:de:03:5d:8f:d1:0f:e4:d1:8d:f9:6c:a9 # SHA1 Fingerprint: a9:e9:78:08:14:37:58:88:f2:05:19:b0:6d:2b:0d:2b:60:16:90:7d # SHA256 Fingerprint: ca:2d:82:a0:86:77:07:2f:8a:b6:76:4f:f0:35:67:6c:fe:3e:5e:32:5e:01:21:72:df:3f:92:09:6d:b7:9b:85 -----BEGIN CERTIFICATE----- MIIDZjCCAk6gAwIBAgIBATANBgkqhkiG9w0BAQUFADBEMQswCQYDVQQGEwJVUzEW MBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEdMBsGA1UEAxMUR2VvVHJ1c3QgR2xvYmFs IENBIDIwHhcNMDQwMzA0MDUwMDAwWhcNMTkwMzA0MDUwMDAwWjBEMQswCQYDVQQG EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEdMBsGA1UEAxMUR2VvVHJ1c3Qg R2xvYmFsIENBIDIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDvPE1A PRDfO1MA4Wf+lGAVPoWI8YkNkMgoI5kF6CsgncbzYEbYwbLVjDHZ3CB5JIG/NTL8 Y2nbsSpr7iFY8gjpeMtvy/wWUsiRxP89c96xPqfCfWbB9X5SJBri1WeR0IIQ13hL TytCOb1kLUCgsBDTOEhGiKEMuzozKmKY+wCdE1l/bztyqu6mD4b5BWHqZ38MN5aL 5mkWRxHCJ1kDs6ZgwiFAVvqgx306E+PsV8ez1q6diYD3Aecs9pYrEw15LNnA5IZ7 S4wMcoKK+xfNAGw6EzywhIdLFnopsk/bHdQL82Y3vdj2V7teJHq4PIu5+pIaGoSe 2HSPqht/XvT+RSIhAgMBAAGjYzBhMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYE FHE4NvICMVNHK266ZUapEBVYIAUJMB8GA1UdIwQYMBaAFHE4NvICMVNHK266ZUap EBVYIAUJMA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQUFAAOCAQEAA/e1K6td EPx7srJerJsOflN4WT5CBP51o62sgU7XAotexC3IUnbHLB/8gTKY0UvGkpMzNTEv /NgdRN3ggX+d6YvhZJFiCzkIjKx0nVnZellSlxG5FntvRdOW2TF9AjYPnDtuzywN A0ZF66D0f0hExghAzN4bcLUprbqLOzRldRtxIR0sFAqwlpW41uryZfspuk/qkZN0 abby/+Ea0AzRdoXLiiW9l14sbxWZJue2Kf8i7MkCx1YAzUm5s2x7UwQa4qjJqhIF I8LO57sEAszAR6LkxCkvW0VXiVHuPOtSCP8HNR6fNWpHSlaY0VqFH4z1Ir+rzoPz 4iIprn2DQKi6bA== -----END CERTIFICATE----- # Issuer: CN=GeoTrust Universal CA O=GeoTrust Inc. # Subject: CN=GeoTrust Universal CA O=GeoTrust Inc. # Label: "GeoTrust Universal CA" # Serial: 1 # MD5 Fingerprint: 92:65:58:8b:a2:1a:31:72:73:68:5c:b4:a5:7a:07:48 # SHA1 Fingerprint: e6:21:f3:35:43:79:05:9a:4b:68:30:9d:8a:2f:74:22:15:87:ec:79 # SHA256 Fingerprint: a0:45:9b:9f:63:b2:25:59:f5:fa:5d:4c:6d:b3:f9:f7:2f:f1:93:42:03:35:78:f0:73:bf:1d:1b:46:cb:b9:12 -----BEGIN CERTIFICATE----- MIIFaDCCA1CgAwIBAgIBATANBgkqhkiG9w0BAQUFADBFMQswCQYDVQQGEwJVUzEW MBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEeMBwGA1UEAxMVR2VvVHJ1c3QgVW5pdmVy c2FsIENBMB4XDTA0MDMwNDA1MDAwMFoXDTI5MDMwNDA1MDAwMFowRTELMAkGA1UE BhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xHjAcBgNVBAMTFUdlb1RydXN0 IFVuaXZlcnNhbCBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAKYV VaCjxuAfjJ0hUNfBvitbtaSeodlyWL0AG0y/YckUHUWCq8YdgNY96xCcOq9tJPi8 cQGeBvV8Xx7BDlXKg5pZMK4ZyzBIle0iN430SppyZj6tlcDgFgDgEB8rMQ7XlFTT QjOgNB0eRXbdT8oYN+yFFXoZCPzVx5zw8qkuEKmS5j1YPakWaDwvdSEYfyh3peFh F7em6fgemdtzbvQKoiFs7tqqhZJmr/Z6a4LauiIINQ/PQvE1+mrufislzDoR5G2v c7J2Ha3QsnhnGqQ5HFELZ1aD/ThdDc7d8Lsrlh/eezJS/R27tQahsiFepdaVaH/w mZ7cRQg+59IJDTWU3YBOU5fXtQlEIGQWFwMCTFMNaN7VqnJNk22CDtucvc+081xd VHppCZbW2xHBjXWotM85yM48vCR85mLK4b19p71XZQvk/iXttmkQ3CgaRr0BHdCX teGYO8A3ZNY9lO4L4fUorgtWv3GLIylBjobFS1J72HGrH4oVpjuDWtdYAVHGTEHZ f9hBZ3KiKN9gg6meyHv8U3NyWfWTehd2Ds735VzZC1U0oqpbtWpU5xPKV+yXbfRe Bi9Fi1jUIxaS5BZuKGNZMN9QAZxjiRqf2xeUgnA3wySemkfWWspOqGmJch+RbNt+ nhutxx9z3SxPGWX9f5NAEC7S8O08ni4oPmkmM8V7AgMBAAGjYzBhMA8GA1UdEwEB /wQFMAMBAf8wHQYDVR0OBBYEFNq7LqqwDLiIJlF0XG0D08DYj3rWMB8GA1UdIwQY MBaAFNq7LqqwDLiIJlF0XG0D08DYj3rWMA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG 9w0BAQUFAAOCAgEAMXjmx7XfuJRAyXHEqDXsRh3ChfMoWIawC/yOsjmPRFWrZIRc aanQmjg8+uUfNeVE44B5lGiku8SfPeE0zTBGi1QrlaXv9z+ZhP015s8xxtxqv6fX IwjhmF7DWgh2qaavdy+3YL1ERmrvl/9zlcGO6JP7/TG37FcREUWbMPEaiDnBTzyn ANXH/KttgCJwpQzgXQQpAvvLoJHRfNbDflDVnVi+QTjruXU8FdmbyUqDWcDaU/0z uzYYm4UPFd3uLax2k7nZAY1IEKj79TiG8dsKxr2EoyNB3tZ3b4XUhRxQ4K5RirqN Pnbiucon8l+f725ZDQbYKxek0nxru18UGkiPGkzns0ccjkxFKyDuSN/n3QmOGKja QI2SJhFTYXNd673nxE0pN2HrrDktZy4W1vUAg4WhzH92xH3kt0tm7wNFYGm2DFKW koRepqO1pD4r2czYG0eq8kTaT/kD6PAUyz/zg97QwVTjt+gKN02LIFkDMBmhLMi9 ER/frslKxfMnZmaGrGiR/9nmUxwPi1xpZQomyB40w11Re9epnAahNt3ViZS82eQt DF4JbAiXfKM9fJP/P6EUp8+1Xevb2xzEdt+Iub1FBZUbrvxGakyvSOPOrg/Sfuvm bJxPgWp6ZKy7PtXny3YuxadIwVyQD8vIP/rmMuGNG2+k5o7Y+SlIis5z/iw= -----END CERTIFICATE----- # Issuer: CN=GeoTrust Universal CA 2 O=GeoTrust Inc. # Subject: CN=GeoTrust Universal CA 2 O=GeoTrust Inc. # Label: "GeoTrust Universal CA 2" # Serial: 1 # MD5 Fingerprint: 34:fc:b8:d0:36:db:9e:14:b3:c2:f2:db:8f:e4:94:c7 # SHA1 Fingerprint: 37:9a:19:7b:41:85:45:35:0c:a6:03:69:f3:3c:2e:af:47:4f:20:79 # SHA256 Fingerprint: a0:23:4f:3b:c8:52:7c:a5:62:8e:ec:81:ad:5d:69:89:5d:a5:68:0d:c9:1d:1c:b8:47:7f:33:f8:78:b9:5b:0b -----BEGIN CERTIFICATE----- MIIFbDCCA1SgAwIBAgIBATANBgkqhkiG9w0BAQUFADBHMQswCQYDVQQGEwJVUzEW MBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEgMB4GA1UEAxMXR2VvVHJ1c3QgVW5pdmVy c2FsIENBIDIwHhcNMDQwMzA0MDUwMDAwWhcNMjkwMzA0MDUwMDAwWjBHMQswCQYD VQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEgMB4GA1UEAxMXR2VvVHJ1 c3QgVW5pdmVyc2FsIENBIDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC AQCzVFLByT7y2dyxUxpZKeexw0Uo5dfR7cXFS6GqdHtXr0om/Nj1XqduGdt0DE81 WzILAePb63p3NeqqWuDW6KFXlPCQo3RWlEQwAx5cTiuFJnSCegx2oG9NzkEtoBUG FF+3Qs17j1hhNNwqCPkuwwGmIkQcTAeC5lvO0Ep8BNMZcyfwqph/Lq9O64ceJHdq XbboW0W63MOhBW9Wjo8QJqVJwy7XQYci4E+GymC16qFjwAGXEHm9ADwSbSsVsaxL se4YuU6W3Nx2/zu+z18DwPw76L5GG//aQMJS9/7jOvdqdzXQ2o3rXhhqMcceujwb KNZrVMaqW9eiLBsZzKIC9ptZvTdrhrVtgrrY6slWvKk2WP0+GfPtDCapkzj4T8Fd IgbQl+rhrcZV4IErKIM6+vR7IVEAvlI4zs1meaj0gVbi0IMJR1FbUGrP20gaXT73 y/Zl92zxlfgCOzJWgjl6W70viRu/obTo/3+NjN8D8WBOWBFM66M/ECuDmgFz2ZRt hAAnZqzwcEAJQpKtT5MNYQlRJNiS1QuUYbKHsu3/mjX/hVTK7URDrBs8FmtISgoc QIgfksILAAX/8sgCSqSqqcyZlpwvWOB94b67B9xfBHJcMTTD7F8t4D1kkCLm0ey4 Lt1ZrtmhN79UNdxzMk+MBB4zsslG8dhcyFVQyWi9qLo2CQIDAQABo2MwYTAPBgNV HRMBAf8EBTADAQH/MB0GA1UdDgQWBBR281Xh+qQ2+/CfXGJx7Tz0RzgQKzAfBgNV HSMEGDAWgBR281Xh+qQ2+/CfXGJx7Tz0RzgQKzAOBgNVHQ8BAf8EBAMCAYYwDQYJ KoZIhvcNAQEFBQADggIBAGbBxiPz2eAubl/oz66wsCVNK/g7WJtAJDday6sWSf+z dXkzoS9tcBc0kf5nfo/sm+VegqlVHy/c1FEHEv6sFj4sNcZj/NwQ6w2jqtB8zNHQ L1EuxBRa3ugZ4T7GzKQp5y6EqgYweHZUcyiYWTjgAA1i00J9IZ+uPTqM1fp3DRgr Fg5fNuH8KrUwJM/gYwx7WBr+mbpCErGR9Hxo4sjoryzqyX6uuyo9DRXcNJW2GHSo ag/HtPQTxORb7QrSpJdMKu0vbBKJPfEncKpqA1Ihn0CoZ1Dy81of398j9tx4TuaY T1U6U+Pv8vSfx3zYWK8pIpe44L2RLrB27FcRz+8pRPPphXpgY+RdM4kX2TGq2tbz GDVyz4crL2MjhF2EjD9XoIj8mZEoJmmZ1I+XRL6O1UixpCgp8RW04eWe3fiPpm8m 1wk8OhwRDqZsN/etRIcsKMfYdIKz0G9KV7s1KSegi+ghp4dkNl3M2Basx7InQJJV OCiNUW7dFGdTbHFcJoRNdVq2fmBWqU2t+5sel/MN2dKXVHfaPRK34B7vCAas+YWH 6aLcr34YEoP9VhdBLtUpgn2Z9DH2canPLAEnpQW5qrJITirvn5NSUZU8UnOOVkwX QMAJKOSLakhT2+zNVVXxxvjpoixMptEmX36vWkzaH6byHCx+rgIW0lbQL1dTR+iS -----END CERTIFICATE----- # Issuer: CN=America Online Root Certification Authority 1 O=America Online Inc. # Subject: CN=America Online Root Certification Authority 1 O=America Online Inc. # Label: "America Online Root Certification Authority 1" # Serial: 1 # MD5 Fingerprint: 14:f1:08:ad:9d:fa:64:e2:89:e7:1c:cf:a8:ad:7d:5e # SHA1 Fingerprint: 39:21:c1:15:c1:5d:0e:ca:5c:cb:5b:c4:f0:7d:21:d8:05:0b:56:6a # SHA256 Fingerprint: 77:40:73:12:c6:3a:15:3d:5b:c0:0b:4e:51:75:9c:df:da:c2:37:dc:2a:33:b6:79:46:e9:8e:9b:fa:68:0a:e3 -----BEGIN CERTIFICATE----- MIIDpDCCAoygAwIBAgIBATANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEc MBoGA1UEChMTQW1lcmljYSBPbmxpbmUgSW5jLjE2MDQGA1UEAxMtQW1lcmljYSBP bmxpbmUgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAxMB4XDTAyMDUyODA2 MDAwMFoXDTM3MTExOTIwNDMwMFowYzELMAkGA1UEBhMCVVMxHDAaBgNVBAoTE0Ft ZXJpY2EgT25saW5lIEluYy4xNjA0BgNVBAMTLUFtZXJpY2EgT25saW5lIFJvb3Qg Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkgMTCCASIwDQYJKoZIhvcNAQEBBQADggEP ADCCAQoCggEBAKgv6KRpBgNHw+kqmP8ZonCaxlCyfqXfaE0bfA+2l2h9LaaLl+lk hsmj76CGv2BlnEtUiMJIxUo5vxTjWVXlGbR0yLQFOVwWpeKVBeASrlmLojNoWBym 1BW32J/X3HGrfpq/m44zDyL9Hy7nBzbvYjnF3cu6JRQj3gzGPTzOggjmZj7aUTsW OqMFf6Dch9Wc/HKpoH145LcxVR5lu9RhsCFg7RAycsWSJR74kEoYeEfffjA3PlAb 2xzTa5qGUwew76wGePiEmf4hjUyAtgyC9mZweRrTT6PP8c9GsEsPPt2IYriMqQko O3rHl+Ee5fSfwMCuJKDIodkP1nsmgmkyPacCAwEAAaNjMGEwDwYDVR0TAQH/BAUw AwEB/zAdBgNVHQ4EFgQUAK3Zo/Z59m50qX8zPYEX10zPM94wHwYDVR0jBBgwFoAU AK3Zo/Z59m50qX8zPYEX10zPM94wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEB BQUAA4IBAQB8itEfGDeC4Liwo+1WlchiYZwFos3CYiZhzRAW18y0ZTTQEYqtqKkF Zu90821fnZmv9ov761KyBZiibyrFVL0lvV+uyIbqRizBs73B6UlwGBaXCBOMIOAb LjpHyx7kADCVW/RFo8AasAFOq73AI25jP4BKxQft3OJvx8Fi8eNy1gTIdGcL+oir oQHIb/AUr9KZzVGTfu0uOMe9zkZQPXLjeSWdm4grECDdpbgyn43gKd8hdIaC2y+C MMbHNYaz+ZZfRtsMRf3zUMNvxsNIrUam4SdHCh0Om7bCd39j8uB9Gr784N/Xx6ds sPmuujz9dLQR6FgNgLzTqIA6me11zEZ7 -----END CERTIFICATE----- # Issuer: CN=America Online Root Certification Authority 2 O=America Online Inc. # Subject: CN=America Online Root Certification Authority 2 O=America Online Inc. # Label: "America Online Root Certification Authority 2" # Serial: 1 # MD5 Fingerprint: d6:ed:3c:ca:e2:66:0f:af:10:43:0d:77:9b:04:09:bf # SHA1 Fingerprint: 85:b5:ff:67:9b:0c:79:96:1f:c8:6e:44:22:00:46:13:db:17:92:84 # SHA256 Fingerprint: 7d:3b:46:5a:60:14:e5:26:c0:af:fc:ee:21:27:d2:31:17:27:ad:81:1c:26:84:2d:00:6a:f3:73:06:cc:80:bd -----BEGIN CERTIFICATE----- MIIFpDCCA4ygAwIBAgIBATANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEc MBoGA1UEChMTQW1lcmljYSBPbmxpbmUgSW5jLjE2MDQGA1UEAxMtQW1lcmljYSBP bmxpbmUgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAyMB4XDTAyMDUyODA2 MDAwMFoXDTM3MDkyOTE0MDgwMFowYzELMAkGA1UEBhMCVVMxHDAaBgNVBAoTE0Ft ZXJpY2EgT25saW5lIEluYy4xNjA0BgNVBAMTLUFtZXJpY2EgT25saW5lIFJvb3Qg Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkgMjCCAiIwDQYJKoZIhvcNAQEBBQADggIP ADCCAgoCggIBAMxBRR3pPU0Q9oyxQcngXssNt79Hc9PwVU3dxgz6sWYFas14tNwC 206B89enfHG8dWOgXeMHDEjsJcQDIPT/DjsS/5uN4cbVG7RtIuOx238hZK+GvFci KtZHgVdEglZTvYYUAQv8f3SkWq7xuhG1m1hagLQ3eAkzfDJHA1zEpYNI9FdWboE2 JxhP7JsowtS013wMPgwr38oE18aO6lhOqKSlGBxsRZijQdEt0sdtjRnxrXm3gT+9 BoInLRBYBbV4Bbkv2wxrkJB+FFk4u5QkE+XRnRTf04JNRvCAOVIyD+OEsnpD8l7e Xz8d3eOyG6ChKiMDbi4BFYdcpnV1x5dhvt6G3NRI270qv0pV2uh9UPu0gBe4lL8B PeraunzgWGcXuVjgiIZGZ2ydEEdYMtA1fHkqkKJaEBEjNa0vzORKW6fIJ/KD3l67 Xnfn6KVuY8INXWHQjNJsWiEOyiijzirplcdIz5ZvHZIlyMbGwcEMBawmxNJ10uEq Z8A9W6Wa6897GqidFEXlD6CaZd4vKL3Ob5Rmg0gp2OpljK+T2WSfVVcmv2/LNzGZ o2C7HK2JNDJiuEMhBnIMoVxtRsX6Kc8w3onccVvdtjc+31D1uAclJuW8tf48ArO3 +L5DwYcRlJ4jbBeKuIonDFRH8KmzwICMoCfrHRnjB453cMor9H124HhnAgMBAAGj YzBhMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFE1FwWg4u3OpaaEg5+31IqEj FNeeMB8GA1UdIwQYMBaAFE1FwWg4u3OpaaEg5+31IqEjFNeeMA4GA1UdDwEB/wQE AwIBhjANBgkqhkiG9w0BAQUFAAOCAgEAZ2sGuV9FOypLM7PmG2tZTiLMubekJcmn xPBUlgtk87FYT15R/LKXeydlwuXK5w0MJXti4/qftIe3RUavg6WXSIylvfEWK5t2 LHo1YGwRgJfMqZJS5ivmae2p+DYtLHe/YUjRYwu5W1LtGLBDQiKmsXeu3mnFzccc obGlHBD7GL4acN3Bkku+KVqdPzW+5X1R+FXgJXUjhx5c3LqdsKyzadsXg8n33gy8 CNyRnqjQ1xU3c6U1uPx+xURABsPr+CKAXEfOAuMRn0T//ZoyzH1kUQ7rVyZ2OuMe IjzCpjbdGe+n/BLzJsBZMYVMnNjP36TMzCmT/5RtdlwTCJfy7aULTd3oyWgOZtMA DjMSW7yV5TKQqLPGbIOtd+6Lfn6xqavT4fG2wLHqiMDn05DpKJKUe2h7lyoKZy2F AjgQ5ANh1NolNscIWC2hp1GvMApJ9aZphwctREZ2jirlmjvXGKL8nDgQzMY70rUX Om/9riW99XJZZLF0KjhfGEzfz3EEWjbUvy+ZnOjZurGV5gJLIaFb1cFPj65pbVPb AZO1XB4Y3WRayhgoPmMEEf0cjQAPuDffZ4qdZqkCapH/E8ovXYO8h5Ns3CRRFgQl Zvqz2cK6Kb6aSDiCmfS/O0oxGfm/jiEzFMpPVF/7zvuPcX/9XhmgD0uRuMRUvAaw RY8mkaKO/qk= -----END CERTIFICATE----- # Issuer: CN=AAA Certificate Services O=Comodo CA Limited # Subject: CN=AAA Certificate Services O=Comodo CA Limited # Label: "Comodo AAA Services root" # Serial: 1 # MD5 Fingerprint: 49:79:04:b0:eb:87:19:ac:47:b0:bc:11:51:9b:74:d0 # SHA1 Fingerprint: d1:eb:23:a4:6d:17:d6:8f:d9:25:64:c2:f1:f1:60:17:64:d8:e3:49 # SHA256 Fingerprint: d7:a7:a0:fb:5d:7e:27:31:d7:71:e9:48:4e:bc:de:f7:1d:5f:0c:3e:0a:29:48:78:2b:c8:3e:e0:ea:69:9e:f4 -----BEGIN CERTIFICATE----- MIIEMjCCAxqgAwIBAgIBATANBgkqhkiG9w0BAQUFADB7MQswCQYDVQQGEwJHQjEb MBkGA1UECAwSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRow GAYDVQQKDBFDb21vZG8gQ0EgTGltaXRlZDEhMB8GA1UEAwwYQUFBIENlcnRpZmlj YXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAwMDAwMFoXDTI4MTIzMTIzNTk1OVowezEL MAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE BwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxITAfBgNVBAMM GEFBQSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCCASIwDQYJKoZIhvcNAQEBBQADggEP ADCCAQoCggEBAL5AnfRu4ep2hxxNRUSOvkbIgwadwSr+GB+O5AL686tdUIoWMQua BtDFcCLNSS1UY8y2bmhGC1Pqy0wkwLxyTurxFa70VJoSCsN6sjNg4tqJVfMiWPPe 3M/vg4aijJRPn2jymJBGhCfHdr/jzDUsi14HZGWCwEiwqJH5YZ92IFCokcdmtet4 YgNW8IoaE+oxox6gmf049vYnMlhvB/VruPsUK6+3qszWY19zjNoFmag4qMsXeDZR rOme9Hg6jc8P2ULimAyrL58OAd7vn5lJ8S3frHRNG5i1R8XlKdH5kBjHYpy+g8cm ez6KJcfA3Z3mNWgQIJ2P2N7Sw4ScDV7oL8kCAwEAAaOBwDCBvTAdBgNVHQ4EFgQU oBEKIz6W8Qfs4q8p74Klf9AwpLQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQF MAMBAf8wewYDVR0fBHQwcjA4oDagNIYyaHR0cDovL2NybC5jb21vZG9jYS5jb20v QUFBQ2VydGlmaWNhdGVTZXJ2aWNlcy5jcmwwNqA0oDKGMGh0dHA6Ly9jcmwuY29t b2RvLm5ldC9BQUFDZXJ0aWZpY2F0ZVNlcnZpY2VzLmNybDANBgkqhkiG9w0BAQUF AAOCAQEACFb8AvCb6P+k+tZ7xkSAzk/ExfYAWMymtrwUSWgEdujm7l3sAg9g1o1Q GE8mTgHj5rCl7r+8dFRBv/38ErjHT1r0iWAFf2C3BUrz9vHCv8S5dIa2LX1rzNLz Rt0vxuBqw8M0Ayx9lt1awg6nCpnBBYurDC/zXDrPbDdVCYfeU0BsWO/8tqtlbgT2 G9w84FoVxp7Z8VlIMCFlA2zs6SFz7JsDoeA3raAVGI/6ugLOpyypEBMs1OUIJqsi l2D4kF501KKaU73yqWjgom7C12yxow+ev+to51byrvLjKzg6CYG1a4XXvi3tPxq3 smPi9WIsgtRqAEFQ8TmDn5XpNpaYbg== -----END CERTIFICATE----- # Issuer: CN=Secure Certificate Services O=Comodo CA Limited # Subject: CN=Secure Certificate Services O=Comodo CA Limited # Label: "Comodo Secure Services root" # Serial: 1 # MD5 Fingerprint: d3:d9:bd:ae:9f:ac:67:24:b3:c8:1b:52:e1:b9:a9:bd # SHA1 Fingerprint: 4a:65:d5:f4:1d:ef:39:b8:b8:90:4a:4a:d3:64:81:33:cf:c7:a1:d1 # SHA256 Fingerprint: bd:81:ce:3b:4f:65:91:d1:1a:67:b5:fc:7a:47:fd:ef:25:52:1b:f9:aa:4e:18:b9:e3:df:2e:34:a7:80:3b:e8 -----BEGIN CERTIFICATE----- MIIEPzCCAyegAwIBAgIBATANBgkqhkiG9w0BAQUFADB+MQswCQYDVQQGEwJHQjEb MBkGA1UECAwSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRow GAYDVQQKDBFDb21vZG8gQ0EgTGltaXRlZDEkMCIGA1UEAwwbU2VjdXJlIENlcnRp ZmljYXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAwMDAwMFoXDTI4MTIzMTIzNTk1OVow fjELMAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G A1UEBwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxJDAiBgNV BAMMG1NlY3VyZSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCCASIwDQYJKoZIhvcNAQEB BQADggEPADCCAQoCggEBAMBxM4KK0HDrc4eCQNUd5MvJDkKQ+d40uaG6EfQlhfPM cm3ye5drswfxdySRXyWP9nQ95IDC+DwN879A6vfIUtFyb+/Iq0G4bi4XKpVpDM3S HpR7LZQdqnXXs5jLrLxkU0C8j6ysNstcrbvd4JQX7NFc0L/vpZXJkMWwrPsbQ996 CF23uPJAGysnnlDOXmWCiIxe004MeuoIkbY2qitC++rCoznl2yY4rYsK7hljxxwk 3wN42ubqwUcaCwtGCd0C/N7Lh1/XMGNooa7cMqG6vv5Eq2i2pRcV/b3Vp6ea5EQz 6YiO/O1R65NxTq0B50SOqy3LqP4BSUjwwN3HaNiS/j0CAwEAAaOBxzCBxDAdBgNV HQ4EFgQUPNiTiMLAggnMAZkGkyDpnnAJY08wDgYDVR0PAQH/BAQDAgEGMA8GA1Ud EwEB/wQFMAMBAf8wgYEGA1UdHwR6MHgwO6A5oDeGNWh0dHA6Ly9jcmwuY29tb2Rv Y2EuY29tL1NlY3VyZUNlcnRpZmljYXRlU2VydmljZXMuY3JsMDmgN6A1hjNodHRw Oi8vY3JsLmNvbW9kby5uZXQvU2VjdXJlQ2VydGlmaWNhdGVTZXJ2aWNlcy5jcmww DQYJKoZIhvcNAQEFBQADggEBAIcBbSMdflsXfcFhMs+P5/OKlFlm4J4oqF7Tt/Q0 5qo5spcWxYJvMqTpjOev/e/C6LlLqqP05tqNZSH7uoDrJiiFGv45jN5bBAS0VPmj Z55B+glSzAVIqMk/IQQezkhr/IXownuvf7fM+F86/TXGDe+X3EyrEeFryzHRbPtI gKvcnDe4IRRLDXE97IMzbtFuMhbsmMcWi1mmNKsFVy2T96oTy9IT4rcuO81rUBcJ aD61JlfutuC23bkpgHl9j6PwpCikFcSF9CfUa7/lXORlAnZUtOM3ZiTTGWHIUhDl izeauan5Hb/qmZJhlv8BzaFfDbxxvA6sCx1HRR3B7Hzs/Sk= -----END CERTIFICATE----- # Issuer: CN=Trusted Certificate Services O=Comodo CA Limited # Subject: CN=Trusted Certificate Services O=Comodo CA Limited # Label: "Comodo Trusted Services root" # Serial: 1 # MD5 Fingerprint: 91:1b:3f:6e:cd:9e:ab:ee:07:fe:1f:71:d2:b3:61:27 # SHA1 Fingerprint: e1:9f:e3:0e:8b:84:60:9e:80:9b:17:0d:72:a8:c5:ba:6e:14:09:bd # SHA256 Fingerprint: 3f:06:e5:56:81:d4:96:f5:be:16:9e:b5:38:9f:9f:2b:8f:f6:1e:17:08:df:68:81:72:48:49:cd:5d:27:cb:69 -----BEGIN CERTIFICATE----- MIIEQzCCAyugAwIBAgIBATANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJHQjEb MBkGA1UECAwSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRow GAYDVQQKDBFDb21vZG8gQ0EgTGltaXRlZDElMCMGA1UEAwwcVHJ1c3RlZCBDZXJ0 aWZpY2F0ZSBTZXJ2aWNlczAeFw0wNDAxMDEwMDAwMDBaFw0yODEyMzEyMzU5NTla MH8xCzAJBgNVBAYTAkdCMRswGQYDVQQIDBJHcmVhdGVyIE1hbmNoZXN0ZXIxEDAO BgNVBAcMB1NhbGZvcmQxGjAYBgNVBAoMEUNvbW9kbyBDQSBMaW1pdGVkMSUwIwYD VQQDDBxUcnVzdGVkIENlcnRpZmljYXRlIFNlcnZpY2VzMIIBIjANBgkqhkiG9w0B AQEFAAOCAQ8AMIIBCgKCAQEA33FvNlhTWvI2VFeAxHQIIO0Yfyod5jWaHiWsnOWW fnJSoBVC21ndZHoa0Lh73TkVvFVIxO06AOoxEbrycXQaZ7jPM8yoMa+j49d/vzMt TGo87IvDktJTdyR0nAducPy9C1t2ul/y/9c3S0pgePfw+spwtOpZqqPOSC+pw7IL fhdyFgymBwwbOM/JYrc/oJOlh0Hyt3BAd9i+FHzjqMB6juljatEPmsbS9Is6FARW 1O24zG71++IsWL1/T2sr92AkWCTOJu80kTrV44HQsvAEAtdbtz6SrGsSivnkBbA7 kUlcsutT6vifR4buv5XAwAaf0lteERv0xwQ1KdJVXOTt6wIDAQABo4HJMIHGMB0G A1UdDgQWBBTFe1i97doladL3WRaoszLAeydb9DAOBgNVHQ8BAf8EBAMCAQYwDwYD VR0TAQH/BAUwAwEB/zCBgwYDVR0fBHwwejA8oDqgOIY2aHR0cDovL2NybC5jb21v ZG9jYS5jb20vVHJ1c3RlZENlcnRpZmljYXRlU2VydmljZXMuY3JsMDqgOKA2hjRo dHRwOi8vY3JsLmNvbW9kby5uZXQvVHJ1c3RlZENlcnRpZmljYXRlU2VydmljZXMu Y3JsMA0GCSqGSIb3DQEBBQUAA4IBAQDIk4E7ibSvuIQSTI3S8NtwuleGFTQQuS9/ HrCoiWChisJ3DFBKmwCL2Iv0QeLQg4pKHBQGsKNoBXAxMKdTmw7pSqBYaWcOrp32 pSxBvzwGa+RZzG0Q8ZZvH9/0BAKkn0U+yNj6NkZEUD+Cl5EfKNsYEYwq5GWDVxIS jBc/lDb+XbDABHcTuPQV1T84zJQ6VdCsmPW6AF/ghhmBeC8owH7TzEIK9a5QoNE+ xqFx7D+gIIxmOom0jtTYsU0lR+4viMi14QVFwL4Ucd56/Y57fU0IlqUSc/Atyjcn dBInTMu2l+nZrghtWjlA3QVHdWpaIbOjGM9O9y5Xt5hwXsjEeLBi -----END CERTIFICATE----- # Issuer: CN=UTN - DATACorp SGC O=The USERTRUST Network OU=http://www.usertrust.com # Subject: CN=UTN - DATACorp SGC O=The USERTRUST Network OU=http://www.usertrust.com # Label: "UTN DATACorp SGC Root CA" # Serial: 91374294542884689855167577680241077609 # MD5 Fingerprint: b3:a5:3e:77:21:6d:ac:4a:c0:c9:fb:d5:41:3d:ca:06 # SHA1 Fingerprint: 58:11:9f:0e:12:82:87:ea:50:fd:d9:87:45:6f:4f:78:dc:fa:d6:d4 # SHA256 Fingerprint: 85:fb:2f:91:dd:12:27:5a:01:45:b6:36:53:4f:84:02:4a:d6:8b:69:b8:ee:88:68:4f:f7:11:37:58:05:b3:48 -----BEGIN CERTIFICATE----- MIIEXjCCA0agAwIBAgIQRL4Mi1AAIbQR0ypoBqmtaTANBgkqhkiG9w0BAQUFADCB kzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2Ug Q2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExho dHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xGzAZBgNVBAMTElVUTiAtIERBVEFDb3Jw IFNHQzAeFw05OTA2MjQxODU3MjFaFw0xOTA2MjQxOTA2MzBaMIGTMQswCQYDVQQG EwJVUzELMAkGA1UECBMCVVQxFzAVBgNVBAcTDlNhbHQgTGFrZSBDaXR5MR4wHAYD VQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxITAfBgNVBAsTGGh0dHA6Ly93d3cu dXNlcnRydXN0LmNvbTEbMBkGA1UEAxMSVVROIC0gREFUQUNvcnAgU0dDMIIBIjAN BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3+5YEKIrblXEjr8uRgnn4AgPLit6 E5Qbvfa2gI5lBZMAHryv4g+OGQ0SR+ysraP6LnD43m77VkIVni5c7yPeIbkFdicZ D0/Ww5y0vpQZY/KmEQrrU0icvvIpOxboGqBMpsn0GFlowHDyUwDAXlCCpVZvNvlK 4ESGoE1O1kduSUrLZ9emxAW5jh70/P/N5zbgnAVssjMiFdC04MwXwLLA9P4yPykq lXvY8qdOD1R8oQ2AswkDwf9c3V6aPryuvEeKaq5xyh+xKrhfQgUL7EYw0XILyulW bfXv33i+Ybqypa4ETLyorGkVl73v67SMvzX41MPRKA5cOp9wGDMgd8SirwIDAQAB o4GrMIGoMAsGA1UdDwQEAwIBxjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRT MtGzz3/64PGgXYVOktKeRR20TzA9BgNVHR8ENjA0MDKgMKAuhixodHRwOi8vY3Js LnVzZXJ0cnVzdC5jb20vVVROLURBVEFDb3JwU0dDLmNybDAqBgNVHSUEIzAhBggr BgEFBQcDAQYKKwYBBAGCNwoDAwYJYIZIAYb4QgQBMA0GCSqGSIb3DQEBBQUAA4IB AQAnNZcAiosovcYzMB4p/OL31ZjUQLtgyr+rFywJNn9Q+kHcrpY6CiM+iVnJowft Gzet/Hy+UUla3joKVAgWRcKZsYfNjGjgaQPpxE6YsjuMFrMOoAyYUJuTqXAJyCyj j98C5OBxOvG0I3KgqgHf35g+FFCgMSa9KOlaMCZ1+XtgHI3zzVAmbQQnmt/VDUVH KWss5nbZqSl9Mt3JNjy9rjXxEZ4du5A/EkdOjtd+D2JzHVImOBwYSf0wdJrE5SIv 2MCN7ZF6TACPcn9d2t0bi0Vr591pl6jFVkwPDPafepE39peC4N1xaf92P2BNPM/3 mfnGV/TJVTl4uix5yaaIK/QI -----END CERTIFICATE----- # Issuer: CN=UTN-USERFirst-Hardware O=The USERTRUST Network OU=http://www.usertrust.com # Subject: CN=UTN-USERFirst-Hardware O=The USERTRUST Network OU=http://www.usertrust.com # Label: "UTN USERFirst Hardware Root CA" # Serial: 91374294542884704022267039221184531197 # MD5 Fingerprint: 4c:56:41:e5:0d:bb:2b:e8:ca:a3:ed:18:08:ad:43:39 # SHA1 Fingerprint: 04:83:ed:33:99:ac:36:08:05:87:22:ed:bc:5e:46:00:e3:be:f9:d7 # SHA256 Fingerprint: 6e:a5:47:41:d0:04:66:7e:ed:1b:48:16:63:4a:a3:a7:9e:6e:4b:96:95:0f:82:79:da:fc:8d:9b:d8:81:21:37 -----BEGIN CERTIFICATE----- MIIEdDCCA1ygAwIBAgIQRL4Mi1AAJLQR0zYq/mUK/TANBgkqhkiG9w0BAQUFADCB lzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2Ug Q2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExho dHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xHzAdBgNVBAMTFlVUTi1VU0VSRmlyc3Qt SGFyZHdhcmUwHhcNOTkwNzA5MTgxMDQyWhcNMTkwNzA5MTgxOTIyWjCBlzELMAkG A1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2UgQ2l0eTEe MBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExhodHRwOi8v d3d3LnVzZXJ0cnVzdC5jb20xHzAdBgNVBAMTFlVUTi1VU0VSRmlyc3QtSGFyZHdh cmUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCx98M4P7Sof885glFn 0G2f0v9Y8+efK+wNiVSZuTiZFvfgIXlIwrthdBKWHTxqctU8EGc6Oe0rE81m65UJ M6Rsl7HoxuzBdXmcRl6Nq9Bq/bkqVRcQVLMZ8Jr28bFdtqdt++BxF2uiiPsA3/4a MXcMmgF6sTLjKwEHOG7DpV4jvEWbe1DByTCP2+UretNb+zNAHqDVmBe8i4fDidNd oI6yqqr2jmmIBsX6iSHzCJ1pLgkzmykNRg+MzEk0sGlRvfkGzWitZky8PqxhvQqI DsjfPe58BEydCl5rkdbux+0ojatNh4lz0G6k0B4WixThdkQDf2Os5M1JnMWS9Ksy oUhbAgMBAAGjgbkwgbYwCwYDVR0PBAQDAgHGMA8GA1UdEwEB/wQFMAMBAf8wHQYD VR0OBBYEFKFyXyYbKJhDlV0HN9WFlp1L0sNFMEQGA1UdHwQ9MDswOaA3oDWGM2h0 dHA6Ly9jcmwudXNlcnRydXN0LmNvbS9VVE4tVVNFUkZpcnN0LUhhcmR3YXJlLmNy bDAxBgNVHSUEKjAoBggrBgEFBQcDAQYIKwYBBQUHAwUGCCsGAQUFBwMGBggrBgEF BQcDBzANBgkqhkiG9w0BAQUFAAOCAQEARxkP3nTGmZev/K0oXnWO6y1n7k57K9cM //bey1WiCuFMVGWTYGufEpytXoMs61quwOQt9ABjHbjAbPLPSbtNk28Gpgoiskli CE7/yMgUsogWXecB5BKV5UU0s4tpvc+0hY91UZ59Ojg6FEgSxvunOxqNDYJAB+gE CJChicsZUN/KHAG8HQQZexB2lzvukJDKxA4fFm517zP4029bHpbj4HR3dHuKom4t 3XbWOTCC8KucUvIqx69JXn7HaOWCgchqJ/kniCrVWFCVH/A7HFe7fRQ5YiuayZSS KqMiDP+JJn1fIytH1xUdqWqeUQ0qUZ6B+dQ7XnASfxAynB67nfhmqA== -----END CERTIFICATE----- # Issuer: CN=XRamp Global Certification Authority O=XRamp Security Services Inc OU=www.xrampsecurity.com # Subject: CN=XRamp Global Certification Authority O=XRamp Security Services Inc OU=www.xrampsecurity.com # Label: "XRamp Global CA Root" # Serial: 107108908803651509692980124233745014957 # MD5 Fingerprint: a1:0b:44:b3:ca:10:d8:00:6e:9d:0f:d8:0f:92:0a:d1 # SHA1 Fingerprint: b8:01:86:d1:eb:9c:86:a5:41:04:cf:30:54:f3:4c:52:b7:e5:58:c6 # SHA256 Fingerprint: ce:cd:dc:90:50:99:d8:da:df:c5:b1:d2:09:b7:37:cb:e2:c1:8c:fb:2c:10:c0:ff:0b:cf:0d:32:86:fc:1a:a2 -----BEGIN CERTIFICATE----- MIIEMDCCAxigAwIBAgIQUJRs7Bjq1ZxN1ZfvdY+grTANBgkqhkiG9w0BAQUFADCB gjELMAkGA1UEBhMCVVMxHjAcBgNVBAsTFXd3dy54cmFtcHNlY3VyaXR5LmNvbTEk MCIGA1UEChMbWFJhbXAgU2VjdXJpdHkgU2VydmljZXMgSW5jMS0wKwYDVQQDEyRY UmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQxMTAxMTcx NDA0WhcNMzUwMTAxMDUzNzE5WjCBgjELMAkGA1UEBhMCVVMxHjAcBgNVBAsTFXd3 dy54cmFtcHNlY3VyaXR5LmNvbTEkMCIGA1UEChMbWFJhbXAgU2VjdXJpdHkgU2Vy dmljZXMgSW5jMS0wKwYDVQQDEyRYUmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBB dXRob3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCYJB69FbS6 38eMpSe2OAtp87ZOqCwuIR1cRN8hXX4jdP5efrRKt6atH67gBhbim1vZZ3RrXYCP KZ2GG9mcDZhtdhAoWORlsH9KmHmf4MMxfoArtYzAQDsRhtDLooY2YKTVMIJt2W7Q DxIEM5dfT2Fa8OT5kavnHTu86M/0ay00fOJIYRyO82FEzG+gSqmUsE3a56k0enI4 qEHMPJQRfevIpoy3hsvKMzvZPTeL+3o+hiznc9cKV6xkmxnr9A8ECIqsAxcZZPRa JSKNNCyy9mgdEm3Tih4U2sSPpuIjhdV6Db1q4Ons7Be7QhtnqiXtRYMh/MHJfNVi PvryxS3T/dRlAgMBAAGjgZ8wgZwwEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0P BAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFMZPoj0GY4QJnM5i5ASs jVy16bYbMDYGA1UdHwQvMC0wK6ApoCeGJWh0dHA6Ly9jcmwueHJhbXBzZWN1cml0 eS5jb20vWEdDQS5jcmwwEAYJKwYBBAGCNxUBBAMCAQEwDQYJKoZIhvcNAQEFBQAD ggEBAJEVOQMBG2f7Shz5CmBbodpNl2L5JFMn14JkTpAuw0kbK5rc/Kh4ZzXxHfAR vbdI4xD2Dd8/0sm2qlWkSLoC295ZLhVbO50WfUfXN+pfTXYSNrsf16GBBEYgoyxt qZ4Bfj8pzgCT3/3JknOJiWSe5yvkHJEs0rnOfc5vMZnT5r7SHpDwCRR5XCOrTdLa IR9NmXmd4c8nnxCbHIgNsIpkQTG4DmyQJKSbXHGPurt+HBvbaoAPIbzp26a3QPSy i6mx5O+aGtA9aZnuqCij4Tyz8LIRnM98QObd50N9otg6tamN8jSZxNQQ4Qb9CYQQ O+7ETPTsJ3xCwnR8gooJybQDJbw= -----END CERTIFICATE----- # Issuer: O=The Go Daddy Group, Inc. OU=Go Daddy Class 2 Certification Authority # Subject: O=The Go Daddy Group, Inc. OU=Go Daddy Class 2 Certification Authority # Label: "Go Daddy Class 2 CA" # Serial: 0 # MD5 Fingerprint: 91:de:06:25:ab:da:fd:32:17:0c:bb:25:17:2a:84:67 # SHA1 Fingerprint: 27:96:ba:e6:3f:18:01:e2:77:26:1b:a0:d7:77:70:02:8f:20:ee:e4 # SHA256 Fingerprint: c3:84:6b:f2:4b:9e:93:ca:64:27:4c:0e:c6:7c:1e:cc:5e:02:4f:fc:ac:d2:d7:40:19:35:0e:81:fe:54:6a:e4 -----BEGIN CERTIFICATE----- MIIEADCCAuigAwIBAgIBADANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEh MB8GA1UEChMYVGhlIEdvIERhZGR5IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBE YWRkeSBDbGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA0MDYyOTE3 MDYyMFoXDTM0MDYyOTE3MDYyMFowYzELMAkGA1UEBhMCVVMxITAfBgNVBAoTGFRo ZSBHbyBEYWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28gRGFkZHkgQ2xhc3Mg MiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASAwDQYJKoZIhvcNAQEBBQADggEN ADCCAQgCggEBAN6d1+pXGEmhW+vXX0iG6r7d/+TvZxz0ZWizV3GgXne77ZtJ6XCA PVYYYwhv2vLM0D9/AlQiVBDYsoHUwHU9S3/Hd8M+eKsaA7Ugay9qK7HFiH7Eux6w wdhFJ2+qN1j3hybX2C32qRe3H3I2TqYXP2WYktsqbl2i/ojgC95/5Y0V4evLOtXi EqITLdiOr18SPaAIBQi2XKVlOARFmR6jYGB0xUGlcmIbYsUfb18aQr4CUWWoriMY avx4A6lNf4DD+qta/KFApMoZFv6yyO9ecw3ud72a9nmYvLEHZ6IVDd2gWMZEewo+ YihfukEHU1jPEX44dMX4/7VpkI+EdOqXG68CAQOjgcAwgb0wHQYDVR0OBBYEFNLE sNKR1EwRcbNhyz2h/t2oatTjMIGNBgNVHSMEgYUwgYKAFNLEsNKR1EwRcbNhyz2h /t2oatTjoWekZTBjMQswCQYDVQQGEwJVUzEhMB8GA1UEChMYVGhlIEdvIERhZGR5 IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBEYWRkeSBDbGFzcyAyIENlcnRpZmlj YXRpb24gQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQAD ggEBADJL87LKPpH8EsahB4yOd6AzBhRckB4Y9wimPQoZ+YeAEW5p5JYXMP80kWNy OO7MHAGjHZQopDH2esRU1/blMVgDoszOYtuURXO1v0XJJLXVggKtI3lpjbi2Tc7P TMozI+gciKqdi0FuFskg5YmezTvacPd+mSYgFFQlq25zheabIZ0KbIIOqPjCDPoQ HmyW74cNxA9hi63ugyuV+I6ShHI56yDqg+2DzZduCLzrTia2cyvk0/ZM/iZx4mER dEr/VxqHD3VILs9RaRegAhJhldXRQLIQTO7ErBBDpqWeCtWVYpoNz4iCxTIM5Cuf ReYNnyicsbkqWletNw+vHX/bvZ8= -----END CERTIFICATE----- # Issuer: O=Starfield Technologies, Inc. OU=Starfield Class 2 Certification Authority # Subject: O=Starfield Technologies, Inc. OU=Starfield Class 2 Certification Authority # Label: "Starfield Class 2 CA" # Serial: 0 # MD5 Fingerprint: 32:4a:4b:bb:c8:63:69:9b:be:74:9a:c6:dd:1d:46:24 # SHA1 Fingerprint: ad:7e:1c:28:b0:64:ef:8f:60:03:40:20:14:c3:d0:e3:37:0e:b5:8a # SHA256 Fingerprint: 14:65:fa:20:53:97:b8:76:fa:a6:f0:a9:95:8e:55:90:e4:0f:cc:7f:aa:4f:b7:c2:c8:67:75:21:fb:5f:b6:58 -----BEGIN CERTIFICATE----- MIIEDzCCAvegAwIBAgIBADANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJVUzEl MCMGA1UEChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMp U3RhcmZpZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQw NjI5MTczOTE2WhcNMzQwNjI5MTczOTE2WjBoMQswCQYDVQQGEwJVUzElMCMGA1UE ChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMpU3RhcmZp ZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggEgMA0GCSqGSIb3 DQEBAQUAA4IBDQAwggEIAoIBAQC3Msj+6XGmBIWtDBFk385N78gDGIc/oav7PKaf 8MOh2tTYbitTkPskpD6E8J7oX+zlJ0T1KKY/e97gKvDIr1MvnsoFAZMej2YcOadN +lq2cwQlZut3f+dZxkqZJRRU6ybH838Z1TBwj6+wRir/resp7defqgSHo9T5iaU0 X9tDkYI22WY8sbi5gv2cOj4QyDvvBmVmepsZGD3/cVE8MC5fvj13c7JdBmzDI1aa K4UmkhynArPkPw2vCHmCuDY96pzTNbO8acr1zJ3o/WSNF4Azbl5KXZnJHoe0nRrA 1W4TNSNe35tfPe/W93bC6j67eA0cQmdrBNj41tpvi/JEoAGrAgEDo4HFMIHCMB0G A1UdDgQWBBS/X7fRzt0fhvRbVazc1xDCDqmI5zCBkgYDVR0jBIGKMIGHgBS/X7fR zt0fhvRbVazc1xDCDqmI56FspGowaDELMAkGA1UEBhMCVVMxJTAjBgNVBAoTHFN0 YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAsTKVN0YXJmaWVsZCBD bGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8w DQYJKoZIhvcNAQEFBQADggEBAAWdP4id0ckaVaGsafPzWdqbAYcaT1epoXkJKtv3 L7IezMdeatiDh6GX70k1PncGQVhiv45YuApnP+yz3SFmH8lU+nLMPUxA2IGvd56D eruix/U0F47ZEUD0/CwqTRV/p2JdLiXTAAsgGh1o+Re49L2L7ShZ3U0WixeDyLJl xy16paq8U4Zt3VekyvggQQto8PT7dL5WXXp59fkdheMtlb71cZBDzI0fmgAKhynp VSJYACPq4xJDKVtHCN2MQWplBqjlIapBtJUhlbl90TSrE9atvNziPTnNvT51cKEY WQPJIrSPnNVeKtelttQKbfi3QBFGmh95DmK/D5fs4C8fF5Q= -----END CERTIFICATE----- # Issuer: CN=StartCom Certification Authority O=StartCom Ltd. OU=Secure Digital Certificate Signing # Subject: CN=StartCom Certification Authority O=StartCom Ltd. OU=Secure Digital Certificate Signing # Label: "StartCom Certification Authority" # Serial: 1 # MD5 Fingerprint: 22:4d:8f:8a:fc:f7:35:c2:bb:57:34:90:7b:8b:22:16 # SHA1 Fingerprint: 3e:2b:f7:f2:03:1b:96:f3:8c:e6:c4:d8:a8:5d:3e:2d:58:47:6a:0f # SHA256 Fingerprint: c7:66:a9:be:f2:d4:07:1c:86:3a:31:aa:49:20:e8:13:b2:d1:98:60:8c:b7:b7:cf:e2:11:43:b8:36:df:09:ea -----BEGIN CERTIFICATE----- MIIHyTCCBbGgAwIBAgIBATANBgkqhkiG9w0BAQUFADB9MQswCQYDVQQGEwJJTDEW MBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwg Q2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMgU3RhcnRDb20gQ2VydGlmaWNh dGlvbiBBdXRob3JpdHkwHhcNMDYwOTE3MTk0NjM2WhcNMzYwOTE3MTk0NjM2WjB9 MQswCQYDVQQGEwJJTDEWMBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMi U2VjdXJlIERpZ2l0YWwgQ2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMgU3Rh cnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUA A4ICDwAwggIKAoICAQDBiNsJvGxGfHiflXu1M5DycmLWwTYgIiRezul38kMKogZk pMyONvg45iPwbm2xPN1yo4UcodM9tDMr0y+v/uqwQVlntsQGfQqedIXWeUyAN3rf OQVSWff0G0ZDpNKFhdLDcfN1YjS6LIp/Ho/u7TTQEceWzVI9ujPW3U3eCztKS5/C Ji/6tRYccjV3yjxd5srhJosaNnZcAdt0FCX+7bWgiA/deMotHweXMAEtcnn6RtYT Kqi5pquDSR3l8u/d5AGOGAqPY1MWhWKpDhk6zLVmpsJrdAfkK+F2PrRt2PZE4XNi HzvEvqBTViVsUQn3qqvKv3b9bZvzndu/PWa8DFaqr5hIlTpL36dYUNk4dalb6kMM Av+Z6+hsTXBbKWWc3apdzK8BMewM69KN6Oqce+Zu9ydmDBpI125C4z/eIT574Q1w +2OqqGwaVLRcJXrJosmLFqa7LH4XXgVNWG4SHQHuEhANxjJ/GP/89PrNbpHoNkm+ Gkhpi8KWTRoSsmkXwQqQ1vp5Iki/untp+HDH+no32NgN0nZPV/+Qt+OR0t3vwmC3 Zzrd/qqc8NSLf3Iizsafl7b4r4qgEKjZ+xjGtrVcUjyJthkqcwEKDwOzEmDyei+B 26Nu/yYwl/WL3YlXtq09s68rxbd2AvCl1iuahhQqcvbjM4xdCUsT37uMdBNSSwID AQABo4ICUjCCAk4wDAYDVR0TBAUwAwEB/zALBgNVHQ8EBAMCAa4wHQYDVR0OBBYE FE4L7xqkQFulF2mHMMo0aEPQQa7yMGQGA1UdHwRdMFswLKAqoCiGJmh0dHA6Ly9j ZXJ0LnN0YXJ0Y29tLm9yZy9zZnNjYS1jcmwuY3JsMCugKaAnhiVodHRwOi8vY3Js LnN0YXJ0Y29tLm9yZy9zZnNjYS1jcmwuY3JsMIIBXQYDVR0gBIIBVDCCAVAwggFM BgsrBgEEAYG1NwEBATCCATswLwYIKwYBBQUHAgEWI2h0dHA6Ly9jZXJ0LnN0YXJ0 Y29tLm9yZy9wb2xpY3kucGRmMDUGCCsGAQUFBwIBFilodHRwOi8vY2VydC5zdGFy dGNvbS5vcmcvaW50ZXJtZWRpYXRlLnBkZjCB0AYIKwYBBQUHAgIwgcMwJxYgU3Rh cnQgQ29tbWVyY2lhbCAoU3RhcnRDb20pIEx0ZC4wAwIBARqBl0xpbWl0ZWQgTGlh YmlsaXR5LCByZWFkIHRoZSBzZWN0aW9uICpMZWdhbCBMaW1pdGF0aW9ucyogb2Yg dGhlIFN0YXJ0Q29tIENlcnRpZmljYXRpb24gQXV0aG9yaXR5IFBvbGljeSBhdmFp bGFibGUgYXQgaHR0cDovL2NlcnQuc3RhcnRjb20ub3JnL3BvbGljeS5wZGYwEQYJ YIZIAYb4QgEBBAQDAgAHMDgGCWCGSAGG+EIBDQQrFilTdGFydENvbSBGcmVlIFNT TCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTANBgkqhkiG9w0BAQUFAAOCAgEAFmyZ 9GYMNPXQhV59CuzaEE44HF7fpiUFS5Eyweg78T3dRAlbB0mKKctmArexmvclmAk8 jhvh3TaHK0u7aNM5Zj2gJsfyOZEdUauCe37Vzlrk4gNXcGmXCPleWKYK34wGmkUW FjgKXlf2Ysd6AgXmvB618p70qSmD+LIU424oh0TDkBreOKk8rENNZEXO3SipXPJz ewT4F+irsfMuXGRuczE6Eri8sxHkfY+BUZo7jYn0TZNmezwD7dOaHZrzZVD1oNB1 ny+v8OqCQ5j4aZyJecRDjkZy42Q2Eq/3JR44iZB3fsNrarnDy0RLrHiQi+fHLB5L EUTINFInzQpdn4XBidUaePKVEFMy3YCEZnXZtWgo+2EuvoSoOMCZEoalHmdkrQYu L6lwhceWD3yJZfWOQ1QOq92lgDmUYMA0yZZwLKMS9R9Ie70cfmu3nZD0Ijuu+Pwq yvqCUqDvr0tVk+vBtfAii6w0TiYiBKGHLHVKt+V9E9e4DGTANtLJL4YSjCMJwRuC O3NJo2pXh5Tl1njFmUNj403gdy3hZZlyaQQaRwnmDwFWJPsfvw55qVguucQJAX6V um0ABj6y6koQOdjQK/W/7HW/lwLFCRsI3FU34oH7N4RDYiDK51ZLZer+bMEkkySh NOsF/5oirpt9P/FlUQqmMGqz9IgcgA38corog14= -----END CERTIFICATE----- # Issuer: CN=DigiCert Assured ID Root CA O=DigiCert Inc OU=www.digicert.com # Subject: CN=DigiCert Assured ID Root CA O=DigiCert Inc OU=www.digicert.com # Label: "DigiCert Assured ID Root CA" # Serial: 17154717934120587862167794914071425081 # MD5 Fingerprint: 87:ce:0b:7b:2a:0e:49:00:e1:58:71:9b:37:a8:93:72 # SHA1 Fingerprint: 05:63:b8:63:0d:62:d7:5a:bb:c8:ab:1e:4b:df:b5:a8:99:b2:4d:43 # SHA256 Fingerprint: 3e:90:99:b5:01:5e:8f:48:6c:00:bc:ea:9d:11:1e:e7:21:fa:ba:35:5a:89:bc:f1:df:69:56:1e:3d:c6:32:5c -----BEGIN CERTIFICATE----- MIIDtzCCAp+gAwIBAgIQDOfg5RfYRv6P5WD8G/AwOTANBgkqhkiG9w0BAQUFADBl MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJv b3QgQ0EwHhcNMDYxMTEwMDAwMDAwWhcNMzExMTEwMDAwMDAwWjBlMQswCQYDVQQG EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNl cnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgQ0EwggEi MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCtDhXO5EOAXLGH87dg+XESpa7c JpSIqvTO9SA5KFhgDPiA2qkVlTJhPLWxKISKityfCgyDF3qPkKyK53lTXDGEKvYP mDI2dsze3Tyoou9q+yHyUmHfnyDXH+Kx2f4YZNISW1/5WBg1vEfNoTb5a3/UsDg+ wRvDjDPZ2C8Y/igPs6eD1sNuRMBhNZYW/lmci3Zt1/GiSw0r/wty2p5g0I6QNcZ4 VYcgoc/lbQrISXwxmDNsIumH0DJaoroTghHtORedmTpyoeb6pNnVFzF1roV9Iq4/ AUaG9ih5yLHa5FcXxH4cDrC0kqZWs72yl+2qp/C3xag/lRbQ/6GW6whfGHdPAgMB AAGjYzBhMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQW BBRF66Kv9JLLgjEtUYunpyGd823IDzAfBgNVHSMEGDAWgBRF66Kv9JLLgjEtUYun pyGd823IDzANBgkqhkiG9w0BAQUFAAOCAQEAog683+Lt8ONyc3pklL/3cmbYMuRC dWKuh+vy1dneVrOfzM4UKLkNl2BcEkxY5NM9g0lFWJc1aRqoR+pWxnmrEthngYTf fwk8lOa4JiwgvT2zKIn3X/8i4peEH+ll74fg38FnSbNd67IJKusm7Xi+fT8r87cm NW1fiQG2SVufAQWbqz0lwcy2f8Lxb4bG+mRo64EtlOtCt/qMHt1i8b5QZ7dsvfPx H2sMNgcWfzd8qVttevESRmCD1ycEvkvOl77DZypoEd+A5wwzZr8TDRRu838fYxAe +o0bJW1sj6W3YQGx0qMmoRBxna3iw/nDmVG3KwcIzi7mULKn+gpFL6Lw8g== -----END CERTIFICATE----- # Issuer: CN=DigiCert Global Root CA O=DigiCert Inc OU=www.digicert.com # Subject: CN=DigiCert Global Root CA O=DigiCert Inc OU=www.digicert.com # Label: "DigiCert Global Root CA" # Serial: 10944719598952040374951832963794454346 # MD5 Fingerprint: 79:e4:a9:84:0d:7d:3a:96:d7:c0:4f:e2:43:4c:89:2e # SHA1 Fingerprint: a8:98:5d:3a:65:e5:e5:c4:b2:d7:d6:6d:40:c6:dd:2f:b1:9c:54:36 # SHA256 Fingerprint: 43:48:a0:e9:44:4c:78:cb:26:5e:05:8d:5e:89:44:b4:d8:4f:96:62:bd:26:db:25:7f:89:34:a4:43:c7:01:61 -----BEGIN CERTIFICATE----- MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBh MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD QTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAwMDAwMDBaMGExCzAJBgNVBAYTAlVT MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkqhkiG 9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsB CSDMAZOnTjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97 nh6Vfe63SKMI2tavegw5BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt 43C/dxC//AH2hdmoRBBYMql1GNXRor5H4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7P T19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y7vrTC0LUq7dBMtoM1O/4 gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQABo2MwYTAO BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbR TLtm8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUw DQYJKoZIhvcNAQEFBQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/Esr hMAtudXH/vTBH1jLuG2cenTnmCmrEbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg 06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIttep3Sp+dWOIrWcBAI+0tKIJF PnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886UAb3LujEV0ls YSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4= -----END CERTIFICATE----- # Issuer: CN=DigiCert High Assurance EV Root CA O=DigiCert Inc OU=www.digicert.com # Subject: CN=DigiCert High Assurance EV Root CA O=DigiCert Inc OU=www.digicert.com # Label: "DigiCert High Assurance EV Root CA" # Serial: 3553400076410547919724730734378100087 # MD5 Fingerprint: d4:74:de:57:5c:39:b2:d3:9c:85:83:c5:c0:65:49:8a # SHA1 Fingerprint: 5f:b7:ee:06:33:e2:59:db:ad:0c:4c:9a:e6:d3:8f:1a:61:c7:dc:25 # SHA256 Fingerprint: 74:31:e5:f4:c3:c1:ce:46:90:77:4f:0b:61:e0:54:40:88:3b:a9:a0:1e:d0:0b:a6:ab:d7:80:6e:d3:b1:18:cf -----BEGIN CERTIFICATE----- MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBs MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j ZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTMxMTExMDAwMDAwMFowbDEL MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3 LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFuY2Ug RVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm +9S75S0tMqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTW PNt0OKRKzE0lgvdKpVMSOO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEM xChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFB Ik5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQNAQTXKFx01p8VdteZOE3 hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUeh10aUAsg EsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQF MAMBAf8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaA FLE+w2kD+L9HAdSYJhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3Nec nzyIZgYIVyHbIUf4KmeqvxgydkAQV8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6z eM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFpmyPInngiK3BD41VHMWEZ71jF hS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkKmNEVX58Svnw2 Yzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep +OkuE6N36B9K -----END CERTIFICATE----- # Issuer: CN=GeoTrust Primary Certification Authority O=GeoTrust Inc. # Subject: CN=GeoTrust Primary Certification Authority O=GeoTrust Inc. # Label: "GeoTrust Primary Certification Authority" # Serial: 32798226551256963324313806436981982369 # MD5 Fingerprint: 02:26:c3:01:5e:08:30:37:43:a9:d0:7d:cf:37:e6:bf # SHA1 Fingerprint: 32:3c:11:8e:1b:f7:b8:b6:52:54:e2:e2:10:0d:d6:02:90:37:f0:96 # SHA256 Fingerprint: 37:d5:10:06:c5:12:ea:ab:62:64:21:f1:ec:8c:92:01:3f:c5:f8:2a:e9:8e:e5:33:eb:46:19:b8:de:b4:d0:6c -----BEGIN CERTIFICATE----- MIIDfDCCAmSgAwIBAgIQGKy1av1pthU6Y2yv2vrEoTANBgkqhkiG9w0BAQUFADBY MQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjExMC8GA1UEAxMo R2VvVHJ1c3QgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjEx MjcwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMFgxCzAJBgNVBAYTAlVTMRYwFAYDVQQK Ew1HZW9UcnVzdCBJbmMuMTEwLwYDVQQDEyhHZW9UcnVzdCBQcmltYXJ5IENlcnRp ZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC AQEAvrgVe//UfH1nrYNke8hCUy3f9oQIIGHWAVlqnEQRr+92/ZV+zmEwu3qDXwK9 AWbK7hWNb6EwnL2hhZ6UOvNWiAAxz9juapYC2e0DjPt1befquFUWBRaa9OBesYjA ZIVcFU2Ix7e64HXprQU9nceJSOC7KMgD4TCTZF5SwFlwIjVXiIrxlQqD17wxcwE0 7e9GceBrAqg1cmuXm2bgyxx5X9gaBGgeRwLmnWDiNpcB3841kt++Z8dtd1k7j53W kBWUvEI0EME5+bEnPn7WinXFsq+W06Lem+SYvn3h6YGttm/81w7a4DSwDRp35+MI mO9Y+pyEtzavwt+s0vQQBnBxNQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4G A1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQULNVQQZcVi/CPNmFbSvtr2ZnJM5IwDQYJ KoZIhvcNAQEFBQADggEBAFpwfyzdtzRP9YZRqSa+S7iq8XEN3GHHoOo0Hnp3DwQ1 6CePbJC/kRYkRj5KTs4rFtULUh38H2eiAkUxT87z+gOneZ1TatnaYzr4gNfTmeGl 4b7UVXGYNTq+k+qurUKykG/g/CFNNWMziUnWm07Kx+dOCQD32sfvmWKZd7aVIl6K oKv0uHiYyjgZmclynnjNS6yvGaBzEi38wkG6gZHaFloxt/m0cYASSJlyc1pZU8Fj UjPtp8nSOQJw+uCxQmYpqptR7TBUIhRf2asdweSU8Pj1K/fqynhG1riR/aYNKxoU AT6A8EKglQdebc3MS6RFjasS6LPeWuWgfOgPIh1a6Vk= -----END CERTIFICATE----- # Issuer: CN=thawte Primary Root CA O=thawte, Inc. OU=Certification Services Division/(c) 2006 thawte, Inc. - For authorized use only # Subject: CN=thawte Primary Root CA O=thawte, Inc. OU=Certification Services Division/(c) 2006 thawte, Inc. - For authorized use only # Label: "thawte Primary Root CA" # Serial: 69529181992039203566298953787712940909 # MD5 Fingerprint: 8c:ca:dc:0b:22:ce:f5:be:72:ac:41:1a:11:a8:d8:12 # SHA1 Fingerprint: 91:c6:d6:ee:3e:8a:c8:63:84:e5:48:c2:99:29:5c:75:6c:81:7b:81 # SHA256 Fingerprint: 8d:72:2f:81:a9:c1:13:c0:79:1d:f1:36:a2:96:6d:b2:6c:95:0a:97:1d:b4:6b:41:99:f4:ea:54:b7:8b:fb:9f -----BEGIN CERTIFICATE----- MIIEIDCCAwigAwIBAgIQNE7VVyDV7exJ9C/ON9srbTANBgkqhkiG9w0BAQUFADCB qTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMf Q2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIw MDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxHzAdBgNV BAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwHhcNMDYxMTE3MDAwMDAwWhcNMzYw NzE2MjM1OTU5WjCBqTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5j LjEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYG A1UECxMvKGMpIDIwMDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNl IG9ubHkxHzAdBgNVBAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwggEiMA0GCSqG SIb3DQEBAQUAA4IBDwAwggEKAoIBAQCsoPD7gFnUnMekz52hWXMJEEUMDSxuaPFs W0hoSVk3/AszGcJ3f8wQLZU0HObrTQmnHNK4yZc2AreJ1CRfBsDMRJSUjQJib+ta 3RGNKJpchJAQeg29dGYvajig4tVUROsdB58Hum/u6f1OCyn1PoSgAfGcq/gcfomk 6KHYcWUNo1F77rzSImANuVud37r8UVsLr5iy6S7pBOhih94ryNdOwUxkHt3Ph1i6 Sk/KaAcdHJ1KxtUvkcx8cXIcxcBn6zL9yZJclNqFwJu/U30rCfSMnZEfl2pSy94J NqR32HuHUETVPm4pafs5SSYeCaWAe0At6+gnhcn+Yf1+5nyXHdWdAgMBAAGjQjBA MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBR7W0XP r87Lev0xkhpqtvNG61dIUDANBgkqhkiG9w0BAQUFAAOCAQEAeRHAS7ORtvzw6WfU DW5FvlXok9LOAz/t2iWwHVfLHjp2oEzsUHboZHIMpKnxuIvW1oeEuzLlQRHAd9mz YJ3rG9XRbkREqaYB7FViHXe4XI5ISXycO1cRrK1zN44veFyQaEfZYGDm/Ac9IiAX xPcW6cTYcvnIc3zfFi8VqT79aie2oetaupgf1eNNZAqdE8hhuvU5HIe6uL17In/2 /qxAeeWsEG89jxt5dovEN7MhGITlNgDrYyCZuen+MwS7QcjBAvlEYyCegc5C09Y/ LHbTY5xZ3Y+m4Q6gLkH3LpVHz7z9M/P2C2F+fpErgUfCJzDupxBdN49cOSvkBPB7 jVaMaA== -----END CERTIFICATE----- # Issuer: CN=VeriSign Class 3 Public Primary Certification Authority - G5 O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 2006 VeriSign, Inc. - For authorized use only # Subject: CN=VeriSign Class 3 Public Primary Certification Authority - G5 O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 2006 VeriSign, Inc. - For authorized use only # Label: "VeriSign Class 3 Public Primary Certification Authority - G5" # Serial: 33037644167568058970164719475676101450 # MD5 Fingerprint: cb:17:e4:31:67:3e:e2:09:fe:45:57:93:f3:0a:fa:1c # SHA1 Fingerprint: 4e:b6:d5:78:49:9b:1c:cf:5f:58:1e:ad:56:be:3d:9b:67:44:a5:e5 # SHA256 Fingerprint: 9a:cf:ab:7e:43:c8:d8:80:d0:6b:26:2a:94:de:ee:e4:b4:65:99:89:c3:d0:ca:f1:9b:af:64:05:e4:1a:b7:df -----BEGIN CERTIFICATE----- MIIE0zCCA7ugAwIBAgIQGNrRniZ96LtKIVjNzGs7SjANBgkqhkiG9w0BAQUFADCB yjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJp U2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxW ZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0 aG9yaXR5IC0gRzUwHhcNMDYxMTA4MDAwMDAwWhcNMzYwNzE2MjM1OTU5WjCByjEL MAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZW ZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJpU2ln biwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJp U2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9y aXR5IC0gRzUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvJAgIKXo1 nmAMqudLO07cfLw8RRy7K+D+KQL5VwijZIUVJ/XxrcgxiV0i6CqqpkKzj/i5Vbex t0uz/o9+B1fs70PbZmIVYc9gDaTY3vjgw2IIPVQT60nKWVSFJuUrjxuf6/WhkcIz SdhDY2pSS9KP6HBRTdGJaXvHcPaz3BJ023tdS1bTlr8Vd6Gw9KIl8q8ckmcY5fQG BO+QueQA5N06tRn/Arr0PO7gi+s3i+z016zy9vA9r911kTMZHRxAy3QkGSGT2RT+ rCpSx4/VBEnkjWNHiDxpg8v+R70rfk/Fla4OndTRQ8Bnc+MUCH7lP59zuDMKz10/ NIeWiu5T6CUVAgMBAAGjgbIwga8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8E BAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJaW1hZ2UvZ2lmMCEwHzAH BgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYjaHR0cDovL2xvZ28udmVy aXNpZ24uY29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFH/TZafC3ey78DAJ80M5+gKv MzEzMA0GCSqGSIb3DQEBBQUAA4IBAQCTJEowX2LP2BqYLz3q3JktvXf2pXkiOOzE p6B4Eq1iDkVwZMXnl2YtmAl+X6/WzChl8gGqCBpH3vn5fJJaCGkgDdk+bW48DW7Y 5gaRQBi5+MHt39tBquCWIMnNZBU4gcmU7qKEKQsTb47bDN0lAtukixlE0kF6BWlK WE9gyn6CagsCqiUXObXbf+eEZSqVir2G3l6BFoMtEMze/aiCKm0oHw0LxOXnGiYZ 4fQRbxC1lfznQgUy286dUV4otp6F01vvpX1FQHKOtw5rDgb7MzVIcbidJ4vEZV8N hnacRHr2lVz2XTIIM6RUthg/aFzyQkqFOFSDX9HoLPKsEdao7WNq -----END CERTIFICATE----- # Issuer: CN=COMODO Certification Authority O=COMODO CA Limited # Subject: CN=COMODO Certification Authority O=COMODO CA Limited # Label: "COMODO Certification Authority" # Serial: 104350513648249232941998508985834464573 # MD5 Fingerprint: 5c:48:dc:f7:42:72:ec:56:94:6d:1c:cc:71:35:80:75 # SHA1 Fingerprint: 66:31:bf:9e:f7:4f:9e:b6:c9:d5:a6:0c:ba:6a:be:d1:f7:bd:ef:7b # SHA256 Fingerprint: 0c:2c:d6:3d:f7:80:6f:a3:99:ed:e8:09:11:6b:57:5b:f8:79:89:f0:65:18:f9:80:8c:86:05:03:17:8b:af:66 -----BEGIN CERTIFICATE----- MIIEHTCCAwWgAwIBAgIQToEtioJl4AsC7j41AkblPTANBgkqhkiG9w0BAQUFADCB gTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G A1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxJzAlBgNV BAMTHkNPTU9ETyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjEyMDEwMDAw MDBaFw0yOTEyMzEyMzU5NTlaMIGBMQswCQYDVQQGEwJHQjEbMBkGA1UECBMSR3Jl YXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHEwdTYWxmb3JkMRowGAYDVQQKExFDT01P RE8gQ0EgTGltaXRlZDEnMCUGA1UEAxMeQ09NT0RPIENlcnRpZmljYXRpb24gQXV0 aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0ECLi3LjkRv3 UcEbVASY06m/weaKXTuH+7uIzg3jLz8GlvCiKVCZrts7oVewdFFxze1CkU1B/qnI 2GqGd0S7WWaXUF601CxwRM/aN5VCaTwwxHGzUvAhTaHYujl8HJ6jJJ3ygxaYqhZ8 Q5sVW7euNJH+1GImGEaaP+vB+fGQV+useg2L23IwambV4EajcNxo2f8ESIl33rXp +2dtQem8Ob0y2WIC8bGoPW43nOIv4tOiJovGuFVDiOEjPqXSJDlqR6sA1KGzqSX+ DT+nHbrTUcELpNqsOO9VUCQFZUaTNE8tja3G1CEZ0o7KBWFxB3NH5YoZEr0ETc5O nKVIrLsm9wIDAQABo4GOMIGLMB0GA1UdDgQWBBQLWOWLxkwVN6RAqTCpIb5HNlpW /zAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zBJBgNVHR8EQjBAMD6g PKA6hjhodHRwOi8vY3JsLmNvbW9kb2NhLmNvbS9DT01PRE9DZXJ0aWZpY2F0aW9u QXV0aG9yaXR5LmNybDANBgkqhkiG9w0BAQUFAAOCAQEAPpiem/Yb6dc5t3iuHXIY SdOH5EOC6z/JqvWote9VfCFSZfnVDeFs9D6Mk3ORLgLETgdxb8CPOGEIqB6BCsAv IC9Bi5HcSEW88cbeunZrM8gALTFGTO3nnc+IlP8zwFboJIYmuNg4ON8qa90SzMc/ RxdMosIGlgnW2/4/PEZB31jiVg88O8EckzXZOFKs7sjsLjBOlDW0JB9LeGna8gI4 zJVSk/BwJVmcIGfE7vmLV2H0knZ9P4SNVbfo5azV8fUZVqZa+5Acr5Pr5RzUZ5dd BA6+C4OmF4O5MBKgxTMVBbkN+8cFduPYSo38NBejxiEovjBFMR7HeL5YYTisO+IB ZQ== -----END CERTIFICATE----- # Issuer: CN=Network Solutions Certificate Authority O=Network Solutions L.L.C. # Subject: CN=Network Solutions Certificate Authority O=Network Solutions L.L.C. # Label: "Network Solutions Certificate Authority" # Serial: 116697915152937497490437556386812487904 # MD5 Fingerprint: d3:f3:a6:16:c0:fa:6b:1d:59:b1:2d:96:4d:0e:11:2e # SHA1 Fingerprint: 74:f8:a3:c3:ef:e7:b3:90:06:4b:83:90:3c:21:64:60:20:e5:df:ce # SHA256 Fingerprint: 15:f0:ba:00:a3:ac:7a:f3:ac:88:4c:07:2b:10:11:a0:77:bd:77:c0:97:f4:01:64:b2:f8:59:8a:bd:83:86:0c -----BEGIN CERTIFICATE----- MIID5jCCAs6gAwIBAgIQV8szb8JcFuZHFhfjkDFo4DANBgkqhkiG9w0BAQUFADBi MQswCQYDVQQGEwJVUzEhMB8GA1UEChMYTmV0d29yayBTb2x1dGlvbnMgTC5MLkMu MTAwLgYDVQQDEydOZXR3b3JrIFNvbHV0aW9ucyBDZXJ0aWZpY2F0ZSBBdXRob3Jp dHkwHhcNMDYxMjAxMDAwMDAwWhcNMjkxMjMxMjM1OTU5WjBiMQswCQYDVQQGEwJV UzEhMB8GA1UEChMYTmV0d29yayBTb2x1dGlvbnMgTC5MLkMuMTAwLgYDVQQDEydO ZXR3b3JrIFNvbHV0aW9ucyBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwggEiMA0GCSqG SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDkvH6SMG3G2I4rC7xGzuAnlt7e+foS0zwz c7MEL7xxjOWftiJgPl9dzgn/ggwbmlFQGiaJ3dVhXRncEg8tCqJDXRfQNJIg6nPP OCwGJgl6cvf6UDL4wpPTaaIjzkGxzOTVHzbRijr4jGPiFFlp7Q3Tf2vouAPlT2rl mGNpSAW+Lv8ztumXWWn4Zxmuk2GWRBXTcrA/vGp97Eh/jcOrqnErU2lBUzS1sLnF BgrEsEX1QV1uiUV7PTsmjHTC5dLRfbIR1PtYMiKagMnc/Qzpf14Dl847ABSHJ3A4 qY5usyd2mFHgBeMhqxrVhSI8KbWaFsWAqPS7azCPL0YCorEMIuDTAgMBAAGjgZcw gZQwHQYDVR0OBBYEFCEwyfsA106Y2oeqKtCnLrFAMadMMA4GA1UdDwEB/wQEAwIB BjAPBgNVHRMBAf8EBTADAQH/MFIGA1UdHwRLMEkwR6BFoEOGQWh0dHA6Ly9jcmwu bmV0c29sc3NsLmNvbS9OZXR3b3JrU29sdXRpb25zQ2VydGlmaWNhdGVBdXRob3Jp dHkuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQC7rkvnt1frf6ott3NHhWrB5KUd5Oc8 6fRZZXe1eltajSU24HqXLjjAV2CDmAaDn7l2em5Q4LqILPxFzBiwmZVRDuwduIj/ h1AcgsLj4DKAv6ALR8jDMe+ZZzKATxcheQxpXN5eNK4CtSbqUN9/GGUsyfJj4akH /nxxH2szJGoeBfcFaMBqEssuXmHLrijTfsK0ZpEmXzwuJF/LWA/rKOyvEZbz3Htv wKeI8lN3s2Berq4o2jUsbzRF0ybh3uxbTydrFny9RAQYgrOJeRcQcT16ohZO9QHN pGxlaKFJdlxDydi8NmdspZS11My5vWo1ViHe2MPr+8ukYEywVaCge1ey -----END CERTIFICATE----- # Issuer: CN=COMODO ECC Certification Authority O=COMODO CA Limited # Subject: CN=COMODO ECC Certification Authority O=COMODO CA Limited # Label: "COMODO ECC Certification Authority" # Serial: 41578283867086692638256921589707938090 # MD5 Fingerprint: 7c:62:ff:74:9d:31:53:5e:68:4a:d5:78:aa:1e:bf:23 # SHA1 Fingerprint: 9f:74:4e:9f:2b:4d:ba:ec:0f:31:2c:50:b6:56:3b:8e:2d:93:c3:11 # SHA256 Fingerprint: 17:93:92:7a:06:14:54:97:89:ad:ce:2f:8f:34:f7:f0:b6:6d:0f:3a:e3:a3:b8:4d:21:ec:15:db:ba:4f:ad:c7 -----BEGIN CERTIFICATE----- MIICiTCCAg+gAwIBAgIQH0evqmIAcFBUTAGem2OZKjAKBggqhkjOPQQDAzCBhTEL MAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE BxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMT IkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDgwMzA2MDAw MDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdy ZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09N T0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlv biBBdXRob3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQDR3svdcmCFYX7deSR FtSrYpn1PlILBs5BAH+X4QokPB0BBO490o0JlwzgdeT6+3eKKvUDYEs2ixYjFq0J cfRK9ChQtP6IHG4/bC8vCVlbpVsLM5niwz2J+Wos77LTBumjQjBAMB0GA1UdDgQW BBR1cacZSBm8nZ3qQUfflMRId5nTeTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/ BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjEA7wNbeqy3eApyt4jf/7VGFAkK+qDm fQjGGoe9GKhzvSbKYAydzpmfz1wPMOG+FDHqAjAU9JM8SaczepBGR7NjfRObTrdv GDeAU/7dIOA1mjbRxwG55tzd8/8dLDoWV9mSOdY= -----END CERTIFICATE----- # Issuer: CN=TC TrustCenter Class 2 CA II O=TC TrustCenter GmbH OU=TC TrustCenter Class 2 CA # Subject: CN=TC TrustCenter Class 2 CA II O=TC TrustCenter GmbH OU=TC TrustCenter Class 2 CA # Label: "TC TrustCenter Class 2 CA II" # Serial: 941389028203453866782103406992443 # MD5 Fingerprint: ce:78:33:5c:59:78:01:6e:18:ea:b9:36:a0:b9:2e:23 # SHA1 Fingerprint: ae:50:83:ed:7c:f4:5c:bc:8f:61:c6:21:fe:68:5d:79:42:21:15:6e # SHA256 Fingerprint: e6:b8:f8:76:64:85:f8:07:ae:7f:8d:ac:16:70:46:1f:07:c0:a1:3e:ef:3a:1f:f7:17:53:8d:7a:ba:d3:91:b4 -----BEGIN CERTIFICATE----- MIIEqjCCA5KgAwIBAgIOLmoAAQACH9dSISwRXDswDQYJKoZIhvcNAQEFBQAwdjEL MAkGA1UEBhMCREUxHDAaBgNVBAoTE1RDIFRydXN0Q2VudGVyIEdtYkgxIjAgBgNV BAsTGVRDIFRydXN0Q2VudGVyIENsYXNzIDIgQ0ExJTAjBgNVBAMTHFRDIFRydXN0 Q2VudGVyIENsYXNzIDIgQ0EgSUkwHhcNMDYwMTEyMTQzODQzWhcNMjUxMjMxMjI1 OTU5WjB2MQswCQYDVQQGEwJERTEcMBoGA1UEChMTVEMgVHJ1c3RDZW50ZXIgR21i SDEiMCAGA1UECxMZVEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMiBDQTElMCMGA1UEAxMc VEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMiBDQSBJSTCCASIwDQYJKoZIhvcNAQEBBQAD ggEPADCCAQoCggEBAKuAh5uO8MN8h9foJIIRszzdQ2Lu+MNF2ujhoF/RKrLqk2jf tMjWQ+nEdVl//OEd+DFwIxuInie5e/060smp6RQvkL4DUsFJzfb95AhmC1eKokKg uNV/aVyQMrKXDcpK3EY+AlWJU+MaWss2xgdW94zPEfRMuzBwBJWl9jmM/XOBCH2J XjIeIqkiRUuwZi4wzJ9l/fzLganx4Duvo4bRierERXlQXa7pIXSSTYtZgo+U4+lK 8edJsBTj9WLL1XK9H7nSn6DNqPoByNkN39r8R52zyFTfSUrxIan+GE7uSNQZu+99 5OKdy1u2bv/jzVrndIIFuoAlOMvkaZ6vQaoahPUCAwEAAaOCATQwggEwMA8GA1Ud EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBTjq1RMgKHbVkO3 kUrL84J6E1wIqzCB7QYDVR0fBIHlMIHiMIHfoIHcoIHZhjVodHRwOi8vd3d3LnRy dXN0Y2VudGVyLmRlL2NybC92Mi90Y19jbGFzc18yX2NhX0lJLmNybIaBn2xkYXA6 Ly93d3cudHJ1c3RjZW50ZXIuZGUvQ049VEMlMjBUcnVzdENlbnRlciUyMENsYXNz JTIwMiUyMENBJTIwSUksTz1UQyUyMFRydXN0Q2VudGVyJTIwR21iSCxPVT1yb290 Y2VydHMsREM9dHJ1c3RjZW50ZXIsREM9ZGU/Y2VydGlmaWNhdGVSZXZvY2F0aW9u TGlzdD9iYXNlPzANBgkqhkiG9w0BAQUFAAOCAQEAjNfffu4bgBCzg/XbEeprS6iS GNn3Bzn1LL4GdXpoUxUc6krtXvwjshOg0wn/9vYua0Fxec3ibf2uWWuFHbhOIprt ZjluS5TmVfwLG4t3wVMTZonZKNaL80VKY7f9ewthXbhtvsPcW3nS7Yblok2+XnR8 au0WOB9/WIFaGusyiC2y8zl3gK9etmF1KdsjTYjKUCjLhdLTEKJZbtOTVAB6okaV hgWcqRmY5TFyDADiZ9lA4CQze28suVyrZZ0srHbqNZn1l7kPJOzHdiEoZa5X6AeI dUpWoNIFOqTmjZKILPPy4cHGYdtBxceb9w4aUUXCYWvcZCcXjFq32nQozZfkvQ== -----END CERTIFICATE----- # Issuer: CN=TC TrustCenter Class 3 CA II O=TC TrustCenter GmbH OU=TC TrustCenter Class 3 CA # Subject: CN=TC TrustCenter Class 3 CA II O=TC TrustCenter GmbH OU=TC TrustCenter Class 3 CA # Label: "TC TrustCenter Class 3 CA II" # Serial: 1506523511417715638772220530020799 # MD5 Fingerprint: 56:5f:aa:80:61:12:17:f6:67:21:e6:2b:6d:61:56:8e # SHA1 Fingerprint: 80:25:ef:f4:6e:70:c8:d4:72:24:65:84:fe:40:3b:8a:8d:6a:db:f5 # SHA256 Fingerprint: 8d:a0:84:fc:f9:9c:e0:77:22:f8:9b:32:05:93:98:06:fa:5c:b8:11:e1:c8:13:f6:a1:08:c7:d3:36:b3:40:8e -----BEGIN CERTIFICATE----- MIIEqjCCA5KgAwIBAgIOSkcAAQAC5aBd1j8AUb8wDQYJKoZIhvcNAQEFBQAwdjEL MAkGA1UEBhMCREUxHDAaBgNVBAoTE1RDIFRydXN0Q2VudGVyIEdtYkgxIjAgBgNV BAsTGVRDIFRydXN0Q2VudGVyIENsYXNzIDMgQ0ExJTAjBgNVBAMTHFRDIFRydXN0 Q2VudGVyIENsYXNzIDMgQ0EgSUkwHhcNMDYwMTEyMTQ0MTU3WhcNMjUxMjMxMjI1 OTU5WjB2MQswCQYDVQQGEwJERTEcMBoGA1UEChMTVEMgVHJ1c3RDZW50ZXIgR21i SDEiMCAGA1UECxMZVEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMyBDQTElMCMGA1UEAxMc VEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMyBDQSBJSTCCASIwDQYJKoZIhvcNAQEBBQAD ggEPADCCAQoCggEBALTgu1G7OVyLBMVMeRwjhjEQY0NVJz/GRcekPewJDRoeIMJW Ht4bNwcwIi9v8Qbxq63WyKthoy9DxLCyLfzDlml7forkzMA5EpBCYMnMNWju2l+Q Vl/NHE1bWEnrDgFPZPosPIlY2C8u4rBo6SI7dYnWRBpl8huXJh0obazovVkdKyT2 1oQDZogkAHhg8fir/gKya/si+zXmFtGt9i4S5Po1auUZuV3bOx4a+9P/FRQI2Alq ukWdFHlgfa9Aigdzs5OW03Q0jTo3Kd5c7PXuLjHCINy+8U9/I1LZW+Jk2ZyqBwi1 Rb3R0DHBq1SfqdLDYmAD8bs5SpJKPQq5ncWg/jcCAwEAAaOCATQwggEwMA8GA1Ud EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBTUovyfs8PYA9NX XAek0CSnwPIA1DCB7QYDVR0fBIHlMIHiMIHfoIHcoIHZhjVodHRwOi8vd3d3LnRy dXN0Y2VudGVyLmRlL2NybC92Mi90Y19jbGFzc18zX2NhX0lJLmNybIaBn2xkYXA6 Ly93d3cudHJ1c3RjZW50ZXIuZGUvQ049VEMlMjBUcnVzdENlbnRlciUyMENsYXNz JTIwMyUyMENBJTIwSUksTz1UQyUyMFRydXN0Q2VudGVyJTIwR21iSCxPVT1yb290 Y2VydHMsREM9dHJ1c3RjZW50ZXIsREM9ZGU/Y2VydGlmaWNhdGVSZXZvY2F0aW9u TGlzdD9iYXNlPzANBgkqhkiG9w0BAQUFAAOCAQEANmDkcPcGIEPZIxpC8vijsrlN irTzwppVMXzEO2eatN9NDoqTSheLG43KieHPOh6sHfGcMrSOWXaiQYUlN6AT0PV8 TtXqluJucsG7Kv5sbviRmEb8yRtXW+rIGjs/sFGYPAfaLFkB2otE6OF0/ado3VS6 g0bsyEa1+K+XwDsJHI/OcpY9M1ZwvJbL2NV9IJqDnxrcOfHFcqMRA/07QlIp2+gB 95tejNaNhk4Z+rwcvsUhpYeeeC422wlxo3I0+GzjBgnyXlal092Y+tTmBvTwtiBj S+opvaqCZh77gaqnN60TGOaSw4HBM7uIHqHn4rS9MWwOUT1v+5ZWgOI2F9Hc5A== -----END CERTIFICATE----- # Issuer: CN=TC TrustCenter Universal CA I O=TC TrustCenter GmbH OU=TC TrustCenter Universal CA # Subject: CN=TC TrustCenter Universal CA I O=TC TrustCenter GmbH OU=TC TrustCenter Universal CA # Label: "TC TrustCenter Universal CA I" # Serial: 601024842042189035295619584734726 # MD5 Fingerprint: 45:e1:a5:72:c5:a9:36:64:40:9e:f5:e4:58:84:67:8c # SHA1 Fingerprint: 6b:2f:34:ad:89:58:be:62:fd:b0:6b:5c:ce:bb:9d:d9:4f:4e:39:f3 # SHA256 Fingerprint: eb:f3:c0:2a:87:89:b1:fb:7d:51:19:95:d6:63:b7:29:06:d9:13:ce:0d:5e:10:56:8a:8a:77:e2:58:61:67:e7 -----BEGIN CERTIFICATE----- MIID3TCCAsWgAwIBAgIOHaIAAQAC7LdggHiNtgYwDQYJKoZIhvcNAQEFBQAweTEL MAkGA1UEBhMCREUxHDAaBgNVBAoTE1RDIFRydXN0Q2VudGVyIEdtYkgxJDAiBgNV BAsTG1RDIFRydXN0Q2VudGVyIFVuaXZlcnNhbCBDQTEmMCQGA1UEAxMdVEMgVHJ1 c3RDZW50ZXIgVW5pdmVyc2FsIENBIEkwHhcNMDYwMzIyMTU1NDI4WhcNMjUxMjMx MjI1OTU5WjB5MQswCQYDVQQGEwJERTEcMBoGA1UEChMTVEMgVHJ1c3RDZW50ZXIg R21iSDEkMCIGA1UECxMbVEMgVHJ1c3RDZW50ZXIgVW5pdmVyc2FsIENBMSYwJAYD VQQDEx1UQyBUcnVzdENlbnRlciBVbml2ZXJzYWwgQ0EgSTCCASIwDQYJKoZIhvcN AQEBBQADggEPADCCAQoCggEBAKR3I5ZEr5D0MacQ9CaHnPM42Q9e3s9B6DGtxnSR JJZ4Hgmgm5qVSkr1YnwCqMqs+1oEdjneX/H5s7/zA1hV0qq34wQi0fiU2iIIAI3T fCZdzHd55yx4Oagmcw6iXSVphU9VDprvxrlE4Vc93x9UIuVvZaozhDrzznq+VZeu jRIPFDPiUHDDSYcTvFHe15gSWu86gzOSBnWLknwSaHtwag+1m7Z3W0hZneTvWq3z wZ7U10VOylY0Ibw+F1tvdwxIAUMpsN0/lm7mlaoMwCC2/T42J5zjXM9OgdwZu5GQ fezmlwQek8wiSdeXhrYTCjxDI3d+8NzmzSQfO4ObNDqDNOMCAwEAAaNjMGEwHwYD VR0jBBgwFoAUkqR1LKSevoFE63n8isWVpesQdXMwDwYDVR0TAQH/BAUwAwEB/zAO BgNVHQ8BAf8EBAMCAYYwHQYDVR0OBBYEFJKkdSyknr6BROt5/IrFlaXrEHVzMA0G CSqGSIb3DQEBBQUAA4IBAQAo0uCG1eb4e/CX3CJrO5UUVg8RMKWaTzqwOuAGy2X1 7caXJ/4l8lfmXpWMPmRgFVp/Lw0BxbFg/UU1z/CyvwbZ71q+s2IhtNerNXxTPqYn 8aEt2hojnczd7Dwtnic0XQ/CNnm8yUpiLe1r2X1BQ3y2qsrtYbE3ghUJGooWMNjs ydZHcnhLEEYUjl8Or+zHL6sQ17bxbuyGssLoDZJz3KL0Dzq/YSMQiZxIQG5wALPT ujdEWBF6AmqI8Dc08BnprNRlc/ZpjGSUOnmFKbAWKwyCPwacx/0QK54PLLae4xW/ 2TYcuiUaUj0a7CIMHOCkoj3w6DnPgcB77V0fb8XQC9eY -----END CERTIFICATE----- # Issuer: CN=Cybertrust Global Root O=Cybertrust, Inc # Subject: CN=Cybertrust Global Root O=Cybertrust, Inc # Label: "Cybertrust Global Root" # Serial: 4835703278459682877484360 # MD5 Fingerprint: 72:e4:4a:87:e3:69:40:80:77:ea:bc:e3:f4:ff:f0:e1 # SHA1 Fingerprint: 5f:43:e5:b1:bf:f8:78:8c:ac:1c:c7:ca:4a:9a:c6:22:2b:cc:34:c6 # SHA256 Fingerprint: 96:0a:df:00:63:e9:63:56:75:0c:29:65:dd:0a:08:67:da:0b:9c:bd:6e:77:71:4a:ea:fb:23:49:ab:39:3d:a3 -----BEGIN CERTIFICATE----- MIIDoTCCAomgAwIBAgILBAAAAAABD4WqLUgwDQYJKoZIhvcNAQEFBQAwOzEYMBYG A1UEChMPQ3liZXJ0cnVzdCwgSW5jMR8wHQYDVQQDExZDeWJlcnRydXN0IEdsb2Jh bCBSb290MB4XDTA2MTIxNTA4MDAwMFoXDTIxMTIxNTA4MDAwMFowOzEYMBYGA1UE ChMPQ3liZXJ0cnVzdCwgSW5jMR8wHQYDVQQDExZDeWJlcnRydXN0IEdsb2JhbCBS b290MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA+Mi8vRRQZhP/8NN5 7CPytxrHjoXxEnOmGaoQ25yiZXRadz5RfVb23CO21O1fWLE3TdVJDm71aofW0ozS J8bi/zafmGWgE07GKmSb1ZASzxQG9Dvj1Ci+6A74q05IlG2OlTEQXO2iLb3VOm2y HLtgwEZLAfVJrn5GitB0jaEMAs7u/OePuGtm839EAL9mJRQr3RAwHQeWP032a7iP t3sMpTjr3kfb1V05/Iin89cqdPHoWqI7n1C6poxFNcJQZZXcY4Lv3b93TZxiyWNz FtApD0mpSPCzqrdsxacwOUBdrsTiXSZT8M4cIwhhqJQZugRiQOwfOHB3EgZxpzAY XSUnpQIDAQABo4GlMIGiMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/ MB0GA1UdDgQWBBS2CHsNesysIEyGVjJez6tuhS1wVzA/BgNVHR8EODA2MDSgMqAw hi5odHRwOi8vd3d3Mi5wdWJsaWMtdHJ1c3QuY29tL2NybC9jdC9jdHJvb3QuY3Js MB8GA1UdIwQYMBaAFLYIew16zKwgTIZWMl7Pq26FLXBXMA0GCSqGSIb3DQEBBQUA A4IBAQBW7wojoFROlZfJ+InaRcHUowAl9B8Tq7ejhVhpwjCt2BWKLePJzYFa+HMj Wqd8BfP9IjsO0QbE2zZMcwSO5bAi5MXzLqXZI+O4Tkogp24CJJ8iYGd7ix1yCcUx XOl5n4BHPa2hCwcUPUf/A2kaDAtE52Mlp3+yybh2hO0j9n0Hq0V+09+zv+mKts2o omcrUtW3ZfA5TGOgkXmTUg9U3YO7n9GPp1Nzw8v/MOx8BLjYRB+TX3EJIrduPuoc A06dGiBh+4E37F78CkWr1+cXVdCg6mCbpvbjjFspwgZgFJ0tl0ypkxWdYcQBX0jW WL1WMRJOEcgh4LMRkWXbtKaIOM5V -----END CERTIFICATE----- # Issuer: CN=GeoTrust Primary Certification Authority - G3 O=GeoTrust Inc. OU=(c) 2008 GeoTrust Inc. - For authorized use only # Subject: CN=GeoTrust Primary Certification Authority - G3 O=GeoTrust Inc. OU=(c) 2008 GeoTrust Inc. - For authorized use only # Label: "GeoTrust Primary Certification Authority - G3" # Serial: 28809105769928564313984085209975885599 # MD5 Fingerprint: b5:e8:34:36:c9:10:44:58:48:70:6d:2e:83:d4:b8:05 # SHA1 Fingerprint: 03:9e:ed:b8:0b:e7:a0:3c:69:53:89:3b:20:d2:d9:32:3a:4c:2a:fd # SHA256 Fingerprint: b4:78:b8:12:25:0d:f8:78:63:5c:2a:a7:ec:7d:15:5e:aa:62:5e:e8:29:16:e2:cd:29:43:61:88:6c:d1:fb:d4 -----BEGIN CERTIFICATE----- MIID/jCCAuagAwIBAgIQFaxulBmyeUtB9iepwxgPHzANBgkqhkiG9w0BAQsFADCB mDELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsT MChjKSAyMDA4IEdlb1RydXN0IEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25s eTE2MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhv cml0eSAtIEczMB4XDTA4MDQwMjAwMDAwMFoXDTM3MTIwMTIzNTk1OVowgZgxCzAJ BgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTkwNwYDVQQLEzAoYykg MjAwOCBHZW9UcnVzdCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxNjA0 BgNVBAMTLUdlb1RydXN0IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkg LSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANziXmJYHTNXOTIz +uvLh4yn1ErdBojqZI4xmKU4kB6Yzy5jK/BGvESyiaHAKAxJcCGVn2TAppMSAmUm hsalifD614SgcK9PGpc/BkTVyetyEH3kMSj7HGHmKAdEc5IiaacDiGydY8hS2pgn 5whMcD60yRLBxWeDXTPzAxHsatBT4tG6NmCUgLthY2xbF37fQJQeqw3CIShwiP/W JmxsYAQlTlV+fe+/lEjetx3dcI0FX4ilm/LC7urRQEFtYjgdVgbFA0dRIBn8exAL DmKudlW/X3e+PkkBUz2YJQN2JFodtNuJ6nnltrM7P7pMKEF/BqxqjsHQ9gUdfeZC huOl1UcCAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYw HQYDVR0OBBYEFMR5yo6hTgMdHNxr2zFblD4/MH8tMA0GCSqGSIb3DQEBCwUAA4IB AQAtxRPPVoB7eni9n64smefv2t+UXglpp+duaIy9cr5HqQ6XErhK8WTTOd8lNNTB zU6B8A8ExCSzNJbGpqow32hhc9f5joWJ7w5elShKKiePEI4ufIbEAp7aDHdlDkQN kv39sxY2+hENHYwOB4lqKVb3cvTdFZx3NWZXqxNT2I7BQMXXExZacse3aQHEerGD AWh9jUGhlBjBJVz88P6DAod8DQ3PLghcSkANPuyBYeYk28rgDi0Hsj5W3I31QYUH SJsMC8tJP33st/3LjWeJGqvtux6jAAgIFyqCXDFdRootD4abdNlF+9RAsXqqaC2G spki4cErx5z481+oghLrGREt -----END CERTIFICATE----- # Issuer: CN=thawte Primary Root CA - G2 O=thawte, Inc. OU=(c) 2007 thawte, Inc. - For authorized use only # Subject: CN=thawte Primary Root CA - G2 O=thawte, Inc. OU=(c) 2007 thawte, Inc. - For authorized use only # Label: "thawte Primary Root CA - G2" # Serial: 71758320672825410020661621085256472406 # MD5 Fingerprint: 74:9d:ea:60:24:c4:fd:22:53:3e:cc:3a:72:d9:29:4f # SHA1 Fingerprint: aa:db:bc:22:23:8f:c4:01:a1:27:bb:38:dd:f4:1d:db:08:9e:f0:12 # SHA256 Fingerprint: a4:31:0d:50:af:18:a6:44:71:90:37:2a:86:af:af:8b:95:1f:fb:43:1d:83:7f:1e:56:88:b4:59:71:ed:15:57 -----BEGIN CERTIFICATE----- MIICiDCCAg2gAwIBAgIQNfwmXNmET8k9Jj1Xm67XVjAKBggqhkjOPQQDAzCBhDEL MAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjE4MDYGA1UECxMvKGMp IDIwMDcgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxJDAi BgNVBAMTG3RoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EgLSBHMjAeFw0wNzExMDUwMDAw MDBaFw0zODAxMTgyMzU5NTlaMIGEMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMdGhh d3RlLCBJbmMuMTgwNgYDVQQLEy8oYykgMjAwNyB0aGF3dGUsIEluYy4gLSBGb3Ig YXV0aG9yaXplZCB1c2Ugb25seTEkMCIGA1UEAxMbdGhhd3RlIFByaW1hcnkgUm9v dCBDQSAtIEcyMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEotWcgnuVnfFSeIf+iha/ BebfowJPDQfGAFG6DAJSLSKkQjnE/o/qycG+1E3/n3qe4rF8mq2nhglzh9HnmuN6 papu+7qzcMBniKI11KOasf2twu8x+qi58/sIxpHR+ymVo0IwQDAPBgNVHRMBAf8E BTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUmtgAMADna3+FGO6Lts6K DPgR4bswCgYIKoZIzj0EAwMDaQAwZgIxAN344FdHW6fmCsO99YCKlzUNG4k8VIZ3 KMqh9HneteY4sPBlcIx/AlTCv//YoT7ZzwIxAMSNlPzcU9LcnXgWHxUzI1NS41ox XZ3Krr0TKUQNJ1uo52icEvdYPy5yAlejj6EULg== -----END CERTIFICATE----- # Issuer: CN=thawte Primary Root CA - G3 O=thawte, Inc. OU=Certification Services Division/(c) 2008 thawte, Inc. - For authorized use only # Subject: CN=thawte Primary Root CA - G3 O=thawte, Inc. OU=Certification Services Division/(c) 2008 thawte, Inc. - For authorized use only # Label: "thawte Primary Root CA - G3" # Serial: 127614157056681299805556476275995414779 # MD5 Fingerprint: fb:1b:5d:43:8a:94:cd:44:c6:76:f2:43:4b:47:e7:31 # SHA1 Fingerprint: f1:8b:53:8d:1b:e9:03:b6:a6:f0:56:43:5b:17:15:89:ca:f3:6b:f2 # SHA256 Fingerprint: 4b:03:f4:58:07:ad:70:f2:1b:fc:2c:ae:71:c9:fd:e4:60:4c:06:4c:f5:ff:b6:86:ba:e5:db:aa:d7:fd:d3:4c -----BEGIN CERTIFICATE----- MIIEKjCCAxKgAwIBAgIQYAGXt0an6rS0mtZLL/eQ+zANBgkqhkiG9w0BAQsFADCB rjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMf Q2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIw MDggdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxJDAiBgNV BAMTG3RoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EgLSBHMzAeFw0wODA0MDIwMDAwMDBa Fw0zNzEyMDEyMzU5NTlaMIGuMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMdGhhd3Rl LCBJbmMuMSgwJgYDVQQLEx9DZXJ0aWZpY2F0aW9uIFNlcnZpY2VzIERpdmlzaW9u MTgwNgYDVQQLEy8oYykgMjAwOCB0aGF3dGUsIEluYy4gLSBGb3IgYXV0aG9yaXpl ZCB1c2Ugb25seTEkMCIGA1UEAxMbdGhhd3RlIFByaW1hcnkgUm9vdCBDQSAtIEcz MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsr8nLPvb2FvdeHsbnndm gcs+vHyu86YnmjSjaDFxODNi5PNxZnmxqWWjpYvVj2AtP0LMqmsywCPLLEHd5N/8 YZzic7IilRFDGF/Eth9XbAoFWCLINkw6fKXRz4aviKdEAhN0cXMKQlkC+BsUa0Lf b1+6a4KinVvnSr0eAXLbS3ToO39/fR8EtCab4LRarEc9VbjXsCZSKAExQGbY2SS9 9irY7CFJXJv2eul/VTV+lmuNk5Mny5K76qxAwJ/C+IDPXfRa3M50hqY+bAtTyr2S zhkGcuYMXDhpxwTWvGzOW/b3aJzcJRVIiKHpqfiYnODz1TEoYRFsZ5aNOZnLwkUk OQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNV HQ4EFgQUrWyqlGCc7eT/+j4KdCtjA/e2Wb8wDQYJKoZIhvcNAQELBQADggEBABpA 2JVlrAmSicY59BDlqQ5mU1143vokkbvnRFHfxhY0Cu9qRFHqKweKA3rD6z8KLFIW oCtDuSWQP3CpMyVtRRooOyfPqsMpQhvfO0zAMzRbQYi/aytlryjvsvXDqmbOe1bu t8jLZ8HJnBoYuMTDSQPxYA5QzUbF83d597YV4Djbxy8ooAw/dyZ02SUS2jHaGh7c KUGRIjxpp7sC8rZcJwOJ9Abqm+RyguOhCcHpABnTPtRwa7pxpqpYrvS76Wy274fM m7v/OeZWYdMKp8RcTGB7BXcmer/YB1IsYvdwY9k5vG8cwnncdimvzsUsZAReiDZu MdRAGmI0Nj81Aa6sY6A= -----END CERTIFICATE----- # Issuer: CN=GeoTrust Primary Certification Authority - G2 O=GeoTrust Inc. OU=(c) 2007 GeoTrust Inc. - For authorized use only # Subject: CN=GeoTrust Primary Certification Authority - G2 O=GeoTrust Inc. OU=(c) 2007 GeoTrust Inc. - For authorized use only # Label: "GeoTrust Primary Certification Authority - G2" # Serial: 80682863203381065782177908751794619243 # MD5 Fingerprint: 01:5e:d8:6b:bd:6f:3d:8e:a1:31:f8:12:e0:98:73:6a # SHA1 Fingerprint: 8d:17:84:d5:37:f3:03:7d:ec:70:fe:57:8b:51:9a:99:e6:10:d7:b0 # SHA256 Fingerprint: 5e:db:7a:c4:3b:82:a0:6a:87:61:e8:d7:be:49:79:eb:f2:61:1f:7d:d7:9b:f9:1c:1c:6b:56:6a:21:9e:d7:66 -----BEGIN CERTIFICATE----- MIICrjCCAjWgAwIBAgIQPLL0SAoA4v7rJDteYD7DazAKBggqhkjOPQQDAzCBmDEL MAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsTMChj KSAyMDA3IEdlb1RydXN0IEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTE2 MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0 eSAtIEcyMB4XDTA3MTEwNTAwMDAwMFoXDTM4MDExODIzNTk1OVowgZgxCzAJBgNV BAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTkwNwYDVQQLEzAoYykgMjAw NyBHZW9UcnVzdCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxNjA0BgNV BAMTLUdlb1RydXN0IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBH MjB2MBAGByqGSM49AgEGBSuBBAAiA2IABBWx6P0DFUPlrOuHNxFi79KDNlJ9RVcL So17VDs6bl8VAsBQps8lL33KSLjHUGMcKiEIfJo22Av+0SbFWDEwKCXzXV2juLal tJLtbCyf691DiaI8S0iRHVDsJt/WYC69IaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAO BgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFBVfNVdRVfslsq0DafwBo/q+EVXVMAoG CCqGSM49BAMDA2cAMGQCMGSWWaboCd6LuvpaiIjwH5HTRqjySkwCY/tsXzjbLkGT qQ7mndwxHLKgpxgceeHHNgIwOlavmnRs9vuD4DPTCF+hnMJbn0bWtsuRBmOiBucz rD6ogRLQy7rQkgu2npaqBA+K -----END CERTIFICATE----- # Issuer: CN=VeriSign Universal Root Certification Authority O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 2008 VeriSign, Inc. - For authorized use only # Subject: CN=VeriSign Universal Root Certification Authority O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 2008 VeriSign, Inc. - For authorized use only # Label: "VeriSign Universal Root Certification Authority" # Serial: 85209574734084581917763752644031726877 # MD5 Fingerprint: 8e:ad:b5:01:aa:4d:81:e4:8c:1d:d1:e1:14:00:95:19 # SHA1 Fingerprint: 36:79:ca:35:66:87:72:30:4d:30:a5:fb:87:3b:0f:a7:7b:b7:0d:54 # SHA256 Fingerprint: 23:99:56:11:27:a5:71:25:de:8c:ef:ea:61:0d:df:2f:a0:78:b5:c8:06:7f:4e:82:82:90:bf:b8:60:e8:4b:3c -----BEGIN CERTIFICATE----- MIIEuTCCA6GgAwIBAgIQQBrEZCGzEyEDDrvkEhrFHTANBgkqhkiG9w0BAQsFADCB vTELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwOCBWZXJp U2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MTgwNgYDVQQDEy9W ZXJpU2lnbiBVbml2ZXJzYWwgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAe Fw0wODA0MDIwMDAwMDBaFw0zNzEyMDEyMzU5NTlaMIG9MQswCQYDVQQGEwJVUzEX MBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0 IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAyMDA4IFZlcmlTaWduLCBJbmMuIC0gRm9y IGF1dGhvcml6ZWQgdXNlIG9ubHkxODA2BgNVBAMTL1ZlcmlTaWduIFVuaXZlcnNh bCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEF AAOCAQ8AMIIBCgKCAQEAx2E3XrEBNNti1xWb/1hajCMj1mCOkdeQmIN65lgZOIzF 9uVkhbSicfvtvbnazU0AtMgtc6XHaXGVHzk8skQHnOgO+k1KxCHfKWGPMiJhgsWH H26MfF8WIFFE0XBPV+rjHOPMee5Y2A7Cs0WTwCznmhcrewA3ekEzeOEz4vMQGn+H LL729fdC4uW/h2KJXwBL38Xd5HVEMkE6HnFuacsLdUYI0crSK5XQz/u5QGtkjFdN /BMReYTtXlT2NJ8IAfMQJQYXStrxHXpma5hgZqTZ79IugvHw7wnqRMkVauIDbjPT rJ9VAMf2CGqUuV/c4DPxhGD5WycRtPwW8rtWaoAljQIDAQABo4GyMIGvMA8GA1Ud EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMG0GCCsGAQUFBwEMBGEwX6FdoFsw WTBXMFUWCWltYWdlL2dpZjAhMB8wBwYFKw4DAhoEFI/l0xqGrI2Oa8PPgGrUSBgs exkuMCUWI2h0dHA6Ly9sb2dvLnZlcmlzaWduLmNvbS92c2xvZ28uZ2lmMB0GA1Ud DgQWBBS2d/ppSEefUxLVwuoHMnYH0ZcHGTANBgkqhkiG9w0BAQsFAAOCAQEASvj4 sAPmLGd75JR3Y8xuTPl9Dg3cyLk1uXBPY/ok+myDjEedO2Pzmvl2MpWRsXe8rJq+ seQxIcaBlVZaDrHC1LGmWazxY8u4TB1ZkErvkBYoH1quEPuBUDgMbMzxPcP1Y+Oz 4yHJJDnp/RVmRvQbEdBNc6N9Rvk97ahfYtTxP/jgdFcrGJ2BtMQo2pSXpXDrrB2+ BxHw1dvd5Yzw1TKwg+ZX4o+/vqGqvz0dtdQ46tewXDpPaj+PwGZsY6rp2aQW9IHR lRQOfc2VNNnSj3BzgXucfr2YYdhFh5iQxeuGMMY1v/D/w1WIg0vvBZIGcfK4mJO3 7M2CYfE45k+XmCpajQ== -----END CERTIFICATE----- # Issuer: CN=VeriSign Class 3 Public Primary Certification Authority - G4 O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 2007 VeriSign, Inc. - For authorized use only # Subject: CN=VeriSign Class 3 Public Primary Certification Authority - G4 O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 2007 VeriSign, Inc. - For authorized use only # Label: "VeriSign Class 3 Public Primary Certification Authority - G4" # Serial: 63143484348153506665311985501458640051 # MD5 Fingerprint: 3a:52:e1:e7:fd:6f:3a:e3:6f:f3:6f:99:1b:f9:22:41 # SHA1 Fingerprint: 22:d5:d8:df:8f:02:31:d1:8d:f7:9d:b7:cf:8a:2d:64:c9:3f:6c:3a # SHA256 Fingerprint: 69:dd:d7:ea:90:bb:57:c9:3e:13:5d:c8:5e:a6:fc:d5:48:0b:60:32:39:bd:c4:54:fc:75:8b:2a:26:cf:7f:79 -----BEGIN CERTIFICATE----- MIIDhDCCAwqgAwIBAgIQL4D+I4wOIg9IZxIokYesszAKBggqhkjOPQQDAzCByjEL MAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZW ZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNyBWZXJpU2ln biwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJp U2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9y aXR5IC0gRzQwHhcNMDcxMTA1MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCByjELMAkG A1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJp U2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNyBWZXJpU2lnbiwg SW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2ln biBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5 IC0gRzQwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAASnVnp8Utpkmw4tXNherJI9/gHm GUo9FANL+mAnINmDiWn6VMaaGF5VKmTeBvaNSjutEDxlPZCIBIngMGGzrl0Bp3ve fLK+ymVhAIau2o970ImtTR1ZmkGxvEeA3J5iw/mjgbIwga8wDwYDVR0TAQH/BAUw AwEB/zAOBgNVHQ8BAf8EBAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJ aW1hZ2UvZ2lmMCEwHzAHBgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYj aHR0cDovL2xvZ28udmVyaXNpZ24uY29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFLMW kf3upm7ktS5Jj4d4gYDs5bG1MAoGCCqGSM49BAMDA2gAMGUCMGYhDBgmYFo4e1ZC 4Kf8NoRRkSAsdk1DPcQdhCPQrNZ8NQbOzWm9kA3bbEhCHQ6qQgIxAJw9SDkjOVga FRJZap7v1VmyHVIsmXHNxynfGyphe3HR3vPA5Q06Sqotp9iGKt0uEA== -----END CERTIFICATE----- # Issuer: O=VeriSign, Inc. OU=Class 3 Public Primary Certification Authority # Subject: O=VeriSign, Inc. OU=Class 3 Public Primary Certification Authority # Label: "Verisign Class 3 Public Primary Certification Authority" # Serial: 80507572722862485515306429940691309246 # MD5 Fingerprint: ef:5a:f1:33:ef:f1:cd:bb:51:02:ee:12:14:4b:96:c4 # SHA1 Fingerprint: a1:db:63:93:91:6f:17:e4:18:55:09:40:04:15:c7:02:40:b0:ae:6b # SHA256 Fingerprint: a4:b6:b3:99:6f:c2:f3:06:b3:fd:86:81:bd:63:41:3d:8c:50:09:cc:4f:a3:29:c2:cc:f0:e2:fa:1b:14:03:05 -----BEGIN CERTIFICATE----- MIICPDCCAaUCEDyRMcsf9tAbDpq40ES/Er4wDQYJKoZIhvcNAQEFBQAwXzELMAkG A1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFz cyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTk2 MDEyOTAwMDAwMFoXDTI4MDgwMjIzNTk1OVowXzELMAkGA1UEBhMCVVMxFzAVBgNV BAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAzIFB1YmxpYyBQcmlt YXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGfMA0GCSqGSIb3DQEBAQUAA4GN ADCBiQKBgQDJXFme8huKARS0EN8EQNvjV69qRUCPhAwL0TPZ2RHP7gJYHyX3KqhE BarsAx94f56TuZoAqiN91qyFomNFx3InzPRMxnVx0jnvT0Lwdd8KkMaOIG+YD/is I19wKTakyYbnsZogy1Olhec9vn2a/iRFM9x2Fe0PonFkTGUugWhFpwIDAQABMA0G CSqGSIb3DQEBBQUAA4GBABByUqkFFBkyCEHwxWsKzH4PIRnN5GfcX6kb5sroc50i 2JhucwNhkcV8sEVAbkSdjbCxlnRhLQ2pRdKkkirWmnWXbj9T/UWZYB2oK0z5XqcJ 2HUw19JlYD1n1khVdWk/kfVIC0dpImmClr7JyDiGSnoscxlIaU5rfGW/D/xwzoiQ -----END CERTIFICATE----- # Issuer: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R3 # Subject: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R3 # Label: "GlobalSign Root CA - R3" # Serial: 4835703278459759426209954 # MD5 Fingerprint: c5:df:b8:49:ca:05:13:55:ee:2d:ba:1a:c3:3e:b0:28 # SHA1 Fingerprint: d6:9b:56:11:48:f0:1c:77:c5:45:78:c1:09:26:df:5b:85:69:76:ad # SHA256 Fingerprint: cb:b5:22:d7:b7:f1:27:ad:6a:01:13:86:5b:df:1c:d4:10:2e:7d:07:59:af:63:5a:7c:f4:72:0d:c9:63:c5:3b -----BEGIN CERTIFICATE----- MIIDXzCCAkegAwIBAgILBAAAAAABIVhTCKIwDQYJKoZIhvcNAQELBQAwTDEgMB4G A1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjMxEzARBgNVBAoTCkdsb2JhbFNp Z24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDkwMzE4MTAwMDAwWhcNMjkwMzE4 MTAwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMzETMBEG A1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCASIwDQYJKoZI hvcNAQEBBQADggEPADCCAQoCggEBAMwldpB5BngiFvXAg7aEyiie/QV2EcWtiHL8 RgJDx7KKnQRfJMsuS+FggkbhUqsMgUdwbN1k0ev1LKMPgj0MK66X17YUhhB5uzsT gHeMCOFJ0mpiLx9e+pZo34knlTifBtc+ycsmWQ1z3rDI6SYOgxXG71uL0gRgykmm KPZpO/bLyCiR5Z2KYVc3rHQU3HTgOu5yLy6c+9C7v/U9AOEGM+iCK65TpjoWc4zd QQ4gOsC0p6Hpsk+QLjJg6VfLuQSSaGjlOCZgdbKfd/+RFO+uIEn8rUAVSNECMWEZ XriX7613t2Saer9fwRPvm2L7DWzgVGkWqQPabumDk3F2xmmFghcCAwEAAaNCMEAw DgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFI/wS3+o LkUkrk1Q+mOai97i3Ru8MA0GCSqGSIb3DQEBCwUAA4IBAQBLQNvAUKr+yAzv95ZU RUm7lgAJQayzE4aGKAczymvmdLm6AC2upArT9fHxD4q/c2dKg8dEe3jgr25sbwMp jjM5RcOO5LlXbKr8EpbsU8Yt5CRsuZRj+9xTaGdWPoO4zzUhw8lo/s7awlOqzJCK 6fBdRoyV3XpYKBovHd7NADdBj+1EbddTKJd+82cEHhXXipa0095MJ6RMG3NzdvQX mcIfeg7jLQitChws/zyrVQ4PkX4268NXSb7hLi18YIvDQVETI53O9zJrlAGomecs Mx86OyXShkDOOyyGeMlhLxS67ttVb9+E7gUJTb0o2HLO02JQZR7rkpeDMdmztcpH WD9f -----END CERTIFICATE----- # Issuer: CN=TC TrustCenter Universal CA III O=TC TrustCenter GmbH OU=TC TrustCenter Universal CA # Subject: CN=TC TrustCenter Universal CA III O=TC TrustCenter GmbH OU=TC TrustCenter Universal CA # Label: "TC TrustCenter Universal CA III" # Serial: 2010889993983507346460533407902964 # MD5 Fingerprint: 9f:dd:db:ab:ff:8e:ff:45:21:5f:f0:6c:9d:8f:fe:2b # SHA1 Fingerprint: 96:56:cd:7b:57:96:98:95:d0:e1:41:46:68:06:fb:b8:c6:11:06:87 # SHA256 Fingerprint: 30:9b:4a:87:f6:ca:56:c9:31:69:aa:a9:9c:6d:98:88:54:d7:89:2b:d5:43:7e:2d:07:b2:9c:be:da:55:d3:5d -----BEGIN CERTIFICATE----- MIID4TCCAsmgAwIBAgIOYyUAAQACFI0zFQLkbPQwDQYJKoZIhvcNAQEFBQAwezEL MAkGA1UEBhMCREUxHDAaBgNVBAoTE1RDIFRydXN0Q2VudGVyIEdtYkgxJDAiBgNV BAsTG1RDIFRydXN0Q2VudGVyIFVuaXZlcnNhbCBDQTEoMCYGA1UEAxMfVEMgVHJ1 c3RDZW50ZXIgVW5pdmVyc2FsIENBIElJSTAeFw0wOTA5MDkwODE1MjdaFw0yOTEy MzEyMzU5NTlaMHsxCzAJBgNVBAYTAkRFMRwwGgYDVQQKExNUQyBUcnVzdENlbnRl ciBHbWJIMSQwIgYDVQQLExtUQyBUcnVzdENlbnRlciBVbml2ZXJzYWwgQ0ExKDAm BgNVBAMTH1RDIFRydXN0Q2VudGVyIFVuaXZlcnNhbCBDQSBJSUkwggEiMA0GCSqG SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDC2pxisLlxErALyBpXsq6DFJmzNEubkKLF 5+cvAqBNLaT6hdqbJYUtQCggbergvbFIgyIpRJ9Og+41URNzdNW88jBmlFPAQDYv DIRlzg9uwliT6CwLOunBjvvya8o84pxOjuT5fdMnnxvVZ3iHLX8LR7PH6MlIfK8v zArZQe+f/prhsq75U7Xl6UafYOPfjdN/+5Z+s7Vy+EutCHnNaYlAJ/Uqwa1D7KRT yGG299J5KmcYdkhtWyUB0SbFt1dpIxVbYYqt8Bst2a9c8SaQaanVDED1M4BDj5yj dipFtK+/fz6HP3bFzSreIMUWWMv5G/UPyw0RUmS40nZid4PxWJ//AgMBAAGjYzBh MB8GA1UdIwQYMBaAFFbn4VslQ4Dg9ozhcbyO5YAvxEjiMA8GA1UdEwEB/wQFMAMB Af8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBRW5+FbJUOA4PaM4XG8juWAL8RI 4jANBgkqhkiG9w0BAQUFAAOCAQEAg8ev6n9NCjw5sWi+e22JLumzCecYV42Fmhfz dkJQEw/HkG8zrcVJYCtsSVgZ1OK+t7+rSbyUyKu+KGwWaODIl0YgoGhnYIg5IFHY aAERzqf2EQf27OysGh+yZm5WZ2B6dF7AbZc2rrUNXWZzwCUyRdhKBgePxLcHsU0G DeGl6/R1yrqc0L2z0zIkTO5+4nYES0lT2PLpVDP85XEfPRRclkvxOvIAu2y0+pZV CIgJwcyRGSmwIC3/yzikQOEXvnlhgP8HA4ZMTnsGnxGGjYnuJ8Tb4rwZjgvDwxPH LQNjO9Po5KIqwoIIlBZU8O8fJ5AluA0OKBtHd0e9HKgl8ZS0Zg== -----END CERTIFICATE----- # Issuer: CN=Go Daddy Root Certificate Authority - G2 O=GoDaddy.com, Inc. # Subject: CN=Go Daddy Root Certificate Authority - G2 O=GoDaddy.com, Inc. # Label: "Go Daddy Root Certificate Authority - G2" # Serial: 0 # MD5 Fingerprint: 80:3a:bc:22:c1:e6:fb:8d:9b:3b:27:4a:32:1b:9a:01 # SHA1 Fingerprint: 47:be:ab:c9:22:ea:e8:0e:78:78:34:62:a7:9f:45:c2:54:fd:e6:8b # SHA256 Fingerprint: 45:14:0b:32:47:eb:9c:c8:c5:b4:f0:d7:b5:30:91:f7:32:92:08:9e:6e:5a:63:e2:74:9d:d3:ac:a9:19:8e:da -----BEGIN CERTIFICATE----- MIIDxTCCAq2gAwIBAgIBADANBgkqhkiG9w0BAQsFADCBgzELMAkGA1UEBhMCVVMx EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAYBgNVBAoT EUdvRGFkZHkuY29tLCBJbmMuMTEwLwYDVQQDEyhHbyBEYWRkeSBSb290IENlcnRp ZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAwMFoXDTM3MTIzMTIz NTk1OVowgYMxCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6b25hMRMwEQYDVQQH EwpTY290dHNkYWxlMRowGAYDVQQKExFHb0RhZGR5LmNvbSwgSW5jLjExMC8GA1UE AxMoR28gRGFkZHkgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIw DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL9xYgjx+lk09xvJGKP3gElY6SKD E6bFIEMBO4Tx5oVJnyfq9oQbTqC023CYxzIBsQU+B07u9PpPL1kwIuerGVZr4oAH /PMWdYA5UXvl+TW2dE6pjYIT5LY/qQOD+qK+ihVqf94Lw7YZFAXK6sOoBJQ7Rnwy DfMAZiLIjWltNowRGLfTshxgtDj6AozO091GB94KPutdfMh8+7ArU6SSYmlRJQVh GkSBjCypQ5Yj36w6gZoOKcUcqeldHraenjAKOc7xiID7S13MMuyFYkMlNAJWJwGR tDtwKj9useiciAF9n9T521NtYJ2/LOdYq7hfRvzOxBsDPAnrSTFcaUaz4EcCAwEA AaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYE FDqahQcQZyi27/a9BUFuIMGU2g/eMA0GCSqGSIb3DQEBCwUAA4IBAQCZ21151fmX WWcDYfF+OwYxdS2hII5PZYe096acvNjpL9DbWu7PdIxztDhC2gV7+AJ1uP2lsdeu 9tfeE8tTEH6KRtGX+rcuKxGrkLAngPnon1rpN5+r5N9ss4UXnT3ZJE95kTXWXwTr gIOrmgIttRD02JDHBHNA7XIloKmf7J6raBKZV8aPEjoJpL1E/QYVN8Gb5DKj7Tjo 2GTzLH4U/ALqn83/B2gX2yKQOC16jdFU8WnjXzPKej17CuPKf1855eJ1usV2GDPO LPAvTK33sefOT6jEm0pUBsV/fdUID+Ic/n4XuKxe9tQWskMJDE32p2u0mYRlynqI 4uJEvlz36hz1 -----END CERTIFICATE----- # Issuer: CN=Starfield Root Certificate Authority - G2 O=Starfield Technologies, Inc. # Subject: CN=Starfield Root Certificate Authority - G2 O=Starfield Technologies, Inc. # Label: "Starfield Root Certificate Authority - G2" # Serial: 0 # MD5 Fingerprint: d6:39:81:c6:52:7e:96:69:fc:fc:ca:66:ed:05:f2:96 # SHA1 Fingerprint: b5:1c:06:7c:ee:2b:0c:3d:f8:55:ab:2d:92:f4:fe:39:d4:e7:0f:0e # SHA256 Fingerprint: 2c:e1:cb:0b:f9:d2:f9:e1:02:99:3f:be:21:51:52:c3:b2:dd:0c:ab:de:1c:68:e5:31:9b:83:91:54:db:b7:f5 -----BEGIN CERTIFICATE----- MIID3TCCAsWgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBjzELMAkGA1UEBhMCVVMx EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT HFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAMTKVN0YXJmaWVs ZCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAw MFoXDTM3MTIzMTIzNTk1OVowgY8xCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6 b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFyZmllbGQgVGVj aG5vbG9naWVzLCBJbmMuMTIwMAYDVQQDEylTdGFyZmllbGQgUm9vdCBDZXJ0aWZp Y2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC ggEBAL3twQP89o/8ArFvW59I2Z154qK3A2FWGMNHttfKPTUuiUP3oWmb3ooa/RMg nLRJdzIpVv257IzdIvpy3Cdhl+72WoTsbhm5iSzchFvVdPtrX8WJpRBSiUZV9Lh1 HOZ/5FSuS/hVclcCGfgXcVnrHigHdMWdSL5stPSksPNkN3mSwOxGXn/hbVNMYq/N Hwtjuzqd+/x5AJhhdM8mgkBj87JyahkNmcrUDnXMN/uLicFZ8WJ/X7NfZTD4p7dN dloedl40wOiWVpmKs/B/pM293DIxfJHP4F8R+GuqSVzRmZTRouNjWwl2tVZi4Ut0 HZbUJtQIBFnQmA4O5t78w+wfkPECAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAO BgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFHwMMh+n2TB/xH1oo2Kooc6rB1snMA0G CSqGSIb3DQEBCwUAA4IBAQARWfolTwNvlJk7mh+ChTnUdgWUXuEok21iXQnCoKjU sHU48TRqneSfioYmUeYs0cYtbpUgSpIB7LiKZ3sx4mcujJUDJi5DnUox9g61DLu3 4jd/IroAow57UvtruzvE03lRTs2Q9GcHGcg8RnoNAX3FWOdt5oUwF5okxBDgBPfg 8n/Uqgr/Qh037ZTlZFkSIHc40zI+OIF1lnP6aI+xy84fxez6nH7PfrHxBy22/L/K pL/QlwVKvOoYKAKQvVR4CSFx09F9HdkWsKlhPdAKACL8x3vLCWRFCztAgfd9fDL1 mMpYjn0q7pBZc2T5NnReJaH1ZgUufzkVqSr7UIuOhWn0 -----END CERTIFICATE----- # Issuer: CN=Starfield Services Root Certificate Authority - G2 O=Starfield Technologies, Inc. # Subject: CN=Starfield Services Root Certificate Authority - G2 O=Starfield Technologies, Inc. # Label: "Starfield Services Root Certificate Authority - G2" # Serial: 0 # MD5 Fingerprint: 17:35:74:af:7b:61:1c:eb:f4:f9:3c:e2:ee:40:f9:a2 # SHA1 Fingerprint: 92:5a:8f:8d:2c:6d:04:e0:66:5f:59:6a:ff:22:d8:63:e8:25:6f:3f # SHA256 Fingerprint: 56:8d:69:05:a2:c8:87:08:a4:b3:02:51:90:ed:cf:ed:b1:97:4a:60:6a:13:c6:e5:29:0f:cb:2a:e6:3e:da:b5 -----BEGIN CERTIFICATE----- MIID7zCCAtegAwIBAgIBADANBgkqhkiG9w0BAQsFADCBmDELMAkGA1UEBhMCVVMx EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT HFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xOzA5BgNVBAMTMlN0YXJmaWVs ZCBTZXJ2aWNlcyBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5 MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgZgxCzAJBgNVBAYTAlVTMRAwDgYD VQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFy ZmllbGQgVGVjaG5vbG9naWVzLCBJbmMuMTswOQYDVQQDEzJTdGFyZmllbGQgU2Vy dmljZXMgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZI hvcNAQEBBQADggEPADCCAQoCggEBANUMOsQq+U7i9b4Zl1+OiFOxHz/Lz58gE20p OsgPfTz3a3Y4Y9k2YKibXlwAgLIvWX/2h/klQ4bnaRtSmpDhcePYLQ1Ob/bISdm2 8xpWriu2dBTrz/sm4xq6HZYuajtYlIlHVv8loJNwU4PahHQUw2eeBGg6345AWh1K Ts9DkTvnVtYAcMtS7nt9rjrnvDH5RfbCYM8TWQIrgMw0R9+53pBlbQLPLJGmpufe hRhJfGZOozptqbXuNC66DQO4M99H67FrjSXZm86B0UVGMpZwh94CDklDhbZsc7tk 6mFBrMnUVN+HL8cisibMn1lUaJ/8viovxFUcdUBgF4UCVTmLfwUCAwEAAaNCMEAw DwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJxfAN+q AdcwKziIorhtSpzyEZGDMA0GCSqGSIb3DQEBCwUAA4IBAQBLNqaEd2ndOxmfZyMI bw5hyf2E3F/YNoHN2BtBLZ9g3ccaaNnRbobhiCPPE95Dz+I0swSdHynVv/heyNXB ve6SbzJ08pGCL72CQnqtKrcgfU28elUSwhXqvfdqlS5sdJ/PHLTyxQGjhdByPq1z qwubdQxtRbeOlKyWN7Wg0I8VRw7j6IPdj/3vQQF3zCepYoUz8jcI73HPdwbeyBkd iEDPfUYd/x7H4c7/I9vG+o1VTqkC50cRRj70/b17KSa7qWFiNyi2LSr2EIZkyXCn 0q23KXB56jzaYyWf/Wi3MOxw+3WKt21gZ7IeyLnp2KhvAotnDU0mV3HaIPzBSlCN sSi6 -----END CERTIFICATE----- # Issuer: CN=AffirmTrust Commercial O=AffirmTrust # Subject: CN=AffirmTrust Commercial O=AffirmTrust # Label: "AffirmTrust Commercial" # Serial: 8608355977964138876 # MD5 Fingerprint: 82:92:ba:5b:ef:cd:8a:6f:a6:3d:55:f9:84:f6:d6:b7 # SHA1 Fingerprint: f9:b5:b6:32:45:5f:9c:be:ec:57:5f:80:dc:e9:6e:2c:c7:b2:78:b7 # SHA256 Fingerprint: 03:76:ab:1d:54:c5:f9:80:3c:e4:b2:e2:01:a0:ee:7e:ef:7b:57:b6:36:e8:a9:3c:9b:8d:48:60:c9:6f:5f:a7 -----BEGIN CERTIFICATE----- MIIDTDCCAjSgAwIBAgIId3cGJyapsXwwDQYJKoZIhvcNAQELBQAwRDELMAkGA1UE BhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVz dCBDb21tZXJjaWFsMB4XDTEwMDEyOTE0MDYwNloXDTMwMTIzMTE0MDYwNlowRDEL MAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZp cm1UcnVzdCBDb21tZXJjaWFsMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC AQEA9htPZwcroRX1BiLLHwGy43NFBkRJLLtJJRTWzsO3qyxPxkEylFf6EqdbDuKP Hx6GGaeqtS25Xw2Kwq+FNXkyLbscYjfysVtKPcrNcV/pQr6U6Mje+SJIZMblq8Yr ba0F8PrVC8+a5fBQpIs7R6UjW3p6+DM/uO+Zl+MgwdYoic+U+7lF7eNAFxHUdPAL MeIrJmqbTFeurCA+ukV6BfO9m2kVrn1OIGPENXY6BwLJN/3HR+7o8XYdcxXyl6S1 yHp52UKqK39c/s4mT6NmgTWvRLpUHhwwMmWd5jyTXlBOeuM61G7MGvv50jeuJCqr VwMiKA1JdX+3KNp1v47j3A55MQIDAQABo0IwQDAdBgNVHQ4EFgQUnZPGU4teyq8/ nx4P5ZmVvCT2lI8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwDQYJ KoZIhvcNAQELBQADggEBAFis9AQOzcAN/wr91LoWXym9e2iZWEnStB03TX8nfUYG XUPGhi4+c7ImfU+TqbbEKpqrIZcUsd6M06uJFdhrJNTxFq7YpFzUf1GO7RgBsZNj vbz4YYCanrHOQnDiqX0GJX0nof5v7LMeJNrjS1UaADs1tDvZ110w/YETifLCBivt Z8SOyUOyXGsViQK8YvxO8rUzqrJv0wqiUOP2O+guRMLbZjipM1ZI8W0bM40NjD9g N53Tym1+NH4Nn3J2ixufcv1SNUFFApYvHLKac0khsUlHRUe072o0EclNmsxZt9YC nlpOZbWUrhvfKbAW8b8Angc6F2S1BLUjIZkKlTuXfO8= -----END CERTIFICATE----- # Issuer: CN=AffirmTrust Networking O=AffirmTrust # Subject: CN=AffirmTrust Networking O=AffirmTrust # Label: "AffirmTrust Networking" # Serial: 8957382827206547757 # MD5 Fingerprint: 42:65:ca:be:01:9a:9a:4c:a9:8c:41:49:cd:c0:d5:7f # SHA1 Fingerprint: 29:36:21:02:8b:20:ed:02:f5:66:c5:32:d1:d6:ed:90:9f:45:00:2f # SHA256 Fingerprint: 0a:81:ec:5a:92:97:77:f1:45:90:4a:f3:8d:5d:50:9f:66:b5:e2:c5:8f:cd:b5:31:05:8b:0e:17:f3:f0:b4:1b -----BEGIN CERTIFICATE----- MIIDTDCCAjSgAwIBAgIIfE8EORzUmS0wDQYJKoZIhvcNAQEFBQAwRDELMAkGA1UE BhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVz dCBOZXR3b3JraW5nMB4XDTEwMDEyOTE0MDgyNFoXDTMwMTIzMTE0MDgyNFowRDEL MAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZp cm1UcnVzdCBOZXR3b3JraW5nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC AQEAtITMMxcua5Rsa2FSoOujz3mUTOWUgJnLVWREZY9nZOIG41w3SfYvm4SEHi3y YJ0wTsyEheIszx6e/jarM3c1RNg1lho9Nuh6DtjVR6FqaYvZ/Ls6rnla1fTWcbua kCNrmreIdIcMHl+5ni36q1Mr3Lt2PpNMCAiMHqIjHNRqrSK6mQEubWXLviRmVSRL QESxG9fhwoXA3hA/Pe24/PHxI1Pcv2WXb9n5QHGNfb2V1M6+oF4nI979ptAmDgAp 6zxG8D1gvz9Q0twmQVGeFDdCBKNwV6gbh+0t+nvujArjqWaJGctB+d1ENmHP4ndG yH329JKBNv3bNPFyfvMMFr20FQIDAQABo0IwQDAdBgNVHQ4EFgQUBx/S55zawm6i QLSwelAQUHTEyL0wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwDQYJ KoZIhvcNAQEFBQADggEBAIlXshZ6qML91tmbmzTCnLQyFE2npN/svqe++EPbkTfO tDIuUFUaNU52Q3Eg75N3ThVwLofDwR1t3Mu1J9QsVtFSUzpE0nPIxBsFZVpikpzu QY0x2+c06lkh1QF612S4ZDnNye2v7UsDSKegmQGA3GWjNq5lWUhPgkvIZfFXHeVZ Lgo/bNjR9eUJtGxUAArgFU2HdW23WJZa3W3SAKD0m0i+wzekujbgfIeFlxoVot4u olu9rxj5kFDNcFn4J2dHy8egBzp90SxdbBk6ZrV9/ZFvgrG+CJPbFEfxojfHRZ48 x3evZKiT3/Zpg4Jg8klCNO1aAFSFHBY2kgxc+qatv9s= -----END CERTIFICATE----- # Issuer: CN=AffirmTrust Premium O=AffirmTrust # Subject: CN=AffirmTrust Premium O=AffirmTrust # Label: "AffirmTrust Premium" # Serial: 7893706540734352110 # MD5 Fingerprint: c4:5d:0e:48:b6:ac:28:30:4e:0a:bc:f9:38:16:87:57 # SHA1 Fingerprint: d8:a6:33:2c:e0:03:6f:b1:85:f6:63:4f:7d:6a:06:65:26:32:28:27 # SHA256 Fingerprint: 70:a7:3f:7f:37:6b:60:07:42:48:90:45:34:b1:14:82:d5:bf:0e:69:8e:cc:49:8d:f5:25:77:eb:f2:e9:3b:9a -----BEGIN CERTIFICATE----- MIIFRjCCAy6gAwIBAgIIbYwURrGmCu4wDQYJKoZIhvcNAQEMBQAwQTELMAkGA1UE BhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MRwwGgYDVQQDDBNBZmZpcm1UcnVz dCBQcmVtaXVtMB4XDTEwMDEyOTE0MTAzNloXDTQwMTIzMTE0MTAzNlowQTELMAkG A1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MRwwGgYDVQQDDBNBZmZpcm1U cnVzdCBQcmVtaXVtMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAxBLf qV/+Qd3d9Z+K4/as4Tx4mrzY8H96oDMq3I0gW64tb+eT2TZwamjPjlGjhVtnBKAQ JG9dKILBl1fYSCkTtuG+kU3fhQxTGJoeJKJPj/CihQvL9Cl/0qRY7iZNyaqoe5rZ +jjeRFcV5fiMyNlI4g0WJx0eyIOFJbe6qlVBzAMiSy2RjYvmia9mx+n/K+k8rNrS s8PhaJyJ+HoAVt70VZVs+7pk3WKL3wt3MutizCaam7uqYoNMtAZ6MMgpv+0GTZe5 HMQxK9VfvFMSF5yZVylmd2EhMQcuJUmdGPLu8ytxjLW6OQdJd/zvLpKQBY0tL3d7 70O/Nbua2Plzpyzy0FfuKE4mX4+QaAkvuPjcBukumj5Rp9EixAqnOEhss/n/fauG V+O61oV4d7pD6kh/9ti+I20ev9E2bFhc8e6kGVQa9QPSdubhjL08s9NIS+LI+H+S qHZGnEJlPqQewQcDWkYtuJfzt9WyVSHvutxMAJf7FJUnM7/oQ0dG0giZFmA7mn7S 5u046uwBHjxIVkkJx0w3AJ6IDsBz4W9m6XJHMD4Q5QsDyZpCAGzFlH5hxIrff4Ia C1nEWTJ3s7xgaVY5/bQGeyzWZDbZvUjthB9+pSKPKrhC9IK31FOQeE4tGv2Bb0TX OwF0lkLgAOIua+rF7nKsu7/+6qqo+Nz2snmKtmcCAwEAAaNCMEAwHQYDVR0OBBYE FJ3AZ6YMItkm9UWrpmVSESfYRaxjMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/ BAQDAgEGMA0GCSqGSIb3DQEBDAUAA4ICAQCzV00QYk465KzquByvMiPIs0laUZx2 KI15qldGF9X1Uva3ROgIRL8YhNILgM3FEv0AVQVhh0HctSSePMTYyPtwni94loMg Nt58D2kTiKV1NpgIpsbfrM7jWNa3Pt668+s0QNiigfV4Py/VpfzZotReBA4Xrf5B 8OWycvpEgjNC6C1Y91aMYj+6QrCcDFx+LmUmXFNPALJ4fqENmS2NuB2OosSw/WDQ MKSOyARiqcTtNd56l+0OOF6SL5Nwpamcb6d9Ex1+xghIsV5n61EIJenmJWtSKZGc 0jlzCFfemQa0W50QBuHCAKi4HEoCChTQwUHK+4w1IX2COPKpVJEZNZOUbWo6xbLQ u4mGk+ibyQ86p3q4ofB4Rvr8Ny/lioTz3/4E2aFooC8k4gmVBtWVyuEklut89pMF u+1z6S3RdTnX5yTb2E5fQ4+e0BQ5v1VwSJlXMbSc7kqYA5YwH2AG7hsj/oFgIxpH YoWlzBk0gG+zrBrjn/B7SK3VAdlntqlyk+otZrWyuOQ9PLLvTIzq6we/qzWaVYa8 GKa1qF60g2xraUDTn9zxw2lrueFtCfTxqlB2Cnp9ehehVZZCmTEJ3WARjQUwfuaO RtGdFNrHF+QFlozEJLUbzxQHskD4o55BhrwE0GuWyCqANP2/7waj3VjFhT0+j/6e KeC2uAloGRwYQw== -----END CERTIFICATE----- # Issuer: CN=AffirmTrust Premium ECC O=AffirmTrust # Subject: CN=AffirmTrust Premium ECC O=AffirmTrust # Label: "AffirmTrust Premium ECC" # Serial: 8401224907861490260 # MD5 Fingerprint: 64:b0:09:55:cf:b1:d5:99:e2:be:13:ab:a6:5d:ea:4d # SHA1 Fingerprint: b8:23:6b:00:2f:1d:16:86:53:01:55:6c:11:a4:37:ca:eb:ff:c3:bb # SHA256 Fingerprint: bd:71:fd:f6:da:97:e4:cf:62:d1:64:7a:dd:25:81:b0:7d:79:ad:f8:39:7e:b4:ec:ba:9c:5e:84:88:82:14:23 -----BEGIN CERTIFICATE----- MIIB/jCCAYWgAwIBAgIIdJclisc/elQwCgYIKoZIzj0EAwMwRTELMAkGA1UEBhMC VVMxFDASBgNVBAoMC0FmZmlybVRydXN0MSAwHgYDVQQDDBdBZmZpcm1UcnVzdCBQ cmVtaXVtIEVDQzAeFw0xMDAxMjkxNDIwMjRaFw00MDEyMzExNDIwMjRaMEUxCzAJ BgNVBAYTAlVTMRQwEgYDVQQKDAtBZmZpcm1UcnVzdDEgMB4GA1UEAwwXQWZmaXJt VHJ1c3QgUHJlbWl1bSBFQ0MwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQNMF4bFZ0D 0KF5Nbc6PJJ6yhUczWLznCZcBz3lVPqj1swS6vQUX+iOGasvLkjmrBhDeKzQN8O9 ss0s5kfiGuZjuD0uL3jET9v0D6RoTFVya5UdThhClXjMNzyR4ptlKymjQjBAMB0G A1UdDgQWBBSaryl6wBE1NSZRMADDav5A1a7WPDAPBgNVHRMBAf8EBTADAQH/MA4G A1UdDwEB/wQEAwIBBjAKBggqhkjOPQQDAwNnADBkAjAXCfOHiFBar8jAQr9HX/Vs aobgxCd05DhT1wV/GzTjxi+zygk8N53X57hG8f2h4nECMEJZh0PUUd+60wkyWs6I flc9nF9Ca/UHLbXwgpP5WW+uZPpY5Yse42O+tYHNbwKMeQ== -----END CERTIFICATE----- # Issuer: CN=StartCom Certification Authority O=StartCom Ltd. OU=Secure Digital Certificate Signing # Subject: CN=StartCom Certification Authority O=StartCom Ltd. OU=Secure Digital Certificate Signing # Label: "StartCom Certification Authority" # Serial: 45 # MD5 Fingerprint: c9:3b:0d:84:41:fc:a4:76:79:23:08:57:de:10:19:16 # SHA1 Fingerprint: a3:f1:33:3f:e2:42:bf:cf:c5:d1:4e:8f:39:42:98:40:68:10:d1:a0 # SHA256 Fingerprint: e1:78:90:ee:09:a3:fb:f4:f4:8b:9c:41:4a:17:d6:37:b7:a5:06:47:e9:bc:75:23:22:72:7f:cc:17:42:a9:11 -----BEGIN CERTIFICATE----- MIIHhzCCBW+gAwIBAgIBLTANBgkqhkiG9w0BAQsFADB9MQswCQYDVQQGEwJJTDEW MBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwg Q2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMgU3RhcnRDb20gQ2VydGlmaWNh dGlvbiBBdXRob3JpdHkwHhcNMDYwOTE3MTk0NjM3WhcNMzYwOTE3MTk0NjM2WjB9 MQswCQYDVQQGEwJJTDEWMBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMi U2VjdXJlIERpZ2l0YWwgQ2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMgU3Rh cnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUA A4ICDwAwggIKAoICAQDBiNsJvGxGfHiflXu1M5DycmLWwTYgIiRezul38kMKogZk pMyONvg45iPwbm2xPN1yo4UcodM9tDMr0y+v/uqwQVlntsQGfQqedIXWeUyAN3rf OQVSWff0G0ZDpNKFhdLDcfN1YjS6LIp/Ho/u7TTQEceWzVI9ujPW3U3eCztKS5/C Ji/6tRYccjV3yjxd5srhJosaNnZcAdt0FCX+7bWgiA/deMotHweXMAEtcnn6RtYT Kqi5pquDSR3l8u/d5AGOGAqPY1MWhWKpDhk6zLVmpsJrdAfkK+F2PrRt2PZE4XNi HzvEvqBTViVsUQn3qqvKv3b9bZvzndu/PWa8DFaqr5hIlTpL36dYUNk4dalb6kMM Av+Z6+hsTXBbKWWc3apdzK8BMewM69KN6Oqce+Zu9ydmDBpI125C4z/eIT574Q1w +2OqqGwaVLRcJXrJosmLFqa7LH4XXgVNWG4SHQHuEhANxjJ/GP/89PrNbpHoNkm+ Gkhpi8KWTRoSsmkXwQqQ1vp5Iki/untp+HDH+no32NgN0nZPV/+Qt+OR0t3vwmC3 Zzrd/qqc8NSLf3Iizsafl7b4r4qgEKjZ+xjGtrVcUjyJthkqcwEKDwOzEmDyei+B 26Nu/yYwl/WL3YlXtq09s68rxbd2AvCl1iuahhQqcvbjM4xdCUsT37uMdBNSSwID AQABo4ICEDCCAgwwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYD VR0OBBYEFE4L7xqkQFulF2mHMMo0aEPQQa7yMB8GA1UdIwQYMBaAFE4L7xqkQFul F2mHMMo0aEPQQa7yMIIBWgYDVR0gBIIBUTCCAU0wggFJBgsrBgEEAYG1NwEBATCC ATgwLgYIKwYBBQUHAgEWImh0dHA6Ly93d3cuc3RhcnRzc2wuY29tL3BvbGljeS5w ZGYwNAYIKwYBBQUHAgEWKGh0dHA6Ly93d3cuc3RhcnRzc2wuY29tL2ludGVybWVk aWF0ZS5wZGYwgc8GCCsGAQUFBwICMIHCMCcWIFN0YXJ0IENvbW1lcmNpYWwgKFN0 YXJ0Q29tKSBMdGQuMAMCAQEagZZMaW1pdGVkIExpYWJpbGl0eSwgcmVhZCB0aGUg c2VjdGlvbiAqTGVnYWwgTGltaXRhdGlvbnMqIG9mIHRoZSBTdGFydENvbSBDZXJ0 aWZpY2F0aW9uIEF1dGhvcml0eSBQb2xpY3kgYXZhaWxhYmxlIGF0IGh0dHA6Ly93 d3cuc3RhcnRzc2wuY29tL3BvbGljeS5wZGYwEQYJYIZIAYb4QgEBBAQDAgAHMDgG CWCGSAGG+EIBDQQrFilTdGFydENvbSBGcmVlIFNTTCBDZXJ0aWZpY2F0aW9uIEF1 dGhvcml0eTANBgkqhkiG9w0BAQsFAAOCAgEAjo/n3JR5fPGFf59Jb2vKXfuM/gTF wWLRfUKKvFO3lANmMD+x5wqnUCBVJX92ehQN6wQOQOY+2IirByeDqXWmN3PH/UvS Ta0XQMhGvjt/UfzDtgUx3M2FIk5xt/JxXrAaxrqTi3iSSoX4eA+D/i+tLPfkpLst 0OcNOrg+zvZ49q5HJMqjNTbOx8aHmNrs++myziebiMMEofYLWWivydsQD032ZGNc pRJvkrKTlMeIFw6Ttn5ii5B/q06f/ON1FE8qMt9bDeD1e5MNq6HPh+GlBEXoPBKl CcWw0bdT82AUuoVpaiF8H3VhFyAXe2w7QSlc4axa0c2Mm+tgHRns9+Ww2vl5GKVF P0lDV9LdJNUso/2RjSe15esUBppMeyG7Oq0wBhjA2MFrLH9ZXF2RsXAiV+uKa0hK 1Q8p7MZAwC+ITGgBF3f0JBlPvfrhsiAhS90a2Cl9qrjeVOwhVYBsHvUwyKMQ5bLm KhQxw4UtjJixhlpPiVktucf3HMiKf8CdBUrmQk9io20ppB+Fq9vlgcitKj1MXVuE JnHEhV5xJMqlG2zYYdMa4FTbzrqpMrUi9nNBCV24F10OD5mQ1kfabwo6YigUZ4LZ 8dCAWZvLMdibD4x3TrVoivJs9iQOLWxwxXPR3hTQcY+203sC9uO41Alua551hDnm fyWl8kgAwKQB2j8= -----END CERTIFICATE----- # Issuer: CN=StartCom Certification Authority G2 O=StartCom Ltd. # Subject: CN=StartCom Certification Authority G2 O=StartCom Ltd. # Label: "StartCom Certification Authority G2" # Serial: 59 # MD5 Fingerprint: 78:4b:fb:9e:64:82:0a:d3:b8:4c:62:f3:64:f2:90:64 # SHA1 Fingerprint: 31:f1:fd:68:22:63:20:ee:c6:3b:3f:9d:ea:4a:3e:53:7c:7c:39:17 # SHA256 Fingerprint: c7:ba:65:67:de:93:a7:98:ae:1f:aa:79:1e:71:2d:37:8f:ae:1f:93:c4:39:7f:ea:44:1b:b7:cb:e6:fd:59:95 -----BEGIN CERTIFICATE----- MIIFYzCCA0ugAwIBAgIBOzANBgkqhkiG9w0BAQsFADBTMQswCQYDVQQGEwJJTDEW MBQGA1UEChMNU3RhcnRDb20gTHRkLjEsMCoGA1UEAxMjU3RhcnRDb20gQ2VydGlm aWNhdGlvbiBBdXRob3JpdHkgRzIwHhcNMTAwMTAxMDEwMDAxWhcNMzkxMjMxMjM1 OTAxWjBTMQswCQYDVQQGEwJJTDEWMBQGA1UEChMNU3RhcnRDb20gTHRkLjEsMCoG A1UEAxMjU3RhcnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgRzIwggIiMA0G CSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC2iTZbB7cgNr2Cu+EWIAOVeq8Oo1XJ JZlKxdBWQYeQTSFgpBSHO839sj60ZwNq7eEPS8CRhXBF4EKe3ikj1AENoBB5uNsD vfOpL9HG4A/LnooUCri99lZi8cVytjIl2bLzvWXFDSxu1ZJvGIsAQRSCb0AgJnoo D/Uefyf3lLE3PbfHkffiAez9lInhzG7TNtYKGXmu1zSCZf98Qru23QumNK9LYP5/ Q0kGi4xDuFby2X8hQxfqp0iVAXV16iulQ5XqFYSdCI0mblWbq9zSOdIxHWDirMxW RST1HFSr7obdljKF+ExP6JV2tgXdNiNnvP8V4so75qbsO+wmETRIjfaAKxojAuuK HDp2KntWFhxyKrOq42ClAJ8Em+JvHhRYW6Vsi1g8w7pOOlz34ZYrPu8HvKTlXcxN nw3h3Kq74W4a7I/htkxNeXJdFzULHdfBR9qWJODQcqhaX2YtENwvKhOuJv4KHBnM 0D4LnMgJLvlblnpHnOl68wVQdJVznjAJ85eCXuaPOQgeWeU1FEIT/wCc976qUM/i UUjXuG+v+E5+M5iSFGI6dWPPe/regjupuznixL0sAA7IF6wT700ljtizkC+p2il9 Ha90OrInwMEePnWjFqmveiJdnxMaz6eg6+OGCtP95paV1yPIN93EfKo2rJgaErHg TuixO/XWb/Ew1wIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQE AwIBBjAdBgNVHQ4EFgQUS8W0QGutHLOlHGVuRjaJhwUMDrYwDQYJKoZIhvcNAQEL BQADggIBAHNXPyzVlTJ+N9uWkusZXn5T50HsEbZH77Xe7XRcxfGOSeD8bpkTzZ+K 2s06Ctg6Wgk/XzTQLwPSZh0avZyQN8gMjgdalEVGKua+etqhqaRpEpKwfTbURIfX UfEpY9Z1zRbkJ4kd+MIySP3bmdCPX1R0zKxnNBFi2QwKN4fRoxdIjtIXHfbX/dtl 6/2o1PXWT6RbdejF0mCy2wl+JYt7ulKSnj7oxXehPOBKc2thz4bcQ///If4jXSRK 9dNtD2IEBVeC2m6kMyV5Sy5UGYvMLD0w6dEG/+gyRr61M3Z3qAFdlsHB1b6uJcDJ HgoJIIihDsnzb02CVAAgp9KP5DlUFy6NHrgbuxu9mk47EDTcnIhT76IxW1hPkWLI wpqazRVdOKnWvvgTtZ8SafJQYqz7Fzf07rh1Z2AQ+4NQ+US1dZxAF7L+/XldblhY XzD8AK6vM8EOTmy6p6ahfzLbOOCxchcKK5HsamMm7YnUeMx0HgX4a/6ManY5Ka5l IxKVCCIcl85bBu4M4ru8H0ST9tg4RQUh7eStqxK2A6RCLi3ECToDZ2mEmuFZkIoo hdVddLHRDiBYmxOlsGOm7XtH/UVVMKTumtTm4ofvmMkyghEpIrwACjFeLQ/Ajulr so8uBtjRkcfGEvRM/TAXw8HaOFvjqermobp573PYtlNXLfbQ4ddI -----END CERTIFICATE----- includes/Google/IO/Abstract.php000064400000025253152214270100012352 0ustar00 null, "PUT" => null); private static $HOP_BY_HOP = array( 'connection' => true, 'keep-alive' => true, 'proxy-authenticate' => true, 'proxy-authorization' => true, 'te' => true, 'trailers' => true, 'transfer-encoding' => true, 'upgrade' => true ); /** @var UDP_Google_Client */ protected $client; public function __construct(UDP_Google_Client $client) { $this->client = $client; $timeout = $client->getClassConfig('UDP_Google_IO_Abstract', 'request_timeout_seconds'); if ($timeout > 0) { $this->setTimeout($timeout); } } /** * Executes a Google_Http_Request * @param Google_Http_Request $request the http request to be executed * @return array containing response headers, body, and http code * @throws UDP_Google_IO_Exception on curl or IO error */ abstract public function executeRequest(UDP_Google_Http_Request $request); /** * Set options that update the transport implementation's behavior. * @param $options */ abstract public function setOptions($options); /** * Set the maximum request time in seconds. * @param $timeout in seconds */ abstract public function setTimeout($timeout); /** * Get the maximum request time in seconds. * @return timeout in seconds */ abstract public function getTimeout(); /** * Test for the presence of a cURL header processing bug * * The cURL bug was present in versions prior to 7.30.0 and caused the header * length to be miscalculated when a "Connection established" header added by * some proxies was present. * * @return boolean */ abstract protected function needsQuirk(); /** * @visible for testing. * Cache the response to an HTTP request if it is cacheable. * @param Google_Http_Request $request * @return bool Returns true if the insertion was successful. * Otherwise, return false. */ public function setCachedRequest(UDP_Google_Http_Request $request) { // Determine if the request is cacheable. if (Google_Http_CacheParser::isResponseCacheable($request)) { $this->client->getCache()->set($request->getCacheKey(), $request); return true; } return false; } /** * Execute an HTTP Request * * @param Google_Http_Request $request the http request to be executed * @return Google_Http_Request http request with the response http code, * response headers and response body filled in * @throws UDP_Google_IO_Exception on curl or IO error */ public function makeRequest(UDP_Google_Http_Request $request) { // First, check to see if we have a valid cached version. $cached = $this->getCachedRequest($request); if ($cached !== false && $cached instanceof UDP_Google_Http_Request) { if (!$this->checkMustRevalidateCachedRequest($cached, $request)) { return $cached; } } if (array_key_exists($request->getRequestMethod(), self::$ENTITY_HTTP_METHODS)) { $request = $this->processEntityRequest($request); } list($responseData, $responseHeaders, $respHttpCode) = $this->executeRequest($request); if ($respHttpCode == 304 && $cached) { // If the server responded NOT_MODIFIED, return the cached request. $this->updateCachedRequest($cached, $responseHeaders); return $cached; } if (!isset($responseHeaders['Date']) && !isset($responseHeaders['date'])) { $responseHeaders['date'] = date("r"); } $request->setResponseHttpCode($respHttpCode); $request->setResponseHeaders($responseHeaders); $request->setResponseBody($responseData); // Store the request in cache (the function checks to see if the request // can actually be cached) $this->setCachedRequest($request); return $request; } /** * @visible for testing. * @param Google_Http_Request $request * @return Google_Http_Request|bool Returns the cached object or * false if the operation was unsuccessful. */ public function getCachedRequest(UDP_Google_Http_Request $request) { if (false === Google_Http_CacheParser::isRequestCacheable($request)) { return false; } return $this->client->getCache()->get($request->getCacheKey()); } /** * @visible for testing * Process an http request that contains an enclosed entity. * @param Google_Http_Request $request * @return Google_Http_Request Processed request with the enclosed entity. */ public function processEntityRequest(UDP_Google_Http_Request $request) { $postBody = $request->getPostBody(); $contentType = $request->getRequestHeader("content-type"); // Set the default content-type as application/x-www-form-urlencoded. if (false == $contentType) { $contentType = self::FORM_URLENCODED; $request->setRequestHeaders(array('content-type' => $contentType)); } // Force the payload to match the content-type asserted in the header. if ($contentType == self::FORM_URLENCODED && is_array($postBody)) { $postBody = http_build_query($postBody, '', '&'); $request->setPostBody($postBody); } // Make sure the content-length header is set. if (!$postBody || is_string($postBody)) { $postsLength = strlen($postBody); $request->setRequestHeaders(array('content-length' => $postsLength)); } return $request; } /** * Check if an already cached request must be revalidated, and if so update * the request with the correct ETag headers. * @param Google_Http_Request $cached A previously cached response. * @param Google_Http_Request $request The outbound request. * return bool If the cached object needs to be revalidated, false if it is * still current and can be re-used. */ protected function checkMustRevalidateCachedRequest($cached, $request) { if (Google_Http_CacheParser::mustRevalidate($cached)) { $addHeaders = array(); if ($cached->getResponseHeader('etag')) { // [13.3.4] If an entity tag has been provided by the origin server, // we must use that entity tag in any cache-conditional request. $addHeaders['If-None-Match'] = $cached->getResponseHeader('etag'); } elseif ($cached->getResponseHeader('date')) { $addHeaders['If-Modified-Since'] = $cached->getResponseHeader('date'); } $request->setRequestHeaders($addHeaders); return true; } else { return false; } } /** * Update a cached request, using the headers from the last response. * @param Google_Http_Request $cached A previously cached response. * @param mixed Associative array of response headers from the last request. */ protected function updateCachedRequest($cached, $responseHeaders) { $hopByHop = self::$HOP_BY_HOP; if (!empty($responseHeaders['connection'])) { $connectionHeaders = array_map( 'strtolower', array_filter( array_map('trim', explode(',', $responseHeaders['connection'])) ) ); $hopByHop += array_fill_keys($connectionHeaders, true); } $endToEnd = array_diff_key($responseHeaders, $hopByHop); $cached->setResponseHeaders($endToEnd); } /** * Used by the IO lib and also the batch processing. * * @param $respData * @param $headerSize * @return array */ public function parseHttpResponse($respData, $headerSize) { // check proxy header foreach (self::$CONNECTION_ESTABLISHED_HEADERS as $established_header) { if (stripos($respData, $established_header) !== false) { // existed, remove it $respData = str_ireplace($established_header, '', $respData); // Subtract the proxy header size unless the cURL bug prior to 7.30.0 // is present which prevented the proxy header size from being taken into // account. if (!$this->needsQuirk()) { $headerSize -= strlen($established_header); } break; } } if ($headerSize) { $responseBody = substr($respData, $headerSize); $responseHeaders = substr($respData, 0, $headerSize); } else { $responseSegments = explode("\r\n\r\n", $respData, 2); $responseHeaders = $responseSegments[0]; $responseBody = isset($responseSegments[1]) ? $responseSegments[1] : null; } $responseHeaders = $this->getHttpResponseHeaders($responseHeaders); return array($responseHeaders, $responseBody); } /** * Parse out headers from raw headers * @param rawHeaders array or string * @return array */ public function getHttpResponseHeaders($rawHeaders) { if (is_array($rawHeaders)) { return $this->parseArrayHeaders($rawHeaders); } else { return $this->parseStringHeaders($rawHeaders); } } private function parseStringHeaders($rawHeaders) { $headers = array(); $responseHeaderLines = explode("\r\n", $rawHeaders); foreach ($responseHeaderLines as $headerLine) { if ($headerLine && strpos($headerLine, ':') !== false) { list($header, $value) = explode(': ', $headerLine, 2); $header = strtolower($header); if (isset($headers[$header])) { $headers[$header] .= "\n" . $value; } else { $headers[$header] = $value; } } } return $headers; } private function parseArrayHeaders($rawHeaders) { $header_count = count($rawHeaders); $headers = array(); for ($i = 0; $i < $header_count; $i++) { $header = $rawHeaders[$i]; // Times will have colons in - so we just want the first match. $header_parts = explode(': ', $header, 2); if (count($header_parts) == 2) { $headers[strtolower($header_parts[0])] = $header_parts[1]; } } return $headers; } } includes/Google/IO/Stream.php000064400000017527152214270100012047 0ustar00 */ if (!class_exists('UDP_Google_Client')) { require_once dirname(__FILE__) . '/../autoload.php'; } class UDP_Google_IO_Stream extends UDP_Google_IO_Abstract { const TIMEOUT = "timeout"; const ZLIB = "compress.zlib://"; private $options = array(); private $trappedErrorNumber; private $trappedErrorString; private static $DEFAULT_HTTP_CONTEXT = array( "follow_location" => 0, "ignore_errors" => 1, ); private static $DEFAULT_SSL_CONTEXT = array( "verify_peer" => true, ); public function __construct(UDP_Google_Client $client) { if (!ini_get('allow_url_fopen')) { $error = 'The stream IO handler requires the allow_url_fopen runtime ' . 'configuration to be enabled'; $client->getLogger()->critical($error); throw new UDP_Google_IO_Exception($error); } parent::__construct($client); } /** * Execute an HTTP Request * * @param Google_Http_Request $request the http request to be executed * @return array containing response headers, body, and http code * @throws UDP_Google_IO_Exception on curl or IO error */ public function executeRequest(UDP_Google_Http_Request $request) { $default_options = stream_context_get_options(stream_context_get_default()); $requestHttpContext = array_key_exists('http', $default_options) ? $default_options['http'] : array(); if ($request->getPostBody()) { $requestHttpContext["content"] = $request->getPostBody(); } $requestHeaders = $request->getRequestHeaders(); if ($requestHeaders && is_array($requestHeaders)) { $headers = ""; foreach ($requestHeaders as $k => $v) { $headers .= "$k: $v\r\n"; } $requestHttpContext["header"] = $headers; } $requestHttpContext["method"] = $request->getRequestMethod(); $requestHttpContext["user_agent"] = $request->getUserAgent(); $requestSslContext = array_key_exists('ssl', $default_options) ? $default_options['ssl'] : array(); # UpdraftPlus patch // if (!array_key_exists("cafile", $requestSslContext)) { // $requestSslContext["cafile"] = dirname(__FILE__) . '/cacerts.pem'; // } $url = $request->getUrl(); if (preg_match('#^https?://([^/]+)/#', $url, $umatches)) { $cname = $umatches[1]; } else { $cname = false; } # UpdraftPlus patch // Added if (empty($this->options['disable_verify_peer'])) { $requestSslContext['verify_peer'] = true; if (version_compare(PHP_VERSION, '5.6.0', '>=')) { if (!empty($cname)) $requestSslContext['peer_name'] = $cname; } else { if (!empty($cname)) { $requestSslContext['CN_match'] = $cname; $retry_on_fail = true; } } } else { $requestSslContext['allow_self_signed'] = true; } if (!empty($this->options['cafile'])) $requestSslContext['cafile'] = $this->options['cafile']; $options = array( "http" => array_merge( self::$DEFAULT_HTTP_CONTEXT, $requestHttpContext ), "ssl" => array_merge( # UpdraftPlus patch // self::$DEFAULT_SSL_CONTEXT, $requestSslContext ) ); $context = stream_context_create($options); # UpdraftPlus patch // $url = $request->getUrl(); if ($request->canGzip()) { $url = self::ZLIB . $url; } $this->client->getLogger()->debug( 'Stream request', array( 'url' => $url, 'method' => $request->getRequestMethod(), 'headers' => $requestHeaders, 'body' => $request->getPostBody() ) ); // We are trapping any thrown errors in this method only and // throwing an exception. $this->trappedErrorNumber = null; $this->trappedErrorString = null; // START - error trap. set_error_handler(array($this, 'trapError')); $fh = fopen($url, 'r', false, $context); # UpdraftPLus patch if (!$fh && isset($retry_on_fail) && !empty($cname) && 'www.googleapis.com' == $cname) { // Reset $this->trappedErrorNumber = null; $this->trappedErrorString = null; global $updraftplus; $updraftplus->log("Using Stream, and fopen failed; retrying different CN match to try to overcome"); // www.googleapis.com does not match the cert now being presented - *.storage.googleapis.com; presumably, PHP's stream handler isn't handling alternative names properly. Rather than turn off all verification, let's retry with a new name to match. $options['ssl']['CN_match'] = 'www.storage.googleapis.com'; $context = stream_context_create($options); $fh = fopen($url, 'r', false, $context); } restore_error_handler(); // END - error trap. if ($this->trappedErrorNumber) { $error = sprintf( "HTTP Error: Unable to connect: '%s'", $this->trappedErrorString ); $this->client->getLogger()->error('Stream ' . $error); throw new UDP_Google_IO_Exception($error, $this->trappedErrorNumber); } $response_data = false; $respHttpCode = self::UNKNOWN_CODE; if ($fh) { if (isset($this->options[self::TIMEOUT])) { stream_set_timeout($fh, $this->options[self::TIMEOUT]); } $response_data = stream_get_contents($fh); fclose($fh); $respHttpCode = $this->getHttpResponseCode($http_response_header); } if (false === $response_data) { $error = sprintf( "HTTP Error: Unable to connect: '%s'", $respHttpCode ); $this->client->getLogger()->error('Stream ' . $error); throw new UDP_Google_IO_Exception($error, $respHttpCode); } $responseHeaders = $this->getHttpResponseHeaders($http_response_header); $this->client->getLogger()->debug( 'Stream response', array( 'code' => $respHttpCode, 'headers' => $responseHeaders, 'body' => $response_data, ) ); return array($response_data, $responseHeaders, $respHttpCode); } /** * Set options that update the transport implementation's behavior. * @param $options */ public function setOptions($options) { $this->options = $options + $this->options; } /** * Method to handle errors, used for error handling around * stream connection methods. */ public function trapError($errno, $errstr) { $this->trappedErrorNumber = $errno; $this->trappedErrorString = $errstr; } /** * Set the maximum request time in seconds. * @param $timeout in seconds */ public function setTimeout($timeout) { $this->options[self::TIMEOUT] = $timeout; } /** * Get the maximum request time in seconds. * @return timeout in seconds */ public function getTimeout() { return $this->options[self::TIMEOUT]; } /** * Test for the presence of a cURL header processing bug * * {@inheritDoc} * * @return boolean */ protected function needsQuirk() { return false; } protected function getHttpResponseCode($response_headers) { $header_count = count($response_headers); for ($i = 0; $i < $header_count; $i++) { $header = $response_headers[$i]; if (strncasecmp("HTTP", $header, strlen("HTTP")) == 0) { $response = explode(' ', $header); return $response[1]; } } return self::UNKNOWN_CODE; } } includes/Google/IO/Exception.php000064400000003457152214270100012547 0ustar00= 0) { parent::__construct($message, $code, $previous); } else { parent::__construct($message, $code); } if (is_array($retryMap)) { $this->retryMap = $retryMap; } } /** * Gets the number of times the associated task can be retried. * * NOTE: -1 is returned if the task can be retried indefinitely * * @return integer */ public function allowedRetries() { if (isset($this->retryMap[$this->code])) { return $this->retryMap[$this->code]; } return 0; } } includes/Google/IO/Curl.php000064400000012540152214270100011507 0ustar00 */ if (!class_exists('UDP_Google_Client')) { require_once dirname(__FILE__) . '/../autoload.php'; } class UDP_Google_IO_Curl extends UDP_Google_IO_Abstract { // cURL hex representation of version 7.30.0 const NO_QUIRK_VERSION = 0x071E00; private $options = array(); public function __construct(UDP_Google_Client $client) { if (!extension_loaded('curl')) { $error = 'The cURL IO handler requires the cURL extension to be enabled'; $client->getLogger()->critical($error); throw new UDP_Google_IO_Exception($error); } parent::__construct($client); } /** * Execute an HTTP Request * * @param Google_Http_Request $request the http request to be executed * @return array containing response headers, body, and http code * @throws UDP_Google_IO_Exception on curl or IO error */ public function executeRequest(UDP_Google_Http_Request $request) { $curl = curl_init(); if ($request->getPostBody()) { curl_setopt($curl, CURLOPT_POSTFIELDS, $request->getPostBody()); } $requestHeaders = $request->getRequestHeaders(); if ($requestHeaders && is_array($requestHeaders)) { $curlHeaders = array(); foreach ($requestHeaders as $k => $v) { $curlHeaders[] = "$k: $v"; } curl_setopt($curl, CURLOPT_HTTPHEADER, $curlHeaders); } curl_setopt($curl, CURLOPT_URL, $request->getUrl()); curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $request->getRequestMethod()); curl_setopt($curl, CURLOPT_USERAGENT, $request->getUserAgent()); curl_setopt($curl, CURLOPT_FOLLOWLOCATION, false); curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, true); // 1 is CURL_SSLVERSION_TLSv1, which is not always defined in PHP. // UpdraftPlus patch // The SDK leaves this on the default setting in later releases // curl_setopt($curl, CURLOPT_SSLVERSION, 1); curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); curl_setopt($curl, CURLOPT_HEADER, true); if ($request->canGzip()) { curl_setopt($curl, CURLOPT_ENCODING, 'gzip,deflate'); } $options = $this->client->getClassConfig('UDP_Google_IO_Curl', 'options'); if (is_array($options)) { $this->setOptions($options); } foreach ($this->options as $key => $var) { curl_setopt($curl, $key, $var); } if (!isset($this->options[CURLOPT_CAINFO])) { curl_setopt($curl, CURLOPT_CAINFO, dirname(__FILE__) . '/cacerts.pem'); } $this->client->getLogger()->debug( 'cURL request', array( 'url' => $request->getUrl(), 'method' => $request->getRequestMethod(), 'headers' => $requestHeaders, 'body' => $request->getPostBody() ) ); $response = curl_exec($curl); if ($response === false) { $error = curl_error($curl); $code = curl_errno($curl); $map = $this->client->getClassConfig('UDP_Google_IO_Exception', 'retry_map'); $this->client->getLogger()->error('cURL ' . $error); throw new UDP_Google_IO_Exception($error, $code, null, $map); } $headerSize = curl_getinfo($curl, CURLINFO_HEADER_SIZE); list($responseHeaders, $responseBody) = $this->parseHttpResponse($response, $headerSize); $responseCode = curl_getinfo($curl, CURLINFO_HTTP_CODE); $this->client->getLogger()->debug( 'cURL response', array( 'code' => $responseCode, 'headers' => $responseHeaders, 'body' => $responseBody, ) ); return array($responseBody, $responseHeaders, $responseCode); } /** * Set options that update the transport implementation's behavior. * @param $options */ public function setOptions($options) { $this->options = $options + $this->options; } /** * Set the maximum request time in seconds. * @param $timeout in seconds */ public function setTimeout($timeout) { // Since this timeout is really for putting a bound on the time // we'll set them both to the same. If you need to specify a longer // CURLOPT_TIMEOUT, or a higher CONNECTTIMEOUT, the best thing to // do is use the setOptions method for the values individually. $this->options[CURLOPT_CONNECTTIMEOUT] = $timeout; $this->options[CURLOPT_TIMEOUT] = $timeout; } /** * Get the maximum request time in seconds. * @return timeout in seconds */ public function getTimeout() { return $this->options[CURLOPT_TIMEOUT]; } /** * Test for the presence of a cURL header processing bug * * {@inheritDoc} * * @return boolean */ protected function needsQuirk() { $ver = curl_version(); $versionNum = $ver['version_number']; return $versionNum < UDP_Google_IO_Curl::NO_QUIRK_VERSION; } } includes/Google/Logger/Null.php000064400000002045152214270100012423 0ustar00 600, self::ALERT => 550, self::CRITICAL => 500, self::ERROR => 400, self::WARNING => 300, self::NOTICE => 250, self::INFO => 200, self::DEBUG => 100, ); /** * @var integer $level The minimum logging level */ protected $level = self::DEBUG; /** * @var string $logFormat The current log format */ protected $logFormat = self::DEFAULT_LOG_FORMAT; /** * @var string $dateFormat The current date format */ protected $dateFormat = self::DEFAULT_DATE_FORMAT; /** * @var boolean $allowNewLines If newlines are allowed */ protected $allowNewLines = false; /** * @param UDP_Google_Client $client The current Google client */ public function __construct(UDP_Google_Client $client) { $this->setLevel( $client->getClassConfig('Google_Logger_Abstract', 'level') ); $format = $client->getClassConfig('Google_Logger_Abstract', 'log_format'); $this->logFormat = $format ? $format : self::DEFAULT_LOG_FORMAT; $format = $client->getClassConfig('Google_Logger_Abstract', 'date_format'); $this->dateFormat = $format ? $format : self::DEFAULT_DATE_FORMAT; $this->allowNewLines = (bool) $client->getClassConfig( 'Google_Logger_Abstract', 'allow_newlines' ); } /** * Sets the minimum logging level that this logger handles. * * @param integer $level */ public function setLevel($level) { $this->level = $this->normalizeLevel($level); } /** * Checks if the logger should handle messages at the provided level. * * @param integer $level * @return boolean */ public function shouldHandle($level) { return $this->normalizeLevel($level) >= $this->level; } /** * System is unusable. * * @param string $message The log message * @param array $context The log context */ public function emergency($message, array $context = array()) { $this->log(self::EMERGENCY, $message, $context); } /** * Action must be taken immediately. * * Example: Entire website down, database unavailable, etc. This should * trigger the SMS alerts and wake you up. * * @param string $message The log message * @param array $context The log context */ public function alert($message, array $context = array()) { $this->log(self::ALERT, $message, $context); } /** * Critical conditions. * * Example: Application component unavailable, unexpected exception. * * @param string $message The log message * @param array $context The log context */ public function critical($message, array $context = array()) { $this->log(self::CRITICAL, $message, $context); } /** * Runtime errors that do not require immediate action but should typically * be logged and monitored. * * @param string $message The log message * @param array $context The log context */ public function error($message, array $context = array()) { $this->log(self::ERROR, $message, $context); } /** * Exceptional occurrences that are not errors. * * Example: Use of deprecated APIs, poor use of an API, undesirable things * that are not necessarily wrong. * * @param string $message The log message * @param array $context The log context */ public function warning($message, array $context = array()) { $this->log(self::WARNING, $message, $context); } /** * Normal but significant events. * * @param string $message The log message * @param array $context The log context */ public function notice($message, array $context = array()) { $this->log(self::NOTICE, $message, $context); } /** * Interesting events. * * Example: User logs in, SQL logs. * * @param string $message The log message * @param array $context The log context */ public function info($message, array $context = array()) { $this->log(self::INFO, $message, $context); } /** * Detailed debug information. * * @param string $message The log message * @param array $context The log context */ public function debug($message, array $context = array()) { $this->log(self::DEBUG, $message, $context); } /** * Logs with an arbitrary level. * * @param mixed $level The log level * @param string $message The log message * @param array $context The log context */ public function log($level, $message, array $context = array()) { if (!$this->shouldHandle($level)) { return false; } $levelName = is_int($level) ? array_search($level, self::$levels) : $level; $message = $this->interpolate( array( 'message' => $message, 'context' => $context, 'level' => strtoupper($levelName), 'datetime' => new DateTime(), ) ); $this->write($message); } /** * Interpolates log variables into the defined log format. * * @param array $variables The log variables. * @return string */ protected function interpolate(array $variables = array()) { $template = $this->logFormat; if (!$variables['context']) { $template = str_replace('%context%', '', $template); unset($variables['context']); } else { $this->reverseJsonInContext($variables['context']); } foreach ($variables as $key => $value) { if (strpos($template, '%'. $key .'%') !== false) { $template = str_replace( '%' . $key . '%', $this->export($value), $template ); } } return $template; } /** * Reverses JSON encoded PHP arrays and objects so that they log better. * * @param array $context The log context */ protected function reverseJsonInContext(array &$context) { if (!$context) { return; } foreach ($context as $key => $val) { if (!$val || !is_string($val) || !($val[0] == '{' || $val[0] == '[')) { continue; } $json = @json_decode($val); if (is_object($json) || is_array($json)) { $context[$key] = $json; } } } /** * Exports a PHP value for logging to a string. * * @param mixed $value The value to */ protected function export($value) { if (is_string($value)) { if ($this->allowNewLines) { return $value; } return preg_replace('/[\r\n]+/', ' ', $value); } if (is_resource($value)) { return sprintf( 'resource(%d) of type (%s)', $value, get_resource_type($value) ); } if ($value instanceof DateTime) { return $value->format($this->dateFormat); } if (version_compare(PHP_VERSION, '5.4.0', '>=')) { // @codingStandardsIgnoreLine $options = JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE; if ($this->allowNewLines) { // @codingStandardsIgnoreLine $options |= JSON_PRETTY_PRINT; } return @json_encode($value, $options); } return str_replace('\\/', '/', @json_encode($value)); } /** * Converts a given log level to the integer form. * * @param mixed $level The logging level * @return integer $level The normalized level * @throws Google_Logger_Exception If $level is invalid */ protected function normalizeLevel($level) { if (is_int($level) && array_search($level, self::$levels) !== false) { return $level; } if (is_string($level) && isset(self::$levels[$level])) { return self::$levels[$level]; } throw new Google_Logger_Exception( sprintf("Unknown LogLevel: '%s'", $level) ); } /** * Writes a message to the current log implementation. * * @param string $message The message */ abstract protected function write($message); } includes/Google/Logger/Psr.php000064400000004643152214270100012263 0ustar00setLogger($logger); } } /** * Sets the PSR-3 logger where logging will be delegated. * * NOTE: The `$logger` should technically implement * `Psr\Log\LoggerInterface`, but we don't explicitly require this so that * we can be compatible with PHP 5.2. * * @param Psr\Log\LoggerInterface $logger The PSR-3 logger */ public function setLogger(/*Psr\Log\LoggerInterface*/ $logger) { $this->logger = $logger; } /** * {@inheritdoc} */ public function shouldHandle($level) { return isset($this->logger) && parent::shouldHandle($level); } /** * {@inheritdoc} */ public function log($level, $message, array $context = array()) { if (!$this->shouldHandle($level)) { return false; } if ($context) { $this->reverseJsonInContext($context); } $levelName = is_int($level) ? array_search($level, self::$levels) : $level; $this->logger->log($levelName, $message, $context); } /** * {@inheritdoc} */ protected function write($message, array $context = array()) { } } includes/Google/Logger/File.php000064400000007156152214270100012400 0ustar00getClassConfig('Google_Logger_File', 'file'); if (!is_string($file) && !is_resource($file)) { throw new Google_Logger_Exception( 'File logger requires a filename or a valid file pointer' ); } $mode = $client->getClassConfig('Google_Logger_File', 'mode'); if (!$mode) { $this->mode = $mode; } $this->lock = (bool) $client->getClassConfig('Google_Logger_File', 'lock'); $this->file = $file; } /** * {@inheritdoc} */ protected function write($message) { if (is_string($this->file)) { $this->open(); } elseif (!is_resource($this->file)) { throw new Google_Logger_Exception('File pointer is no longer available'); } if ($this->lock) { flock($this->file, LOCK_EX); } fwrite($this->file, (string) $message); if ($this->lock) { flock($this->file, LOCK_UN); } } /** * Opens the log for writing. * * @return resource */ private function open() { // Used for trapping `fopen()` errors. $this->trappedErrorNumber = null; $this->trappedErrorString = null; $old = set_error_handler(array($this, 'trapError')); $needsChmod = !file_exists($this->file); $fh = fopen($this->file, 'a'); restore_error_handler(); // Handles trapped `fopen()` errors. if ($this->trappedErrorNumber) { throw new Google_Logger_Exception( sprintf( "Logger Error: '%s'", $this->trappedErrorString ), $this->trappedErrorNumber ); } if ($needsChmod) { @chmod($this->file, $this->mode & ~umask()); } return $this->file = $fh; } /** * Closes the log stream resource. */ private function close() { if (is_resource($this->file)) { fclose($this->file); } } /** * Traps `fopen()` errors. * * @param integer $errno The error number * @param string $errstr The error string */ private function trapError($errno, $errstr) { $this->trappedErrorNumber = $errno; $this->trappedErrorString = $errstr; } public function __destruct() { $this->close(); } } includes/Google/Logger/Exception.php000064400000001371152214270100013450 0ustar00 * Lets you access OAuth2 protocol related APIs.

* *

* For more information about this service, see the API * Documentation *

* * @author Google, Inc. */ class UDP_Google_Service_Oauth2 extends UDP_Google_Service { /** Know your basic profile info and list of people in your circles.. */ const PLUS_LOGIN = "https://www.googleapis.com/auth/plus.login"; /** Know who you are on Google. */ const PLUS_ME = "https://www.googleapis.com/auth/plus.me"; /** View your email address. */ const USERINFO_EMAIL = "https://www.googleapis.com/auth/userinfo.email"; /** View your basic profile info. */ const USERINFO_PROFILE = "https://www.googleapis.com/auth/userinfo.profile"; public $userinfo; public $userinfo_v2_me; private $serviceName; private $base_methods; /** * Constructs the internal representation of the Oauth2 service. * * @param UDP_Google_Client $client */ public function __construct(UDP_Google_Client $client) { parent::__construct($client); $this->servicePath = ''; $this->version = 'v2'; $this->serviceName = 'oauth2'; $this->userinfo = new Google_Service_Oauth2_Userinfo_Resource( $this, $this->serviceName, 'userinfo', array( 'methods' => array( 'get' => array( 'path' => 'oauth2/v2/userinfo', 'httpMethod' => 'GET', 'parameters' => array(), ), ) ) ); $this->userinfo_v2_me = new Google_Service_Oauth2_UserinfoV2Me_Resource( $this, $this->serviceName, 'me', array( 'methods' => array( 'get' => array( 'path' => 'userinfo/v2/me', 'httpMethod' => 'GET', 'parameters' => array(), ), ) ) ); $this->base_methods = new UDP_Google_Service_Resource( $this, $this->serviceName, '', array( 'methods' => array( 'getCertForOpenIdConnect' => array( 'path' => 'oauth2/v2/certs', 'httpMethod' => 'GET', 'parameters' => array(), ),'tokeninfo' => array( 'path' => 'oauth2/v2/tokeninfo', 'httpMethod' => 'POST', 'parameters' => array( 'access_token' => array( 'location' => 'query', 'type' => 'string', ), 'id_token' => array( 'location' => 'query', 'type' => 'string', ), 'token_handle' => array( 'location' => 'query', 'type' => 'string', ), ), ), ) ) ); } /** * (getCertForOpenIdConnect) * * @param array $optParams Optional parameters. * @return Google_Service_Oauth2_Jwk */ public function getCertForOpenIdConnect($optParams = array()) { $params = array(); $params = array_merge($params, $optParams); return $this->base_methods->call('getCertForOpenIdConnect', array($params), "Google_Service_Oauth2_Jwk"); } /** * (tokeninfo) * * @param array $optParams Optional parameters. * * @opt_param string access_token * @opt_param string id_token * @opt_param string token_handle * @return Google_Service_Oauth2_Tokeninfo */ public function tokeninfo($optParams = array()) { $params = array(); $params = array_merge($params, $optParams); return $this->base_methods->call('tokeninfo', array($params), "Google_Service_Oauth2_Tokeninfo"); } } /** * The "userinfo" collection of methods. * Typical usage is: * * $oauth2Service = new UDP_Google_Service_Oauth2(...); * $userinfo = $oauth2Service->userinfo; * */ class Google_Service_Oauth2_Userinfo_Resource extends UDP_Google_Service_Resource { /** * (userinfo.get) * * @param array $optParams Optional parameters. * @return Google_Service_Oauth2_Userinfoplus */ public function get($optParams = array()) { $params = array(); $params = array_merge($params, $optParams); return $this->call('get', array($params), "Google_Service_Oauth2_Userinfoplus"); } } /** * The "v2" collection of methods. * Typical usage is: * * $oauth2Service = new UDP_Google_Service_Oauth2(...); * $v2 = $oauth2Service->v2; * */ class Google_Service_Oauth2_UserinfoV2_Resource extends UDP_Google_Service_Resource { } /** * The "me" collection of methods. * Typical usage is: * * $oauth2Service = new UDP_Google_Service_Oauth2(...); * $me = $oauth2Service->me; * */ class Google_Service_Oauth2_UserinfoV2Me_Resource extends UDP_Google_Service_Resource { /** * (me.get) * * @param array $optParams Optional parameters. * @return Google_Service_Oauth2_Userinfoplus */ public function get($optParams = array()) { $params = array(); $params = array_merge($params, $optParams); return $this->call('get', array($params), "Google_Service_Oauth2_Userinfoplus"); } } class Google_Service_Oauth2_Jwk extends Google_Collection { protected $collection_key = 'keys'; protected $internal_gapi_mappings = array( ); protected $keysType = 'Google_Service_Oauth2_JwkKeys'; protected $keysDataType = 'array'; public function setKeys($keys) { $this->keys = $keys; } public function getKeys() { return $this->keys; } } class Google_Service_Oauth2_JwkKeys extends Google_Model { protected $internal_gapi_mappings = array( ); public $alg; public $e; public $kid; public $kty; public $n; public $use; public function setAlg($alg) { $this->alg = $alg; } public function getAlg() { return $this->alg; } public function setE($e) { $this->e = $e; } public function getE() { return $this->e; } public function setKid($kid) { $this->kid = $kid; } public function getKid() { return $this->kid; } public function setKty($kty) { $this->kty = $kty; } public function getKty() { return $this->kty; } public function setN($n) { $this->n = $n; } public function getN() { return $this->n; } public function setUse($use) { $this->use = $use; } public function getUse() { return $this->use; } } class Google_Service_Oauth2_Tokeninfo extends Google_Model { protected $internal_gapi_mappings = array( "accessType" => "access_type", "expiresIn" => "expires_in", "issuedTo" => "issued_to", "tokenHandle" => "token_handle", "userId" => "user_id", "verifiedEmail" => "verified_email", ); public $accessType; public $audience; public $email; public $expiresIn; public $issuedTo; public $scope; public $tokenHandle; public $userId; public $verifiedEmail; public function setAccessType($accessType) { $this->accessType = $accessType; } public function getAccessType() { return $this->accessType; } public function setAudience($audience) { $this->audience = $audience; } public function getAudience() { return $this->audience; } public function setEmail($email) { $this->email = $email; } public function getEmail() { return $this->email; } public function setExpiresIn($expiresIn) { $this->expiresIn = $expiresIn; } public function getExpiresIn() { return $this->expiresIn; } public function setIssuedTo($issuedTo) { $this->issuedTo = $issuedTo; } public function getIssuedTo() { return $this->issuedTo; } public function setScope($scope) { $this->scope = $scope; } public function getScope() { return $this->scope; } public function setTokenHandle($tokenHandle) { $this->tokenHandle = $tokenHandle; } public function getTokenHandle() { return $this->tokenHandle; } public function setUserId($userId) { $this->userId = $userId; } public function getUserId() { return $this->userId; } public function setVerifiedEmail($verifiedEmail) { $this->verifiedEmail = $verifiedEmail; } public function getVerifiedEmail() { return $this->verifiedEmail; } } class Google_Service_Oauth2_Userinfoplus extends Google_Model { protected $internal_gapi_mappings = array( "familyName" => "family_name", "givenName" => "given_name", "verifiedEmail" => "verified_email", ); public $email; public $familyName; public $gender; public $givenName; public $hd; public $id; public $link; public $locale; public $name; public $picture; public $verifiedEmail; public function setEmail($email) { $this->email = $email; } public function getEmail() { return $this->email; } public function setFamilyName($familyName) { $this->familyName = $familyName; } public function getFamilyName() { return $this->familyName; } public function setGender($gender) { $this->gender = $gender; } public function getGender() { return $this->gender; } public function setGivenName($givenName) { $this->givenName = $givenName; } public function getGivenName() { return $this->givenName; } public function setHd($hd) { $this->hd = $hd; } public function getHd() { return $this->hd; } public function setId($id) { $this->id = $id; } public function getId() { return $this->id; } public function setLink($link) { $this->link = $link; } public function getLink() { return $this->link; } public function setLocale($locale) { $this->locale = $locale; } public function getLocale() { return $this->locale; } public function setName($name) { $this->name = $name; } public function getName() { return $this->name; } public function setPicture($picture) { $this->picture = $picture; } public function getPicture() { return $this->picture; } public function setVerifiedEmail($verifiedEmail) { $this->verifiedEmail = $verifiedEmail; } public function getVerifiedEmail() { return $this->verifiedEmail; } } includes/Google/Service/Logging.php000064400000117514152214270100013270 0ustar00 * Google Cloud Logging API lets you create logs, ingest log entries, and manage * log sinks.

* *

* For more information about this service, see the API * Documentation *

* * @author Google, Inc. */ class Google_Service_Logging extends UDP_Google_Service { /** View and manage your data across Google Cloud Platform services. */ const CLOUD_PLATFORM = "https://www.googleapis.com/auth/cloud-platform"; public $projects_logServices; public $projects_logServices_indexes; public $projects_logServices_sinks; public $projects_logs; public $projects_logs_entries; public $projects_logs_sinks; /** * Constructs the internal representation of the Logging service. * * @param Google_Client $client */ public function __construct(UDP_Google_Client $client) { parent::__construct($client); $this->servicePath = ''; $this->version = 'v1beta3'; $this->serviceName = 'logging'; $this->projects_logServices = new Google_Service_Logging_ProjectsLogServices_Resource( $this, $this->serviceName, 'logServices', array( 'methods' => array( 'list' => array( 'path' => 'v1beta3/projects/{projectsId}/logServices', 'httpMethod' => 'GET', 'parameters' => array( 'projectsId' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'pageToken' => array( 'location' => 'query', 'type' => 'string', ), 'log' => array( 'location' => 'query', 'type' => 'string', ), 'pageSize' => array( 'location' => 'query', 'type' => 'integer', ), ), ), ) ) ); $this->projects_logServices_indexes = new Google_Service_Logging_ProjectsLogServicesIndexes_Resource( $this, $this->serviceName, 'indexes', array( 'methods' => array( 'list' => array( 'path' => 'v1beta3/projects/{projectsId}/logServices/{logServicesId}/indexes', 'httpMethod' => 'GET', 'parameters' => array( 'projectsId' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'logServicesId' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'log' => array( 'location' => 'query', 'type' => 'string', ), 'pageSize' => array( 'location' => 'query', 'type' => 'integer', ), 'pageToken' => array( 'location' => 'query', 'type' => 'string', ), 'depth' => array( 'location' => 'query', 'type' => 'integer', ), 'indexPrefix' => array( 'location' => 'query', 'type' => 'string', ), ), ), ) ) ); $this->projects_logServices_sinks = new Google_Service_Logging_ProjectsLogServicesSinks_Resource( $this, $this->serviceName, 'sinks', array( 'methods' => array( 'create' => array( 'path' => 'v1beta3/projects/{projectsId}/logServices/{logServicesId}/sinks', 'httpMethod' => 'POST', 'parameters' => array( 'projectsId' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'logServicesId' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), ), ),'delete' => array( 'path' => 'v1beta3/projects/{projectsId}/logServices/{logServicesId}/sinks/{sinksId}', 'httpMethod' => 'DELETE', 'parameters' => array( 'projectsId' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'logServicesId' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'sinksId' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), ), ),'get' => array( 'path' => 'v1beta3/projects/{projectsId}/logServices/{logServicesId}/sinks/{sinksId}', 'httpMethod' => 'GET', 'parameters' => array( 'projectsId' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'logServicesId' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'sinksId' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), ), ),'list' => array( 'path' => 'v1beta3/projects/{projectsId}/logServices/{logServicesId}/sinks', 'httpMethod' => 'GET', 'parameters' => array( 'projectsId' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'logServicesId' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), ), ),'update' => array( 'path' => 'v1beta3/projects/{projectsId}/logServices/{logServicesId}/sinks/{sinksId}', 'httpMethod' => 'PUT', 'parameters' => array( 'projectsId' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'logServicesId' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'sinksId' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), ), ), ) ) ); $this->projects_logs = new Google_Service_Logging_ProjectsLogs_Resource( $this, $this->serviceName, 'logs', array( 'methods' => array( 'delete' => array( 'path' => 'v1beta3/projects/{projectsId}/logs/{logsId}', 'httpMethod' => 'DELETE', 'parameters' => array( 'projectsId' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'logsId' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), ), ),'list' => array( 'path' => 'v1beta3/projects/{projectsId}/logs', 'httpMethod' => 'GET', 'parameters' => array( 'projectsId' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'pageToken' => array( 'location' => 'query', 'type' => 'string', ), 'serviceName' => array( 'location' => 'query', 'type' => 'string', ), 'serviceIndexPrefix' => array( 'location' => 'query', 'type' => 'string', ), 'pageSize' => array( 'location' => 'query', 'type' => 'integer', ), ), ), ) ) ); $this->projects_logs_entries = new Google_Service_Logging_ProjectsLogsEntries_Resource( $this, $this->serviceName, 'entries', array( 'methods' => array( 'write' => array( 'path' => 'v1beta3/projects/{projectsId}/logs/{logsId}/entries:write', 'httpMethod' => 'POST', 'parameters' => array( 'projectsId' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'logsId' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), ), ), ) ) ); $this->projects_logs_sinks = new Google_Service_Logging_ProjectsLogsSinks_Resource( $this, $this->serviceName, 'sinks', array( 'methods' => array( 'create' => array( 'path' => 'v1beta3/projects/{projectsId}/logs/{logsId}/sinks', 'httpMethod' => 'POST', 'parameters' => array( 'projectsId' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'logsId' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), ), ),'delete' => array( 'path' => 'v1beta3/projects/{projectsId}/logs/{logsId}/sinks/{sinksId}', 'httpMethod' => 'DELETE', 'parameters' => array( 'projectsId' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'logsId' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'sinksId' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), ), ),'get' => array( 'path' => 'v1beta3/projects/{projectsId}/logs/{logsId}/sinks/{sinksId}', 'httpMethod' => 'GET', 'parameters' => array( 'projectsId' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'logsId' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'sinksId' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), ), ),'list' => array( 'path' => 'v1beta3/projects/{projectsId}/logs/{logsId}/sinks', 'httpMethod' => 'GET', 'parameters' => array( 'projectsId' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'logsId' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), ), ),'update' => array( 'path' => 'v1beta3/projects/{projectsId}/logs/{logsId}/sinks/{sinksId}', 'httpMethod' => 'PUT', 'parameters' => array( 'projectsId' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'logsId' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'sinksId' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), ), ), ) ) ); } } /** * The "projects" collection of methods. * Typical usage is: * * $loggingService = new Google_Service_Logging(...); * $projects = $loggingService->projects; * */ class Google_Service_Logging_Projects_Resource extends UDP_Google_Service_Resource { } /** * The "logServices" collection of methods. * Typical usage is: * * $loggingService = new Google_Service_Logging(...); * $logServices = $loggingService->logServices; * */ class Google_Service_Logging_ProjectsLogServices_Resource extends UDP_Google_Service_Resource { /** * Lists log services associated with log entries ingested for a project. * (logServices.listProjectsLogServices) * * @param string $projectsId Part of `projectName`. The project resource whose * services are to be listed. * @param array $optParams Optional parameters. * * @opt_param string pageToken An opaque token, returned as `nextPageToken` by a * prior `ListLogServices` operation. If `pageToken` is supplied, then the other * fields of this request are ignored, and instead the previous * `ListLogServices` operation is continued. * @opt_param string log The name of the log resource whose services are to be * listed. log for which to list services. When empty, all services are listed. * @opt_param int pageSize The maximum number of `LogService` objects to return * in one operation. * @return Google_Service_Logging_ListLogServicesResponse */ public function listProjectsLogServices($projectsId, $optParams = array()) { $params = array('projectsId' => $projectsId); $params = array_merge($params, $optParams); return $this->call('list', array($params), "Google_Service_Logging_ListLogServicesResponse"); } } /** * The "indexes" collection of methods. * Typical usage is: * * $loggingService = new Google_Service_Logging(...); * $indexes = $loggingService->indexes; * */ class Google_Service_Logging_ProjectsLogServicesIndexes_Resource extends UDP_Google_Service_Resource { /** * Lists log service indexes associated with a log service. * (indexes.listProjectsLogServicesIndexes) * * @param string $projectsId Part of `serviceName`. A log service resource of * the form `/projects/logServices`. The service indexes of the log service are * returned. Example: `"/projects/myProj/logServices/appengine.googleapis.com"`. * @param string $logServicesId Part of `serviceName`. See documentation of * `projectsId`. * @param array $optParams Optional parameters. * * @opt_param string log A log resource like * `/projects/project_id/logs/log_name`, identifying the log for which to list * service indexes. * @opt_param int pageSize The maximum number of log service index resources to * return in one operation. * @opt_param string pageToken An opaque token, returned as `nextPageToken` by a * prior `ListLogServiceIndexes` operation. If `pageToken` is supplied, then the * other fields of this request are ignored, and instead the previous * `ListLogServiceIndexes` operation is continued. * @opt_param int depth A limit to the number of levels of the index hierarchy * that are expanded. If `depth` is 0, it defaults to the level specified by the * prefix field (the number of slash separators). The default empty prefix * implies a `depth` of 1. It is an error for `depth` to be any non-zero value * less than the number of components in `indexPrefix`. * @opt_param string indexPrefix Restricts the indexes returned to be those with * a specified prefix. The prefix has the form `"/label_value/label_value/..."`, * in order corresponding to the [`LogService * indexKeys`][google.logging.v1.LogService.index_keys]. Non-empty prefixes must * begin with `/` . Example prefixes: + `"/myModule/"` retrieves App Engine * versions associated with `myModule`. The trailing slash terminates the value. * + `"/myModule"` retrieves App Engine modules with names beginning with * `myModule`. + `""` retrieves all indexes. * @return Google_Service_Logging_ListLogServiceIndexesResponse */ public function listProjectsLogServicesIndexes($projectsId, $logServicesId, $optParams = array()) { $params = array('projectsId' => $projectsId, 'logServicesId' => $logServicesId); $params = array_merge($params, $optParams); return $this->call('list', array($params), "Google_Service_Logging_ListLogServiceIndexesResponse"); } } /** * The "sinks" collection of methods. * Typical usage is: * * $loggingService = new Google_Service_Logging(...); * $sinks = $loggingService->sinks; * */ class Google_Service_Logging_ProjectsLogServicesSinks_Resource extends UDP_Google_Service_Resource { /** * Creates the specified log service sink resource. (sinks.create) * * @param string $projectsId Part of `serviceName`. The name of the service in * which to create a sink. * @param string $logServicesId Part of `serviceName`. See documentation of * `projectsId`. * @param Google_LogSink $postBody * @param array $optParams Optional parameters. * @return Google_Service_Logging_LogSink */ public function create($projectsId, $logServicesId, Google_Service_Logging_LogSink $postBody, $optParams = array()) { $params = array('projectsId' => $projectsId, 'logServicesId' => $logServicesId, 'postBody' => $postBody); $params = array_merge($params, $optParams); return $this->call('create', array($params), "Google_Service_Logging_LogSink"); } /** * Deletes the specified log service sink. (sinks.delete) * * @param string $projectsId Part of `sinkName`. The name of the sink to delete. * @param string $logServicesId Part of `sinkName`. See documentation of * `projectsId`. * @param string $sinksId Part of `sinkName`. See documentation of `projectsId`. * @param array $optParams Optional parameters. * @return Google_Service_Logging_Empty */ public function delete($projectsId, $logServicesId, $sinksId, $optParams = array()) { $params = array('projectsId' => $projectsId, 'logServicesId' => $logServicesId, 'sinksId' => $sinksId); $params = array_merge($params, $optParams); return $this->call('delete', array($params), "Google_Service_Logging_Empty"); } /** * Gets the specified log service sink resource. (sinks.get) * * @param string $projectsId Part of `sinkName`. The name of the sink to return. * @param string $logServicesId Part of `sinkName`. See documentation of * `projectsId`. * @param string $sinksId Part of `sinkName`. See documentation of `projectsId`. * @param array $optParams Optional parameters. * @return Google_Service_Logging_LogSink */ public function get($projectsId, $logServicesId, $sinksId, $optParams = array()) { $params = array('projectsId' => $projectsId, 'logServicesId' => $logServicesId, 'sinksId' => $sinksId); $params = array_merge($params, $optParams); return $this->call('get', array($params), "Google_Service_Logging_LogSink"); } /** * Lists log service sinks associated with the specified service. * (sinks.listProjectsLogServicesSinks) * * @param string $projectsId Part of `serviceName`. The name of the service for * which to list sinks. * @param string $logServicesId Part of `serviceName`. See documentation of * `projectsId`. * @param array $optParams Optional parameters. * @return Google_Service_Logging_ListLogServiceSinksResponse */ public function listProjectsLogServicesSinks($projectsId, $logServicesId, $optParams = array()) { $params = array('projectsId' => $projectsId, 'logServicesId' => $logServicesId); $params = array_merge($params, $optParams); return $this->call('list', array($params), "Google_Service_Logging_ListLogServiceSinksResponse"); } /** * Creates or update the specified log service sink resource. (sinks.update) * * @param string $projectsId Part of `sinkName`. The name of the sink to update. * @param string $logServicesId Part of `sinkName`. See documentation of * `projectsId`. * @param string $sinksId Part of `sinkName`. See documentation of `projectsId`. * @param Google_LogSink $postBody * @param array $optParams Optional parameters. * @return Google_Service_Logging_LogSink */ public function update($projectsId, $logServicesId, $sinksId, Google_Service_Logging_LogSink $postBody, $optParams = array()) { $params = array('projectsId' => $projectsId, 'logServicesId' => $logServicesId, 'sinksId' => $sinksId, 'postBody' => $postBody); $params = array_merge($params, $optParams); return $this->call('update', array($params), "Google_Service_Logging_LogSink"); } } /** * The "logs" collection of methods. * Typical usage is: * * $loggingService = new Google_Service_Logging(...); * $logs = $loggingService->logs; * */ class Google_Service_Logging_ProjectsLogs_Resource extends UDP_Google_Service_Resource { /** * Deletes the specified log resource and all log entries contained in it. * (logs.delete) * * @param string $projectsId Part of `logName`. The log resource to delete. * @param string $logsId Part of `logName`. See documentation of `projectsId`. * @param array $optParams Optional parameters. * @return Google_Service_Logging_Empty */ public function delete($projectsId, $logsId, $optParams = array()) { $params = array('projectsId' => $projectsId, 'logsId' => $logsId); $params = array_merge($params, $optParams); return $this->call('delete', array($params), "Google_Service_Logging_Empty"); } /** * Lists log resources belonging to the specified project. * (logs.listProjectsLogs) * * @param string $projectsId Part of `projectName`. The project name for which * to list the log resources. * @param array $optParams Optional parameters. * * @opt_param string pageToken An opaque token, returned as `nextPageToken` by a * prior `ListLogs` operation. If `pageToken` is supplied, then the other fields * of this request are ignored, and instead the previous `ListLogs` operation is * continued. * @opt_param string serviceName A service name for which to list logs. Only * logs containing entries whose metadata includes this service name are * returned. If `serviceName` and `serviceIndexPrefix` are both empty, then all * log names are returned. To list all log names, regardless of service, leave * both the `serviceName` and `serviceIndexPrefix` empty. To list log names * containing entries with a particular service name (or explicitly empty * service name) set `serviceName` to the desired value and `serviceIndexPrefix` * to `"/"`. * @opt_param string serviceIndexPrefix A log service index prefix for which to * list logs. Only logs containing entries whose metadata that includes these * label values (associated with index keys) are returned. The prefix is a slash * separated list of values, and need not specify all index labels. An empty * index (or a single slash) matches all log service indexes. * @opt_param int pageSize The maximum number of results to return. * @return Google_Service_Logging_ListLogsResponse */ public function listProjectsLogs($projectsId, $optParams = array()) { $params = array('projectsId' => $projectsId); $params = array_merge($params, $optParams); return $this->call('list', array($params), "Google_Service_Logging_ListLogsResponse"); } } /** * The "entries" collection of methods. * Typical usage is: * * $loggingService = new Google_Service_Logging(...); * $entries = $loggingService->entries; * */ class Google_Service_Logging_ProjectsLogsEntries_Resource extends UDP_Google_Service_Resource { /** * Creates one or more log entries in a log. You must supply a list of * `LogEntry` objects, named `entries`. Each `LogEntry` object must contain a * payload object and a `LogEntryMetadata` object that describes the entry. You * must fill in all the fields of the entry, metadata, and payload. You can also * supply a map, `commonLabels`, that supplies default (key, value) data for the * `entries[].metadata.labels` maps, saving you the trouble of creating * identical copies for each entry. (entries.write) * * @param string $projectsId Part of `logName`. The name of the log resource * into which to insert the log entries. * @param string $logsId Part of `logName`. See documentation of `projectsId`. * @param Google_WriteLogEntriesRequest $postBody * @param array $optParams Optional parameters. * @return Google_Service_Logging_WriteLogEntriesResponse */ public function write($projectsId, $logsId, Google_Service_Logging_WriteLogEntriesRequest $postBody, $optParams = array()) { $params = array('projectsId' => $projectsId, 'logsId' => $logsId, 'postBody' => $postBody); $params = array_merge($params, $optParams); return $this->call('write', array($params), "Google_Service_Logging_WriteLogEntriesResponse"); } } /** * The "sinks" collection of methods. * Typical usage is: * * $loggingService = new Google_Service_Logging(...); * $sinks = $loggingService->sinks; * */ class Google_Service_Logging_ProjectsLogsSinks_Resource extends UDP_Google_Service_Resource { /** * Creates the specified log sink resource. (sinks.create) * * @param string $projectsId Part of `logName`. The log in which to create a * sink resource. * @param string $logsId Part of `logName`. See documentation of `projectsId`. * @param Google_LogSink $postBody * @param array $optParams Optional parameters. * @return Google_Service_Logging_LogSink */ public function create($projectsId, $logsId, Google_Service_Logging_LogSink $postBody, $optParams = array()) { $params = array('projectsId' => $projectsId, 'logsId' => $logsId, 'postBody' => $postBody); $params = array_merge($params, $optParams); return $this->call('create', array($params), "Google_Service_Logging_LogSink"); } /** * Deletes the specified log sink resource. (sinks.delete) * * @param string $projectsId Part of `sinkName`. The name of the sink to delete. * @param string $logsId Part of `sinkName`. See documentation of `projectsId`. * @param string $sinksId Part of `sinkName`. See documentation of `projectsId`. * @param array $optParams Optional parameters. * @return Google_Service_Logging_Empty */ public function delete($projectsId, $logsId, $sinksId, $optParams = array()) { $params = array('projectsId' => $projectsId, 'logsId' => $logsId, 'sinksId' => $sinksId); $params = array_merge($params, $optParams); return $this->call('delete', array($params), "Google_Service_Logging_Empty"); } /** * Gets the specified log sink resource. (sinks.get) * * @param string $projectsId Part of `sinkName`. The name of the sink resource * to return. * @param string $logsId Part of `sinkName`. See documentation of `projectsId`. * @param string $sinksId Part of `sinkName`. See documentation of `projectsId`. * @param array $optParams Optional parameters. * @return Google_Service_Logging_LogSink */ public function get($projectsId, $logsId, $sinksId, $optParams = array()) { $params = array('projectsId' => $projectsId, 'logsId' => $logsId, 'sinksId' => $sinksId); $params = array_merge($params, $optParams); return $this->call('get', array($params), "Google_Service_Logging_LogSink"); } /** * Lists log sinks associated with the specified log. * (sinks.listProjectsLogsSinks) * * @param string $projectsId Part of `logName`. The log for which to list sinks. * @param string $logsId Part of `logName`. See documentation of `projectsId`. * @param array $optParams Optional parameters. * @return Google_Service_Logging_ListLogSinksResponse */ public function listProjectsLogsSinks($projectsId, $logsId, $optParams = array()) { $params = array('projectsId' => $projectsId, 'logsId' => $logsId); $params = array_merge($params, $optParams); return $this->call('list', array($params), "Google_Service_Logging_ListLogSinksResponse"); } /** * Creates or updates the specified log sink resource. (sinks.update) * * @param string $projectsId Part of `sinkName`. The name of the sink to update. * @param string $logsId Part of `sinkName`. See documentation of `projectsId`. * @param string $sinksId Part of `sinkName`. See documentation of `projectsId`. * @param Google_LogSink $postBody * @param array $optParams Optional parameters. * @return Google_Service_Logging_LogSink */ public function update($projectsId, $logsId, $sinksId, Google_Service_Logging_LogSink $postBody, $optParams = array()) { $params = array('projectsId' => $projectsId, 'logsId' => $logsId, 'sinksId' => $sinksId, 'postBody' => $postBody); $params = array_merge($params, $optParams); return $this->call('update', array($params), "Google_Service_Logging_LogSink"); } } class Google_Service_Logging_Empty extends Google_Model { } class Google_Service_Logging_ListLogServiceIndexesResponse extends Google_Collection { protected $collection_key = 'serviceIndexPrefixes'; protected $internal_gapi_mappings = array( ); public $nextPageToken; public $serviceIndexPrefixes; public function setNextPageToken($nextPageToken) { $this->nextPageToken = $nextPageToken; } public function getNextPageToken() { return $this->nextPageToken; } public function setServiceIndexPrefixes($serviceIndexPrefixes) { $this->serviceIndexPrefixes = $serviceIndexPrefixes; } public function getServiceIndexPrefixes() { return $this->serviceIndexPrefixes; } } class Google_Service_Logging_ListLogServiceSinksResponse extends Google_Collection { protected $collection_key = 'sinks'; protected $internal_gapi_mappings = array( ); protected $sinksType = 'Google_Service_Logging_LogSink'; protected $sinksDataType = 'array'; public function setSinks($sinks) { $this->sinks = $sinks; } public function getSinks() { return $this->sinks; } } class Google_Service_Logging_ListLogServicesResponse extends Google_Collection { protected $collection_key = 'logServices'; protected $internal_gapi_mappings = array( ); protected $logServicesType = 'Google_Service_Logging_LogService'; protected $logServicesDataType = 'array'; public $nextPageToken; public function setLogServices($logServices) { $this->logServices = $logServices; } public function getLogServices() { return $this->logServices; } public function setNextPageToken($nextPageToken) { $this->nextPageToken = $nextPageToken; } public function getNextPageToken() { return $this->nextPageToken; } } class Google_Service_Logging_ListLogSinksResponse extends Google_Collection { protected $collection_key = 'sinks'; protected $internal_gapi_mappings = array( ); protected $sinksType = 'Google_Service_Logging_LogSink'; protected $sinksDataType = 'array'; public function setSinks($sinks) { $this->sinks = $sinks; } public function getSinks() { return $this->sinks; } } class Google_Service_Logging_ListLogsResponse extends Google_Collection { protected $collection_key = 'logs'; protected $internal_gapi_mappings = array( ); protected $logsType = 'Google_Service_Logging_Log'; protected $logsDataType = 'array'; public $nextPageToken; public function setLogs($logs) { $this->logs = $logs; } public function getLogs() { return $this->logs; } public function setNextPageToken($nextPageToken) { $this->nextPageToken = $nextPageToken; } public function getNextPageToken() { return $this->nextPageToken; } } class Google_Service_Logging_Log extends Google_Model { protected $internal_gapi_mappings = array( ); public $displayName; public $name; public $payloadType; public function setDisplayName($displayName) { $this->displayName = $displayName; } public function getDisplayName() { return $this->displayName; } public function setName($name) { $this->name = $name; } public function getName() { return $this->name; } public function setPayloadType($payloadType) { $this->payloadType = $payloadType; } public function getPayloadType() { return $this->payloadType; } } class Google_Service_Logging_LogEntry extends Google_Model { protected $internal_gapi_mappings = array( ); public $insertId; public $log; protected $metadataType = 'Google_Service_Logging_LogEntryMetadata'; protected $metadataDataType = ''; public $protoPayload; public $structPayload; public $textPayload; public function setInsertId($insertId) { $this->insertId = $insertId; } public function getInsertId() { return $this->insertId; } public function setLog($log) { $this->log = $log; } public function getLog() { return $this->log; } public function setMetadata(Google_Service_Logging_LogEntryMetadata $metadata) { $this->metadata = $metadata; } public function getMetadata() { return $this->metadata; } public function setProtoPayload($protoPayload) { $this->protoPayload = $protoPayload; } public function getProtoPayload() { return $this->protoPayload; } public function setStructPayload($structPayload) { $this->structPayload = $structPayload; } public function getStructPayload() { return $this->structPayload; } public function setTextPayload($textPayload) { $this->textPayload = $textPayload; } public function getTextPayload() { return $this->textPayload; } } class Google_Service_Logging_LogEntryMetadata extends Google_Model { protected $internal_gapi_mappings = array( ); public $labels; public $projectId; public $region; public $serviceName; public $severity; public $timestamp; public $userId; public $zone; public function setLabels($labels) { $this->labels = $labels; } public function getLabels() { return $this->labels; } public function setProjectId($projectId) { $this->projectId = $projectId; } public function getProjectId() { return $this->projectId; } public function setRegion($region) { $this->region = $region; } public function getRegion() { return $this->region; } public function setServiceName($serviceName) { $this->serviceName = $serviceName; } public function getServiceName() { return $this->serviceName; } public function setSeverity($severity) { $this->severity = $severity; } public function getSeverity() { return $this->severity; } public function setTimestamp($timestamp) { $this->timestamp = $timestamp; } public function getTimestamp() { return $this->timestamp; } public function setUserId($userId) { $this->userId = $userId; } public function getUserId() { return $this->userId; } public function setZone($zone) { $this->zone = $zone; } public function getZone() { return $this->zone; } } class Google_Service_Logging_LogEntryMetadataLabels extends Google_Model { } class Google_Service_Logging_LogEntryProtoPayload extends Google_Model { } class Google_Service_Logging_LogEntryStructPayload extends Google_Model { } class Google_Service_Logging_LogError extends Google_Model { protected $internal_gapi_mappings = array( ); public $resource; protected $statusType = 'Google_Service_Logging_Status'; protected $statusDataType = ''; public $timeNanos; public function setResource($resource) { $this->resource = $resource; } public function getResource() { return $this->resource; } public function setStatus(Google_Service_Logging_Status $status) { $this->status = $status; } public function getStatus() { return $this->status; } public function setTimeNanos($timeNanos) { $this->timeNanos = $timeNanos; } public function getTimeNanos() { return $this->timeNanos; } } class Google_Service_Logging_LogService extends Google_Collection { protected $collection_key = 'indexKeys'; protected $internal_gapi_mappings = array( ); public $indexKeys; public $name; public function setIndexKeys($indexKeys) { $this->indexKeys = $indexKeys; } public function getIndexKeys() { return $this->indexKeys; } public function setName($name) { $this->name = $name; } public function getName() { return $this->name; } } class Google_Service_Logging_LogSink extends Google_Collection { protected $collection_key = 'errors'; protected $internal_gapi_mappings = array( ); public $destination; protected $errorsType = 'Google_Service_Logging_LogError'; protected $errorsDataType = 'array'; public $name; public function setDestination($destination) { $this->destination = $destination; } public function getDestination() { return $this->destination; } public function setErrors($errors) { $this->errors = $errors; } public function getErrors() { return $this->errors; } public function setName($name) { $this->name = $name; } public function getName() { return $this->name; } } class Google_Service_Logging_Status extends Google_Collection { protected $collection_key = 'details'; protected $internal_gapi_mappings = array( ); public $code; public $details; public $message; public function setCode($code) { $this->code = $code; } public function getCode() { return $this->code; } public function setDetails($details) { $this->details = $details; } public function getDetails() { return $this->details; } public function setMessage($message) { $this->message = $message; } public function getMessage() { return $this->message; } } class Google_Service_Logging_StatusDetails extends Google_Model { } class Google_Service_Logging_WriteLogEntriesRequest extends Google_Collection { protected $collection_key = 'entries'; protected $internal_gapi_mappings = array( ); public $commonLabels; protected $entriesType = 'Google_Service_Logging_LogEntry'; protected $entriesDataType = 'array'; public function setCommonLabels($commonLabels) { $this->commonLabels = $commonLabels; } public function getCommonLabels() { return $this->commonLabels; } public function setEntries($entries) { $this->entries = $entries; } public function getEntries() { return $this->entries; } } class Google_Service_Logging_WriteLogEntriesRequestCommonLabels extends Google_Model { } class Google_Service_Logging_WriteLogEntriesResponse extends Google_Model { } includes/Google/Service/Dns.php000064400000062242152214270100012423 0ustar00 * The Google Cloud DNS API provides services for configuring and serving * authoritative DNS records.

* *

* For more information about this service, see the API * Documentation *

* * @author Google, Inc. */ class Google_Service_Dns extends UDP_Google_Service { /** View and manage your data across Google Cloud Platform services. */ const CLOUD_PLATFORM = "https://www.googleapis.com/auth/cloud-platform"; /** View your DNS records hosted by Google Cloud DNS. */ const NDEV_CLOUDDNS_READONLY = "https://www.googleapis.com/auth/ndev.clouddns.readonly"; /** View and manage your DNS records hosted by Google Cloud DNS. */ const NDEV_CLOUDDNS_READWRITE = "https://www.googleapis.com/auth/ndev.clouddns.readwrite"; public $changes; public $managedZones; public $projects; public $resourceRecordSets; /** * Constructs the internal representation of the Dns service. * * @param Google_Client $client */ public function __construct(UDP_Google_Client $client) { parent::__construct($client); $this->servicePath = 'dns/v1/projects/'; $this->version = 'v1'; $this->serviceName = 'dns'; $this->changes = new Google_Service_Dns_Changes_Resource( $this, $this->serviceName, 'changes', array( 'methods' => array( 'create' => array( 'path' => '{project}/managedZones/{managedZone}/changes', 'httpMethod' => 'POST', 'parameters' => array( 'project' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'managedZone' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), ), ),'get' => array( 'path' => '{project}/managedZones/{managedZone}/changes/{changeId}', 'httpMethod' => 'GET', 'parameters' => array( 'project' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'managedZone' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'changeId' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), ), ),'list' => array( 'path' => '{project}/managedZones/{managedZone}/changes', 'httpMethod' => 'GET', 'parameters' => array( 'project' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'managedZone' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'maxResults' => array( 'location' => 'query', 'type' => 'integer', ), 'pageToken' => array( 'location' => 'query', 'type' => 'string', ), 'sortBy' => array( 'location' => 'query', 'type' => 'string', ), 'sortOrder' => array( 'location' => 'query', 'type' => 'string', ), ), ), ) ) ); $this->managedZones = new Google_Service_Dns_ManagedZones_Resource( $this, $this->serviceName, 'managedZones', array( 'methods' => array( 'create' => array( 'path' => '{project}/managedZones', 'httpMethod' => 'POST', 'parameters' => array( 'project' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), ), ),'delete' => array( 'path' => '{project}/managedZones/{managedZone}', 'httpMethod' => 'DELETE', 'parameters' => array( 'project' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'managedZone' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), ), ),'get' => array( 'path' => '{project}/managedZones/{managedZone}', 'httpMethod' => 'GET', 'parameters' => array( 'project' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'managedZone' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), ), ),'list' => array( 'path' => '{project}/managedZones', 'httpMethod' => 'GET', 'parameters' => array( 'project' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'pageToken' => array( 'location' => 'query', 'type' => 'string', ), 'maxResults' => array( 'location' => 'query', 'type' => 'integer', ), ), ), ) ) ); $this->projects = new Google_Service_Dns_Projects_Resource( $this, $this->serviceName, 'projects', array( 'methods' => array( 'get' => array( 'path' => '{project}', 'httpMethod' => 'GET', 'parameters' => array( 'project' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), ), ), ) ) ); $this->resourceRecordSets = new Google_Service_Dns_ResourceRecordSets_Resource( $this, $this->serviceName, 'resourceRecordSets', array( 'methods' => array( 'list' => array( 'path' => '{project}/managedZones/{managedZone}/rrsets', 'httpMethod' => 'GET', 'parameters' => array( 'project' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'managedZone' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'name' => array( 'location' => 'query', 'type' => 'string', ), 'maxResults' => array( 'location' => 'query', 'type' => 'integer', ), 'pageToken' => array( 'location' => 'query', 'type' => 'string', ), 'type' => array( 'location' => 'query', 'type' => 'string', ), ), ), ) ) ); } } /** * The "changes" collection of methods. * Typical usage is: * * $dnsService = new Google_Service_Dns(...); * $changes = $dnsService->changes; * */ class Google_Service_Dns_Changes_Resource extends UDP_Google_Service_Resource { /** * Atomically update the ResourceRecordSet collection. (changes.create) * * @param string $project Identifies the project addressed by this request. * @param string $managedZone Identifies the managed zone addressed by this * request. Can be the managed zone name or id. * @param Google_Change $postBody * @param array $optParams Optional parameters. * @return Google_Service_Dns_Change */ public function create($project, $managedZone, Google_Service_Dns_Change $postBody, $optParams = array()) { $params = array('project' => $project, 'managedZone' => $managedZone, 'postBody' => $postBody); $params = array_merge($params, $optParams); return $this->call('create', array($params), "Google_Service_Dns_Change"); } /** * Fetch the representation of an existing Change. (changes.get) * * @param string $project Identifies the project addressed by this request. * @param string $managedZone Identifies the managed zone addressed by this * request. Can be the managed zone name or id. * @param string $changeId The identifier of the requested change, from a * previous ResourceRecordSetsChangeResponse. * @param array $optParams Optional parameters. * @return Google_Service_Dns_Change */ public function get($project, $managedZone, $changeId, $optParams = array()) { $params = array('project' => $project, 'managedZone' => $managedZone, 'changeId' => $changeId); $params = array_merge($params, $optParams); return $this->call('get', array($params), "Google_Service_Dns_Change"); } /** * Enumerate Changes to a ResourceRecordSet collection. (changes.listChanges) * * @param string $project Identifies the project addressed by this request. * @param string $managedZone Identifies the managed zone addressed by this * request. Can be the managed zone name or id. * @param array $optParams Optional parameters. * * @opt_param int maxResults Optional. Maximum number of results to be returned. * If unspecified, the server will decide how many results to return. * @opt_param string pageToken Optional. A tag returned by a previous list * request that was truncated. Use this parameter to continue a previous list * request. * @opt_param string sortBy Sorting criterion. The only supported value is * change sequence. * @opt_param string sortOrder Sorting order direction: 'ascending' or * 'descending'. * @return Google_Service_Dns_ChangesListResponse */ public function listChanges($project, $managedZone, $optParams = array()) { $params = array('project' => $project, 'managedZone' => $managedZone); $params = array_merge($params, $optParams); return $this->call('list', array($params), "Google_Service_Dns_ChangesListResponse"); } } /** * The "managedZones" collection of methods. * Typical usage is: * * $dnsService = new Google_Service_Dns(...); * $managedZones = $dnsService->managedZones; * */ class Google_Service_Dns_ManagedZones_Resource extends UDP_Google_Service_Resource { /** * Create a new ManagedZone. (managedZones.create) * * @param string $project Identifies the project addressed by this request. * @param Google_ManagedZone $postBody * @param array $optParams Optional parameters. * @return Google_Service_Dns_ManagedZone */ public function create($project, Google_Service_Dns_ManagedZone $postBody, $optParams = array()) { $params = array('project' => $project, 'postBody' => $postBody); $params = array_merge($params, $optParams); return $this->call('create', array($params), "Google_Service_Dns_ManagedZone"); } /** * Delete a previously created ManagedZone. (managedZones.delete) * * @param string $project Identifies the project addressed by this request. * @param string $managedZone Identifies the managed zone addressed by this * request. Can be the managed zone name or id. * @param array $optParams Optional parameters. */ public function delete($project, $managedZone, $optParams = array()) { $params = array('project' => $project, 'managedZone' => $managedZone); $params = array_merge($params, $optParams); return $this->call('delete', array($params)); } /** * Fetch the representation of an existing ManagedZone. (managedZones.get) * * @param string $project Identifies the project addressed by this request. * @param string $managedZone Identifies the managed zone addressed by this * request. Can be the managed zone name or id. * @param array $optParams Optional parameters. * @return Google_Service_Dns_ManagedZone */ public function get($project, $managedZone, $optParams = array()) { $params = array('project' => $project, 'managedZone' => $managedZone); $params = array_merge($params, $optParams); return $this->call('get', array($params), "Google_Service_Dns_ManagedZone"); } /** * Enumerate ManagedZones that have been created but not yet deleted. * (managedZones.listManagedZones) * * @param string $project Identifies the project addressed by this request. * @param array $optParams Optional parameters. * * @opt_param string pageToken Optional. A tag returned by a previous list * request that was truncated. Use this parameter to continue a previous list * request. * @opt_param int maxResults Optional. Maximum number of results to be returned. * If unspecified, the server will decide how many results to return. * @return Google_Service_Dns_ManagedZonesListResponse */ public function listManagedZones($project, $optParams = array()) { $params = array('project' => $project); $params = array_merge($params, $optParams); return $this->call('list', array($params), "Google_Service_Dns_ManagedZonesListResponse"); } } /** * The "projects" collection of methods. * Typical usage is: * * $dnsService = new Google_Service_Dns(...); * $projects = $dnsService->projects; * */ class Google_Service_Dns_Projects_Resource extends UDP_Google_Service_Resource { /** * Fetch the representation of an existing Project. (projects.get) * * @param string $project Identifies the project addressed by this request. * @param array $optParams Optional parameters. * @return Google_Service_Dns_Project */ public function get($project, $optParams = array()) { $params = array('project' => $project); $params = array_merge($params, $optParams); return $this->call('get', array($params), "Google_Service_Dns_Project"); } } /** * The "resourceRecordSets" collection of methods. * Typical usage is: * * $dnsService = new Google_Service_Dns(...); * $resourceRecordSets = $dnsService->resourceRecordSets; * */ class Google_Service_Dns_ResourceRecordSets_Resource extends UDP_Google_Service_Resource { /** * Enumerate ResourceRecordSets that have been created but not yet deleted. * (resourceRecordSets.listResourceRecordSets) * * @param string $project Identifies the project addressed by this request. * @param string $managedZone Identifies the managed zone addressed by this * request. Can be the managed zone name or id. * @param array $optParams Optional parameters. * * @opt_param string name Restricts the list to return only records with this * fully qualified domain name. * @opt_param int maxResults Optional. Maximum number of results to be returned. * If unspecified, the server will decide how many results to return. * @opt_param string pageToken Optional. A tag returned by a previous list * request that was truncated. Use this parameter to continue a previous list * request. * @opt_param string type Restricts the list to return only records of this * type. If present, the "name" parameter must also be present. * @return Google_Service_Dns_ResourceRecordSetsListResponse */ public function listResourceRecordSets($project, $managedZone, $optParams = array()) { $params = array('project' => $project, 'managedZone' => $managedZone); $params = array_merge($params, $optParams); return $this->call('list', array($params), "Google_Service_Dns_ResourceRecordSetsListResponse"); } } class Google_Service_Dns_Change extends Google_Collection { protected $collection_key = 'deletions'; protected $internal_gapi_mappings = array( ); protected $additionsType = 'Google_Service_Dns_ResourceRecordSet'; protected $additionsDataType = 'array'; protected $deletionsType = 'Google_Service_Dns_ResourceRecordSet'; protected $deletionsDataType = 'array'; public $id; public $kind; public $startTime; public $status; public function setAdditions($additions) { $this->additions = $additions; } public function getAdditions() { return $this->additions; } public function setDeletions($deletions) { $this->deletions = $deletions; } public function getDeletions() { return $this->deletions; } public function setId($id) { $this->id = $id; } public function getId() { return $this->id; } public function setKind($kind) { $this->kind = $kind; } public function getKind() { return $this->kind; } public function setStartTime($startTime) { $this->startTime = $startTime; } public function getStartTime() { return $this->startTime; } public function setStatus($status) { $this->status = $status; } public function getStatus() { return $this->status; } } class Google_Service_Dns_ChangesListResponse extends Google_Collection { protected $collection_key = 'changes'; protected $internal_gapi_mappings = array( ); protected $changesType = 'Google_Service_Dns_Change'; protected $changesDataType = 'array'; public $kind; public $nextPageToken; public function setChanges($changes) { $this->changes = $changes; } public function getChanges() { return $this->changes; } public function setKind($kind) { $this->kind = $kind; } public function getKind() { return $this->kind; } public function setNextPageToken($nextPageToken) { $this->nextPageToken = $nextPageToken; } public function getNextPageToken() { return $this->nextPageToken; } } class Google_Service_Dns_ManagedZone extends Google_Collection { protected $collection_key = 'nameServers'; protected $internal_gapi_mappings = array( ); public $creationTime; public $description; public $dnsName; public $id; public $kind; public $name; public $nameServerSet; public $nameServers; public function setCreationTime($creationTime) { $this->creationTime = $creationTime; } public function getCreationTime() { return $this->creationTime; } public function setDescription($description) { $this->description = $description; } public function getDescription() { return $this->description; } public function setDnsName($dnsName) { $this->dnsName = $dnsName; } public function getDnsName() { return $this->dnsName; } public function setId($id) { $this->id = $id; } public function getId() { return $this->id; } public function setKind($kind) { $this->kind = $kind; } public function getKind() { return $this->kind; } public function setName($name) { $this->name = $name; } public function getName() { return $this->name; } public function setNameServerSet($nameServerSet) { $this->nameServerSet = $nameServerSet; } public function getNameServerSet() { return $this->nameServerSet; } public function setNameServers($nameServers) { $this->nameServers = $nameServers; } public function getNameServers() { return $this->nameServers; } } class Google_Service_Dns_ManagedZonesListResponse extends Google_Collection { protected $collection_key = 'managedZones'; protected $internal_gapi_mappings = array( ); public $kind; protected $managedZonesType = 'Google_Service_Dns_ManagedZone'; protected $managedZonesDataType = 'array'; public $nextPageToken; public function setKind($kind) { $this->kind = $kind; } public function getKind() { return $this->kind; } public function setManagedZones($managedZones) { $this->managedZones = $managedZones; } public function getManagedZones() { return $this->managedZones; } public function setNextPageToken($nextPageToken) { $this->nextPageToken = $nextPageToken; } public function getNextPageToken() { return $this->nextPageToken; } } class Google_Service_Dns_Project extends Google_Model { protected $internal_gapi_mappings = array( ); public $id; public $kind; public $number; protected $quotaType = 'Google_Service_Dns_Quota'; protected $quotaDataType = ''; public function setId($id) { $this->id = $id; } public function getId() { return $this->id; } public function setKind($kind) { $this->kind = $kind; } public function getKind() { return $this->kind; } public function setNumber($number) { $this->number = $number; } public function getNumber() { return $this->number; } public function setQuota(Google_Service_Dns_Quota $quota) { $this->quota = $quota; } public function getQuota() { return $this->quota; } } class Google_Service_Dns_Quota extends Google_Model { protected $internal_gapi_mappings = array( ); public $kind; public $managedZones; public $resourceRecordsPerRrset; public $rrsetAdditionsPerChange; public $rrsetDeletionsPerChange; public $rrsetsPerManagedZone; public $totalRrdataSizePerChange; public function setKind($kind) { $this->kind = $kind; } public function getKind() { return $this->kind; } public function setManagedZones($managedZones) { $this->managedZones = $managedZones; } public function getManagedZones() { return $this->managedZones; } public function setResourceRecordsPerRrset($resourceRecordsPerRrset) { $this->resourceRecordsPerRrset = $resourceRecordsPerRrset; } public function getResourceRecordsPerRrset() { return $this->resourceRecordsPerRrset; } public function setRrsetAdditionsPerChange($rrsetAdditionsPerChange) { $this->rrsetAdditionsPerChange = $rrsetAdditionsPerChange; } public function getRrsetAdditionsPerChange() { return $this->rrsetAdditionsPerChange; } public function setRrsetDeletionsPerChange($rrsetDeletionsPerChange) { $this->rrsetDeletionsPerChange = $rrsetDeletionsPerChange; } public function getRrsetDeletionsPerChange() { return $this->rrsetDeletionsPerChange; } public function setRrsetsPerManagedZone($rrsetsPerManagedZone) { $this->rrsetsPerManagedZone = $rrsetsPerManagedZone; } public function getRrsetsPerManagedZone() { return $this->rrsetsPerManagedZone; } public function setTotalRrdataSizePerChange($totalRrdataSizePerChange) { $this->totalRrdataSizePerChange = $totalRrdataSizePerChange; } public function getTotalRrdataSizePerChange() { return $this->totalRrdataSizePerChange; } } class Google_Service_Dns_ResourceRecordSet extends Google_Collection { protected $collection_key = 'rrdatas'; protected $internal_gapi_mappings = array( ); public $kind; public $name; public $rrdatas; public $ttl; public $type; public function setKind($kind) { $this->kind = $kind; } public function getKind() { return $this->kind; } public function setName($name) { $this->name = $name; } public function getName() { return $this->name; } public function setRrdatas($rrdatas) { $this->rrdatas = $rrdatas; } public function getRrdatas() { return $this->rrdatas; } public function setTtl($ttl) { $this->ttl = $ttl; } public function getTtl() { return $this->ttl; } public function setType($type) { $this->type = $type; } public function getType() { return $this->type; } } class Google_Service_Dns_ResourceRecordSetsListResponse extends Google_Collection { protected $collection_key = 'rrsets'; protected $internal_gapi_mappings = array( ); public $kind; public $nextPageToken; protected $rrsetsType = 'Google_Service_Dns_ResourceRecordSet'; protected $rrsetsDataType = 'array'; public function setKind($kind) { $this->kind = $kind; } public function getKind() { return $this->kind; } public function setNextPageToken($nextPageToken) { $this->nextPageToken = $nextPageToken; } public function getNextPageToken() { return $this->nextPageToken; } public function setRrsets($rrsets) { $this->rrsets = $rrsets; } public function getRrsets() { return $this->rrsets; } } includes/Google/Service/Drive.php000064400000451035152214270100012752 0ustar00 * The API to interact with Drive.

* *

* For more information about this service, see the API * Documentation *

* * @author Google, Inc. */ class UDP_Google_Service_Drive extends UDP_Google_Service { /** View and manage the files in your Google Drive. */ const DRIVE = "https://www.googleapis.com/auth/drive"; /** View and manage its own configuration data in your Google Drive. */ const DRIVE_APPDATA = "https://www.googleapis.com/auth/drive.appdata"; /** View your Google Drive apps. */ const DRIVE_APPS_READONLY = "https://www.googleapis.com/auth/drive.apps.readonly"; /** View and manage Google Drive files that you have opened or created with this app. */ const DRIVE_FILE = "https://www.googleapis.com/auth/drive.file"; /** View and manage metadata of files in your Google Drive. */ const DRIVE_METADATA = "https://www.googleapis.com/auth/drive.metadata"; /** View metadata for files in your Google Drive. */ const DRIVE_METADATA_READONLY = "https://www.googleapis.com/auth/drive.metadata.readonly"; /** View the files in your Google Drive. */ const DRIVE_READONLY = "https://www.googleapis.com/auth/drive.readonly"; /** Modify your Google Apps Script scripts' behavior. */ const DRIVE_SCRIPTS = "https://www.googleapis.com/auth/drive.scripts"; public $about; public $apps; public $changes; public $channels; public $children; public $comments; public $files; public $parents; public $permissions; public $properties; public $realtime; public $replies; public $revisions; /** * Google Drive service name. The default value is drive. * @var String */ protected $serviceName; /** * Constructs the internal representation of the Drive service. * * @param UDP_Google_Client $client */ public function __construct(UDP_Google_Client $client) { parent::__construct($client); $this->servicePath = 'drive/v2/'; $this->version = 'v2'; $this->serviceName = 'drive'; $this->about = new Google_Service_Drive_About_Resource( $this, $this->serviceName, 'about', array( 'methods' => array( 'get' => array( 'path' => 'about', 'httpMethod' => 'GET', 'parameters' => array( 'includeSubscribed' => array( 'location' => 'query', 'type' => 'boolean', ), 'maxChangeIdCount' => array( 'location' => 'query', 'type' => 'string', ), 'startChangeId' => array( 'location' => 'query', 'type' => 'string', ), ), ), ) ) ); $this->apps = new Google_Service_Drive_Apps_Resource( $this, $this->serviceName, 'apps', array( 'methods' => array( 'get' => array( 'path' => 'apps/{appId}', 'httpMethod' => 'GET', 'parameters' => array( 'appId' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), ), ),'list' => array( 'path' => 'apps', 'httpMethod' => 'GET', 'parameters' => array( 'languageCode' => array( 'location' => 'query', 'type' => 'string', ), 'appFilterExtensions' => array( 'location' => 'query', 'type' => 'string', ), 'appFilterMimeTypes' => array( 'location' => 'query', 'type' => 'string', ), ), ), ) ) ); $this->changes = new Google_Service_Drive_Changes_Resource( $this, $this->serviceName, 'changes', array( 'methods' => array( 'get' => array( 'path' => 'changes/{changeId}', 'httpMethod' => 'GET', 'parameters' => array( 'changeId' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), ), ),'list' => array( 'path' => 'changes', 'httpMethod' => 'GET', 'parameters' => array( 'includeSubscribed' => array( 'location' => 'query', 'type' => 'boolean', ), 'startChangeId' => array( 'location' => 'query', 'type' => 'string', ), 'includeDeleted' => array( 'location' => 'query', 'type' => 'boolean', ), 'maxResults' => array( 'location' => 'query', 'type' => 'integer', ), 'pageToken' => array( 'location' => 'query', 'type' => 'string', ), ), ),'watch' => array( 'path' => 'changes/watch', 'httpMethod' => 'POST', 'parameters' => array( 'includeSubscribed' => array( 'location' => 'query', 'type' => 'boolean', ), 'startChangeId' => array( 'location' => 'query', 'type' => 'string', ), 'includeDeleted' => array( 'location' => 'query', 'type' => 'boolean', ), 'maxResults' => array( 'location' => 'query', 'type' => 'integer', ), 'pageToken' => array( 'location' => 'query', 'type' => 'string', ), ), ), ) ) ); $this->channels = new Google_Service_Drive_Channels_Resource( $this, $this->serviceName, 'channels', array( 'methods' => array( 'stop' => array( 'path' => 'channels/stop', 'httpMethod' => 'POST', 'parameters' => array(), ), ) ) ); $this->children = new Google_Service_Drive_Children_Resource( $this, $this->serviceName, 'children', array( 'methods' => array( 'delete' => array( 'path' => 'files/{folderId}/children/{childId}', 'httpMethod' => 'DELETE', 'parameters' => array( 'folderId' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'childId' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), ), ),'get' => array( 'path' => 'files/{folderId}/children/{childId}', 'httpMethod' => 'GET', 'parameters' => array( 'folderId' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'childId' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), ), ),'insert' => array( 'path' => 'files/{folderId}/children', 'httpMethod' => 'POST', 'parameters' => array( 'folderId' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), ), ),'list' => array( 'path' => 'files/{folderId}/children', 'httpMethod' => 'GET', 'parameters' => array( 'folderId' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'q' => array( 'location' => 'query', 'type' => 'string', ), 'pageToken' => array( 'location' => 'query', 'type' => 'string', ), 'maxResults' => array( 'location' => 'query', 'type' => 'integer', ), ), ), ) ) ); $this->comments = new Google_Service_Drive_Comments_Resource( $this, $this->serviceName, 'comments', array( 'methods' => array( 'delete' => array( 'path' => 'files/{fileId}/comments/{commentId}', 'httpMethod' => 'DELETE', 'parameters' => array( 'fileId' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'commentId' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), ), ),'get' => array( 'path' => 'files/{fileId}/comments/{commentId}', 'httpMethod' => 'GET', 'parameters' => array( 'fileId' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'commentId' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'includeDeleted' => array( 'location' => 'query', 'type' => 'boolean', ), ), ),'insert' => array( 'path' => 'files/{fileId}/comments', 'httpMethod' => 'POST', 'parameters' => array( 'fileId' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), ), ),'list' => array( 'path' => 'files/{fileId}/comments', 'httpMethod' => 'GET', 'parameters' => array( 'fileId' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'pageToken' => array( 'location' => 'query', 'type' => 'string', ), 'updatedMin' => array( 'location' => 'query', 'type' => 'string', ), 'includeDeleted' => array( 'location' => 'query', 'type' => 'boolean', ), 'maxResults' => array( 'location' => 'query', 'type' => 'integer', ), ), ),'patch' => array( 'path' => 'files/{fileId}/comments/{commentId}', 'httpMethod' => 'PATCH', 'parameters' => array( 'fileId' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'commentId' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), ), ),'update' => array( 'path' => 'files/{fileId}/comments/{commentId}', 'httpMethod' => 'PUT', 'parameters' => array( 'fileId' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'commentId' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), ), ), ) ) ); $this->files = new Google_Service_Drive_Files_Resource( $this, $this->serviceName, 'files', array( 'methods' => array( 'copy' => array( 'path' => 'files/{fileId}/copy', 'httpMethod' => 'POST', 'parameters' => array( 'fileId' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'convert' => array( 'location' => 'query', 'type' => 'boolean', ), 'ocrLanguage' => array( 'location' => 'query', 'type' => 'string', ), 'visibility' => array( 'location' => 'query', 'type' => 'string', ), 'pinned' => array( 'location' => 'query', 'type' => 'boolean', ), 'ocr' => array( 'location' => 'query', 'type' => 'boolean', ), 'timedTextTrackName' => array( 'location' => 'query', 'type' => 'string', ), 'timedTextLanguage' => array( 'location' => 'query', 'type' => 'string', ), ), ),'delete' => array( 'path' => 'files/{fileId}', 'httpMethod' => 'DELETE', 'parameters' => array( 'fileId' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), ), ),'emptyTrash' => array( 'path' => 'files/trash', 'httpMethod' => 'DELETE', 'parameters' => array(), ),'get' => array( 'path' => 'files/{fileId}', 'httpMethod' => 'GET', 'parameters' => array( 'fileId' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'acknowledgeAbuse' => array( 'location' => 'query', 'type' => 'boolean', ), 'updateViewedDate' => array( 'location' => 'query', 'type' => 'boolean', ), 'revisionId' => array( 'location' => 'query', 'type' => 'string', ), 'projection' => array( 'location' => 'query', 'type' => 'string', ), ), ),'insert' => array( 'path' => 'files', 'httpMethod' => 'POST', 'parameters' => array( 'convert' => array( 'location' => 'query', 'type' => 'boolean', ), 'useContentAsIndexableText' => array( 'location' => 'query', 'type' => 'boolean', ), 'ocrLanguage' => array( 'location' => 'query', 'type' => 'string', ), 'visibility' => array( 'location' => 'query', 'type' => 'string', ), 'pinned' => array( 'location' => 'query', 'type' => 'boolean', ), 'ocr' => array( 'location' => 'query', 'type' => 'boolean', ), 'timedTextTrackName' => array( 'location' => 'query', 'type' => 'string', ), 'timedTextLanguage' => array( 'location' => 'query', 'type' => 'string', ), ), ),'list' => array( 'path' => 'files', 'httpMethod' => 'GET', 'parameters' => array( 'q' => array( 'location' => 'query', 'type' => 'string', ), 'pageToken' => array( 'location' => 'query', 'type' => 'string', ), 'corpus' => array( 'location' => 'query', 'type' => 'string', ), 'projection' => array( 'location' => 'query', 'type' => 'string', ), 'maxResults' => array( 'location' => 'query', 'type' => 'integer', ), ), ),'patch' => array( 'path' => 'files/{fileId}', 'httpMethod' => 'PATCH', 'parameters' => array( 'fileId' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'addParents' => array( 'location' => 'query', 'type' => 'string', ), 'updateViewedDate' => array( 'location' => 'query', 'type' => 'boolean', ), 'removeParents' => array( 'location' => 'query', 'type' => 'string', ), 'setModifiedDate' => array( 'location' => 'query', 'type' => 'boolean', ), 'convert' => array( 'location' => 'query', 'type' => 'boolean', ), 'useContentAsIndexableText' => array( 'location' => 'query', 'type' => 'boolean', ), 'ocrLanguage' => array( 'location' => 'query', 'type' => 'string', ), 'pinned' => array( 'location' => 'query', 'type' => 'boolean', ), 'newRevision' => array( 'location' => 'query', 'type' => 'boolean', ), 'ocr' => array( 'location' => 'query', 'type' => 'boolean', ), 'timedTextLanguage' => array( 'location' => 'query', 'type' => 'string', ), 'timedTextTrackName' => array( 'location' => 'query', 'type' => 'string', ), ), ),'touch' => array( 'path' => 'files/{fileId}/touch', 'httpMethod' => 'POST', 'parameters' => array( 'fileId' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), ), ),'trash' => array( 'path' => 'files/{fileId}/trash', 'httpMethod' => 'POST', 'parameters' => array( 'fileId' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), ), ),'untrash' => array( 'path' => 'files/{fileId}/untrash', 'httpMethod' => 'POST', 'parameters' => array( 'fileId' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), ), ),'update' => array( 'path' => 'files/{fileId}', 'httpMethod' => 'PUT', 'parameters' => array( 'fileId' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'addParents' => array( 'location' => 'query', 'type' => 'string', ), 'updateViewedDate' => array( 'location' => 'query', 'type' => 'boolean', ), 'removeParents' => array( 'location' => 'query', 'type' => 'string', ), 'setModifiedDate' => array( 'location' => 'query', 'type' => 'boolean', ), 'convert' => array( 'location' => 'query', 'type' => 'boolean', ), 'useContentAsIndexableText' => array( 'location' => 'query', 'type' => 'boolean', ), 'ocrLanguage' => array( 'location' => 'query', 'type' => 'string', ), 'pinned' => array( 'location' => 'query', 'type' => 'boolean', ), 'newRevision' => array( 'location' => 'query', 'type' => 'boolean', ), 'ocr' => array( 'location' => 'query', 'type' => 'boolean', ), 'timedTextLanguage' => array( 'location' => 'query', 'type' => 'string', ), 'timedTextTrackName' => array( 'location' => 'query', 'type' => 'string', ), ), ),'watch' => array( 'path' => 'files/{fileId}/watch', 'httpMethod' => 'POST', 'parameters' => array( 'fileId' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'acknowledgeAbuse' => array( 'location' => 'query', 'type' => 'boolean', ), 'updateViewedDate' => array( 'location' => 'query', 'type' => 'boolean', ), 'revisionId' => array( 'location' => 'query', 'type' => 'string', ), 'projection' => array( 'location' => 'query', 'type' => 'string', ), ), ), ) ) ); $this->parents = new Google_Service_Drive_Parents_Resource( $this, $this->serviceName, 'parents', array( 'methods' => array( 'delete' => array( 'path' => 'files/{fileId}/parents/{parentId}', 'httpMethod' => 'DELETE', 'parameters' => array( 'fileId' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'parentId' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), ), ),'get' => array( 'path' => 'files/{fileId}/parents/{parentId}', 'httpMethod' => 'GET', 'parameters' => array( 'fileId' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'parentId' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), ), ),'insert' => array( 'path' => 'files/{fileId}/parents', 'httpMethod' => 'POST', 'parameters' => array( 'fileId' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), ), ),'list' => array( 'path' => 'files/{fileId}/parents', 'httpMethod' => 'GET', 'parameters' => array( 'fileId' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), ), ), ) ) ); $this->permissions = new Google_Service_Drive_Permissions_Resource( $this, $this->serviceName, 'permissions', array( 'methods' => array( 'delete' => array( 'path' => 'files/{fileId}/permissions/{permissionId}', 'httpMethod' => 'DELETE', 'parameters' => array( 'fileId' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'permissionId' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), ), ),'get' => array( 'path' => 'files/{fileId}/permissions/{permissionId}', 'httpMethod' => 'GET', 'parameters' => array( 'fileId' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'permissionId' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), ), ),'getIdForEmail' => array( 'path' => 'permissionIds/{email}', 'httpMethod' => 'GET', 'parameters' => array( 'email' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), ), ),'insert' => array( 'path' => 'files/{fileId}/permissions', 'httpMethod' => 'POST', 'parameters' => array( 'fileId' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'emailMessage' => array( 'location' => 'query', 'type' => 'string', ), 'sendNotificationEmails' => array( 'location' => 'query', 'type' => 'boolean', ), ), ),'list' => array( 'path' => 'files/{fileId}/permissions', 'httpMethod' => 'GET', 'parameters' => array( 'fileId' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), ), ),'patch' => array( 'path' => 'files/{fileId}/permissions/{permissionId}', 'httpMethod' => 'PATCH', 'parameters' => array( 'fileId' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'permissionId' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'transferOwnership' => array( 'location' => 'query', 'type' => 'boolean', ), ), ),'update' => array( 'path' => 'files/{fileId}/permissions/{permissionId}', 'httpMethod' => 'PUT', 'parameters' => array( 'fileId' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'permissionId' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'transferOwnership' => array( 'location' => 'query', 'type' => 'boolean', ), ), ), ) ) ); $this->properties = new Google_Service_Drive_Properties_Resource( $this, $this->serviceName, 'properties', array( 'methods' => array( 'delete' => array( 'path' => 'files/{fileId}/properties/{propertyKey}', 'httpMethod' => 'DELETE', 'parameters' => array( 'fileId' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'propertyKey' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'visibility' => array( 'location' => 'query', 'type' => 'string', ), ), ),'get' => array( 'path' => 'files/{fileId}/properties/{propertyKey}', 'httpMethod' => 'GET', 'parameters' => array( 'fileId' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'propertyKey' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'visibility' => array( 'location' => 'query', 'type' => 'string', ), ), ),'insert' => array( 'path' => 'files/{fileId}/properties', 'httpMethod' => 'POST', 'parameters' => array( 'fileId' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), ), ),'list' => array( 'path' => 'files/{fileId}/properties', 'httpMethod' => 'GET', 'parameters' => array( 'fileId' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), ), ),'patch' => array( 'path' => 'files/{fileId}/properties/{propertyKey}', 'httpMethod' => 'PATCH', 'parameters' => array( 'fileId' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'propertyKey' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'visibility' => array( 'location' => 'query', 'type' => 'string', ), ), ),'update' => array( 'path' => 'files/{fileId}/properties/{propertyKey}', 'httpMethod' => 'PUT', 'parameters' => array( 'fileId' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'propertyKey' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'visibility' => array( 'location' => 'query', 'type' => 'string', ), ), ), ) ) ); $this->realtime = new Google_Service_Drive_Realtime_Resource( $this, $this->serviceName, 'realtime', array( 'methods' => array( 'get' => array( 'path' => 'files/{fileId}/realtime', 'httpMethod' => 'GET', 'parameters' => array( 'fileId' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'revision' => array( 'location' => 'query', 'type' => 'integer', ), ), ),'update' => array( 'path' => 'files/{fileId}/realtime', 'httpMethod' => 'PUT', 'parameters' => array( 'fileId' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'baseRevision' => array( 'location' => 'query', 'type' => 'string', ), ), ), ) ) ); $this->replies = new Google_Service_Drive_Replies_Resource( $this, $this->serviceName, 'replies', array( 'methods' => array( 'delete' => array( 'path' => 'files/{fileId}/comments/{commentId}/replies/{replyId}', 'httpMethod' => 'DELETE', 'parameters' => array( 'fileId' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'commentId' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'replyId' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), ), ),'get' => array( 'path' => 'files/{fileId}/comments/{commentId}/replies/{replyId}', 'httpMethod' => 'GET', 'parameters' => array( 'fileId' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'commentId' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'replyId' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'includeDeleted' => array( 'location' => 'query', 'type' => 'boolean', ), ), ),'insert' => array( 'path' => 'files/{fileId}/comments/{commentId}/replies', 'httpMethod' => 'POST', 'parameters' => array( 'fileId' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'commentId' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), ), ),'list' => array( 'path' => 'files/{fileId}/comments/{commentId}/replies', 'httpMethod' => 'GET', 'parameters' => array( 'fileId' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'commentId' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'pageToken' => array( 'location' => 'query', 'type' => 'string', ), 'includeDeleted' => array( 'location' => 'query', 'type' => 'boolean', ), 'maxResults' => array( 'location' => 'query', 'type' => 'integer', ), ), ),'patch' => array( 'path' => 'files/{fileId}/comments/{commentId}/replies/{replyId}', 'httpMethod' => 'PATCH', 'parameters' => array( 'fileId' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'commentId' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'replyId' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), ), ),'update' => array( 'path' => 'files/{fileId}/comments/{commentId}/replies/{replyId}', 'httpMethod' => 'PUT', 'parameters' => array( 'fileId' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'commentId' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'replyId' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), ), ), ) ) ); $this->revisions = new Google_Service_Drive_Revisions_Resource( $this, $this->serviceName, 'revisions', array( 'methods' => array( 'delete' => array( 'path' => 'files/{fileId}/revisions/{revisionId}', 'httpMethod' => 'DELETE', 'parameters' => array( 'fileId' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'revisionId' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), ), ),'get' => array( 'path' => 'files/{fileId}/revisions/{revisionId}', 'httpMethod' => 'GET', 'parameters' => array( 'fileId' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'revisionId' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), ), ),'list' => array( 'path' => 'files/{fileId}/revisions', 'httpMethod' => 'GET', 'parameters' => array( 'fileId' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), ), ),'patch' => array( 'path' => 'files/{fileId}/revisions/{revisionId}', 'httpMethod' => 'PATCH', 'parameters' => array( 'fileId' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'revisionId' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), ), ),'update' => array( 'path' => 'files/{fileId}/revisions/{revisionId}', 'httpMethod' => 'PUT', 'parameters' => array( 'fileId' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'revisionId' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), ), ), ) ) ); } } /** * The "about" collection of methods. * Typical usage is: * * $driveService = new Google_Service_Drive(...); * $about = $driveService->about; * */ class Google_Service_Drive_About_Resource extends UDP_Google_Service_Resource { /** * Gets the information about the current user along with Drive API settings * (about.get) * * @param array $optParams Optional parameters. * * @opt_param bool includeSubscribed When calculating the number of remaining * change IDs, whether to include public files the user has opened and shared * files. When set to false, this counts only change IDs for owned files and any * shared or public files that the user has explicitly added to a folder they * own. * @opt_param string maxChangeIdCount Maximum number of remaining change IDs to * count * @opt_param string startChangeId Change ID to start counting from when * calculating number of remaining change IDs * @return Google_Service_Drive_About */ public function get($optParams = array()) { $params = array(); $params = array_merge($params, $optParams); return $this->call('get', array($params), "Google_Service_Drive_About"); } } /** * The "apps" collection of methods. * Typical usage is: * * $driveService = new Google_Service_Drive(...); * $apps = $driveService->apps; * */ class Google_Service_Drive_Apps_Resource extends UDP_Google_Service_Resource { /** * Gets a specific app. (apps.get) * * @param string $appId The ID of the app. * @param array $optParams Optional parameters. * @return Google_Service_Drive_App */ public function get($appId, $optParams = array()) { $params = array('appId' => $appId); $params = array_merge($params, $optParams); return $this->call('get', array($params), "Google_Service_Drive_App"); } /** * Lists a user's installed apps. (apps.listApps) * * @param array $optParams Optional parameters. * * @opt_param string languageCode A language or locale code, as defined by BCP * 47, with some extensions from Unicode's LDML format * (http://www.unicode.org/reports/tr35/). * @opt_param string appFilterExtensions A comma-separated list of file * extensions for open with filtering. All apps within the given app query scope * which can open any of the given file extensions will be included in the * response. If appFilterMimeTypes are provided as well, the result is a union * of the two resulting app lists. * @opt_param string appFilterMimeTypes A comma-separated list of MIME types for * open with filtering. All apps within the given app query scope which can open * any of the given MIME types will be included in the response. If * appFilterExtensions are provided as well, the result is a union of the two * resulting app lists. * @return Google_Service_Drive_AppList */ public function listApps($optParams = array()) { $params = array(); $params = array_merge($params, $optParams); return $this->call('list', array($params), "Google_Service_Drive_AppList"); } } /** * The "changes" collection of methods. * Typical usage is: * * $driveService = new Google_Service_Drive(...); * $changes = $driveService->changes; * */ class Google_Service_Drive_Changes_Resource extends UDP_Google_Service_Resource { /** * Gets a specific change. (changes.get) * * @param string $changeId The ID of the change. * @param array $optParams Optional parameters. * @return Google_Service_Drive_Change */ public function get($changeId, $optParams = array()) { $params = array('changeId' => $changeId); $params = array_merge($params, $optParams); return $this->call('get', array($params), "Google_Service_Drive_Change"); } /** * Lists the changes for a user. (changes.listChanges) * * @param array $optParams Optional parameters. * * @opt_param bool includeSubscribed Whether to include public files the user * has opened and shared files. When set to false, the list only includes owned * files plus any shared or public files the user has explicitly added to a * folder they own. * @opt_param string startChangeId Change ID to start listing changes from. * @opt_param bool includeDeleted Whether to include deleted items. * @opt_param int maxResults Maximum number of changes to return. * @opt_param string pageToken Page token for changes. * @return Google_Service_Drive_ChangeList */ public function listChanges($optParams = array()) { $params = array(); $params = array_merge($params, $optParams); return $this->call('list', array($params), "Google_Service_Drive_ChangeList"); } /** * Subscribe to changes for a user. (changes.watch) * * @param Google_Channel $postBody * @param array $optParams Optional parameters. * * @opt_param bool includeSubscribed Whether to include public files the user * has opened and shared files. When set to false, the list only includes owned * files plus any shared or public files the user has explicitly added to a * folder they own. * @opt_param string startChangeId Change ID to start listing changes from. * @opt_param bool includeDeleted Whether to include deleted items. * @opt_param int maxResults Maximum number of changes to return. * @opt_param string pageToken Page token for changes. * @return Google_Service_Drive_Channel */ public function watch(Google_Service_Drive_Channel $postBody, $optParams = array()) { $params = array('postBody' => $postBody); $params = array_merge($params, $optParams); return $this->call('watch', array($params), "Google_Service_Drive_Channel"); } } /** * The "channels" collection of methods. * Typical usage is: * * $driveService = new Google_Service_Drive(...); * $channels = $driveService->channels; * */ class Google_Service_Drive_Channels_Resource extends UDP_Google_Service_Resource { /** * Stop watching resources through this channel (channels.stop) * * @param Google_Channel $postBody * @param array $optParams Optional parameters. */ public function stop(Google_Service_Drive_Channel $postBody, $optParams = array()) { $params = array('postBody' => $postBody); $params = array_merge($params, $optParams); return $this->call('stop', array($params)); } } /** * The "children" collection of methods. * Typical usage is: * * $driveService = new Google_Service_Drive(...); * $children = $driveService->children; * */ class Google_Service_Drive_Children_Resource extends UDP_Google_Service_Resource { /** * Removes a child from a folder. (children.delete) * * @param string $folderId The ID of the folder. * @param string $childId The ID of the child. * @param array $optParams Optional parameters. */ public function delete($folderId, $childId, $optParams = array()) { $params = array('folderId' => $folderId, 'childId' => $childId); $params = array_merge($params, $optParams); return $this->call('delete', array($params)); } /** * Gets a specific child reference. (children.get) * * @param string $folderId The ID of the folder. * @param string $childId The ID of the child. * @param array $optParams Optional parameters. * @return Google_Service_Drive_ChildReference */ public function get($folderId, $childId, $optParams = array()) { $params = array('folderId' => $folderId, 'childId' => $childId); $params = array_merge($params, $optParams); return $this->call('get', array($params), "Google_Service_Drive_ChildReference"); } /** * Inserts a file into a folder. (children.insert) * * @param string $folderId The ID of the folder. * @param Google_ChildReference $postBody * @param array $optParams Optional parameters. * @return Google_Service_Drive_ChildReference */ public function insert($folderId, Google_Service_Drive_ChildReference $postBody, $optParams = array()) { $params = array('folderId' => $folderId, 'postBody' => $postBody); $params = array_merge($params, $optParams); return $this->call('insert', array($params), "Google_Service_Drive_ChildReference"); } /** * Lists a folder's children. (children.listChildren) * * @param string $folderId The ID of the folder. * @param array $optParams Optional parameters. * * @opt_param string q Query string for searching children. * @opt_param string pageToken Page token for children. * @opt_param int maxResults Maximum number of children to return. * @return Google_Service_Drive_ChildList */ public function listChildren($folderId, $optParams = array()) { $params = array('folderId' => $folderId); $params = array_merge($params, $optParams); return $this->call('list', array($params), "Google_Service_Drive_ChildList"); } } /** * The "comments" collection of methods. * Typical usage is: * * $driveService = new Google_Service_Drive(...); * $comments = $driveService->comments; * */ class Google_Service_Drive_Comments_Resource extends UDP_Google_Service_Resource { /** * Deletes a comment. (comments.delete) * * @param string $fileId The ID of the file. * @param string $commentId The ID of the comment. * @param array $optParams Optional parameters. */ public function delete($fileId, $commentId, $optParams = array()) { $params = array('fileId' => $fileId, 'commentId' => $commentId); $params = array_merge($params, $optParams); return $this->call('delete', array($params)); } /** * Gets a comment by ID. (comments.get) * * @param string $fileId The ID of the file. * @param string $commentId The ID of the comment. * @param array $optParams Optional parameters. * * @opt_param bool includeDeleted If set, this will succeed when retrieving a * deleted comment, and will include any deleted replies. * @return Google_Service_Drive_Comment */ public function get($fileId, $commentId, $optParams = array()) { $params = array('fileId' => $fileId, 'commentId' => $commentId); $params = array_merge($params, $optParams); return $this->call('get', array($params), "Google_Service_Drive_Comment"); } /** * Creates a new comment on the given file. (comments.insert) * * @param string $fileId The ID of the file. * @param Google_Comment $postBody * @param array $optParams Optional parameters. * @return Google_Service_Drive_Comment */ public function insert($fileId, Google_Service_Drive_Comment $postBody, $optParams = array()) { $params = array('fileId' => $fileId, 'postBody' => $postBody); $params = array_merge($params, $optParams); return $this->call('insert', array($params), "Google_Service_Drive_Comment"); } /** * Lists a file's comments. (comments.listComments) * * @param string $fileId The ID of the file. * @param array $optParams Optional parameters. * * @opt_param string pageToken The continuation token, used to page through * large result sets. To get the next page of results, set this parameter to the * value of "nextPageToken" from the previous response. * @opt_param string updatedMin Only discussions that were updated after this * timestamp will be returned. Formatted as an RFC 3339 timestamp. * @opt_param bool includeDeleted If set, all comments and replies, including * deleted comments and replies (with content stripped) will be returned. * @opt_param int maxResults The maximum number of discussions to include in the * response, used for paging. * @return Google_Service_Drive_CommentList */ public function listComments($fileId, $optParams = array()) { $params = array('fileId' => $fileId); $params = array_merge($params, $optParams); return $this->call('list', array($params), "Google_Service_Drive_CommentList"); } /** * Updates an existing comment. This method supports patch semantics. * (comments.patch) * * @param string $fileId The ID of the file. * @param string $commentId The ID of the comment. * @param Google_Comment $postBody * @param array $optParams Optional parameters. * @return Google_Service_Drive_Comment */ public function patch($fileId, $commentId, Google_Service_Drive_Comment $postBody, $optParams = array()) { $params = array('fileId' => $fileId, 'commentId' => $commentId, 'postBody' => $postBody); $params = array_merge($params, $optParams); return $this->call('patch', array($params), "Google_Service_Drive_Comment"); } /** * Updates an existing comment. (comments.update) * * @param string $fileId The ID of the file. * @param string $commentId The ID of the comment. * @param Google_Comment $postBody * @param array $optParams Optional parameters. * @return Google_Service_Drive_Comment */ public function update($fileId, $commentId, Google_Service_Drive_Comment $postBody, $optParams = array()) { $params = array('fileId' => $fileId, 'commentId' => $commentId, 'postBody' => $postBody); $params = array_merge($params, $optParams); return $this->call('update', array($params), "Google_Service_Drive_Comment"); } } /** * The "files" collection of methods. * Typical usage is: * * $driveService = new Google_Service_Drive(...); * $files = $driveService->files; * */ class Google_Service_Drive_Files_Resource extends UDP_Google_Service_Resource { /** * Creates a copy of the specified file. (files.copy) * * @param string $fileId The ID of the file to copy. * @param Google_DriveFile $postBody * @param array $optParams Optional parameters. * * @opt_param bool convert Whether to convert this file to the corresponding * Google Docs format. * @opt_param string ocrLanguage If ocr is true, hints at the language to use. * Valid values are ISO 639-1 codes. * @opt_param string visibility The visibility of the new file. This parameter * is only relevant when the source is not a native Google Doc and * convert=false. * @opt_param bool pinned Whether to pin the head revision of the new copy. A * file can have a maximum of 200 pinned revisions. * @opt_param bool ocr Whether to attempt OCR on .jpg, .png, .gif, or .pdf * uploads. * @opt_param string timedTextTrackName The timed text track name. * @opt_param string timedTextLanguage The language of the timed text. * @return UDP_Google_Service_Drive_DriveFile */ public function copy($fileId, UDP_Google_Service_Drive_DriveFile $postBody, $optParams = array()) { $params = array('fileId' => $fileId, 'postBody' => $postBody); $params = array_merge($params, $optParams); return $this->call('copy', array($params), "UDP_Google_Service_Drive_DriveFile"); } /** * Permanently deletes a file by ID. Skips the trash. The currently * authenticated user must own the file. (files.delete) * * @param string $fileId The ID of the file to delete. * @param array $optParams Optional parameters. */ public function delete($fileId, $optParams = array()) { $params = array('fileId' => $fileId); $params = array_merge($params, $optParams); return $this->call('delete', array($params)); } /** * Permanently deletes all of the user's trashed files. (files.emptyTrash) * * @param array $optParams Optional parameters. */ public function emptyTrash($optParams = array()) { $params = array(); $params = array_merge($params, $optParams); return $this->call('emptyTrash', array($params)); } /** * Gets a file's metadata by ID. (files.get) * * @param string $fileId The ID for the file in question. * @param array $optParams Optional parameters. * * @opt_param bool acknowledgeAbuse Whether the user is acknowledging the risk * of downloading known malware or other abusive files. * @opt_param bool updateViewedDate Whether to update the view date after * successfully retrieving the file. * @opt_param string revisionId Specifies the Revision ID that should be * downloaded. Ignored unless alt=media is specified. * @opt_param string projection This parameter is deprecated and has no * function. * @return UDP_Google_Service_Drive_DriveFile */ public function get($fileId, $optParams = array()) { $params = array('fileId' => $fileId); $params = array_merge($params, $optParams); return $this->call('get', array($params), "UDP_Google_Service_Drive_DriveFile"); } /** * Insert a new file. (files.insert) * * @param Google_DriveFile $postBody * @param array $optParams Optional parameters. * * @opt_param bool convert Whether to convert this file to the corresponding * Google Docs format. * @opt_param bool useContentAsIndexableText Whether to use the content as * indexable text. * @opt_param string ocrLanguage If ocr is true, hints at the language to use. * Valid values are ISO 639-1 codes. * @opt_param string visibility The visibility of the new file. This parameter * is only relevant when convert=false. * @opt_param bool pinned Whether to pin the head revision of the uploaded file. * A file can have a maximum of 200 pinned revisions. * @opt_param bool ocr Whether to attempt OCR on .jpg, .png, .gif, or .pdf * uploads. * @opt_param string timedTextTrackName The timed text track name. * @opt_param string timedTextLanguage The language of the timed text. * @return UDP_Google_Service_Drive_DriveFile */ public function insert(UDP_Google_Service_Drive_DriveFile $postBody, $optParams = array()) { $params = array('postBody' => $postBody); $params = array_merge($params, $optParams); return $this->call('insert', array($params), "UDP_Google_Service_Drive_DriveFile"); } /** * Lists the user's files. (files.listFiles) * * @param array $optParams Optional parameters. * * @opt_param string q Query string for searching files. * @opt_param string pageToken Page token for files. * @opt_param string corpus The body of items (files/documents) to which the * query applies. * @opt_param string projection This parameter is deprecated and has no * function. * @opt_param int maxResults Maximum number of files to return. * @return Google_Service_Drive_FileList */ public function listFiles($optParams = array()) { $params = array(); $params = array_merge($params, $optParams); return $this->call('list', array($params), "Google_Service_Drive_FileList"); } /** * Updates file metadata and/or content. This method supports patch semantics. * (files.patch) * * @param string $fileId The ID of the file to update. * @param Google_DriveFile $postBody * @param array $optParams Optional parameters. * * @opt_param string addParents Comma-separated list of parent IDs to add. * @opt_param bool updateViewedDate Whether to update the view date after * successfully updating the file. * @opt_param string removeParents Comma-separated list of parent IDs to remove. * @opt_param bool setModifiedDate Whether to set the modified date with the * supplied modified date. * @opt_param bool convert Whether to convert this file to the corresponding * Google Docs format. * @opt_param bool useContentAsIndexableText Whether to use the content as * indexable text. * @opt_param string ocrLanguage If ocr is true, hints at the language to use. * Valid values are ISO 639-1 codes. * @opt_param bool pinned Whether to pin the new revision. A file can have a * maximum of 200 pinned revisions. * @opt_param bool newRevision Whether a blob upload should create a new * revision. If false, the blob data in the current head revision is replaced. * If true or not set, a new blob is created as head revision, and previous * revisions are preserved (causing increased use of the user's data storage * quota). * @opt_param bool ocr Whether to attempt OCR on .jpg, .png, .gif, or .pdf * uploads. * @opt_param string timedTextLanguage The language of the timed text. * @opt_param string timedTextTrackName The timed text track name. * @return UDP_Google_Service_Drive_DriveFile */ public function patch($fileId, UDP_Google_Service_Drive_DriveFile $postBody, $optParams = array()) { $params = array('fileId' => $fileId, 'postBody' => $postBody); $params = array_merge($params, $optParams); return $this->call('patch', array($params), "UDP_Google_Service_Drive_DriveFile"); } /** * Set the file's updated time to the current server time. (files.touch) * * @param string $fileId The ID of the file to update. * @param array $optParams Optional parameters. * @return UDP_Google_Service_Drive_DriveFile */ public function touch($fileId, $optParams = array()) { $params = array('fileId' => $fileId); $params = array_merge($params, $optParams); return $this->call('touch', array($params), "UDP_Google_Service_Drive_DriveFile"); } /** * Moves a file to the trash. (files.trash) * * @param string $fileId The ID of the file to trash. * @param array $optParams Optional parameters. * @return UDP_Google_Service_Drive_DriveFile */ public function trash($fileId, $optParams = array()) { $params = array('fileId' => $fileId); $params = array_merge($params, $optParams); return $this->call('trash', array($params), "UDP_Google_Service_Drive_DriveFile"); } /** * Restores a file from the trash. (files.untrash) * * @param string $fileId The ID of the file to untrash. * @param array $optParams Optional parameters. * @return UDP_Google_Service_Drive_DriveFile */ public function untrash($fileId, $optParams = array()) { $params = array('fileId' => $fileId); $params = array_merge($params, $optParams); return $this->call('untrash', array($params), "UDP_Google_Service_Drive_DriveFile"); } /** * Updates file metadata and/or content. (files.update) * * @param string $fileId The ID of the file to update. * @param Google_DriveFile $postBody * @param array $optParams Optional parameters. * * @opt_param string addParents Comma-separated list of parent IDs to add. * @opt_param bool updateViewedDate Whether to update the view date after * successfully updating the file. * @opt_param string removeParents Comma-separated list of parent IDs to remove. * @opt_param bool setModifiedDate Whether to set the modified date with the * supplied modified date. * @opt_param bool convert Whether to convert this file to the corresponding * Google Docs format. * @opt_param bool useContentAsIndexableText Whether to use the content as * indexable text. * @opt_param string ocrLanguage If ocr is true, hints at the language to use. * Valid values are ISO 639-1 codes. * @opt_param bool pinned Whether to pin the new revision. A file can have a * maximum of 200 pinned revisions. * @opt_param bool newRevision Whether a blob upload should create a new * revision. If false, the blob data in the current head revision is replaced. * If true or not set, a new blob is created as head revision, and previous * revisions are preserved (causing increased use of the user's data storage * quota). * @opt_param bool ocr Whether to attempt OCR on .jpg, .png, .gif, or .pdf * uploads. * @opt_param string timedTextLanguage The language of the timed text. * @opt_param string timedTextTrackName The timed text track name. * @return UDP_Google_Service_Drive_DriveFile */ public function update($fileId, UDP_Google_Service_Drive_DriveFile $postBody, $optParams = array()) { $params = array('fileId' => $fileId, 'postBody' => $postBody); $params = array_merge($params, $optParams); return $this->call('update', array($params), "UDP_Google_Service_Drive_DriveFile"); } /** * Subscribe to changes on a file (files.watch) * * @param string $fileId The ID for the file in question. * @param Google_Channel $postBody * @param array $optParams Optional parameters. * * @opt_param bool acknowledgeAbuse Whether the user is acknowledging the risk * of downloading known malware or other abusive files. * @opt_param bool updateViewedDate Whether to update the view date after * successfully retrieving the file. * @opt_param string revisionId Specifies the Revision ID that should be * downloaded. Ignored unless alt=media is specified. * @opt_param string projection This parameter is deprecated and has no * function. * @return Google_Service_Drive_Channel */ public function watch($fileId, Google_Service_Drive_Channel $postBody, $optParams = array()) { $params = array('fileId' => $fileId, 'postBody' => $postBody); $params = array_merge($params, $optParams); return $this->call('watch', array($params), "Google_Service_Drive_Channel"); } } /** * The "parents" collection of methods. * Typical usage is: * * $driveService = new Google_Service_Drive(...); * $parents = $driveService->parents; * */ class Google_Service_Drive_Parents_Resource extends UDP_Google_Service_Resource { /** * Removes a parent from a file. (parents.delete) * * @param string $fileId The ID of the file. * @param string $parentId The ID of the parent. * @param array $optParams Optional parameters. */ public function delete($fileId, $parentId, $optParams = array()) { $params = array('fileId' => $fileId, 'parentId' => $parentId); $params = array_merge($params, $optParams); return $this->call('delete', array($params)); } /** * Gets a specific parent reference. (parents.get) * * @param string $fileId The ID of the file. * @param string $parentId The ID of the parent. * @param array $optParams Optional parameters. * @return UDP_Google_Service_Drive_ParentReference */ public function get($fileId, $parentId, $optParams = array()) { $params = array('fileId' => $fileId, 'parentId' => $parentId); $params = array_merge($params, $optParams); return $this->call('get', array($params), "UDP_Google_Service_Drive_ParentReference"); } /** * Adds a parent folder for a file. (parents.insert) * * @param string $fileId The ID of the file. * @param Google_ParentReference $postBody * @param array $optParams Optional parameters. * @return UDP_Google_Service_Drive_ParentReference */ public function insert($fileId, UDP_Google_Service_Drive_ParentReference $postBody, $optParams = array()) { $params = array('fileId' => $fileId, 'postBody' => $postBody); $params = array_merge($params, $optParams); return $this->call('insert', array($params), "UDP_Google_Service_Drive_ParentReference"); } /** * Lists a file's parents. (parents.listParents) * * @param string $fileId The ID of the file. * @param array $optParams Optional parameters. * @return Google_Service_Drive_ParentList */ public function listParents($fileId, $optParams = array()) { $params = array('fileId' => $fileId); $params = array_merge($params, $optParams); return $this->call('list', array($params), "Google_Service_Drive_ParentList"); } } /** * The "permissions" collection of methods. * Typical usage is: * * $driveService = new Google_Service_Drive(...); * $permissions = $driveService->permissions; * */ class Google_Service_Drive_Permissions_Resource extends UDP_Google_Service_Resource { /** * Deletes a permission from a file. (permissions.delete) * * @param string $fileId The ID for the file. * @param string $permissionId The ID for the permission. * @param array $optParams Optional parameters. */ public function delete($fileId, $permissionId, $optParams = array()) { $params = array('fileId' => $fileId, 'permissionId' => $permissionId); $params = array_merge($params, $optParams); return $this->call('delete', array($params)); } /** * Gets a permission by ID. (permissions.get) * * @param string $fileId The ID for the file. * @param string $permissionId The ID for the permission. * @param array $optParams Optional parameters. * @return Google_Service_Drive_Permission */ public function get($fileId, $permissionId, $optParams = array()) { $params = array('fileId' => $fileId, 'permissionId' => $permissionId); $params = array_merge($params, $optParams); return $this->call('get', array($params), "Google_Service_Drive_Permission"); } /** * Returns the permission ID for an email address. (permissions.getIdForEmail) * * @param string $email The email address for which to return a permission ID * @param array $optParams Optional parameters. * @return Google_Service_Drive_PermissionId */ public function getIdForEmail($email, $optParams = array()) { $params = array('email' => $email); $params = array_merge($params, $optParams); return $this->call('getIdForEmail', array($params), "Google_Service_Drive_PermissionId"); } /** * Inserts a permission for a file. (permissions.insert) * * @param string $fileId The ID for the file. * @param Google_Permission $postBody * @param array $optParams Optional parameters. * * @opt_param string emailMessage A custom message to include in notification * emails. * @opt_param bool sendNotificationEmails Whether to send notification emails * when sharing to users or groups. This parameter is ignored and an email is * sent if the role is owner. * @return Google_Service_Drive_Permission */ public function insert($fileId, Google_Service_Drive_Permission $postBody, $optParams = array()) { $params = array('fileId' => $fileId, 'postBody' => $postBody); $params = array_merge($params, $optParams); return $this->call('insert', array($params), "Google_Service_Drive_Permission"); } /** * Lists a file's permissions. (permissions.listPermissions) * * @param string $fileId The ID for the file. * @param array $optParams Optional parameters. * @return Google_Service_Drive_PermissionList */ public function listPermissions($fileId, $optParams = array()) { $params = array('fileId' => $fileId); $params = array_merge($params, $optParams); return $this->call('list', array($params), "Google_Service_Drive_PermissionList"); } /** * Updates a permission. This method supports patch semantics. * (permissions.patch) * * @param string $fileId The ID for the file. * @param string $permissionId The ID for the permission. * @param Google_Permission $postBody * @param array $optParams Optional parameters. * * @opt_param bool transferOwnership Whether changing a role to 'owner' * downgrades the current owners to writers. Does nothing if the specified role * is not 'owner'. * @return Google_Service_Drive_Permission */ public function patch($fileId, $permissionId, Google_Service_Drive_Permission $postBody, $optParams = array()) { $params = array('fileId' => $fileId, 'permissionId' => $permissionId, 'postBody' => $postBody); $params = array_merge($params, $optParams); return $this->call('patch', array($params), "Google_Service_Drive_Permission"); } /** * Updates a permission. (permissions.update) * * @param string $fileId The ID for the file. * @param string $permissionId The ID for the permission. * @param Google_Permission $postBody * @param array $optParams Optional parameters. * * @opt_param bool transferOwnership Whether changing a role to 'owner' * downgrades the current owners to writers. Does nothing if the specified role * is not 'owner'. * @return Google_Service_Drive_Permission */ public function update($fileId, $permissionId, Google_Service_Drive_Permission $postBody, $optParams = array()) { $params = array('fileId' => $fileId, 'permissionId' => $permissionId, 'postBody' => $postBody); $params = array_merge($params, $optParams); return $this->call('update', array($params), "Google_Service_Drive_Permission"); } } /** * The "properties" collection of methods. * Typical usage is: * * $driveService = new Google_Service_Drive(...); * $properties = $driveService->properties; * */ class Google_Service_Drive_Properties_Resource extends UDP_Google_Service_Resource { /** * Deletes a property. (properties.delete) * * @param string $fileId The ID of the file. * @param string $propertyKey The key of the property. * @param array $optParams Optional parameters. * * @opt_param string visibility The visibility of the property. */ public function delete($fileId, $propertyKey, $optParams = array()) { $params = array('fileId' => $fileId, 'propertyKey' => $propertyKey); $params = array_merge($params, $optParams); return $this->call('delete', array($params)); } /** * Gets a property by its key. (properties.get) * * @param string $fileId The ID of the file. * @param string $propertyKey The key of the property. * @param array $optParams Optional parameters. * * @opt_param string visibility The visibility of the property. * @return Google_Service_Drive_Property */ public function get($fileId, $propertyKey, $optParams = array()) { $params = array('fileId' => $fileId, 'propertyKey' => $propertyKey); $params = array_merge($params, $optParams); return $this->call('get', array($params), "Google_Service_Drive_Property"); } /** * Adds a property to a file. (properties.insert) * * @param string $fileId The ID of the file. * @param Google_Property $postBody * @param array $optParams Optional parameters. * @return Google_Service_Drive_Property */ public function insert($fileId, Google_Service_Drive_Property $postBody, $optParams = array()) { $params = array('fileId' => $fileId, 'postBody' => $postBody); $params = array_merge($params, $optParams); return $this->call('insert', array($params), "Google_Service_Drive_Property"); } /** * Lists a file's properties. (properties.listProperties) * * @param string $fileId The ID of the file. * @param array $optParams Optional parameters. * @return Google_Service_Drive_PropertyList */ public function listProperties($fileId, $optParams = array()) { $params = array('fileId' => $fileId); $params = array_merge($params, $optParams); return $this->call('list', array($params), "Google_Service_Drive_PropertyList"); } /** * Updates a property. This method supports patch semantics. (properties.patch) * * @param string $fileId The ID of the file. * @param string $propertyKey The key of the property. * @param Google_Property $postBody * @param array $optParams Optional parameters. * * @opt_param string visibility The visibility of the property. * @return Google_Service_Drive_Property */ public function patch($fileId, $propertyKey, Google_Service_Drive_Property $postBody, $optParams = array()) { $params = array('fileId' => $fileId, 'propertyKey' => $propertyKey, 'postBody' => $postBody); $params = array_merge($params, $optParams); return $this->call('patch', array($params), "Google_Service_Drive_Property"); } /** * Updates a property. (properties.update) * * @param string $fileId The ID of the file. * @param string $propertyKey The key of the property. * @param Google_Property $postBody * @param array $optParams Optional parameters. * * @opt_param string visibility The visibility of the property. * @return Google_Service_Drive_Property */ public function update($fileId, $propertyKey, Google_Service_Drive_Property $postBody, $optParams = array()) { $params = array('fileId' => $fileId, 'propertyKey' => $propertyKey, 'postBody' => $postBody); $params = array_merge($params, $optParams); return $this->call('update', array($params), "Google_Service_Drive_Property"); } } /** * The "realtime" collection of methods. * Typical usage is: * * $driveService = new Google_Service_Drive(...); * $realtime = $driveService->realtime; * */ class Google_Service_Drive_Realtime_Resource extends UDP_Google_Service_Resource { /** * Exports the contents of the Realtime API data model associated with this file * as JSON. (realtime.get) * * @param string $fileId The ID of the file that the Realtime API data model is * associated with. * @param array $optParams Optional parameters. * * @opt_param int revision The revision of the Realtime API data model to * export. Revisions start at 1 (the initial empty data model) and are * incremented with each change. If this parameter is excluded, the most recent * data model will be returned. */ public function get($fileId, $optParams = array()) { $params = array('fileId' => $fileId); $params = array_merge($params, $optParams); return $this->call('get', array($params)); } /** * Overwrites the Realtime API data model associated with this file with the * provided JSON data model. (realtime.update) * * @param string $fileId The ID of the file that the Realtime API data model is * associated with. * @param array $optParams Optional parameters. * * @opt_param string baseRevision The revision of the model to diff the uploaded * model against. If set, the uploaded model is diffed against the provided * revision and those differences are merged with any changes made to the model * after the provided revision. If not set, the uploaded model replaces the * current model on the server. */ public function update($fileId, $optParams = array()) { $params = array('fileId' => $fileId); $params = array_merge($params, $optParams); return $this->call('update', array($params)); } } /** * The "replies" collection of methods. * Typical usage is: * * $driveService = new Google_Service_Drive(...); * $replies = $driveService->replies; * */ class Google_Service_Drive_Replies_Resource extends UDP_Google_Service_Resource { /** * Deletes a reply. (replies.delete) * * @param string $fileId The ID of the file. * @param string $commentId The ID of the comment. * @param string $replyId The ID of the reply. * @param array $optParams Optional parameters. */ public function delete($fileId, $commentId, $replyId, $optParams = array()) { $params = array('fileId' => $fileId, 'commentId' => $commentId, 'replyId' => $replyId); $params = array_merge($params, $optParams); return $this->call('delete', array($params)); } /** * Gets a reply. (replies.get) * * @param string $fileId The ID of the file. * @param string $commentId The ID of the comment. * @param string $replyId The ID of the reply. * @param array $optParams Optional parameters. * * @opt_param bool includeDeleted If set, this will succeed when retrieving a * deleted reply. * @return Google_Service_Drive_CommentReply */ public function get($fileId, $commentId, $replyId, $optParams = array()) { $params = array('fileId' => $fileId, 'commentId' => $commentId, 'replyId' => $replyId); $params = array_merge($params, $optParams); return $this->call('get', array($params), "Google_Service_Drive_CommentReply"); } /** * Creates a new reply to the given comment. (replies.insert) * * @param string $fileId The ID of the file. * @param string $commentId The ID of the comment. * @param Google_CommentReply $postBody * @param array $optParams Optional parameters. * @return Google_Service_Drive_CommentReply */ public function insert($fileId, $commentId, Google_Service_Drive_CommentReply $postBody, $optParams = array()) { $params = array('fileId' => $fileId, 'commentId' => $commentId, 'postBody' => $postBody); $params = array_merge($params, $optParams); return $this->call('insert', array($params), "Google_Service_Drive_CommentReply"); } /** * Lists all of the replies to a comment. (replies.listReplies) * * @param string $fileId The ID of the file. * @param string $commentId The ID of the comment. * @param array $optParams Optional parameters. * * @opt_param string pageToken The continuation token, used to page through * large result sets. To get the next page of results, set this parameter to the * value of "nextPageToken" from the previous response. * @opt_param bool includeDeleted If set, all replies, including deleted replies * (with content stripped) will be returned. * @opt_param int maxResults The maximum number of replies to include in the * response, used for paging. * @return Google_Service_Drive_CommentReplyList */ public function listReplies($fileId, $commentId, $optParams = array()) { $params = array('fileId' => $fileId, 'commentId' => $commentId); $params = array_merge($params, $optParams); return $this->call('list', array($params), "Google_Service_Drive_CommentReplyList"); } /** * Updates an existing reply. This method supports patch semantics. * (replies.patch) * * @param string $fileId The ID of the file. * @param string $commentId The ID of the comment. * @param string $replyId The ID of the reply. * @param Google_CommentReply $postBody * @param array $optParams Optional parameters. * @return Google_Service_Drive_CommentReply */ public function patch($fileId, $commentId, $replyId, Google_Service_Drive_CommentReply $postBody, $optParams = array()) { $params = array('fileId' => $fileId, 'commentId' => $commentId, 'replyId' => $replyId, 'postBody' => $postBody); $params = array_merge($params, $optParams); return $this->call('patch', array($params), "Google_Service_Drive_CommentReply"); } /** * Updates an existing reply. (replies.update) * * @param string $fileId The ID of the file. * @param string $commentId The ID of the comment. * @param string $replyId The ID of the reply. * @param Google_CommentReply $postBody * @param array $optParams Optional parameters. * @return Google_Service_Drive_CommentReply */ public function update($fileId, $commentId, $replyId, Google_Service_Drive_CommentReply $postBody, $optParams = array()) { $params = array('fileId' => $fileId, 'commentId' => $commentId, 'replyId' => $replyId, 'postBody' => $postBody); $params = array_merge($params, $optParams); return $this->call('update', array($params), "Google_Service_Drive_CommentReply"); } } /** * The "revisions" collection of methods. * Typical usage is: * * $driveService = new Google_Service_Drive(...); * $revisions = $driveService->revisions; * */ class Google_Service_Drive_Revisions_Resource extends UDP_Google_Service_Resource { /** * Removes a revision. (revisions.delete) * * @param string $fileId The ID of the file. * @param string $revisionId The ID of the revision. * @param array $optParams Optional parameters. */ public function delete($fileId, $revisionId, $optParams = array()) { $params = array('fileId' => $fileId, 'revisionId' => $revisionId); $params = array_merge($params, $optParams); return $this->call('delete', array($params)); } /** * Gets a specific revision. (revisions.get) * * @param string $fileId The ID of the file. * @param string $revisionId The ID of the revision. * @param array $optParams Optional parameters. * @return Google_Service_Drive_Revision */ public function get($fileId, $revisionId, $optParams = array()) { $params = array('fileId' => $fileId, 'revisionId' => $revisionId); $params = array_merge($params, $optParams); return $this->call('get', array($params), "Google_Service_Drive_Revision"); } /** * Lists a file's revisions. (revisions.listRevisions) * * @param string $fileId The ID of the file. * @param array $optParams Optional parameters. * @return Google_Service_Drive_RevisionList */ public function listRevisions($fileId, $optParams = array()) { $params = array('fileId' => $fileId); $params = array_merge($params, $optParams); return $this->call('list', array($params), "Google_Service_Drive_RevisionList"); } /** * Updates a revision. This method supports patch semantics. (revisions.patch) * * @param string $fileId The ID for the file. * @param string $revisionId The ID for the revision. * @param Google_Revision $postBody * @param array $optParams Optional parameters. * @return Google_Service_Drive_Revision */ public function patch($fileId, $revisionId, Google_Service_Drive_Revision $postBody, $optParams = array()) { $params = array('fileId' => $fileId, 'revisionId' => $revisionId, 'postBody' => $postBody); $params = array_merge($params, $optParams); return $this->call('patch', array($params), "Google_Service_Drive_Revision"); } /** * Updates a revision. (revisions.update) * * @param string $fileId The ID for the file. * @param string $revisionId The ID for the revision. * @param Google_Revision $postBody * @param array $optParams Optional parameters. * @return Google_Service_Drive_Revision */ public function update($fileId, $revisionId, Google_Service_Drive_Revision $postBody, $optParams = array()) { $params = array('fileId' => $fileId, 'revisionId' => $revisionId, 'postBody' => $postBody); $params = array_merge($params, $optParams); return $this->call('update', array($params), "Google_Service_Drive_Revision"); } } class Google_Service_Drive_About extends Google_Collection { protected $collection_key = 'quotaBytesByService'; protected $internal_gapi_mappings = array( ); protected $additionalRoleInfoType = 'Google_Service_Drive_AboutAdditionalRoleInfo'; protected $additionalRoleInfoDataType = 'array'; public $domainSharingPolicy; public $etag; protected $exportFormatsType = 'Google_Service_Drive_AboutExportFormats'; protected $exportFormatsDataType = 'array'; protected $featuresType = 'Google_Service_Drive_AboutFeatures'; protected $featuresDataType = 'array'; public $folderColorPalette; protected $importFormatsType = 'Google_Service_Drive_AboutImportFormats'; protected $importFormatsDataType = 'array'; public $isCurrentAppInstalled; public $kind; public $languageCode; public $largestChangeId; protected $maxUploadSizesType = 'Google_Service_Drive_AboutMaxUploadSizes'; protected $maxUploadSizesDataType = 'array'; public $name; public $permissionId; protected $quotaBytesByServiceType = 'Google_Service_Drive_AboutQuotaBytesByService'; protected $quotaBytesByServiceDataType = 'array'; public $quotaBytesTotal; public $quotaBytesUsed; public $quotaBytesUsedAggregate; public $quotaBytesUsedInTrash; public $quotaType; public $remainingChangeIds; public $rootFolderId; public $selfLink; protected $userType = 'Google_Service_Drive_User'; protected $userDataType = ''; public function setAdditionalRoleInfo($additionalRoleInfo) { $this->additionalRoleInfo = $additionalRoleInfo; } public function getAdditionalRoleInfo() { return $this->additionalRoleInfo; } public function setDomainSharingPolicy($domainSharingPolicy) { $this->domainSharingPolicy = $domainSharingPolicy; } public function getDomainSharingPolicy() { return $this->domainSharingPolicy; } public function setEtag($etag) { $this->etag = $etag; } public function getEtag() { return $this->etag; } public function setExportFormats($exportFormats) { $this->exportFormats = $exportFormats; } public function getExportFormats() { return $this->exportFormats; } public function setFeatures($features) { $this->features = $features; } public function getFeatures() { return $this->features; } public function setFolderColorPalette($folderColorPalette) { $this->folderColorPalette = $folderColorPalette; } public function getFolderColorPalette() { return $this->folderColorPalette; } public function setImportFormats($importFormats) { $this->importFormats = $importFormats; } public function getImportFormats() { return $this->importFormats; } public function setIsCurrentAppInstalled($isCurrentAppInstalled) { $this->isCurrentAppInstalled = $isCurrentAppInstalled; } public function getIsCurrentAppInstalled() { return $this->isCurrentAppInstalled; } public function setKind($kind) { $this->kind = $kind; } public function getKind() { return $this->kind; } public function setLanguageCode($languageCode) { $this->languageCode = $languageCode; } public function getLanguageCode() { return $this->languageCode; } public function setLargestChangeId($largestChangeId) { $this->largestChangeId = $largestChangeId; } public function getLargestChangeId() { return $this->largestChangeId; } public function setMaxUploadSizes($maxUploadSizes) { $this->maxUploadSizes = $maxUploadSizes; } public function getMaxUploadSizes() { return $this->maxUploadSizes; } public function setName($name) { $this->name = $name; } public function getName() { return $this->name; } public function setPermissionId($permissionId) { $this->permissionId = $permissionId; } public function getPermissionId() { return $this->permissionId; } public function setQuotaBytesByService($quotaBytesByService) { $this->quotaBytesByService = $quotaBytesByService; } public function getQuotaBytesByService() { return $this->quotaBytesByService; } public function setQuotaBytesTotal($quotaBytesTotal) { $this->quotaBytesTotal = $quotaBytesTotal; } public function getQuotaBytesTotal() { return $this->quotaBytesTotal; } public function setQuotaBytesUsed($quotaBytesUsed) { $this->quotaBytesUsed = $quotaBytesUsed; } public function getQuotaBytesUsed() { return $this->quotaBytesUsed; } public function setQuotaBytesUsedAggregate($quotaBytesUsedAggregate) { $this->quotaBytesUsedAggregate = $quotaBytesUsedAggregate; } public function getQuotaBytesUsedAggregate() { return $this->quotaBytesUsedAggregate; } public function setQuotaBytesUsedInTrash($quotaBytesUsedInTrash) { $this->quotaBytesUsedInTrash = $quotaBytesUsedInTrash; } public function getQuotaBytesUsedInTrash() { return $this->quotaBytesUsedInTrash; } public function setQuotaType($quotaType) { $this->quotaType = $quotaType; } public function getQuotaType() { return $this->quotaType; } public function setRemainingChangeIds($remainingChangeIds) { $this->remainingChangeIds = $remainingChangeIds; } public function getRemainingChangeIds() { return $this->remainingChangeIds; } public function setRootFolderId($rootFolderId) { $this->rootFolderId = $rootFolderId; } public function getRootFolderId() { return $this->rootFolderId; } public function setSelfLink($selfLink) { $this->selfLink = $selfLink; } public function getSelfLink() { return $this->selfLink; } public function setUser(Google_Service_Drive_User $user) { $this->user = $user; } public function getUser() { return $this->user; } } class Google_Service_Drive_AboutAdditionalRoleInfo extends Google_Collection { protected $collection_key = 'roleSets'; protected $internal_gapi_mappings = array( ); protected $roleSetsType = 'Google_Service_Drive_AboutAdditionalRoleInfoRoleSets'; protected $roleSetsDataType = 'array'; public $type; public function setRoleSets($roleSets) { $this->roleSets = $roleSets; } public function getRoleSets() { return $this->roleSets; } public function setType($type) { $this->type = $type; } public function getType() { return $this->type; } } class Google_Service_Drive_AboutAdditionalRoleInfoRoleSets extends Google_Collection { protected $collection_key = 'additionalRoles'; protected $internal_gapi_mappings = array( ); public $additionalRoles; public $primaryRole; public function setAdditionalRoles($additionalRoles) { $this->additionalRoles = $additionalRoles; } public function getAdditionalRoles() { return $this->additionalRoles; } public function setPrimaryRole($primaryRole) { $this->primaryRole = $primaryRole; } public function getPrimaryRole() { return $this->primaryRole; } } class Google_Service_Drive_AboutExportFormats extends Google_Collection { protected $collection_key = 'targets'; protected $internal_gapi_mappings = array( ); public $source; public $targets; public function setSource($source) { $this->source = $source; } public function getSource() { return $this->source; } public function setTargets($targets) { $this->targets = $targets; } public function getTargets() { return $this->targets; } } class Google_Service_Drive_AboutFeatures extends Google_Model { protected $internal_gapi_mappings = array( ); public $featureName; public $featureRate; public function setFeatureName($featureName) { $this->featureName = $featureName; } public function getFeatureName() { return $this->featureName; } public function setFeatureRate($featureRate) { $this->featureRate = $featureRate; } public function getFeatureRate() { return $this->featureRate; } } class Google_Service_Drive_AboutImportFormats extends Google_Collection { protected $collection_key = 'targets'; protected $internal_gapi_mappings = array( ); public $source; public $targets; public function setSource($source) { $this->source = $source; } public function getSource() { return $this->source; } public function setTargets($targets) { $this->targets = $targets; } public function getTargets() { return $this->targets; } } class Google_Service_Drive_AboutMaxUploadSizes extends Google_Model { protected $internal_gapi_mappings = array( ); public $size; public $type; public function setSize($size) { $this->size = $size; } public function getSize() { return $this->size; } public function setType($type) { $this->type = $type; } public function getType() { return $this->type; } } class Google_Service_Drive_AboutQuotaBytesByService extends Google_Model { protected $internal_gapi_mappings = array( ); public $bytesUsed; public $serviceName; public function setBytesUsed($bytesUsed) { $this->bytesUsed = $bytesUsed; } public function getBytesUsed() { return $this->bytesUsed; } public function setServiceName($serviceName) { $this->serviceName = $serviceName; } public function getServiceName() { return $this->serviceName; } } class Google_Service_Drive_App extends Google_Collection { protected $collection_key = 'secondaryMimeTypes'; protected $internal_gapi_mappings = array( ); public $authorized; public $createInFolderTemplate; public $createUrl; public $hasDriveWideScope; protected $iconsType = 'Google_Service_Drive_AppIcons'; protected $iconsDataType = 'array'; public $id; public $installed; public $kind; public $longDescription; public $name; public $objectType; public $openUrlTemplate; public $primaryFileExtensions; public $primaryMimeTypes; public $productId; public $productUrl; public $secondaryFileExtensions; public $secondaryMimeTypes; public $shortDescription; public $supportsCreate; public $supportsImport; public $supportsMultiOpen; public $supportsOfflineCreate; public $useByDefault; public function setAuthorized($authorized) { $this->authorized = $authorized; } public function getAuthorized() { return $this->authorized; } public function setCreateInFolderTemplate($createInFolderTemplate) { $this->createInFolderTemplate = $createInFolderTemplate; } public function getCreateInFolderTemplate() { return $this->createInFolderTemplate; } public function setCreateUrl($createUrl) { $this->createUrl = $createUrl; } public function getCreateUrl() { return $this->createUrl; } public function setHasDriveWideScope($hasDriveWideScope) { $this->hasDriveWideScope = $hasDriveWideScope; } public function getHasDriveWideScope() { return $this->hasDriveWideScope; } public function setIcons($icons) { $this->icons = $icons; } public function getIcons() { return $this->icons; } public function setId($id) { $this->id = $id; } public function getId() { return $this->id; } public function setInstalled($installed) { $this->installed = $installed; } public function getInstalled() { return $this->installed; } public function setKind($kind) { $this->kind = $kind; } public function getKind() { return $this->kind; } public function setLongDescription($longDescription) { $this->longDescription = $longDescription; } public function getLongDescription() { return $this->longDescription; } public function setName($name) { $this->name = $name; } public function getName() { return $this->name; } public function setObjectType($objectType) { $this->objectType = $objectType; } public function getObjectType() { return $this->objectType; } public function setOpenUrlTemplate($openUrlTemplate) { $this->openUrlTemplate = $openUrlTemplate; } public function getOpenUrlTemplate() { return $this->openUrlTemplate; } public function setPrimaryFileExtensions($primaryFileExtensions) { $this->primaryFileExtensions = $primaryFileExtensions; } public function getPrimaryFileExtensions() { return $this->primaryFileExtensions; } public function setPrimaryMimeTypes($primaryMimeTypes) { $this->primaryMimeTypes = $primaryMimeTypes; } public function getPrimaryMimeTypes() { return $this->primaryMimeTypes; } public function setProductId($productId) { $this->productId = $productId; } public function getProductId() { return $this->productId; } public function setProductUrl($productUrl) { $this->productUrl = $productUrl; } public function getProductUrl() { return $this->productUrl; } public function setSecondaryFileExtensions($secondaryFileExtensions) { $this->secondaryFileExtensions = $secondaryFileExtensions; } public function getSecondaryFileExtensions() { return $this->secondaryFileExtensions; } public function setSecondaryMimeTypes($secondaryMimeTypes) { $this->secondaryMimeTypes = $secondaryMimeTypes; } public function getSecondaryMimeTypes() { return $this->secondaryMimeTypes; } public function setShortDescription($shortDescription) { $this->shortDescription = $shortDescription; } public function getShortDescription() { return $this->shortDescription; } public function setSupportsCreate($supportsCreate) { $this->supportsCreate = $supportsCreate; } public function getSupportsCreate() { return $this->supportsCreate; } public function setSupportsImport($supportsImport) { $this->supportsImport = $supportsImport; } public function getSupportsImport() { return $this->supportsImport; } public function setSupportsMultiOpen($supportsMultiOpen) { $this->supportsMultiOpen = $supportsMultiOpen; } public function getSupportsMultiOpen() { return $this->supportsMultiOpen; } public function setSupportsOfflineCreate($supportsOfflineCreate) { $this->supportsOfflineCreate = $supportsOfflineCreate; } public function getSupportsOfflineCreate() { return $this->supportsOfflineCreate; } public function setUseByDefault($useByDefault) { $this->useByDefault = $useByDefault; } public function getUseByDefault() { return $this->useByDefault; } } class Google_Service_Drive_AppIcons extends Google_Model { protected $internal_gapi_mappings = array( ); public $category; public $iconUrl; public $size; public function setCategory($category) { $this->category = $category; } public function getCategory() { return $this->category; } public function setIconUrl($iconUrl) { $this->iconUrl = $iconUrl; } public function getIconUrl() { return $this->iconUrl; } public function setSize($size) { $this->size = $size; } public function getSize() { return $this->size; } } class Google_Service_Drive_AppList extends Google_Collection { protected $collection_key = 'items'; protected $internal_gapi_mappings = array( ); public $defaultAppIds; public $etag; protected $itemsType = 'Google_Service_Drive_App'; protected $itemsDataType = 'array'; public $kind; public $selfLink; public function setDefaultAppIds($defaultAppIds) { $this->defaultAppIds = $defaultAppIds; } public function getDefaultAppIds() { return $this->defaultAppIds; } public function setEtag($etag) { $this->etag = $etag; } public function getEtag() { return $this->etag; } public function setItems($items) { $this->items = $items; } public function getItems() { return $this->items; } public function setKind($kind) { $this->kind = $kind; } public function getKind() { return $this->kind; } public function setSelfLink($selfLink) { $this->selfLink = $selfLink; } public function getSelfLink() { return $this->selfLink; } } class Google_Service_Drive_Change extends Google_Model { protected $internal_gapi_mappings = array( ); public $deleted; protected $fileType = 'UDP_Google_Service_Drive_DriveFile'; protected $fileDataType = ''; public $fileId; public $id; public $kind; public $modificationDate; public $selfLink; public function setDeleted($deleted) { $this->deleted = $deleted; } public function getDeleted() { return $this->deleted; } public function setFile(UDP_Google_Service_Drive_DriveFile $file) { $this->file = $file; } public function getFile() { return $this->file; } public function setFileId($fileId) { $this->fileId = $fileId; } public function getFileId() { return $this->fileId; } public function setId($id) { $this->id = $id; } public function getId() { return $this->id; } public function setKind($kind) { $this->kind = $kind; } public function getKind() { return $this->kind; } public function setModificationDate($modificationDate) { $this->modificationDate = $modificationDate; } public function getModificationDate() { return $this->modificationDate; } public function setSelfLink($selfLink) { $this->selfLink = $selfLink; } public function getSelfLink() { return $this->selfLink; } } class Google_Service_Drive_ChangeList extends Google_Collection { protected $collection_key = 'items'; protected $internal_gapi_mappings = array( ); public $etag; protected $itemsType = 'Google_Service_Drive_Change'; protected $itemsDataType = 'array'; public $kind; public $largestChangeId; public $nextLink; public $nextPageToken; public $selfLink; public function setEtag($etag) { $this->etag = $etag; } public function getEtag() { return $this->etag; } public function setItems($items) { $this->items = $items; } public function getItems() { return $this->items; } public function setKind($kind) { $this->kind = $kind; } public function getKind() { return $this->kind; } public function setLargestChangeId($largestChangeId) { $this->largestChangeId = $largestChangeId; } public function getLargestChangeId() { return $this->largestChangeId; } public function setNextLink($nextLink) { $this->nextLink = $nextLink; } public function getNextLink() { return $this->nextLink; } public function setNextPageToken($nextPageToken) { $this->nextPageToken = $nextPageToken; } public function getNextPageToken() { return $this->nextPageToken; } public function setSelfLink($selfLink) { $this->selfLink = $selfLink; } public function getSelfLink() { return $this->selfLink; } } class Google_Service_Drive_Channel extends Google_Model { protected $internal_gapi_mappings = array( ); public $address; public $expiration; public $id; public $kind; public $params; public $payload; public $resourceId; public $resourceUri; public $token; public $type; public function setAddress($address) { $this->address = $address; } public function getAddress() { return $this->address; } public function setExpiration($expiration) { $this->expiration = $expiration; } public function getExpiration() { return $this->expiration; } public function setId($id) { $this->id = $id; } public function getId() { return $this->id; } public function setKind($kind) { $this->kind = $kind; } public function getKind() { return $this->kind; } public function setParams($params) { $this->params = $params; } public function getParams() { return $this->params; } public function setPayload($payload) { $this->payload = $payload; } public function getPayload() { return $this->payload; } public function setResourceId($resourceId) { $this->resourceId = $resourceId; } public function getResourceId() { return $this->resourceId; } public function setResourceUri($resourceUri) { $this->resourceUri = $resourceUri; } public function getResourceUri() { return $this->resourceUri; } public function setToken($token) { $this->token = $token; } public function getToken() { return $this->token; } public function setType($type) { $this->type = $type; } public function getType() { return $this->type; } } class Google_Service_Drive_ChannelParams extends Google_Model { } class Google_Service_Drive_ChildList extends Google_Collection { protected $collection_key = 'items'; protected $internal_gapi_mappings = array( ); public $etag; protected $itemsType = 'Google_Service_Drive_ChildReference'; protected $itemsDataType = 'array'; public $kind; public $nextLink; public $nextPageToken; public $selfLink; public function setEtag($etag) { $this->etag = $etag; } public function getEtag() { return $this->etag; } public function setItems($items) { $this->items = $items; } public function getItems() { return $this->items; } public function setKind($kind) { $this->kind = $kind; } public function getKind() { return $this->kind; } public function setNextLink($nextLink) { $this->nextLink = $nextLink; } public function getNextLink() { return $this->nextLink; } public function setNextPageToken($nextPageToken) { $this->nextPageToken = $nextPageToken; } public function getNextPageToken() { return $this->nextPageToken; } public function setSelfLink($selfLink) { $this->selfLink = $selfLink; } public function getSelfLink() { return $this->selfLink; } } class Google_Service_Drive_ChildReference extends Google_Model { protected $internal_gapi_mappings = array( ); public $childLink; public $id; public $kind; public $selfLink; public function setChildLink($childLink) { $this->childLink = $childLink; } public function getChildLink() { return $this->childLink; } public function setId($id) { $this->id = $id; } public function getId() { return $this->id; } public function setKind($kind) { $this->kind = $kind; } public function getKind() { return $this->kind; } public function setSelfLink($selfLink) { $this->selfLink = $selfLink; } public function getSelfLink() { return $this->selfLink; } } class Google_Service_Drive_Comment extends Google_Collection { protected $collection_key = 'replies'; protected $internal_gapi_mappings = array( ); public $anchor; protected $authorType = 'Google_Service_Drive_User'; protected $authorDataType = ''; public $commentId; public $content; protected $contextType = 'Google_Service_Drive_CommentContext'; protected $contextDataType = ''; public $createdDate; public $deleted; public $fileId; public $fileTitle; public $htmlContent; public $kind; public $modifiedDate; protected $repliesType = 'Google_Service_Drive_CommentReply'; protected $repliesDataType = 'array'; public $selfLink; public $status; public function setAnchor($anchor) { $this->anchor = $anchor; } public function getAnchor() { return $this->anchor; } public function setAuthor(Google_Service_Drive_User $author) { $this->author = $author; } public function getAuthor() { return $this->author; } public function setCommentId($commentId) { $this->commentId = $commentId; } public function getCommentId() { return $this->commentId; } public function setContent($content) { $this->content = $content; } public function getContent() { return $this->content; } public function setContext(Google_Service_Drive_CommentContext $context) { $this->context = $context; } public function getContext() { return $this->context; } public function setCreatedDate($createdDate) { $this->createdDate = $createdDate; } public function getCreatedDate() { return $this->createdDate; } public function setDeleted($deleted) { $this->deleted = $deleted; } public function getDeleted() { return $this->deleted; } public function setFileId($fileId) { $this->fileId = $fileId; } public function getFileId() { return $this->fileId; } public function setFileTitle($fileTitle) { $this->fileTitle = $fileTitle; } public function getFileTitle() { return $this->fileTitle; } public function setHtmlContent($htmlContent) { $this->htmlContent = $htmlContent; } public function getHtmlContent() { return $this->htmlContent; } public function setKind($kind) { $this->kind = $kind; } public function getKind() { return $this->kind; } public function setModifiedDate($modifiedDate) { $this->modifiedDate = $modifiedDate; } public function getModifiedDate() { return $this->modifiedDate; } public function setReplies($replies) { $this->replies = $replies; } public function getReplies() { return $this->replies; } public function setSelfLink($selfLink) { $this->selfLink = $selfLink; } public function getSelfLink() { return $this->selfLink; } public function setStatus($status) { $this->status = $status; } public function getStatus() { return $this->status; } } class Google_Service_Drive_CommentContext extends Google_Model { protected $internal_gapi_mappings = array( ); public $type; public $value; public function setType($type) { $this->type = $type; } public function getType() { return $this->type; } public function setValue($value) { $this->value = $value; } public function getValue() { return $this->value; } } class Google_Service_Drive_CommentList extends Google_Collection { protected $collection_key = 'items'; protected $internal_gapi_mappings = array( ); protected $itemsType = 'Google_Service_Drive_Comment'; protected $itemsDataType = 'array'; public $kind; public $nextLink; public $nextPageToken; public $selfLink; public function setItems($items) { $this->items = $items; } public function getItems() { return $this->items; } public function setKind($kind) { $this->kind = $kind; } public function getKind() { return $this->kind; } public function setNextLink($nextLink) { $this->nextLink = $nextLink; } public function getNextLink() { return $this->nextLink; } public function setNextPageToken($nextPageToken) { $this->nextPageToken = $nextPageToken; } public function getNextPageToken() { return $this->nextPageToken; } public function setSelfLink($selfLink) { $this->selfLink = $selfLink; } public function getSelfLink() { return $this->selfLink; } } class Google_Service_Drive_CommentReply extends Google_Model { protected $internal_gapi_mappings = array( ); protected $authorType = 'Google_Service_Drive_User'; protected $authorDataType = ''; public $content; public $createdDate; public $deleted; public $htmlContent; public $kind; public $modifiedDate; public $replyId; public $verb; public function setAuthor(Google_Service_Drive_User $author) { $this->author = $author; } public function getAuthor() { return $this->author; } public function setContent($content) { $this->content = $content; } public function getContent() { return $this->content; } public function setCreatedDate($createdDate) { $this->createdDate = $createdDate; } public function getCreatedDate() { return $this->createdDate; } public function setDeleted($deleted) { $this->deleted = $deleted; } public function getDeleted() { return $this->deleted; } public function setHtmlContent($htmlContent) { $this->htmlContent = $htmlContent; } public function getHtmlContent() { return $this->htmlContent; } public function setKind($kind) { $this->kind = $kind; } public function getKind() { return $this->kind; } public function setModifiedDate($modifiedDate) { $this->modifiedDate = $modifiedDate; } public function getModifiedDate() { return $this->modifiedDate; } public function setReplyId($replyId) { $this->replyId = $replyId; } public function getReplyId() { return $this->replyId; } public function setVerb($verb) { $this->verb = $verb; } public function getVerb() { return $this->verb; } } class Google_Service_Drive_CommentReplyList extends Google_Collection { protected $collection_key = 'items'; protected $internal_gapi_mappings = array( ); protected $itemsType = 'Google_Service_Drive_CommentReply'; protected $itemsDataType = 'array'; public $kind; public $nextLink; public $nextPageToken; public $selfLink; public function setItems($items) { $this->items = $items; } public function getItems() { return $this->items; } public function setKind($kind) { $this->kind = $kind; } public function getKind() { return $this->kind; } public function setNextLink($nextLink) { $this->nextLink = $nextLink; } public function getNextLink() { return $this->nextLink; } public function setNextPageToken($nextPageToken) { $this->nextPageToken = $nextPageToken; } public function getNextPageToken() { return $this->nextPageToken; } public function setSelfLink($selfLink) { $this->selfLink = $selfLink; } public function getSelfLink() { return $this->selfLink; } } class UDP_Google_Service_Drive_DriveFile extends Google_Collection { protected $collection_key = 'properties'; protected $internal_gapi_mappings = array( ); public $alternateLink; public $appDataContents; public $copyable; public $createdDate; public $defaultOpenWithLink; public $description; public $downloadUrl; public $editable; public $embedLink; public $etag; public $explicitlyTrashed; public $exportLinks; public $fileExtension; public $fileSize; public $folderColorRgb; public $headRevisionId; public $iconLink; public $id; protected $imageMediaMetadataType = 'UDP_Google_Service_Drive_DriveFileImageMediaMetadata'; protected $imageMediaMetadataDataType = ''; protected $indexableTextType = 'UDP_Google_Service_Drive_DriveFileIndexableText'; protected $indexableTextDataType = ''; public $kind; protected $labelsType = 'UDP_Google_Service_Drive_DriveFileLabels'; protected $labelsDataType = ''; protected $lastModifyingUserType = 'Google_Service_Drive_User'; protected $lastModifyingUserDataType = ''; public $lastModifyingUserName; public $lastViewedByMeDate; public $markedViewedByMeDate; public $md5Checksum; public $mimeType; public $modifiedByMeDate; public $modifiedDate; public $openWithLinks; public $originalFilename; public $ownerNames; protected $ownersType = 'Google_Service_Drive_User'; protected $ownersDataType = 'array'; protected $parentsType = 'UDP_Google_Service_Drive_ParentReference'; protected $parentsDataType = 'array'; protected $permissionsType = 'Google_Service_Drive_Permission'; protected $permissionsDataType = 'array'; protected $propertiesType = 'Google_Service_Drive_Property'; protected $propertiesDataType = 'array'; public $quotaBytesUsed; public $selfLink; public $shared; public $sharedWithMeDate; protected $sharingUserType = 'Google_Service_Drive_User'; protected $sharingUserDataType = ''; protected $thumbnailType = 'UDP_Google_Service_Drive_DriveFileThumbnail'; protected $thumbnailDataType = ''; public $thumbnailLink; public $title; protected $userPermissionType = 'Google_Service_Drive_Permission'; protected $userPermissionDataType = ''; public $version; protected $videoMediaMetadataType = 'UDP_Google_Service_Drive_DriveFileVideoMediaMetadata'; /** * Parent resource * * @var Google_Service_Drive_Parents_Resource */ public $parents; protected $videoMediaMetadataDataType = ''; public $webContentLink; public $webViewLink; public $writersCanShare; public function setAlternateLink($alternateLink) { $this->alternateLink = $alternateLink; } public function getAlternateLink() { return $this->alternateLink; } public function setAppDataContents($appDataContents) { $this->appDataContents = $appDataContents; } public function getAppDataContents() { return $this->appDataContents; } public function setCopyable($copyable) { $this->copyable = $copyable; } public function getCopyable() { return $this->copyable; } public function setCreatedDate($createdDate) { $this->createdDate = $createdDate; } public function getCreatedDate() { return $this->createdDate; } public function setDefaultOpenWithLink($defaultOpenWithLink) { $this->defaultOpenWithLink = $defaultOpenWithLink; } public function getDefaultOpenWithLink() { return $this->defaultOpenWithLink; } public function setDescription($description) { $this->description = $description; } public function getDescription() { return $this->description; } public function setDownloadUrl($downloadUrl) { $this->downloadUrl = $downloadUrl; } public function getDownloadUrl() { return $this->downloadUrl; } public function setEditable($editable) { $this->editable = $editable; } public function getEditable() { return $this->editable; } public function setEmbedLink($embedLink) { $this->embedLink = $embedLink; } public function getEmbedLink() { return $this->embedLink; } public function setEtag($etag) { $this->etag = $etag; } public function getEtag() { return $this->etag; } public function setExplicitlyTrashed($explicitlyTrashed) { $this->explicitlyTrashed = $explicitlyTrashed; } public function getExplicitlyTrashed() { return $this->explicitlyTrashed; } public function setExportLinks($exportLinks) { $this->exportLinks = $exportLinks; } public function getExportLinks() { return $this->exportLinks; } public function setFileExtension($fileExtension) { $this->fileExtension = $fileExtension; } public function getFileExtension() { return $this->fileExtension; } public function setFileSize($fileSize) { $this->fileSize = $fileSize; } public function getFileSize() { return $this->fileSize; } public function setFolderColorRgb($folderColorRgb) { $this->folderColorRgb = $folderColorRgb; } public function getFolderColorRgb() { return $this->folderColorRgb; } public function setHeadRevisionId($headRevisionId) { $this->headRevisionId = $headRevisionId; } public function getHeadRevisionId() { return $this->headRevisionId; } public function setIconLink($iconLink) { $this->iconLink = $iconLink; } public function getIconLink() { return $this->iconLink; } public function setId($id) { $this->id = $id; } public function getId() { return $this->id; } public function setImageMediaMetadata(UDP_Google_Service_Drive_DriveFileImageMediaMetadata $imageMediaMetadata) { $this->imageMediaMetadata = $imageMediaMetadata; } public function getImageMediaMetadata() { return $this->imageMediaMetadata; } public function setIndexableText(UDP_Google_Service_Drive_DriveFileIndexableText $indexableText) { $this->indexableText = $indexableText; } public function getIndexableText() { return $this->indexableText; } public function setKind($kind) { $this->kind = $kind; } public function getKind() { return $this->kind; } public function setLabels(UDP_Google_Service_Drive_DriveFileLabels $labels) { $this->labels = $labels; } public function getLabels() { return $this->labels; } public function setLastModifyingUser(Google_Service_Drive_User $lastModifyingUser) { $this->lastModifyingUser = $lastModifyingUser; } public function getLastModifyingUser() { return $this->lastModifyingUser; } public function setLastModifyingUserName($lastModifyingUserName) { $this->lastModifyingUserName = $lastModifyingUserName; } public function getLastModifyingUserName() { return $this->lastModifyingUserName; } public function setLastViewedByMeDate($lastViewedByMeDate) { $this->lastViewedByMeDate = $lastViewedByMeDate; } public function getLastViewedByMeDate() { return $this->lastViewedByMeDate; } public function setMarkedViewedByMeDate($markedViewedByMeDate) { $this->markedViewedByMeDate = $markedViewedByMeDate; } public function getMarkedViewedByMeDate() { return $this->markedViewedByMeDate; } public function setMd5Checksum($md5Checksum) { $this->md5Checksum = $md5Checksum; } public function getMd5Checksum() { return $this->md5Checksum; } public function setMimeType($mimeType) { $this->mimeType = $mimeType; } public function getMimeType() { return $this->mimeType; } public function setModifiedByMeDate($modifiedByMeDate) { $this->modifiedByMeDate = $modifiedByMeDate; } public function getModifiedByMeDate() { return $this->modifiedByMeDate; } public function setModifiedDate($modifiedDate) { $this->modifiedDate = $modifiedDate; } public function getModifiedDate() { return $this->modifiedDate; } public function setOpenWithLinks($openWithLinks) { $this->openWithLinks = $openWithLinks; } public function getOpenWithLinks() { return $this->openWithLinks; } public function setOriginalFilename($originalFilename) { $this->originalFilename = $originalFilename; } public function getOriginalFilename() { return $this->originalFilename; } public function setOwnerNames($ownerNames) { $this->ownerNames = $ownerNames; } public function getOwnerNames() { return $this->ownerNames; } public function setOwners($owners) { $this->owners = $owners; } public function getOwners() { return $this->owners; } public function setParents($parents) { $this->parents = $parents; } public function getParents() { return $this->parents; } public function setPermissions($permissions) { $this->permissions = $permissions; } public function getPermissions() { return $this->permissions; } public function setProperties($properties) { $this->properties = $properties; } public function getProperties() { return $this->properties; } public function setQuotaBytesUsed($quotaBytesUsed) { $this->quotaBytesUsed = $quotaBytesUsed; } public function getQuotaBytesUsed() { return $this->quotaBytesUsed; } public function setSelfLink($selfLink) { $this->selfLink = $selfLink; } public function getSelfLink() { return $this->selfLink; } public function setShared($shared) { $this->shared = $shared; } public function getShared() { return $this->shared; } public function setSharedWithMeDate($sharedWithMeDate) { $this->sharedWithMeDate = $sharedWithMeDate; } public function getSharedWithMeDate() { return $this->sharedWithMeDate; } public function setSharingUser(Google_Service_Drive_User $sharingUser) { $this->sharingUser = $sharingUser; } public function getSharingUser() { return $this->sharingUser; } public function setThumbnail(UDP_Google_Service_Drive_DriveFileThumbnail $thumbnail) { $this->thumbnail = $thumbnail; } public function getThumbnail() { return $this->thumbnail; } public function setThumbnailLink($thumbnailLink) { $this->thumbnailLink = $thumbnailLink; } public function getThumbnailLink() { return $this->thumbnailLink; } public function setTitle($title) { $this->title = $title; } public function getTitle() { return $this->title; } public function setUserPermission(Google_Service_Drive_Permission $userPermission) { $this->userPermission = $userPermission; } public function getUserPermission() { return $this->userPermission; } public function setVersion($version) { $this->version = $version; } public function getVersion() { return $this->version; } public function setVideoMediaMetadata(UDP_Google_Service_Drive_DriveFileVideoMediaMetadata $videoMediaMetadata) { $this->videoMediaMetadata = $videoMediaMetadata; } public function getVideoMediaMetadata() { return $this->videoMediaMetadata; } public function setWebContentLink($webContentLink) { $this->webContentLink = $webContentLink; } public function getWebContentLink() { return $this->webContentLink; } public function setWebViewLink($webViewLink) { $this->webViewLink = $webViewLink; } public function getWebViewLink() { return $this->webViewLink; } public function setWritersCanShare($writersCanShare) { $this->writersCanShare = $writersCanShare; } public function getWritersCanShare() { return $this->writersCanShare; } } class UDP_Google_Service_Drive_DriveFileExportLinks extends Google_Model { } class UDP_Google_Service_Drive_DriveFileImageMediaMetadata extends Google_Model { protected $internal_gapi_mappings = array( ); public $aperture; public $cameraMake; public $cameraModel; public $colorSpace; public $date; public $exposureBias; public $exposureMode; public $exposureTime; public $flashUsed; public $focalLength; public $height; public $isoSpeed; public $lens; protected $locationType = 'UDP_Google_Service_Drive_DriveFileImageMediaMetadataLocation'; protected $locationDataType = ''; public $maxApertureValue; public $meteringMode; public $rotation; public $sensor; public $subjectDistance; public $whiteBalance; public $width; public function setAperture($aperture) { $this->aperture = $aperture; } public function getAperture() { return $this->aperture; } public function setCameraMake($cameraMake) { $this->cameraMake = $cameraMake; } public function getCameraMake() { return $this->cameraMake; } public function setCameraModel($cameraModel) { $this->cameraModel = $cameraModel; } public function getCameraModel() { return $this->cameraModel; } public function setColorSpace($colorSpace) { $this->colorSpace = $colorSpace; } public function getColorSpace() { return $this->colorSpace; } public function setDate($date) { $this->date = $date; } public function getDate() { return $this->date; } public function setExposureBias($exposureBias) { $this->exposureBias = $exposureBias; } public function getExposureBias() { return $this->exposureBias; } public function setExposureMode($exposureMode) { $this->exposureMode = $exposureMode; } public function getExposureMode() { return $this->exposureMode; } public function setExposureTime($exposureTime) { $this->exposureTime = $exposureTime; } public function getExposureTime() { return $this->exposureTime; } public function setFlashUsed($flashUsed) { $this->flashUsed = $flashUsed; } public function getFlashUsed() { return $this->flashUsed; } public function setFocalLength($focalLength) { $this->focalLength = $focalLength; } public function getFocalLength() { return $this->focalLength; } public function setHeight($height) { $this->height = $height; } public function getHeight() { return $this->height; } public function setIsoSpeed($isoSpeed) { $this->isoSpeed = $isoSpeed; } public function getIsoSpeed() { return $this->isoSpeed; } public function setLens($lens) { $this->lens = $lens; } public function getLens() { return $this->lens; } public function setLocation(UDP_Google_Service_Drive_DriveFileImageMediaMetadataLocation $location) { $this->location = $location; } public function getLocation() { return $this->location; } public function setMaxApertureValue($maxApertureValue) { $this->maxApertureValue = $maxApertureValue; } public function getMaxApertureValue() { return $this->maxApertureValue; } public function setMeteringMode($meteringMode) { $this->meteringMode = $meteringMode; } public function getMeteringMode() { return $this->meteringMode; } public function setRotation($rotation) { $this->rotation = $rotation; } public function getRotation() { return $this->rotation; } public function setSensor($sensor) { $this->sensor = $sensor; } public function getSensor() { return $this->sensor; } public function setSubjectDistance($subjectDistance) { $this->subjectDistance = $subjectDistance; } public function getSubjectDistance() { return $this->subjectDistance; } public function setWhiteBalance($whiteBalance) { $this->whiteBalance = $whiteBalance; } public function getWhiteBalance() { return $this->whiteBalance; } public function setWidth($width) { $this->width = $width; } public function getWidth() { return $this->width; } } class UDP_Google_Service_Drive_DriveFileImageMediaMetadataLocation extends Google_Model { protected $internal_gapi_mappings = array( ); public $altitude; public $latitude; public $longitude; public function setAltitude($altitude) { $this->altitude = $altitude; } public function getAltitude() { return $this->altitude; } public function setLatitude($latitude) { $this->latitude = $latitude; } public function getLatitude() { return $this->latitude; } public function setLongitude($longitude) { $this->longitude = $longitude; } public function getLongitude() { return $this->longitude; } } class UDP_Google_Service_Drive_DriveFileIndexableText extends Google_Model { protected $internal_gapi_mappings = array( ); public $text; public function setText($text) { $this->text = $text; } public function getText() { return $this->text; } } class UDP_Google_Service_Drive_DriveFileLabels extends Google_Model { protected $internal_gapi_mappings = array( ); public $hidden; public $restricted; public $starred; public $trashed; public $viewed; public function setHidden($hidden) { $this->hidden = $hidden; } public function getHidden() { return $this->hidden; } public function setRestricted($restricted) { $this->restricted = $restricted; } public function getRestricted() { return $this->restricted; } public function setStarred($starred) { $this->starred = $starred; } public function getStarred() { return $this->starred; } public function setTrashed($trashed) { $this->trashed = $trashed; } public function getTrashed() { return $this->trashed; } public function setViewed($viewed) { $this->viewed = $viewed; } public function getViewed() { return $this->viewed; } } class UDP_Google_Service_Drive_DriveFileOpenWithLinks extends Google_Model { } class UDP_Google_Service_Drive_DriveFileThumbnail extends Google_Model { protected $internal_gapi_mappings = array( ); public $image; public $mimeType; public function setImage($image) { $this->image = $image; } public function getImage() { return $this->image; } public function setMimeType($mimeType) { $this->mimeType = $mimeType; } public function getMimeType() { return $this->mimeType; } } class UDP_Google_Service_Drive_DriveFileVideoMediaMetadata extends Google_Model { protected $internal_gapi_mappings = array( ); public $durationMillis; public $height; public $width; public function setDurationMillis($durationMillis) { $this->durationMillis = $durationMillis; } public function getDurationMillis() { return $this->durationMillis; } public function setHeight($height) { $this->height = $height; } public function getHeight() { return $this->height; } public function setWidth($width) { $this->width = $width; } public function getWidth() { return $this->width; } } class Google_Service_Drive_FileList extends Google_Collection { protected $collection_key = 'items'; protected $internal_gapi_mappings = array( ); public $etag; protected $itemsType = 'UDP_Google_Service_Drive_DriveFile'; protected $itemsDataType = 'array'; public $kind; public $nextLink; public $nextPageToken; public $selfLink; public function setEtag($etag) { $this->etag = $etag; } public function getEtag() { return $this->etag; } public function setItems($items) { $this->items = $items; } public function getItems() { return $this->items; } public function setKind($kind) { $this->kind = $kind; } public function getKind() { return $this->kind; } public function setNextLink($nextLink) { $this->nextLink = $nextLink; } public function getNextLink() { return $this->nextLink; } public function setNextPageToken($nextPageToken) { $this->nextPageToken = $nextPageToken; } public function getNextPageToken() { return $this->nextPageToken; } public function setSelfLink($selfLink) { $this->selfLink = $selfLink; } public function getSelfLink() { return $this->selfLink; } } class Google_Service_Drive_ParentList extends Google_Collection { protected $collection_key = 'items'; protected $internal_gapi_mappings = array( ); public $etag; protected $itemsType = 'UDP_Google_Service_Drive_ParentReference'; protected $itemsDataType = 'array'; public $kind; public $selfLink; public function setEtag($etag) { $this->etag = $etag; } public function getEtag() { return $this->etag; } public function setItems($items) { $this->items = $items; } public function getItems() { return $this->items; } public function setKind($kind) { $this->kind = $kind; } public function getKind() { return $this->kind; } public function setSelfLink($selfLink) { $this->selfLink = $selfLink; } public function getSelfLink() { return $this->selfLink; } } class UDP_Google_Service_Drive_ParentReference extends Google_Model { protected $internal_gapi_mappings = array( ); public $id; public $isRoot; public $kind; public $parentLink; public $selfLink; public function setId($id) { $this->id = $id; } public function getId() { return $this->id; } public function setIsRoot($isRoot) { $this->isRoot = $isRoot; } public function getIsRoot() { return $this->isRoot; } public function setKind($kind) { $this->kind = $kind; } public function getKind() { return $this->kind; } public function setParentLink($parentLink) { $this->parentLink = $parentLink; } public function getParentLink() { return $this->parentLink; } public function setSelfLink($selfLink) { $this->selfLink = $selfLink; } public function getSelfLink() { return $this->selfLink; } } class Google_Service_Drive_Permission extends Google_Collection { protected $collection_key = 'additionalRoles'; protected $internal_gapi_mappings = array( ); public $additionalRoles; public $authKey; public $domain; public $emailAddress; public $etag; public $id; public $kind; public $name; public $photoLink; public $role; public $selfLink; public $type; public $value; public $withLink; public function setAdditionalRoles($additionalRoles) { $this->additionalRoles = $additionalRoles; } public function getAdditionalRoles() { return $this->additionalRoles; } public function setAuthKey($authKey) { $this->authKey = $authKey; } public function getAuthKey() { return $this->authKey; } public function setDomain($domain) { $this->domain = $domain; } public function getDomain() { return $this->domain; } public function setEmailAddress($emailAddress) { $this->emailAddress = $emailAddress; } public function getEmailAddress() { return $this->emailAddress; } public function setEtag($etag) { $this->etag = $etag; } public function getEtag() { return $this->etag; } public function setId($id) { $this->id = $id; } public function getId() { return $this->id; } public function setKind($kind) { $this->kind = $kind; } public function getKind() { return $this->kind; } public function setName($name) { $this->name = $name; } public function getName() { return $this->name; } public function setPhotoLink($photoLink) { $this->photoLink = $photoLink; } public function getPhotoLink() { return $this->photoLink; } public function setRole($role) { $this->role = $role; } public function getRole() { return $this->role; } public function setSelfLink($selfLink) { $this->selfLink = $selfLink; } public function getSelfLink() { return $this->selfLink; } public function setType($type) { $this->type = $type; } public function getType() { return $this->type; } public function setValue($value) { $this->value = $value; } public function getValue() { return $this->value; } public function setWithLink($withLink) { $this->withLink = $withLink; } public function getWithLink() { return $this->withLink; } } class Google_Service_Drive_PermissionId extends Google_Model { protected $internal_gapi_mappings = array( ); public $id; public $kind; public function setId($id) { $this->id = $id; } public function getId() { return $this->id; } public function setKind($kind) { $this->kind = $kind; } public function getKind() { return $this->kind; } } class Google_Service_Drive_PermissionList extends Google_Collection { protected $collection_key = 'items'; protected $internal_gapi_mappings = array( ); public $etag; protected $itemsType = 'Google_Service_Drive_Permission'; protected $itemsDataType = 'array'; public $kind; public $selfLink; public function setEtag($etag) { $this->etag = $etag; } public function getEtag() { return $this->etag; } public function setItems($items) { $this->items = $items; } public function getItems() { return $this->items; } public function setKind($kind) { $this->kind = $kind; } public function getKind() { return $this->kind; } public function setSelfLink($selfLink) { $this->selfLink = $selfLink; } public function getSelfLink() { return $this->selfLink; } } class Google_Service_Drive_Property extends Google_Model { protected $internal_gapi_mappings = array( ); public $etag; public $key; public $kind; public $selfLink; public $value; public $visibility; public function setEtag($etag) { $this->etag = $etag; } public function getEtag() { return $this->etag; } public function setKey($key) { $this->key = $key; } public function getKey() { return $this->key; } public function setKind($kind) { $this->kind = $kind; } public function getKind() { return $this->kind; } public function setSelfLink($selfLink) { $this->selfLink = $selfLink; } public function getSelfLink() { return $this->selfLink; } public function setValue($value) { $this->value = $value; } public function getValue() { return $this->value; } public function setVisibility($visibility) { $this->visibility = $visibility; } public function getVisibility() { return $this->visibility; } } class Google_Service_Drive_PropertyList extends Google_Collection { protected $collection_key = 'items'; protected $internal_gapi_mappings = array( ); public $etag; protected $itemsType = 'Google_Service_Drive_Property'; protected $itemsDataType = 'array'; public $kind; public $selfLink; public function setEtag($etag) { $this->etag = $etag; } public function getEtag() { return $this->etag; } public function setItems($items) { $this->items = $items; } public function getItems() { return $this->items; } public function setKind($kind) { $this->kind = $kind; } public function getKind() { return $this->kind; } public function setSelfLink($selfLink) { $this->selfLink = $selfLink; } public function getSelfLink() { return $this->selfLink; } } class Google_Service_Drive_Revision extends Google_Model { protected $internal_gapi_mappings = array( ); public $downloadUrl; public $etag; public $exportLinks; public $fileSize; public $id; public $kind; protected $lastModifyingUserType = 'Google_Service_Drive_User'; protected $lastModifyingUserDataType = ''; public $lastModifyingUserName; public $md5Checksum; public $mimeType; public $modifiedDate; public $originalFilename; public $pinned; public $publishAuto; public $published; public $publishedLink; public $publishedOutsideDomain; public $selfLink; public function setDownloadUrl($downloadUrl) { $this->downloadUrl = $downloadUrl; } public function getDownloadUrl() { return $this->downloadUrl; } public function setEtag($etag) { $this->etag = $etag; } public function getEtag() { return $this->etag; } public function setExportLinks($exportLinks) { $this->exportLinks = $exportLinks; } public function getExportLinks() { return $this->exportLinks; } public function setFileSize($fileSize) { $this->fileSize = $fileSize; } public function getFileSize() { return $this->fileSize; } public function setId($id) { $this->id = $id; } public function getId() { return $this->id; } public function setKind($kind) { $this->kind = $kind; } public function getKind() { return $this->kind; } public function setLastModifyingUser(Google_Service_Drive_User $lastModifyingUser) { $this->lastModifyingUser = $lastModifyingUser; } public function getLastModifyingUser() { return $this->lastModifyingUser; } public function setLastModifyingUserName($lastModifyingUserName) { $this->lastModifyingUserName = $lastModifyingUserName; } public function getLastModifyingUserName() { return $this->lastModifyingUserName; } public function setMd5Checksum($md5Checksum) { $this->md5Checksum = $md5Checksum; } public function getMd5Checksum() { return $this->md5Checksum; } public function setMimeType($mimeType) { $this->mimeType = $mimeType; } public function getMimeType() { return $this->mimeType; } public function setModifiedDate($modifiedDate) { $this->modifiedDate = $modifiedDate; } public function getModifiedDate() { return $this->modifiedDate; } public function setOriginalFilename($originalFilename) { $this->originalFilename = $originalFilename; } public function getOriginalFilename() { return $this->originalFilename; } public function setPinned($pinned) { $this->pinned = $pinned; } public function getPinned() { return $this->pinned; } public function setPublishAuto($publishAuto) { $this->publishAuto = $publishAuto; } public function getPublishAuto() { return $this->publishAuto; } public function setPublished($published) { $this->published = $published; } public function getPublished() { return $this->published; } public function setPublishedLink($publishedLink) { $this->publishedLink = $publishedLink; } public function getPublishedLink() { return $this->publishedLink; } public function setPublishedOutsideDomain($publishedOutsideDomain) { $this->publishedOutsideDomain = $publishedOutsideDomain; } public function getPublishedOutsideDomain() { return $this->publishedOutsideDomain; } public function setSelfLink($selfLink) { $this->selfLink = $selfLink; } public function getSelfLink() { return $this->selfLink; } } class Google_Service_Drive_RevisionExportLinks extends Google_Model { } class Google_Service_Drive_RevisionList extends Google_Collection { protected $collection_key = 'items'; protected $internal_gapi_mappings = array( ); public $etag; protected $itemsType = 'Google_Service_Drive_Revision'; protected $itemsDataType = 'array'; public $kind; public $selfLink; public function setEtag($etag) { $this->etag = $etag; } public function getEtag() { return $this->etag; } public function setItems($items) { $this->items = $items; } public function getItems() { return $this->items; } public function setKind($kind) { $this->kind = $kind; } public function getKind() { return $this->kind; } public function setSelfLink($selfLink) { $this->selfLink = $selfLink; } public function getSelfLink() { return $this->selfLink; } } class Google_Service_Drive_User extends Google_Model { protected $internal_gapi_mappings = array( ); public $displayName; public $emailAddress; public $isAuthenticatedUser; public $kind; public $permissionId; protected $pictureType = 'Google_Service_Drive_UserPicture'; protected $pictureDataType = ''; public function setDisplayName($displayName) { $this->displayName = $displayName; } public function getDisplayName() { return $this->displayName; } public function setEmailAddress($emailAddress) { $this->emailAddress = $emailAddress; } public function getEmailAddress() { return $this->emailAddress; } public function setIsAuthenticatedUser($isAuthenticatedUser) { $this->isAuthenticatedUser = $isAuthenticatedUser; } public function getIsAuthenticatedUser() { return $this->isAuthenticatedUser; } public function setKind($kind) { $this->kind = $kind; } public function getKind() { return $this->kind; } public function setPermissionId($permissionId) { $this->permissionId = $permissionId; } public function getPermissionId() { return $this->permissionId; } public function setPicture(Google_Service_Drive_UserPicture $picture) { $this->picture = $picture; } public function getPicture() { return $this->picture; } } class Google_Service_Drive_UserPicture extends Google_Model { protected $internal_gapi_mappings = array( ); public $url; public function setUrl($url) { $this->url = $url; } public function getUrl() { return $this->url; } } includes/Google/Service/Resource.php000064400000020424152214270100013462 0ustar00 array('type' => 'string', 'location' => 'query'), 'fields' => array('type' => 'string', 'location' => 'query'), 'trace' => array('type' => 'string', 'location' => 'query'), 'userIp' => array('type' => 'string', 'location' => 'query'), 'quotaUser' => array('type' => 'string', 'location' => 'query'), 'data' => array('type' => 'string', 'location' => 'body'), 'mimeType' => array('type' => 'string', 'location' => 'header'), 'uploadType' => array('type' => 'string', 'location' => 'query'), 'mediaUpload' => array('type' => 'complex', 'location' => 'query'), 'prettyPrint' => array('type' => 'string', 'location' => 'query'), ); /** @var string $rootUrl */ private $rootUrl; /** @var Google_Client $client */ private $client; /** @var string $serviceName */ private $serviceName; /** @var string $servicePath */ private $servicePath; /** @var string $resourceName */ private $resourceName; /** @var array $methods */ private $methods; public function __construct($service, $serviceName, $resourceName, $resource) { $this->rootUrl = $service->rootUrl; $this->client = $service->getClient(); $this->servicePath = $service->servicePath; $this->serviceName = $serviceName; $this->resourceName = $resourceName; $this->methods = is_array($resource) && isset($resource['methods']) ? $resource['methods'] : array($resourceName => $resource); } /** * TODO(ianbarber): This function needs simplifying. * @param $name * @param $arguments * @param $expected_class - optional, the expected class name * @return Google_Http_Request|expected_class * @throws Google_Exception */ public function call($name, $arguments, $expected_class = null) { if (! isset($this->methods[$name])) { $this->client->getLogger()->error( 'Service method unknown', array( 'service' => $this->serviceName, 'resource' => $this->resourceName, 'method' => $name ) ); throw new Google_Exception( "Unknown function: " . "{$this->serviceName}->{$this->resourceName}->{$name}()" ); } $method = $this->methods[$name]; $parameters = $arguments[0]; // postBody is a special case since it's not defined in the discovery // document as parameter, but we abuse the param entry for storing it. $postBody = null; if (isset($parameters['postBody'])) { if ($parameters['postBody'] instanceof Google_Model) { // In the cases the post body is an existing object, we want // to use the smart method to create a simple object for // for JSONification. $parameters['postBody'] = $parameters['postBody']->toSimpleObject(); } else if (is_object($parameters['postBody'])) { // If the post body is another kind of object, we will try and // wrangle it into a sensible format. $parameters['postBody'] = $this->convertToArrayAndStripNulls($parameters['postBody']); } $postBody = json_encode($parameters['postBody']); unset($parameters['postBody']); } // TODO(ianbarber): optParams here probably should have been // handled already - this may well be redundant code. if (isset($parameters['optParams'])) { $optParams = $parameters['optParams']; unset($parameters['optParams']); $parameters = array_merge($parameters, $optParams); } if (!isset($method['parameters'])) { $method['parameters'] = array(); } $method['parameters'] = array_merge( $method['parameters'], $this->stackParameters ); foreach ($parameters as $key => $val) { if ($key != 'postBody' && ! isset($method['parameters'][$key])) { $this->client->getLogger()->error( 'Service parameter unknown', array( 'service' => $this->serviceName, 'resource' => $this->resourceName, 'method' => $name, 'parameter' => $key ) ); throw new Google_Exception("($name) unknown parameter: '$key'"); } } foreach ($method['parameters'] as $paramName => $paramSpec) { if (isset($paramSpec['required']) && $paramSpec['required'] && ! isset($parameters[$paramName]) ) { $this->client->getLogger()->error( 'Service parameter missing', array( 'service' => $this->serviceName, 'resource' => $this->resourceName, 'method' => $name, 'parameter' => $paramName ) ); throw new Google_Exception("($name) missing required param: '$paramName'"); } if (isset($parameters[$paramName])) { $value = $parameters[$paramName]; $parameters[$paramName] = $paramSpec; $parameters[$paramName]['value'] = $value; unset($parameters[$paramName]['required']); } else { // Ensure we don't pass nulls. unset($parameters[$paramName]); } } $this->client->getLogger()->info( 'Service Call', array( 'service' => $this->serviceName, 'resource' => $this->resourceName, 'method' => $name, 'arguments' => $parameters, ) ); $url = UDP_Google_Http_REST::createRequestUri( $this->servicePath, $method['path'], $parameters ); $httpRequest = new UDP_Google_Http_Request( $url, $method['httpMethod'], null, $postBody ); if ($this->rootUrl) { $httpRequest->setBaseComponent($this->rootUrl); } else { $httpRequest->setBaseComponent($this->client->getBasePath()); } if ($postBody) { $contentTypeHeader = array(); $contentTypeHeader['content-type'] = 'application/json; charset=UTF-8'; $httpRequest->setRequestHeaders($contentTypeHeader); $httpRequest->setPostBody($postBody); } $httpRequest = $this->client->getAuth()->sign($httpRequest); $httpRequest->setExpectedClass($expected_class); if (isset($parameters['data']) && ($parameters['uploadType']['value'] == 'media' || $parameters['uploadType']['value'] == 'multipart')) { // If we are doing a simple media upload, trigger that as a convenience. $mfu = new Google_Http_MediaFileUpload( $this->client, $httpRequest, isset($parameters['mimeType']) ? $parameters['mimeType']['value'] : 'application/octet-stream', $parameters['data']['value'] ); } if (isset($parameters['alt']) && $parameters['alt']['value'] == 'media') { $httpRequest->enableExpectedRaw(); } if ($this->client->shouldDefer()) { // If we are in batch or upload mode, return the raw request. return $httpRequest; } return $this->client->execute($httpRequest); } protected function convertToArrayAndStripNulls($o) { $o = (array) $o; foreach ($o as $k => $v) { if ($v === null) { unset($o[$k]); } elseif (is_object($v) || is_array($v)) { $o[$k] = $this->convertToArrayAndStripNulls($o[$k]); } } return $o; } } includes/Google/Service/Cloudsearch.php000064400000002550152214270100014127 0ustar00 * The Google Cloud Search API defines an application interface to index * documents that contain structured data and to search those indexes. It * supports full text search.

* *

* For more information about this service, see the API * Documentation *

* * @author Google, Inc. */ class Google_Service_Cloudsearch extends UDP_Google_Service { /** * Constructs the internal representation of the Cloudsearch service. * * @param Google_Client $client */ public function __construct(UDP_Google_Client $client) { parent::__construct($client); $this->servicePath = ''; $this->version = 'v1'; $this->serviceName = 'cloudsearch'; } } includes/Google/Service/Manager.php000064400000131175152214270100013253 0ustar00 * The Deployment Manager API allows users to declaratively configure, deploy * and run complex solutions on the Google Cloud Platform.

* *

* For more information about this service, see the API * Documentation *

* * @author Google, Inc. */ class Google_Service_Manager extends UDP_Google_Service { /** View and manage your applications deployed on Google App Engine. */ const APPENGINE_ADMIN = "https://www.googleapis.com/auth/appengine.admin"; /** View and manage your data across Google Cloud Platform services. */ const CLOUD_PLATFORM = "https://www.googleapis.com/auth/cloud-platform"; /** View and manage your Google Compute Engine resources. */ const COMPUTE = "https://www.googleapis.com/auth/compute"; /** Manage your data in Google Cloud Storage. */ const DEVSTORAGE_READ_WRITE = "https://www.googleapis.com/auth/devstorage.read_write"; /** View and manage your Google Cloud Platform management resources and deployment status information. */ const NDEV_CLOUDMAN = "https://www.googleapis.com/auth/ndev.cloudman"; /** View your Google Cloud Platform management resources and deployment status information. */ const NDEV_CLOUDMAN_READONLY = "https://www.googleapis.com/auth/ndev.cloudman.readonly"; public $deployments; public $templates; /** * Constructs the internal representation of the Manager service. * * @param Google_Client $client */ public function __construct(UDP_Google_Client $client) { parent::__construct($client); $this->servicePath = 'manager/v1beta2/projects/'; $this->version = 'v1beta2'; $this->serviceName = 'manager'; $this->deployments = new Google_Service_Manager_Deployments_Resource( $this, $this->serviceName, 'deployments', array( 'methods' => array( 'delete' => array( 'path' => '{projectId}/regions/{region}/deployments/{deploymentName}', 'httpMethod' => 'DELETE', 'parameters' => array( 'projectId' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'region' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'deploymentName' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), ), ),'get' => array( 'path' => '{projectId}/regions/{region}/deployments/{deploymentName}', 'httpMethod' => 'GET', 'parameters' => array( 'projectId' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'region' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'deploymentName' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), ), ),'insert' => array( 'path' => '{projectId}/regions/{region}/deployments', 'httpMethod' => 'POST', 'parameters' => array( 'projectId' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'region' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), ), ),'list' => array( 'path' => '{projectId}/regions/{region}/deployments', 'httpMethod' => 'GET', 'parameters' => array( 'projectId' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'region' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'pageToken' => array( 'location' => 'query', 'type' => 'string', ), 'maxResults' => array( 'location' => 'query', 'type' => 'integer', ), ), ), ) ) ); $this->templates = new Google_Service_Manager_Templates_Resource( $this, $this->serviceName, 'templates', array( 'methods' => array( 'delete' => array( 'path' => '{projectId}/templates/{templateName}', 'httpMethod' => 'DELETE', 'parameters' => array( 'projectId' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'templateName' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), ), ),'get' => array( 'path' => '{projectId}/templates/{templateName}', 'httpMethod' => 'GET', 'parameters' => array( 'projectId' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'templateName' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), ), ),'insert' => array( 'path' => '{projectId}/templates', 'httpMethod' => 'POST', 'parameters' => array( 'projectId' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), ), ),'list' => array( 'path' => '{projectId}/templates', 'httpMethod' => 'GET', 'parameters' => array( 'projectId' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'pageToken' => array( 'location' => 'query', 'type' => 'string', ), 'maxResults' => array( 'location' => 'query', 'type' => 'integer', ), ), ), ) ) ); } } /** * The "deployments" collection of methods. * Typical usage is: * * $managerService = new Google_Service_Manager(...); * $deployments = $managerService->deployments; * */ class Google_Service_Manager_Deployments_Resource extends UDP_Google_Service_Resource { /** * (deployments.delete) * * @param string $projectId * @param string $region * @param string $deploymentName * @param array $optParams Optional parameters. */ public function delete($projectId, $region, $deploymentName, $optParams = array()) { $params = array('projectId' => $projectId, 'region' => $region, 'deploymentName' => $deploymentName); $params = array_merge($params, $optParams); return $this->call('delete', array($params)); } /** * (deployments.get) * * @param string $projectId * @param string $region * @param string $deploymentName * @param array $optParams Optional parameters. * @return Google_Service_Manager_Deployment */ public function get($projectId, $region, $deploymentName, $optParams = array()) { $params = array('projectId' => $projectId, 'region' => $region, 'deploymentName' => $deploymentName); $params = array_merge($params, $optParams); return $this->call('get', array($params), "Google_Service_Manager_Deployment"); } /** * (deployments.insert) * * @param string $projectId * @param string $region * @param Google_Deployment $postBody * @param array $optParams Optional parameters. * @return Google_Service_Manager_Deployment */ public function insert($projectId, $region, Google_Service_Manager_Deployment $postBody, $optParams = array()) { $params = array('projectId' => $projectId, 'region' => $region, 'postBody' => $postBody); $params = array_merge($params, $optParams); return $this->call('insert', array($params), "Google_Service_Manager_Deployment"); } /** * (deployments.listDeployments) * * @param string $projectId * @param string $region * @param array $optParams Optional parameters. * * @opt_param string pageToken Specifies a nextPageToken returned by a previous * list request. This token can be used to request the next page of results from * a previous list request. * @opt_param int maxResults Maximum count of results to be returned. Acceptable * values are 0 to 100, inclusive. (Default: 50) * @return Google_Service_Manager_DeploymentsListResponse */ public function listDeployments($projectId, $region, $optParams = array()) { $params = array('projectId' => $projectId, 'region' => $region); $params = array_merge($params, $optParams); return $this->call('list', array($params), "Google_Service_Manager_DeploymentsListResponse"); } } /** * The "templates" collection of methods. * Typical usage is: * * $managerService = new Google_Service_Manager(...); * $templates = $managerService->templates; * */ class Google_Service_Manager_Templates_Resource extends UDP_Google_Service_Resource { /** * (templates.delete) * * @param string $projectId * @param string $templateName * @param array $optParams Optional parameters. */ public function delete($projectId, $templateName, $optParams = array()) { $params = array('projectId' => $projectId, 'templateName' => $templateName); $params = array_merge($params, $optParams); return $this->call('delete', array($params)); } /** * (templates.get) * * @param string $projectId * @param string $templateName * @param array $optParams Optional parameters. * @return Google_Service_Manager_Template */ public function get($projectId, $templateName, $optParams = array()) { $params = array('projectId' => $projectId, 'templateName' => $templateName); $params = array_merge($params, $optParams); return $this->call('get', array($params), "Google_Service_Manager_Template"); } /** * (templates.insert) * * @param string $projectId * @param Google_Template $postBody * @param array $optParams Optional parameters. * @return Google_Service_Manager_Template */ public function insert($projectId, Google_Service_Manager_Template $postBody, $optParams = array()) { $params = array('projectId' => $projectId, 'postBody' => $postBody); $params = array_merge($params, $optParams); return $this->call('insert', array($params), "Google_Service_Manager_Template"); } /** * (templates.listTemplates) * * @param string $projectId * @param array $optParams Optional parameters. * * @opt_param string pageToken Specifies a nextPageToken returned by a previous * list request. This token can be used to request the next page of results from * a previous list request. * @opt_param int maxResults Maximum count of results to be returned. Acceptable * values are 0 to 100, inclusive. (Default: 50) * @return Google_Service_Manager_TemplatesListResponse */ public function listTemplates($projectId, $optParams = array()) { $params = array('projectId' => $projectId); $params = array_merge($params, $optParams); return $this->call('list', array($params), "Google_Service_Manager_TemplatesListResponse"); } } class Google_Service_Manager_AccessConfig extends Google_Model { protected $internal_gapi_mappings = array( ); public $name; public $natIp; public $type; public function setName($name) { $this->name = $name; } public function getName() { return $this->name; } public function setNatIp($natIp) { $this->natIp = $natIp; } public function getNatIp() { return $this->natIp; } public function setType($type) { $this->type = $type; } public function getType() { return $this->type; } } class Google_Service_Manager_Action extends Google_Collection { protected $collection_key = 'commands'; protected $internal_gapi_mappings = array( ); public $commands; public $timeoutMs; public function setCommands($commands) { $this->commands = $commands; } public function getCommands() { return $this->commands; } public function setTimeoutMs($timeoutMs) { $this->timeoutMs = $timeoutMs; } public function getTimeoutMs() { return $this->timeoutMs; } } class Google_Service_Manager_AllowedRule extends Google_Collection { protected $collection_key = 'ports'; protected $internal_gapi_mappings = array( "iPProtocol" => "IPProtocol", ); public $iPProtocol; public $ports; public function setIPProtocol($iPProtocol) { $this->iPProtocol = $iPProtocol; } public function getIPProtocol() { return $this->iPProtocol; } public function setPorts($ports) { $this->ports = $ports; } public function getPorts() { return $this->ports; } } class Google_Service_Manager_AutoscalingModule extends Google_Model { protected $internal_gapi_mappings = array( ); public $coolDownPeriodSec; public $description; public $maxNumReplicas; public $minNumReplicas; public $signalType; public $targetModule; public $targetUtilization; public function setCoolDownPeriodSec($coolDownPeriodSec) { $this->coolDownPeriodSec = $coolDownPeriodSec; } public function getCoolDownPeriodSec() { return $this->coolDownPeriodSec; } public function setDescription($description) { $this->description = $description; } public function getDescription() { return $this->description; } public function setMaxNumReplicas($maxNumReplicas) { $this->maxNumReplicas = $maxNumReplicas; } public function getMaxNumReplicas() { return $this->maxNumReplicas; } public function setMinNumReplicas($minNumReplicas) { $this->minNumReplicas = $minNumReplicas; } public function getMinNumReplicas() { return $this->minNumReplicas; } public function setSignalType($signalType) { $this->signalType = $signalType; } public function getSignalType() { return $this->signalType; } public function setTargetModule($targetModule) { $this->targetModule = $targetModule; } public function getTargetModule() { return $this->targetModule; } public function setTargetUtilization($targetUtilization) { $this->targetUtilization = $targetUtilization; } public function getTargetUtilization() { return $this->targetUtilization; } } class Google_Service_Manager_AutoscalingModuleStatus extends Google_Model { protected $internal_gapi_mappings = array( ); public $autoscalingConfigUrl; public function setAutoscalingConfigUrl($autoscalingConfigUrl) { $this->autoscalingConfigUrl = $autoscalingConfigUrl; } public function getAutoscalingConfigUrl() { return $this->autoscalingConfigUrl; } } class Google_Service_Manager_DeployState extends Google_Model { protected $internal_gapi_mappings = array( ); public $details; public $status; public function setDetails($details) { $this->details = $details; } public function getDetails() { return $this->details; } public function setStatus($status) { $this->status = $status; } public function getStatus() { return $this->status; } } class Google_Service_Manager_Deployment extends Google_Collection { protected $collection_key = 'overrides'; protected $internal_gapi_mappings = array( ); public $creationDate; public $description; protected $modulesType = 'Google_Service_Manager_ModuleStatus'; protected $modulesDataType = 'map'; public $name; protected $overridesType = 'Google_Service_Manager_ParamOverride'; protected $overridesDataType = 'array'; protected $stateType = 'Google_Service_Manager_DeployState'; protected $stateDataType = ''; public $templateName; public function setCreationDate($creationDate) { $this->creationDate = $creationDate; } public function getCreationDate() { return $this->creationDate; } public function setDescription($description) { $this->description = $description; } public function getDescription() { return $this->description; } public function setModules($modules) { $this->modules = $modules; } public function getModules() { return $this->modules; } public function setName($name) { $this->name = $name; } public function getName() { return $this->name; } public function setOverrides($overrides) { $this->overrides = $overrides; } public function getOverrides() { return $this->overrides; } public function setState(Google_Service_Manager_DeployState $state) { $this->state = $state; } public function getState() { return $this->state; } public function setTemplateName($templateName) { $this->templateName = $templateName; } public function getTemplateName() { return $this->templateName; } } class Google_Service_Manager_DeploymentModules extends Google_Model { } class Google_Service_Manager_DeploymentsListResponse extends Google_Collection { protected $collection_key = 'resources'; protected $internal_gapi_mappings = array( ); public $nextPageToken; protected $resourcesType = 'Google_Service_Manager_Deployment'; protected $resourcesDataType = 'array'; public function setNextPageToken($nextPageToken) { $this->nextPageToken = $nextPageToken; } public function getNextPageToken() { return $this->nextPageToken; } public function setResources($resources) { $this->resources = $resources; } public function getResources() { return $this->resources; } } class Google_Service_Manager_DiskAttachment extends Google_Model { protected $internal_gapi_mappings = array( ); public $deviceName; public $index; public function setDeviceName($deviceName) { $this->deviceName = $deviceName; } public function getDeviceName() { return $this->deviceName; } public function setIndex($index) { $this->index = $index; } public function getIndex() { return $this->index; } } class Google_Service_Manager_EnvVariable extends Google_Model { protected $internal_gapi_mappings = array( ); public $hidden; public $value; public function setHidden($hidden) { $this->hidden = $hidden; } public function getHidden() { return $this->hidden; } public function setValue($value) { $this->value = $value; } public function getValue() { return $this->value; } } class Google_Service_Manager_ExistingDisk extends Google_Model { protected $internal_gapi_mappings = array( ); protected $attachmentType = 'Google_Service_Manager_DiskAttachment'; protected $attachmentDataType = ''; public $source; public function setAttachment(Google_Service_Manager_DiskAttachment $attachment) { $this->attachment = $attachment; } public function getAttachment() { return $this->attachment; } public function setSource($source) { $this->source = $source; } public function getSource() { return $this->source; } } class Google_Service_Manager_FirewallModule extends Google_Collection { protected $collection_key = 'targetTags'; protected $internal_gapi_mappings = array( ); protected $allowedType = 'Google_Service_Manager_AllowedRule'; protected $allowedDataType = 'array'; public $description; public $network; public $sourceRanges; public $sourceTags; public $targetTags; public function setAllowed($allowed) { $this->allowed = $allowed; } public function getAllowed() { return $this->allowed; } public function setDescription($description) { $this->description = $description; } public function getDescription() { return $this->description; } public function setNetwork($network) { $this->network = $network; } public function getNetwork() { return $this->network; } public function setSourceRanges($sourceRanges) { $this->sourceRanges = $sourceRanges; } public function getSourceRanges() { return $this->sourceRanges; } public function setSourceTags($sourceTags) { $this->sourceTags = $sourceTags; } public function getSourceTags() { return $this->sourceTags; } public function setTargetTags($targetTags) { $this->targetTags = $targetTags; } public function getTargetTags() { return $this->targetTags; } } class Google_Service_Manager_FirewallModuleStatus extends Google_Model { protected $internal_gapi_mappings = array( ); public $firewallUrl; public function setFirewallUrl($firewallUrl) { $this->firewallUrl = $firewallUrl; } public function getFirewallUrl() { return $this->firewallUrl; } } class Google_Service_Manager_HealthCheckModule extends Google_Model { protected $internal_gapi_mappings = array( ); public $checkIntervalSec; public $description; public $healthyThreshold; public $host; public $path; public $port; public $timeoutSec; public $unhealthyThreshold; public function setCheckIntervalSec($checkIntervalSec) { $this->checkIntervalSec = $checkIntervalSec; } public function getCheckIntervalSec() { return $this->checkIntervalSec; } public function setDescription($description) { $this->description = $description; } public function getDescription() { return $this->description; } public function setHealthyThreshold($healthyThreshold) { $this->healthyThreshold = $healthyThreshold; } public function getHealthyThreshold() { return $this->healthyThreshold; } public function setHost($host) { $this->host = $host; } public function getHost() { return $this->host; } public function setPath($path) { $this->path = $path; } public function getPath() { return $this->path; } public function setPort($port) { $this->port = $port; } public function getPort() { return $this->port; } public function setTimeoutSec($timeoutSec) { $this->timeoutSec = $timeoutSec; } public function getTimeoutSec() { return $this->timeoutSec; } public function setUnhealthyThreshold($unhealthyThreshold) { $this->unhealthyThreshold = $unhealthyThreshold; } public function getUnhealthyThreshold() { return $this->unhealthyThreshold; } } class Google_Service_Manager_HealthCheckModuleStatus extends Google_Model { protected $internal_gapi_mappings = array( ); public $healthCheckUrl; public function setHealthCheckUrl($healthCheckUrl) { $this->healthCheckUrl = $healthCheckUrl; } public function getHealthCheckUrl() { return $this->healthCheckUrl; } } class Google_Service_Manager_LbModule extends Google_Collection { protected $collection_key = 'targetModules'; protected $internal_gapi_mappings = array( ); public $description; public $healthChecks; public $ipAddress; public $ipProtocol; public $portRange; public $sessionAffinity; public $targetModules; public function setDescription($description) { $this->description = $description; } public function getDescription() { return $this->description; } public function setHealthChecks($healthChecks) { $this->healthChecks = $healthChecks; } public function getHealthChecks() { return $this->healthChecks; } public function setIpAddress($ipAddress) { $this->ipAddress = $ipAddress; } public function getIpAddress() { return $this->ipAddress; } public function setIpProtocol($ipProtocol) { $this->ipProtocol = $ipProtocol; } public function getIpProtocol() { return $this->ipProtocol; } public function setPortRange($portRange) { $this->portRange = $portRange; } public function getPortRange() { return $this->portRange; } public function setSessionAffinity($sessionAffinity) { $this->sessionAffinity = $sessionAffinity; } public function getSessionAffinity() { return $this->sessionAffinity; } public function setTargetModules($targetModules) { $this->targetModules = $targetModules; } public function getTargetModules() { return $this->targetModules; } } class Google_Service_Manager_LbModuleStatus extends Google_Model { protected $internal_gapi_mappings = array( ); public $forwardingRuleUrl; public $targetPoolUrl; public function setForwardingRuleUrl($forwardingRuleUrl) { $this->forwardingRuleUrl = $forwardingRuleUrl; } public function getForwardingRuleUrl() { return $this->forwardingRuleUrl; } public function setTargetPoolUrl($targetPoolUrl) { $this->targetPoolUrl = $targetPoolUrl; } public function getTargetPoolUrl() { return $this->targetPoolUrl; } } class Google_Service_Manager_Metadata extends Google_Collection { protected $collection_key = 'items'; protected $internal_gapi_mappings = array( ); public $fingerPrint; protected $itemsType = 'Google_Service_Manager_MetadataItem'; protected $itemsDataType = 'array'; public function setFingerPrint($fingerPrint) { $this->fingerPrint = $fingerPrint; } public function getFingerPrint() { return $this->fingerPrint; } public function setItems($items) { $this->items = $items; } public function getItems() { return $this->items; } } class Google_Service_Manager_MetadataItem extends Google_Model { protected $internal_gapi_mappings = array( ); public $key; public $value; public function setKey($key) { $this->key = $key; } public function getKey() { return $this->key; } public function setValue($value) { $this->value = $value; } public function getValue() { return $this->value; } } class Google_Service_Manager_Module extends Google_Model { protected $internal_gapi_mappings = array( ); protected $autoscalingModuleType = 'Google_Service_Manager_AutoscalingModule'; protected $autoscalingModuleDataType = ''; protected $firewallModuleType = 'Google_Service_Manager_FirewallModule'; protected $firewallModuleDataType = ''; protected $healthCheckModuleType = 'Google_Service_Manager_HealthCheckModule'; protected $healthCheckModuleDataType = ''; protected $lbModuleType = 'Google_Service_Manager_LbModule'; protected $lbModuleDataType = ''; protected $networkModuleType = 'Google_Service_Manager_NetworkModule'; protected $networkModuleDataType = ''; protected $replicaPoolModuleType = 'Google_Service_Manager_ReplicaPoolModule'; protected $replicaPoolModuleDataType = ''; public $type; public function setAutoscalingModule(Google_Service_Manager_AutoscalingModule $autoscalingModule) { $this->autoscalingModule = $autoscalingModule; } public function getAutoscalingModule() { return $this->autoscalingModule; } public function setFirewallModule(Google_Service_Manager_FirewallModule $firewallModule) { $this->firewallModule = $firewallModule; } public function getFirewallModule() { return $this->firewallModule; } public function setHealthCheckModule(Google_Service_Manager_HealthCheckModule $healthCheckModule) { $this->healthCheckModule = $healthCheckModule; } public function getHealthCheckModule() { return $this->healthCheckModule; } public function setLbModule(Google_Service_Manager_LbModule $lbModule) { $this->lbModule = $lbModule; } public function getLbModule() { return $this->lbModule; } public function setNetworkModule(Google_Service_Manager_NetworkModule $networkModule) { $this->networkModule = $networkModule; } public function getNetworkModule() { return $this->networkModule; } public function setReplicaPoolModule(Google_Service_Manager_ReplicaPoolModule $replicaPoolModule) { $this->replicaPoolModule = $replicaPoolModule; } public function getReplicaPoolModule() { return $this->replicaPoolModule; } public function setType($type) { $this->type = $type; } public function getType() { return $this->type; } } class Google_Service_Manager_ModuleStatus extends Google_Model { protected $internal_gapi_mappings = array( ); protected $autoscalingModuleStatusType = 'Google_Service_Manager_AutoscalingModuleStatus'; protected $autoscalingModuleStatusDataType = ''; protected $firewallModuleStatusType = 'Google_Service_Manager_FirewallModuleStatus'; protected $firewallModuleStatusDataType = ''; protected $healthCheckModuleStatusType = 'Google_Service_Manager_HealthCheckModuleStatus'; protected $healthCheckModuleStatusDataType = ''; protected $lbModuleStatusType = 'Google_Service_Manager_LbModuleStatus'; protected $lbModuleStatusDataType = ''; protected $networkModuleStatusType = 'Google_Service_Manager_NetworkModuleStatus'; protected $networkModuleStatusDataType = ''; protected $replicaPoolModuleStatusType = 'Google_Service_Manager_ReplicaPoolModuleStatus'; protected $replicaPoolModuleStatusDataType = ''; protected $stateType = 'Google_Service_Manager_DeployState'; protected $stateDataType = ''; public $type; public function setAutoscalingModuleStatus(Google_Service_Manager_AutoscalingModuleStatus $autoscalingModuleStatus) { $this->autoscalingModuleStatus = $autoscalingModuleStatus; } public function getAutoscalingModuleStatus() { return $this->autoscalingModuleStatus; } public function setFirewallModuleStatus(Google_Service_Manager_FirewallModuleStatus $firewallModuleStatus) { $this->firewallModuleStatus = $firewallModuleStatus; } public function getFirewallModuleStatus() { return $this->firewallModuleStatus; } public function setHealthCheckModuleStatus(Google_Service_Manager_HealthCheckModuleStatus $healthCheckModuleStatus) { $this->healthCheckModuleStatus = $healthCheckModuleStatus; } public function getHealthCheckModuleStatus() { return $this->healthCheckModuleStatus; } public function setLbModuleStatus(Google_Service_Manager_LbModuleStatus $lbModuleStatus) { $this->lbModuleStatus = $lbModuleStatus; } public function getLbModuleStatus() { return $this->lbModuleStatus; } public function setNetworkModuleStatus(Google_Service_Manager_NetworkModuleStatus $networkModuleStatus) { $this->networkModuleStatus = $networkModuleStatus; } public function getNetworkModuleStatus() { return $this->networkModuleStatus; } public function setReplicaPoolModuleStatus(Google_Service_Manager_ReplicaPoolModuleStatus $replicaPoolModuleStatus) { $this->replicaPoolModuleStatus = $replicaPoolModuleStatus; } public function getReplicaPoolModuleStatus() { return $this->replicaPoolModuleStatus; } public function setState(Google_Service_Manager_DeployState $state) { $this->state = $state; } public function getState() { return $this->state; } public function setType($type) { $this->type = $type; } public function getType() { return $this->type; } } class Google_Service_Manager_NetworkInterface extends Google_Collection { protected $collection_key = 'accessConfigs'; protected $internal_gapi_mappings = array( ); protected $accessConfigsType = 'Google_Service_Manager_AccessConfig'; protected $accessConfigsDataType = 'array'; public $name; public $network; public $networkIp; public function setAccessConfigs($accessConfigs) { $this->accessConfigs = $accessConfigs; } public function getAccessConfigs() { return $this->accessConfigs; } public function setName($name) { $this->name = $name; } public function getName() { return $this->name; } public function setNetwork($network) { $this->network = $network; } public function getNetwork() { return $this->network; } public function setNetworkIp($networkIp) { $this->networkIp = $networkIp; } public function getNetworkIp() { return $this->networkIp; } } class Google_Service_Manager_NetworkModule extends Google_Model { protected $internal_gapi_mappings = array( "iPv4Range" => "IPv4Range", ); public $iPv4Range; public $description; public $gatewayIPv4; public function setIPv4Range($iPv4Range) { $this->iPv4Range = $iPv4Range; } public function getIPv4Range() { return $this->iPv4Range; } public function setDescription($description) { $this->description = $description; } public function getDescription() { return $this->description; } public function setGatewayIPv4($gatewayIPv4) { $this->gatewayIPv4 = $gatewayIPv4; } public function getGatewayIPv4() { return $this->gatewayIPv4; } } class Google_Service_Manager_NetworkModuleStatus extends Google_Model { protected $internal_gapi_mappings = array( ); public $networkUrl; public function setNetworkUrl($networkUrl) { $this->networkUrl = $networkUrl; } public function getNetworkUrl() { return $this->networkUrl; } } class Google_Service_Manager_NewDisk extends Google_Model { protected $internal_gapi_mappings = array( ); protected $attachmentType = 'Google_Service_Manager_DiskAttachment'; protected $attachmentDataType = ''; public $autoDelete; public $boot; protected $initializeParamsType = 'Google_Service_Manager_NewDiskInitializeParams'; protected $initializeParamsDataType = ''; public function setAttachment(Google_Service_Manager_DiskAttachment $attachment) { $this->attachment = $attachment; } public function getAttachment() { return $this->attachment; } public function setAutoDelete($autoDelete) { $this->autoDelete = $autoDelete; } public function getAutoDelete() { return $this->autoDelete; } public function setBoot($boot) { $this->boot = $boot; } public function getBoot() { return $this->boot; } public function setInitializeParams(Google_Service_Manager_NewDiskInitializeParams $initializeParams) { $this->initializeParams = $initializeParams; } public function getInitializeParams() { return $this->initializeParams; } } class Google_Service_Manager_NewDiskInitializeParams extends Google_Model { protected $internal_gapi_mappings = array( ); public $diskSizeGb; public $diskType; public $sourceImage; public function setDiskSizeGb($diskSizeGb) { $this->diskSizeGb = $diskSizeGb; } public function getDiskSizeGb() { return $this->diskSizeGb; } public function setDiskType($diskType) { $this->diskType = $diskType; } public function getDiskType() { return $this->diskType; } public function setSourceImage($sourceImage) { $this->sourceImage = $sourceImage; } public function getSourceImage() { return $this->sourceImage; } } class Google_Service_Manager_ParamOverride extends Google_Model { protected $internal_gapi_mappings = array( ); public $path; public $value; public function setPath($path) { $this->path = $path; } public function getPath() { return $this->path; } public function setValue($value) { $this->value = $value; } public function getValue() { return $this->value; } } class Google_Service_Manager_ReplicaPoolModule extends Google_Collection { protected $collection_key = 'healthChecks'; protected $internal_gapi_mappings = array( ); protected $envVariablesType = 'Google_Service_Manager_EnvVariable'; protected $envVariablesDataType = 'map'; public $healthChecks; public $numReplicas; protected $replicaPoolParamsType = 'Google_Service_Manager_ReplicaPoolParams'; protected $replicaPoolParamsDataType = ''; public $resourceView; public function setEnvVariables($envVariables) { $this->envVariables = $envVariables; } public function getEnvVariables() { return $this->envVariables; } public function setHealthChecks($healthChecks) { $this->healthChecks = $healthChecks; } public function getHealthChecks() { return $this->healthChecks; } public function setNumReplicas($numReplicas) { $this->numReplicas = $numReplicas; } public function getNumReplicas() { return $this->numReplicas; } public function setReplicaPoolParams(Google_Service_Manager_ReplicaPoolParams $replicaPoolParams) { $this->replicaPoolParams = $replicaPoolParams; } public function getReplicaPoolParams() { return $this->replicaPoolParams; } public function setResourceView($resourceView) { $this->resourceView = $resourceView; } public function getResourceView() { return $this->resourceView; } } class Google_Service_Manager_ReplicaPoolModuleEnvVariables extends Google_Model { } class Google_Service_Manager_ReplicaPoolModuleStatus extends Google_Model { protected $internal_gapi_mappings = array( ); public $replicaPoolUrl; public $resourceViewUrl; public function setReplicaPoolUrl($replicaPoolUrl) { $this->replicaPoolUrl = $replicaPoolUrl; } public function getReplicaPoolUrl() { return $this->replicaPoolUrl; } public function setResourceViewUrl($resourceViewUrl) { $this->resourceViewUrl = $resourceViewUrl; } public function getResourceViewUrl() { return $this->resourceViewUrl; } } class Google_Service_Manager_ReplicaPoolParams extends Google_Model { protected $internal_gapi_mappings = array( ); protected $v1beta1Type = 'Google_Service_Manager_ReplicaPoolParamsV1Beta1'; protected $v1beta1DataType = ''; public function setV1beta1(Google_Service_Manager_ReplicaPoolParamsV1Beta1 $v1beta1) { $this->v1beta1 = $v1beta1; } public function getV1beta1() { return $this->v1beta1; } } class Google_Service_Manager_ReplicaPoolParamsV1Beta1 extends Google_Collection { protected $collection_key = 'serviceAccounts'; protected $internal_gapi_mappings = array( ); public $autoRestart; public $baseInstanceName; public $canIpForward; public $description; protected $disksToAttachType = 'Google_Service_Manager_ExistingDisk'; protected $disksToAttachDataType = 'array'; protected $disksToCreateType = 'Google_Service_Manager_NewDisk'; protected $disksToCreateDataType = 'array'; public $initAction; public $machineType; protected $metadataType = 'Google_Service_Manager_Metadata'; protected $metadataDataType = ''; protected $networkInterfacesType = 'Google_Service_Manager_NetworkInterface'; protected $networkInterfacesDataType = 'array'; public $onHostMaintenance; protected $serviceAccountsType = 'Google_Service_Manager_ServiceAccount'; protected $serviceAccountsDataType = 'array'; protected $tagsType = 'Google_Service_Manager_Tag'; protected $tagsDataType = ''; public $zone; public function setAutoRestart($autoRestart) { $this->autoRestart = $autoRestart; } public function getAutoRestart() { return $this->autoRestart; } public function setBaseInstanceName($baseInstanceName) { $this->baseInstanceName = $baseInstanceName; } public function getBaseInstanceName() { return $this->baseInstanceName; } public function setCanIpForward($canIpForward) { $this->canIpForward = $canIpForward; } public function getCanIpForward() { return $this->canIpForward; } public function setDescription($description) { $this->description = $description; } public function getDescription() { return $this->description; } public function setDisksToAttach($disksToAttach) { $this->disksToAttach = $disksToAttach; } public function getDisksToAttach() { return $this->disksToAttach; } public function setDisksToCreate($disksToCreate) { $this->disksToCreate = $disksToCreate; } public function getDisksToCreate() { return $this->disksToCreate; } public function setInitAction($initAction) { $this->initAction = $initAction; } public function getInitAction() { return $this->initAction; } public function setMachineType($machineType) { $this->machineType = $machineType; } public function getMachineType() { return $this->machineType; } public function setMetadata(Google_Service_Manager_Metadata $metadata) { $this->metadata = $metadata; } public function getMetadata() { return $this->metadata; } public function setNetworkInterfaces($networkInterfaces) { $this->networkInterfaces = $networkInterfaces; } public function getNetworkInterfaces() { return $this->networkInterfaces; } public function setOnHostMaintenance($onHostMaintenance) { $this->onHostMaintenance = $onHostMaintenance; } public function getOnHostMaintenance() { return $this->onHostMaintenance; } public function setServiceAccounts($serviceAccounts) { $this->serviceAccounts = $serviceAccounts; } public function getServiceAccounts() { return $this->serviceAccounts; } public function setTags(Google_Service_Manager_Tag $tags) { $this->tags = $tags; } public function getTags() { return $this->tags; } public function setZone($zone) { $this->zone = $zone; } public function getZone() { return $this->zone; } } class Google_Service_Manager_ServiceAccount extends Google_Collection { protected $collection_key = 'scopes'; protected $internal_gapi_mappings = array( ); public $email; public $scopes; public function setEmail($email) { $this->email = $email; } public function getEmail() { return $this->email; } public function setScopes($scopes) { $this->scopes = $scopes; } public function getScopes() { return $this->scopes; } } class Google_Service_Manager_Tag extends Google_Collection { protected $collection_key = 'items'; protected $internal_gapi_mappings = array( ); public $fingerPrint; public $items; public function setFingerPrint($fingerPrint) { $this->fingerPrint = $fingerPrint; } public function getFingerPrint() { return $this->fingerPrint; } public function setItems($items) { $this->items = $items; } public function getItems() { return $this->items; } } class Google_Service_Manager_Template extends Google_Model { protected $internal_gapi_mappings = array( ); protected $actionsType = 'Google_Service_Manager_Action'; protected $actionsDataType = 'map'; public $description; protected $modulesType = 'Google_Service_Manager_Module'; protected $modulesDataType = 'map'; public $name; public function setActions($actions) { $this->actions = $actions; } public function getActions() { return $this->actions; } public function setDescription($description) { $this->description = $description; } public function getDescription() { return $this->description; } public function setModules($modules) { $this->modules = $modules; } public function getModules() { return $this->modules; } public function setName($name) { $this->name = $name; } public function getName() { return $this->name; } } class Google_Service_Manager_TemplateActions extends Google_Model { } class Google_Service_Manager_TemplateModules extends Google_Model { } class Google_Service_Manager_TemplatesListResponse extends Google_Collection { protected $collection_key = 'resources'; protected $internal_gapi_mappings = array( ); public $nextPageToken; protected $resourcesType = 'Google_Service_Manager_Template'; protected $resourcesDataType = 'array'; public function setNextPageToken($nextPageToken) { $this->nextPageToken = $nextPageToken; } public function getNextPageToken() { return $this->nextPageToken; } public function setResources($resources) { $this->resources = $resources; } public function getResources() { return $this->resources; } } includes/Google/Service/Storage.php000064400000316067152214270100013312 0ustar00 * Lets you store and retrieve potentially-large, immutable data objects.

* *

* For more information about this service, see the API * Documentation *

* * @author Google, Inc. */ class UDP_Google_Service_Storage extends UDP_Google_Service { /** View and manage your data across Google Cloud Platform services. */ const CLOUD_PLATFORM = "https://www.googleapis.com/auth/cloud-platform"; /** Manage your data and permissions in Google Cloud Storage. */ const DEVSTORAGE_FULL_CONTROL = "https://www.googleapis.com/auth/devstorage.full_control"; /** View your data in Google Cloud Storage. */ const DEVSTORAGE_READ_ONLY = "https://www.googleapis.com/auth/devstorage.read_only"; /** Manage your data in Google Cloud Storage. */ const DEVSTORAGE_READ_WRITE = "https://www.googleapis.com/auth/devstorage.read_write"; /** * Google storage service name. The default value is drive. * @var String */ protected $serviceName; public $bucketAccessControls; public $buckets; public $channels; public $defaultObjectAccessControls; public $objectAccessControls; public $objects; /** * Constructs the internal representation of the Storage service. * * @param UDP_Google_Client $client */ public function __construct(UDP_Google_Client $client) { parent::__construct($client); $this->servicePath = 'storage/v1/'; $this->version = 'v1'; $this->serviceName = 'storage'; $this->bucketAccessControls = new Google_Service_Storage_BucketAccessControls_Resource( $this, $this->serviceName, 'bucketAccessControls', array( 'methods' => array( 'delete' => array( 'path' => 'b/{bucket}/acl/{entity}', 'httpMethod' => 'DELETE', 'parameters' => array( 'bucket' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'entity' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), ), ),'get' => array( 'path' => 'b/{bucket}/acl/{entity}', 'httpMethod' => 'GET', 'parameters' => array( 'bucket' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'entity' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), ), ),'insert' => array( 'path' => 'b/{bucket}/acl', 'httpMethod' => 'POST', 'parameters' => array( 'bucket' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), ), ),'list' => array( 'path' => 'b/{bucket}/acl', 'httpMethod' => 'GET', 'parameters' => array( 'bucket' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), ), ),'patch' => array( 'path' => 'b/{bucket}/acl/{entity}', 'httpMethod' => 'PATCH', 'parameters' => array( 'bucket' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'entity' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), ), ),'update' => array( 'path' => 'b/{bucket}/acl/{entity}', 'httpMethod' => 'PUT', 'parameters' => array( 'bucket' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'entity' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), ), ), ) ) ); $this->buckets = new Google_Service_Storage_Buckets_Resource( $this, $this->serviceName, 'buckets', array( 'methods' => array( 'delete' => array( 'path' => 'b/{bucket}', 'httpMethod' => 'DELETE', 'parameters' => array( 'bucket' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'ifMetagenerationMatch' => array( 'location' => 'query', 'type' => 'string', ), 'ifMetagenerationNotMatch' => array( 'location' => 'query', 'type' => 'string', ), ), ),'get' => array( 'path' => 'b/{bucket}', 'httpMethod' => 'GET', 'parameters' => array( 'bucket' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'ifMetagenerationMatch' => array( 'location' => 'query', 'type' => 'string', ), 'ifMetagenerationNotMatch' => array( 'location' => 'query', 'type' => 'string', ), 'projection' => array( 'location' => 'query', 'type' => 'string', ), ), ),'insert' => array( 'path' => 'b', 'httpMethod' => 'POST', 'parameters' => array( 'project' => array( 'location' => 'query', 'type' => 'string', 'required' => true, ), 'predefinedAcl' => array( 'location' => 'query', 'type' => 'string', ), 'projection' => array( 'location' => 'query', 'type' => 'string', ), 'predefinedDefaultObjectAcl' => array( 'location' => 'query', 'type' => 'string', ), ), ),'list' => array( 'path' => 'b', 'httpMethod' => 'GET', 'parameters' => array( 'project' => array( 'location' => 'query', 'type' => 'string', 'required' => true, ), 'pageToken' => array( 'location' => 'query', 'type' => 'string', ), 'prefix' => array( 'location' => 'query', 'type' => 'string', ), 'projection' => array( 'location' => 'query', 'type' => 'string', ), 'maxResults' => array( 'location' => 'query', 'type' => 'integer', ), ), ),'patch' => array( 'path' => 'b/{bucket}', 'httpMethod' => 'PATCH', 'parameters' => array( 'bucket' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'projection' => array( 'location' => 'query', 'type' => 'string', ), 'ifMetagenerationMatch' => array( 'location' => 'query', 'type' => 'string', ), 'predefinedDefaultObjectAcl' => array( 'location' => 'query', 'type' => 'string', ), 'predefinedAcl' => array( 'location' => 'query', 'type' => 'string', ), 'ifMetagenerationNotMatch' => array( 'location' => 'query', 'type' => 'string', ), ), ),'update' => array( 'path' => 'b/{bucket}', 'httpMethod' => 'PUT', 'parameters' => array( 'bucket' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'projection' => array( 'location' => 'query', 'type' => 'string', ), 'ifMetagenerationMatch' => array( 'location' => 'query', 'type' => 'string', ), 'predefinedDefaultObjectAcl' => array( 'location' => 'query', 'type' => 'string', ), 'predefinedAcl' => array( 'location' => 'query', 'type' => 'string', ), 'ifMetagenerationNotMatch' => array( 'location' => 'query', 'type' => 'string', ), ), ), ) ) ); $this->channels = new Google_Service_Storage_Channels_Resource( $this, $this->serviceName, 'channels', array( 'methods' => array( 'stop' => array( 'path' => 'channels/stop', 'httpMethod' => 'POST', 'parameters' => array(), ), ) ) ); $this->defaultObjectAccessControls = new Google_Service_Storage_DefaultObjectAccessControls_Resource( $this, $this->serviceName, 'defaultObjectAccessControls', array( 'methods' => array( 'delete' => array( 'path' => 'b/{bucket}/defaultObjectAcl/{entity}', 'httpMethod' => 'DELETE', 'parameters' => array( 'bucket' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'entity' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), ), ),'get' => array( 'path' => 'b/{bucket}/defaultObjectAcl/{entity}', 'httpMethod' => 'GET', 'parameters' => array( 'bucket' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'entity' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), ), ),'insert' => array( 'path' => 'b/{bucket}/defaultObjectAcl', 'httpMethod' => 'POST', 'parameters' => array( 'bucket' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), ), ),'list' => array( 'path' => 'b/{bucket}/defaultObjectAcl', 'httpMethod' => 'GET', 'parameters' => array( 'bucket' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'ifMetagenerationMatch' => array( 'location' => 'query', 'type' => 'string', ), 'ifMetagenerationNotMatch' => array( 'location' => 'query', 'type' => 'string', ), ), ),'patch' => array( 'path' => 'b/{bucket}/defaultObjectAcl/{entity}', 'httpMethod' => 'PATCH', 'parameters' => array( 'bucket' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'entity' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), ), ),'update' => array( 'path' => 'b/{bucket}/defaultObjectAcl/{entity}', 'httpMethod' => 'PUT', 'parameters' => array( 'bucket' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'entity' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), ), ), ) ) ); $this->objectAccessControls = new Google_Service_Storage_ObjectAccessControls_Resource( $this, $this->serviceName, 'objectAccessControls', array( 'methods' => array( 'delete' => array( 'path' => 'b/{bucket}/o/{object}/acl/{entity}', 'httpMethod' => 'DELETE', 'parameters' => array( 'bucket' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'object' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'entity' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'generation' => array( 'location' => 'query', 'type' => 'string', ), ), ),'get' => array( 'path' => 'b/{bucket}/o/{object}/acl/{entity}', 'httpMethod' => 'GET', 'parameters' => array( 'bucket' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'object' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'entity' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'generation' => array( 'location' => 'query', 'type' => 'string', ), ), ),'insert' => array( 'path' => 'b/{bucket}/o/{object}/acl', 'httpMethod' => 'POST', 'parameters' => array( 'bucket' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'object' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'generation' => array( 'location' => 'query', 'type' => 'string', ), ), ),'list' => array( 'path' => 'b/{bucket}/o/{object}/acl', 'httpMethod' => 'GET', 'parameters' => array( 'bucket' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'object' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'generation' => array( 'location' => 'query', 'type' => 'string', ), ), ),'patch' => array( 'path' => 'b/{bucket}/o/{object}/acl/{entity}', 'httpMethod' => 'PATCH', 'parameters' => array( 'bucket' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'object' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'entity' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'generation' => array( 'location' => 'query', 'type' => 'string', ), ), ),'update' => array( 'path' => 'b/{bucket}/o/{object}/acl/{entity}', 'httpMethod' => 'PUT', 'parameters' => array( 'bucket' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'object' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'entity' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'generation' => array( 'location' => 'query', 'type' => 'string', ), ), ), ) ) ); $this->objects = new Google_Service_Storage_Objects_Resource( $this, $this->serviceName, 'objects', array( 'methods' => array( 'compose' => array( 'path' => 'b/{destinationBucket}/o/{destinationObject}/compose', 'httpMethod' => 'POST', 'parameters' => array( 'destinationBucket' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'destinationObject' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'ifGenerationMatch' => array( 'location' => 'query', 'type' => 'string', ), 'ifMetagenerationMatch' => array( 'location' => 'query', 'type' => 'string', ), 'destinationPredefinedAcl' => array( 'location' => 'query', 'type' => 'string', ), ), ),'copy' => array( 'path' => 'b/{sourceBucket}/o/{sourceObject}/copyTo/b/{destinationBucket}/o/{destinationObject}', 'httpMethod' => 'POST', 'parameters' => array( 'sourceBucket' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'sourceObject' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'destinationBucket' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'destinationObject' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'ifSourceGenerationNotMatch' => array( 'location' => 'query', 'type' => 'string', ), 'ifGenerationNotMatch' => array( 'location' => 'query', 'type' => 'string', ), 'ifSourceMetagenerationNotMatch' => array( 'location' => 'query', 'type' => 'string', ), 'ifMetagenerationMatch' => array( 'location' => 'query', 'type' => 'string', ), 'sourceGeneration' => array( 'location' => 'query', 'type' => 'string', ), 'destinationPredefinedAcl' => array( 'location' => 'query', 'type' => 'string', ), 'ifSourceGenerationMatch' => array( 'location' => 'query', 'type' => 'string', ), 'ifSourceMetagenerationMatch' => array( 'location' => 'query', 'type' => 'string', ), 'ifGenerationMatch' => array( 'location' => 'query', 'type' => 'string', ), 'ifMetagenerationNotMatch' => array( 'location' => 'query', 'type' => 'string', ), 'projection' => array( 'location' => 'query', 'type' => 'string', ), ), ),'delete' => array( 'path' => 'b/{bucket}/o/{object}', 'httpMethod' => 'DELETE', 'parameters' => array( 'bucket' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'object' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'ifGenerationNotMatch' => array( 'location' => 'query', 'type' => 'string', ), 'generation' => array( 'location' => 'query', 'type' => 'string', ), 'ifMetagenerationMatch' => array( 'location' => 'query', 'type' => 'string', ), 'ifGenerationMatch' => array( 'location' => 'query', 'type' => 'string', ), 'ifMetagenerationNotMatch' => array( 'location' => 'query', 'type' => 'string', ), ), ),'get' => array( 'path' => 'b/{bucket}/o/{object}', 'httpMethod' => 'GET', 'parameters' => array( 'bucket' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'object' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'ifGenerationNotMatch' => array( 'location' => 'query', 'type' => 'string', ), 'generation' => array( 'location' => 'query', 'type' => 'string', ), 'ifMetagenerationMatch' => array( 'location' => 'query', 'type' => 'string', ), 'ifGenerationMatch' => array( 'location' => 'query', 'type' => 'string', ), 'ifMetagenerationNotMatch' => array( 'location' => 'query', 'type' => 'string', ), 'projection' => array( 'location' => 'query', 'type' => 'string', ), ), ),'insert' => array( 'path' => 'b/{bucket}/o', 'httpMethod' => 'POST', 'parameters' => array( 'bucket' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'predefinedAcl' => array( 'location' => 'query', 'type' => 'string', ), 'projection' => array( 'location' => 'query', 'type' => 'string', ), 'ifGenerationNotMatch' => array( 'location' => 'query', 'type' => 'string', ), 'ifMetagenerationMatch' => array( 'location' => 'query', 'type' => 'string', ), 'contentEncoding' => array( 'location' => 'query', 'type' => 'string', ), 'ifGenerationMatch' => array( 'location' => 'query', 'type' => 'string', ), 'ifMetagenerationNotMatch' => array( 'location' => 'query', 'type' => 'string', ), 'name' => array( 'location' => 'query', 'type' => 'string', ), ), ),'list' => array( 'path' => 'b/{bucket}/o', 'httpMethod' => 'GET', 'parameters' => array( 'bucket' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'projection' => array( 'location' => 'query', 'type' => 'string', ), 'versions' => array( 'location' => 'query', 'type' => 'boolean', ), 'prefix' => array( 'location' => 'query', 'type' => 'string', ), 'maxResults' => array( 'location' => 'query', 'type' => 'integer', ), 'pageToken' => array( 'location' => 'query', 'type' => 'string', ), 'delimiter' => array( 'location' => 'query', 'type' => 'string', ), ), ),'patch' => array( 'path' => 'b/{bucket}/o/{object}', 'httpMethod' => 'PATCH', 'parameters' => array( 'bucket' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'object' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'predefinedAcl' => array( 'location' => 'query', 'type' => 'string', ), 'ifGenerationNotMatch' => array( 'location' => 'query', 'type' => 'string', ), 'generation' => array( 'location' => 'query', 'type' => 'string', ), 'ifMetagenerationMatch' => array( 'location' => 'query', 'type' => 'string', ), 'ifGenerationMatch' => array( 'location' => 'query', 'type' => 'string', ), 'ifMetagenerationNotMatch' => array( 'location' => 'query', 'type' => 'string', ), 'projection' => array( 'location' => 'query', 'type' => 'string', ), ), ),'rewrite' => array( 'path' => 'b/{sourceBucket}/o/{sourceObject}/rewriteTo/b/{destinationBucket}/o/{destinationObject}', 'httpMethod' => 'POST', 'parameters' => array( 'sourceBucket' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'sourceObject' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'destinationBucket' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'destinationObject' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'ifSourceGenerationNotMatch' => array( 'location' => 'query', 'type' => 'string', ), 'ifGenerationNotMatch' => array( 'location' => 'query', 'type' => 'string', ), 'rewriteToken' => array( 'location' => 'query', 'type' => 'string', ), 'ifSourceMetagenerationNotMatch' => array( 'location' => 'query', 'type' => 'string', ), 'ifMetagenerationMatch' => array( 'location' => 'query', 'type' => 'string', ), 'sourceGeneration' => array( 'location' => 'query', 'type' => 'string', ), 'destinationPredefinedAcl' => array( 'location' => 'query', 'type' => 'string', ), 'ifSourceGenerationMatch' => array( 'location' => 'query', 'type' => 'string', ), 'maxBytesRewrittenPerCall' => array( 'location' => 'query', 'type' => 'string', ), 'ifSourceMetagenerationMatch' => array( 'location' => 'query', 'type' => 'string', ), 'ifGenerationMatch' => array( 'location' => 'query', 'type' => 'string', ), 'ifMetagenerationNotMatch' => array( 'location' => 'query', 'type' => 'string', ), 'projection' => array( 'location' => 'query', 'type' => 'string', ), ), ),'update' => array( 'path' => 'b/{bucket}/o/{object}', 'httpMethod' => 'PUT', 'parameters' => array( 'bucket' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'object' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'predefinedAcl' => array( 'location' => 'query', 'type' => 'string', ), 'ifGenerationNotMatch' => array( 'location' => 'query', 'type' => 'string', ), 'generation' => array( 'location' => 'query', 'type' => 'string', ), 'ifMetagenerationMatch' => array( 'location' => 'query', 'type' => 'string', ), 'ifGenerationMatch' => array( 'location' => 'query', 'type' => 'string', ), 'ifMetagenerationNotMatch' => array( 'location' => 'query', 'type' => 'string', ), 'projection' => array( 'location' => 'query', 'type' => 'string', ), ), ),'watchAll' => array( 'path' => 'b/{bucket}/o/watch', 'httpMethod' => 'POST', 'parameters' => array( 'bucket' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'projection' => array( 'location' => 'query', 'type' => 'string', ), 'versions' => array( 'location' => 'query', 'type' => 'boolean', ), 'prefix' => array( 'location' => 'query', 'type' => 'string', ), 'maxResults' => array( 'location' => 'query', 'type' => 'integer', ), 'pageToken' => array( 'location' => 'query', 'type' => 'string', ), 'delimiter' => array( 'location' => 'query', 'type' => 'string', ), ), ), ) ) ); } } /** * The "bucketAccessControls" collection of methods. * Typical usage is: * * $storageService = new UDP_Google_Service_Storage(...); * $bucketAccessControls = $storageService->bucketAccessControls; * */ class Google_Service_Storage_BucketAccessControls_Resource extends UDP_Google_Service_Resource { /** * Permanently deletes the ACL entry for the specified entity on the specified * bucket. (bucketAccessControls.delete) * * @param string $bucket Name of a bucket. * @param string $entity The entity holding the permission. Can be user-userId, * user-emailAddress, group-groupId, group-emailAddress, allUsers, or * allAuthenticatedUsers. * @param array $optParams Optional parameters. */ public function delete($bucket, $entity, $optParams = array()) { $params = array('bucket' => $bucket, 'entity' => $entity); $params = array_merge($params, $optParams); return $this->call('delete', array($params)); } /** * Returns the ACL entry for the specified entity on the specified bucket. * (bucketAccessControls.get) * * @param string $bucket Name of a bucket. * @param string $entity The entity holding the permission. Can be user-userId, * user-emailAddress, group-groupId, group-emailAddress, allUsers, or * allAuthenticatedUsers. * @param array $optParams Optional parameters. * @return Google_Service_Storage_BucketAccessControl */ public function get($bucket, $entity, $optParams = array()) { $params = array('bucket' => $bucket, 'entity' => $entity); $params = array_merge($params, $optParams); return $this->call('get', array($params), "Google_Service_Storage_BucketAccessControl"); } /** * Creates a new ACL entry on the specified bucket. * (bucketAccessControls.insert) * * @param string $bucket Name of a bucket. * @param Google_BucketAccessControl $postBody * @param array $optParams Optional parameters. * @return Google_Service_Storage_BucketAccessControl */ public function insert($bucket, Google_Service_Storage_BucketAccessControl $postBody, $optParams = array()) { $params = array('bucket' => $bucket, 'postBody' => $postBody); $params = array_merge($params, $optParams); return $this->call('insert', array($params), "Google_Service_Storage_BucketAccessControl"); } /** * Retrieves ACL entries on the specified bucket. * (bucketAccessControls.listBucketAccessControls) * * @param string $bucket Name of a bucket. * @param array $optParams Optional parameters. * @return Google_Service_Storage_BucketAccessControls */ public function listBucketAccessControls($bucket, $optParams = array()) { $params = array('bucket' => $bucket); $params = array_merge($params, $optParams); return $this->call('list', array($params), "Google_Service_Storage_BucketAccessControls"); } /** * Updates an ACL entry on the specified bucket. This method supports patch * semantics. (bucketAccessControls.patch) * * @param string $bucket Name of a bucket. * @param string $entity The entity holding the permission. Can be user-userId, * user-emailAddress, group-groupId, group-emailAddress, allUsers, or * allAuthenticatedUsers. * @param Google_BucketAccessControl $postBody * @param array $optParams Optional parameters. * @return Google_Service_Storage_BucketAccessControl */ public function patch($bucket, $entity, Google_Service_Storage_BucketAccessControl $postBody, $optParams = array()) { $params = array('bucket' => $bucket, 'entity' => $entity, 'postBody' => $postBody); $params = array_merge($params, $optParams); return $this->call('patch', array($params), "Google_Service_Storage_BucketAccessControl"); } /** * Updates an ACL entry on the specified bucket. (bucketAccessControls.update) * * @param string $bucket Name of a bucket. * @param string $entity The entity holding the permission. Can be user-userId, * user-emailAddress, group-groupId, group-emailAddress, allUsers, or * allAuthenticatedUsers. * @param Google_BucketAccessControl $postBody * @param array $optParams Optional parameters. * @return Google_Service_Storage_BucketAccessControl */ public function update($bucket, $entity, Google_Service_Storage_BucketAccessControl $postBody, $optParams = array()) { $params = array('bucket' => $bucket, 'entity' => $entity, 'postBody' => $postBody); $params = array_merge($params, $optParams); return $this->call('update', array($params), "Google_Service_Storage_BucketAccessControl"); } } /** * The "buckets" collection of methods. * Typical usage is: * * $storageService = new UDP_Google_Service_Storage(...); * $buckets = $storageService->buckets; * */ class Google_Service_Storage_Buckets_Resource extends UDP_Google_Service_Resource { /** * Permanently deletes an empty bucket. (buckets.delete) * * @param string $bucket Name of a bucket. * @param array $optParams Optional parameters. * * @opt_param string ifMetagenerationMatch If set, only deletes the bucket if * its metageneration matches this value. * @opt_param string ifMetagenerationNotMatch If set, only deletes the bucket if * its metageneration does not match this value. */ public function delete($bucket, $optParams = array()) { $params = array('bucket' => $bucket); $params = array_merge($params, $optParams); return $this->call('delete', array($params)); } /** * Returns metadata for the specified bucket. (buckets.get) * * @param string $bucket Name of a bucket. * @param array $optParams Optional parameters. * * @opt_param string ifMetagenerationMatch Makes the return of the bucket * metadata conditional on whether the bucket's current metageneration matches * the given value. * @opt_param string ifMetagenerationNotMatch Makes the return of the bucket * metadata conditional on whether the bucket's current metageneration does not * match the given value. * @opt_param string projection Set of properties to return. Defaults to noAcl. * @return UDP_Google_Service_Storage_Bucket */ public function get($bucket, $optParams = array()) { $params = array('bucket' => $bucket); $params = array_merge($params, $optParams); return $this->call('get', array($params), "UDP_Google_Service_Storage_Bucket"); } /** * Creates a new bucket. (buckets.insert) * * @param string $project A valid API project identifier. * @param Google_Bucket $postBody * @param array $optParams Optional parameters. * * @opt_param string predefinedAcl Apply a predefined set of access controls to * this bucket. * @opt_param string projection Set of properties to return. Defaults to noAcl, * unless the bucket resource specifies acl or defaultObjectAcl properties, when * it defaults to full. * @opt_param string predefinedDefaultObjectAcl Apply a predefined set of * default object access controls to this bucket. * @return UDP_Google_Service_Storage_Bucket */ public function insert($project, UDP_Google_Service_Storage_Bucket $postBody, $optParams = array()) { $params = array('project' => $project, 'postBody' => $postBody); $params = array_merge($params, $optParams); return $this->call('insert', array($params), "UDP_Google_Service_Storage_Bucket"); } /** * Retrieves a list of buckets for a given project. (buckets.listBuckets) * * @param string $project A valid API project identifier. * @param array $optParams Optional parameters. * * @opt_param string pageToken A previously-returned page token representing * part of the larger set of results to view. * @opt_param string prefix Filter results to buckets whose names begin with * this prefix. * @opt_param string projection Set of properties to return. Defaults to noAcl. * @opt_param string maxResults Maximum number of buckets to return. * @return Google_Service_Storage_Buckets */ public function listBuckets($project, $optParams = array()) { $params = array('project' => $project); $params = array_merge($params, $optParams); return $this->call('list', array($params), "Google_Service_Storage_Buckets"); } /** * Updates a bucket. This method supports patch semantics. (buckets.patch) * * @param string $bucket Name of a bucket. * @param Google_Bucket $postBody * @param array $optParams Optional parameters. * * @opt_param string projection Set of properties to return. Defaults to full. * @opt_param string ifMetagenerationMatch Makes the return of the bucket * metadata conditional on whether the bucket's current metageneration matches * the given value. * @opt_param string predefinedDefaultObjectAcl Apply a predefined set of * default object access controls to this bucket. * @opt_param string predefinedAcl Apply a predefined set of access controls to * this bucket. * @opt_param string ifMetagenerationNotMatch Makes the return of the bucket * metadata conditional on whether the bucket's current metageneration does not * match the given value. * @return UDP_Google_Service_Storage_Bucket */ public function patch($bucket, UDP_Google_Service_Storage_Bucket $postBody, $optParams = array()) { $params = array('bucket' => $bucket, 'postBody' => $postBody); $params = array_merge($params, $optParams); return $this->call('patch', array($params), "UDP_Google_Service_Storage_Bucket"); } /** * Updates a bucket. (buckets.update) * * @param string $bucket Name of a bucket. * @param Google_Bucket $postBody * @param array $optParams Optional parameters. * * @opt_param string projection Set of properties to return. Defaults to full. * @opt_param string ifMetagenerationMatch Makes the return of the bucket * metadata conditional on whether the bucket's current metageneration matches * the given value. * @opt_param string predefinedDefaultObjectAcl Apply a predefined set of * default object access controls to this bucket. * @opt_param string predefinedAcl Apply a predefined set of access controls to * this bucket. * @opt_param string ifMetagenerationNotMatch Makes the return of the bucket * metadata conditional on whether the bucket's current metageneration does not * match the given value. * @return UDP_Google_Service_Storage_Bucket */ public function update($bucket, UDP_Google_Service_Storage_Bucket $postBody, $optParams = array()) { $params = array('bucket' => $bucket, 'postBody' => $postBody); $params = array_merge($params, $optParams); return $this->call('update', array($params), "UDP_Google_Service_Storage_Bucket"); } } /** * The "channels" collection of methods. * Typical usage is: * * $storageService = new UDP_Google_Service_Storage(...); * $channels = $storageService->channels; * */ class Google_Service_Storage_Channels_Resource extends UDP_Google_Service_Resource { /** * Stop watching resources through this channel (channels.stop) * * @param Google_Channel $postBody * @param array $optParams Optional parameters. */ public function stop(Google_Service_Storage_Channel $postBody, $optParams = array()) { $params = array('postBody' => $postBody); $params = array_merge($params, $optParams); return $this->call('stop', array($params)); } } /** * The "defaultObjectAccessControls" collection of methods. * Typical usage is: * * $storageService = new UDP_Google_Service_Storage(...); * $defaultObjectAccessControls = $storageService->defaultObjectAccessControls; * */ class Google_Service_Storage_DefaultObjectAccessControls_Resource extends UDP_Google_Service_Resource { /** * Permanently deletes the default object ACL entry for the specified entity on * the specified bucket. (defaultObjectAccessControls.delete) * * @param string $bucket Name of a bucket. * @param string $entity The entity holding the permission. Can be user-userId, * user-emailAddress, group-groupId, group-emailAddress, allUsers, or * allAuthenticatedUsers. * @param array $optParams Optional parameters. */ public function delete($bucket, $entity, $optParams = array()) { $params = array('bucket' => $bucket, 'entity' => $entity); $params = array_merge($params, $optParams); return $this->call('delete', array($params)); } /** * Returns the default object ACL entry for the specified entity on the * specified bucket. (defaultObjectAccessControls.get) * * @param string $bucket Name of a bucket. * @param string $entity The entity holding the permission. Can be user-userId, * user-emailAddress, group-groupId, group-emailAddress, allUsers, or * allAuthenticatedUsers. * @param array $optParams Optional parameters. * @return Google_Service_Storage_ObjectAccessControl */ public function get($bucket, $entity, $optParams = array()) { $params = array('bucket' => $bucket, 'entity' => $entity); $params = array_merge($params, $optParams); return $this->call('get', array($params), "Google_Service_Storage_ObjectAccessControl"); } /** * Creates a new default object ACL entry on the specified bucket. * (defaultObjectAccessControls.insert) * * @param string $bucket Name of a bucket. * @param Google_ObjectAccessControl $postBody * @param array $optParams Optional parameters. * @return Google_Service_Storage_ObjectAccessControl */ public function insert($bucket, Google_Service_Storage_ObjectAccessControl $postBody, $optParams = array()) { $params = array('bucket' => $bucket, 'postBody' => $postBody); $params = array_merge($params, $optParams); return $this->call('insert', array($params), "Google_Service_Storage_ObjectAccessControl"); } /** * Retrieves default object ACL entries on the specified bucket. * (defaultObjectAccessControls.listDefaultObjectAccessControls) * * @param string $bucket Name of a bucket. * @param array $optParams Optional parameters. * * @opt_param string ifMetagenerationMatch If present, only return default ACL * listing if the bucket's current metageneration matches this value. * @opt_param string ifMetagenerationNotMatch If present, only return default * ACL listing if the bucket's current metageneration does not match the given * value. * @return Google_Service_Storage_ObjectAccessControls */ public function listDefaultObjectAccessControls($bucket, $optParams = array()) { $params = array('bucket' => $bucket); $params = array_merge($params, $optParams); return $this->call('list', array($params), "Google_Service_Storage_ObjectAccessControls"); } /** * Updates a default object ACL entry on the specified bucket. This method * supports patch semantics. (defaultObjectAccessControls.patch) * * @param string $bucket Name of a bucket. * @param string $entity The entity holding the permission. Can be user-userId, * user-emailAddress, group-groupId, group-emailAddress, allUsers, or * allAuthenticatedUsers. * @param Google_ObjectAccessControl $postBody * @param array $optParams Optional parameters. * @return Google_Service_Storage_ObjectAccessControl */ public function patch($bucket, $entity, Google_Service_Storage_ObjectAccessControl $postBody, $optParams = array()) { $params = array('bucket' => $bucket, 'entity' => $entity, 'postBody' => $postBody); $params = array_merge($params, $optParams); return $this->call('patch', array($params), "Google_Service_Storage_ObjectAccessControl"); } /** * Updates a default object ACL entry on the specified bucket. * (defaultObjectAccessControls.update) * * @param string $bucket Name of a bucket. * @param string $entity The entity holding the permission. Can be user-userId, * user-emailAddress, group-groupId, group-emailAddress, allUsers, or * allAuthenticatedUsers. * @param Google_ObjectAccessControl $postBody * @param array $optParams Optional parameters. * @return Google_Service_Storage_ObjectAccessControl */ public function update($bucket, $entity, Google_Service_Storage_ObjectAccessControl $postBody, $optParams = array()) { $params = array('bucket' => $bucket, 'entity' => $entity, 'postBody' => $postBody); $params = array_merge($params, $optParams); return $this->call('update', array($params), "Google_Service_Storage_ObjectAccessControl"); } } /** * The "objectAccessControls" collection of methods. * Typical usage is: * * $storageService = new UDP_Google_Service_Storage(...); * $objectAccessControls = $storageService->objectAccessControls; * */ class Google_Service_Storage_ObjectAccessControls_Resource extends UDP_Google_Service_Resource { /** * Permanently deletes the ACL entry for the specified entity on the specified * object. (objectAccessControls.delete) * * @param string $bucket Name of a bucket. * @param string $object Name of the object. * @param string $entity The entity holding the permission. Can be user-userId, * user-emailAddress, group-groupId, group-emailAddress, allUsers, or * allAuthenticatedUsers. * @param array $optParams Optional parameters. * * @opt_param string generation If present, selects a specific revision of this * object (as opposed to the latest version, the default). */ public function delete($bucket, $object, $entity, $optParams = array()) { $params = array('bucket' => $bucket, 'object' => $object, 'entity' => $entity); $params = array_merge($params, $optParams); return $this->call('delete', array($params)); } /** * Returns the ACL entry for the specified entity on the specified object. * (objectAccessControls.get) * * @param string $bucket Name of a bucket. * @param string $object Name of the object. * @param string $entity The entity holding the permission. Can be user-userId, * user-emailAddress, group-groupId, group-emailAddress, allUsers, or * allAuthenticatedUsers. * @param array $optParams Optional parameters. * * @opt_param string generation If present, selects a specific revision of this * object (as opposed to the latest version, the default). * @return Google_Service_Storage_ObjectAccessControl */ public function get($bucket, $object, $entity, $optParams = array()) { $params = array('bucket' => $bucket, 'object' => $object, 'entity' => $entity); $params = array_merge($params, $optParams); return $this->call('get', array($params), "Google_Service_Storage_ObjectAccessControl"); } /** * Creates a new ACL entry on the specified object. * (objectAccessControls.insert) * * @param string $bucket Name of a bucket. * @param string $object Name of the object. * @param Google_ObjectAccessControl $postBody * @param array $optParams Optional parameters. * * @opt_param string generation If present, selects a specific revision of this * object (as opposed to the latest version, the default). * @return Google_Service_Storage_ObjectAccessControl */ public function insert($bucket, $object, Google_Service_Storage_ObjectAccessControl $postBody, $optParams = array()) { $params = array('bucket' => $bucket, 'object' => $object, 'postBody' => $postBody); $params = array_merge($params, $optParams); return $this->call('insert', array($params), "Google_Service_Storage_ObjectAccessControl"); } /** * Retrieves ACL entries on the specified object. * (objectAccessControls.listObjectAccessControls) * * @param string $bucket Name of a bucket. * @param string $object Name of the object. * @param array $optParams Optional parameters. * * @opt_param string generation If present, selects a specific revision of this * object (as opposed to the latest version, the default). * @return Google_Service_Storage_ObjectAccessControls */ public function listObjectAccessControls($bucket, $object, $optParams = array()) { $params = array('bucket' => $bucket, 'object' => $object); $params = array_merge($params, $optParams); return $this->call('list', array($params), "Google_Service_Storage_ObjectAccessControls"); } /** * Updates an ACL entry on the specified object. This method supports patch * semantics. (objectAccessControls.patch) * * @param string $bucket Name of a bucket. * @param string $object Name of the object. * @param string $entity The entity holding the permission. Can be user-userId, * user-emailAddress, group-groupId, group-emailAddress, allUsers, or * allAuthenticatedUsers. * @param Google_ObjectAccessControl $postBody * @param array $optParams Optional parameters. * * @opt_param string generation If present, selects a specific revision of this * object (as opposed to the latest version, the default). * @return Google_Service_Storage_ObjectAccessControl */ public function patch($bucket, $object, $entity, Google_Service_Storage_ObjectAccessControl $postBody, $optParams = array()) { $params = array('bucket' => $bucket, 'object' => $object, 'entity' => $entity, 'postBody' => $postBody); $params = array_merge($params, $optParams); return $this->call('patch', array($params), "Google_Service_Storage_ObjectAccessControl"); } /** * Updates an ACL entry on the specified object. (objectAccessControls.update) * * @param string $bucket Name of a bucket. * @param string $object Name of the object. * @param string $entity The entity holding the permission. Can be user-userId, * user-emailAddress, group-groupId, group-emailAddress, allUsers, or * allAuthenticatedUsers. * @param Google_ObjectAccessControl $postBody * @param array $optParams Optional parameters. * * @opt_param string generation If present, selects a specific revision of this * object (as opposed to the latest version, the default). * @return Google_Service_Storage_ObjectAccessControl */ public function update($bucket, $object, $entity, Google_Service_Storage_ObjectAccessControl $postBody, $optParams = array()) { $params = array('bucket' => $bucket, 'object' => $object, 'entity' => $entity, 'postBody' => $postBody); $params = array_merge($params, $optParams); return $this->call('update', array($params), "Google_Service_Storage_ObjectAccessControl"); } } /** * The "objects" collection of methods. * Typical usage is: * * $storageService = new UDP_Google_Service_Storage(...); * $objects = $storageService->objects; * */ class Google_Service_Storage_Objects_Resource extends UDP_Google_Service_Resource { /** * Concatenates a list of existing objects into a new object in the same bucket. * (objects.compose) * * @param string $destinationBucket Name of the bucket in which to store the new * object. * @param string $destinationObject Name of the new object. * @param Google_ComposeRequest $postBody * @param array $optParams Optional parameters. * * @opt_param string ifGenerationMatch Makes the operation conditional on * whether the object's current generation matches the given value. * @opt_param string ifMetagenerationMatch Makes the operation conditional on * whether the object's current metageneration matches the given value. * @opt_param string destinationPredefinedAcl Apply a predefined set of access * controls to the destination object. * @return UDP_Google_Service_Storage_StorageObject */ public function compose($destinationBucket, $destinationObject, Google_Service_Storage_ComposeRequest $postBody, $optParams = array()) { $params = array('destinationBucket' => $destinationBucket, 'destinationObject' => $destinationObject, 'postBody' => $postBody); $params = array_merge($params, $optParams); return $this->call('compose', array($params), "UDP_Google_Service_Storage_StorageObject"); } /** * Copies an object to a specified location. Optionally overrides metadata. * (objects.copy) * * @param string $sourceBucket Name of the bucket in which to find the source * object. * @param string $sourceObject Name of the source object. * @param string $destinationBucket Name of the bucket in which to store the new * object. Overrides the provided object metadata's bucket value, if any. * @param string $destinationObject Name of the new object. Required when the * object metadata is not otherwise provided. Overrides the object metadata's * name value, if any. * @param Google_StorageObject $postBody * @param array $optParams Optional parameters. * * @opt_param string ifSourceGenerationNotMatch Makes the operation conditional * on whether the source object's generation does not match the given value. * @opt_param string ifGenerationNotMatch Makes the operation conditional on * whether the destination object's current generation does not match the given * value. * @opt_param string ifSourceMetagenerationNotMatch Makes the operation * conditional on whether the source object's current metageneration does not * match the given value. * @opt_param string ifMetagenerationMatch Makes the operation conditional on * whether the destination object's current metageneration matches the given * value. * @opt_param string sourceGeneration If present, selects a specific revision of * the source object (as opposed to the latest version, the default). * @opt_param string destinationPredefinedAcl Apply a predefined set of access * controls to the destination object. * @opt_param string ifSourceGenerationMatch Makes the operation conditional on * whether the source object's generation matches the given value. * @opt_param string ifSourceMetagenerationMatch Makes the operation conditional * on whether the source object's current metageneration matches the given * value. * @opt_param string ifGenerationMatch Makes the operation conditional on * whether the destination object's current generation matches the given value. * @opt_param string ifMetagenerationNotMatch Makes the operation conditional on * whether the destination object's current metageneration does not match the * given value. * @opt_param string projection Set of properties to return. Defaults to noAcl, * unless the object resource specifies the acl property, when it defaults to * full. * @return UDP_Google_Service_Storage_StorageObject */ public function copy($sourceBucket, $sourceObject, $destinationBucket, $destinationObject, UDP_Google_Service_Storage_StorageObject $postBody, $optParams = array()) { $params = array('sourceBucket' => $sourceBucket, 'sourceObject' => $sourceObject, 'destinationBucket' => $destinationBucket, 'destinationObject' => $destinationObject, 'postBody' => $postBody); $params = array_merge($params, $optParams); return $this->call('copy', array($params), "UDP_Google_Service_Storage_StorageObject"); } /** * Deletes an object and its metadata. Deletions are permanent if versioning is * not enabled for the bucket, or if the generation parameter is used. * (objects.delete) * * @param string $bucket Name of the bucket in which the object resides. * @param string $object Name of the object. * @param array $optParams Optional parameters. * * @opt_param string ifGenerationNotMatch Makes the operation conditional on * whether the object's current generation does not match the given value. * @opt_param string generation If present, permanently deletes a specific * revision of this object (as opposed to the latest version, the default). * @opt_param string ifMetagenerationMatch Makes the operation conditional on * whether the object's current metageneration matches the given value. * @opt_param string ifGenerationMatch Makes the operation conditional on * whether the object's current generation matches the given value. * @opt_param string ifMetagenerationNotMatch Makes the operation conditional on * whether the object's current metageneration does not match the given value. */ public function delete($bucket, $object, $optParams = array()) { $params = array('bucket' => $bucket, 'object' => $object); $params = array_merge($params, $optParams); return $this->call('delete', array($params)); } /** * Retrieves an object or its metadata. (objects.get) * * @param string $bucket Name of the bucket in which the object resides. * @param string $object Name of the object. * @param array $optParams Optional parameters. * * @opt_param string ifGenerationNotMatch Makes the operation conditional on * whether the object's generation does not match the given value. * @opt_param string generation If present, selects a specific revision of this * object (as opposed to the latest version, the default). * @opt_param string ifMetagenerationMatch Makes the operation conditional on * whether the object's current metageneration matches the given value. * @opt_param string ifGenerationMatch Makes the operation conditional on * whether the object's generation matches the given value. * @opt_param string ifMetagenerationNotMatch Makes the operation conditional on * whether the object's current metageneration does not match the given value. * @opt_param string projection Set of properties to return. Defaults to noAcl. * @return UDP_Google_Service_Storage_StorageObject */ public function get($bucket, $object, $optParams = array()) { $params = array('bucket' => $bucket, 'object' => $object); $params = array_merge($params, $optParams); return $this->call('get', array($params), "UDP_Google_Service_Storage_StorageObject"); } /** * Stores a new object and metadata. (objects.insert) * * @param string $bucket Name of the bucket in which to store the new object. * Overrides the provided object metadata's bucket value, if any. * @param Google_StorageObject $postBody * @param array $optParams Optional parameters. * * @opt_param string predefinedAcl Apply a predefined set of access controls to * this object. * @opt_param string projection Set of properties to return. Defaults to noAcl, * unless the object resource specifies the acl property, when it defaults to * full. * @opt_param string ifGenerationNotMatch Makes the operation conditional on * whether the object's current generation does not match the given value. * @opt_param string ifMetagenerationMatch Makes the operation conditional on * whether the object's current metageneration matches the given value. * @opt_param string contentEncoding If set, sets the contentEncoding property * of the final object to this value. Setting this parameter is equivalent to * setting the contentEncoding metadata property. This can be useful when * uploading an object with uploadType=media to indicate the encoding of the * content being uploaded. * @opt_param string ifGenerationMatch Makes the operation conditional on * whether the object's current generation matches the given value. * @opt_param string ifMetagenerationNotMatch Makes the operation conditional on * whether the object's current metageneration does not match the given value. * @opt_param string name Name of the object. Required when the object metadata * is not otherwise provided. Overrides the object metadata's name value, if * any. * @return UDP_Google_Service_Storage_StorageObject */ public function insert($bucket, UDP_Google_Service_Storage_StorageObject $postBody, $optParams = array()) { $params = array('bucket' => $bucket, 'postBody' => $postBody); $params = array_merge($params, $optParams); return $this->call('insert', array($params), "UDP_Google_Service_Storage_StorageObject"); } /** * Retrieves a list of objects matching the criteria. (objects.listObjects) * * @param string $bucket Name of the bucket in which to look for objects. * @param array $optParams Optional parameters. * * @opt_param string projection Set of properties to return. Defaults to noAcl. * @opt_param bool versions If true, lists all versions of an object as distinct * results. The default is false. For more information, see Object Versioning. * @opt_param string prefix Filter results to objects whose names begin with * this prefix. * @opt_param string maxResults Maximum number of items plus prefixes to return. * As duplicate prefixes are omitted, fewer total results may be returned than * requested. The default value of this parameter is 1,000 items. * @opt_param string pageToken A previously-returned page token representing * part of the larger set of results to view. * @opt_param string delimiter Returns results in a directory-like mode. items * will contain only objects whose names, aside from the prefix, do not contain * delimiter. Objects whose names, aside from the prefix, contain delimiter will * have their name, truncated after the delimiter, returned in prefixes. * Duplicate prefixes are omitted. * @return Google_Service_Storage_Objects */ public function listObjects($bucket, $optParams = array()) { $params = array('bucket' => $bucket); $params = array_merge($params, $optParams); return $this->call('list', array($params), "Google_Service_Storage_Objects"); } /** * Updates an object's metadata. This method supports patch semantics. * (objects.patch) * * @param string $bucket Name of the bucket in which the object resides. * @param string $object Name of the object. * @param Google_StorageObject $postBody * @param array $optParams Optional parameters. * * @opt_param string predefinedAcl Apply a predefined set of access controls to * this object. * @opt_param string ifGenerationNotMatch Makes the operation conditional on * whether the object's current generation does not match the given value. * @opt_param string generation If present, selects a specific revision of this * object (as opposed to the latest version, the default). * @opt_param string ifMetagenerationMatch Makes the operation conditional on * whether the object's current metageneration matches the given value. * @opt_param string ifGenerationMatch Makes the operation conditional on * whether the object's current generation matches the given value. * @opt_param string ifMetagenerationNotMatch Makes the operation conditional on * whether the object's current metageneration does not match the given value. * @opt_param string projection Set of properties to return. Defaults to full. * @return UDP_Google_Service_Storage_StorageObject */ public function patch($bucket, $object, UDP_Google_Service_Storage_StorageObject $postBody, $optParams = array()) { $params = array('bucket' => $bucket, 'object' => $object, 'postBody' => $postBody); $params = array_merge($params, $optParams); return $this->call('patch', array($params), "UDP_Google_Service_Storage_StorageObject"); } /** * Rewrites a source object to a destination object. Optionally overrides * metadata. (objects.rewrite) * * @param string $sourceBucket Name of the bucket in which to find the source * object. * @param string $sourceObject Name of the source object. * @param string $destinationBucket Name of the bucket in which to store the new * object. Overrides the provided object metadata's bucket value, if any. * @param string $destinationObject Name of the new object. Required when the * object metadata is not otherwise provided. Overrides the object metadata's * name value, if any. * @param Google_StorageObject $postBody * @param array $optParams Optional parameters. * * @opt_param string ifSourceGenerationNotMatch Makes the operation conditional * on whether the source object's generation does not match the given value. * @opt_param string ifGenerationNotMatch Makes the operation conditional on * whether the destination object's current generation does not match the given * value. * @opt_param string rewriteToken Include this field (from the previous Rewrite * response) on each Rewrite request after the first one, until the Rewrite * response 'done' flag is true. Calls that provide a rewriteToken can omit all * other request fields, but if included those fields must match the values * provided in the first rewrite request. * @opt_param string ifSourceMetagenerationNotMatch Makes the operation * conditional on whether the source object's current metageneration does not * match the given value. * @opt_param string ifMetagenerationMatch Makes the operation conditional on * whether the destination object's current metageneration matches the given * value. * @opt_param string sourceGeneration If present, selects a specific revision of * the source object (as opposed to the latest version, the default). * @opt_param string destinationPredefinedAcl Apply a predefined set of access * controls to the destination object. * @opt_param string ifSourceGenerationMatch Makes the operation conditional on * whether the source object's generation matches the given value. * @opt_param string maxBytesRewrittenPerCall The maximum number of bytes that * will be rewritten per Rewrite request. Most callers shouldn't need to specify * this parameter - it is primarily in place to support testing. If specified * the value must be an integral multiple of 1 MiB (1048576). Also, this only * applies to requests where the source and destination span locations and/or * storage classes. Finally, this value must not change across Rewrite calls * else you'll get an error that the rewrite token is invalid. * @opt_param string ifSourceMetagenerationMatch Makes the operation conditional * on whether the source object's current metageneration matches the given * value. * @opt_param string ifGenerationMatch Makes the operation conditional on * whether the destination object's current generation matches the given value. * @opt_param string ifMetagenerationNotMatch Makes the operation conditional on * whether the destination object's current metageneration does not match the * given value. * @opt_param string projection Set of properties to return. Defaults to noAcl, * unless the object resource specifies the acl property, when it defaults to * full. * @return Google_Service_Storage_RewriteResponse */ public function rewrite($sourceBucket, $sourceObject, $destinationBucket, $destinationObject, UDP_Google_Service_Storage_StorageObject $postBody, $optParams = array()) { $params = array('sourceBucket' => $sourceBucket, 'sourceObject' => $sourceObject, 'destinationBucket' => $destinationBucket, 'destinationObject' => $destinationObject, 'postBody' => $postBody); $params = array_merge($params, $optParams); return $this->call('rewrite', array($params), "Google_Service_Storage_RewriteResponse"); } /** * Updates an object's metadata. (objects.update) * * @param string $bucket Name of the bucket in which the object resides. * @param string $object Name of the object. * @param Google_StorageObject $postBody * @param array $optParams Optional parameters. * * @opt_param string predefinedAcl Apply a predefined set of access controls to * this object. * @opt_param string ifGenerationNotMatch Makes the operation conditional on * whether the object's current generation does not match the given value. * @opt_param string generation If present, selects a specific revision of this * object (as opposed to the latest version, the default). * @opt_param string ifMetagenerationMatch Makes the operation conditional on * whether the object's current metageneration matches the given value. * @opt_param string ifGenerationMatch Makes the operation conditional on * whether the object's current generation matches the given value. * @opt_param string ifMetagenerationNotMatch Makes the operation conditional on * whether the object's current metageneration does not match the given value. * @opt_param string projection Set of properties to return. Defaults to full. * @return UDP_Google_Service_Storage_StorageObject */ public function update($bucket, $object, UDP_Google_Service_Storage_StorageObject $postBody, $optParams = array()) { $params = array('bucket' => $bucket, 'object' => $object, 'postBody' => $postBody); $params = array_merge($params, $optParams); return $this->call('update', array($params), "UDP_Google_Service_Storage_StorageObject"); } /** * Watch for changes on all objects in a bucket. (objects.watchAll) * * @param string $bucket Name of the bucket in which to look for objects. * @param Google_Channel $postBody * @param array $optParams Optional parameters. * * @opt_param string projection Set of properties to return. Defaults to noAcl. * @opt_param bool versions If true, lists all versions of an object as distinct * results. The default is false. For more information, see Object Versioning. * @opt_param string prefix Filter results to objects whose names begin with * this prefix. * @opt_param string maxResults Maximum number of items plus prefixes to return. * As duplicate prefixes are omitted, fewer total results may be returned than * requested. The default value of this parameter is 1,000 items. * @opt_param string pageToken A previously-returned page token representing * part of the larger set of results to view. * @opt_param string delimiter Returns results in a directory-like mode. items * will contain only objects whose names, aside from the prefix, do not contain * delimiter. Objects whose names, aside from the prefix, contain delimiter will * have their name, truncated after the delimiter, returned in prefixes. * Duplicate prefixes are omitted. * @return Google_Service_Storage_Channel */ public function watchAll($bucket, Google_Service_Storage_Channel $postBody, $optParams = array()) { $params = array('bucket' => $bucket, 'postBody' => $postBody); $params = array_merge($params, $optParams); return $this->call('watchAll', array($params), "Google_Service_Storage_Channel"); } } class UDP_Google_Service_Storage_Bucket extends Google_Collection { protected $collection_key = 'defaultObjectAcl'; protected $internal_gapi_mappings = array( ); protected $aclType = 'Google_Service_Storage_BucketAccessControl'; protected $aclDataType = 'array'; protected $corsType = 'Google_Service_Storage_BucketCors'; protected $corsDataType = 'array'; protected $defaultObjectAclType = 'Google_Service_Storage_ObjectAccessControl'; protected $defaultObjectAclDataType = 'array'; public $etag; public $id; public $kind; protected $lifecycleType = 'Google_Service_Storage_BucketLifecycle'; protected $lifecycleDataType = ''; public $location; protected $loggingType = 'Google_Service_Storage_BucketLogging'; protected $loggingDataType = ''; public $metageneration; public $name; protected $ownerType = 'Google_Service_Storage_BucketOwner'; protected $ownerDataType = ''; public $projectNumber; public $selfLink; public $storageClass; public $timeCreated; protected $versioningType = 'Google_Service_Storage_BucketVersioning'; protected $versioningDataType = ''; protected $websiteType = 'Google_Service_Storage_BucketWebsite'; protected $websiteDataType = ''; public function setAcl($acl) { $this->acl = $acl; } public function getAcl() { return $this->acl; } public function setCors($cors) { $this->cors = $cors; } public function getCors() { return $this->cors; } public function setDefaultObjectAcl($defaultObjectAcl) { $this->defaultObjectAcl = $defaultObjectAcl; } public function getDefaultObjectAcl() { return $this->defaultObjectAcl; } public function setEtag($etag) { $this->etag = $etag; } public function getEtag() { return $this->etag; } public function setId($id) { $this->id = $id; } public function getId() { return $this->id; } public function setKind($kind) { $this->kind = $kind; } public function getKind() { return $this->kind; } public function setLifecycle(Google_Service_Storage_BucketLifecycle $lifecycle) { $this->lifecycle = $lifecycle; } public function getLifecycle() { return $this->lifecycle; } public function setLocation($location) { $this->location = $location; } public function getLocation() { return $this->location; } public function setLogging(Google_Service_Storage_BucketLogging $logging) { $this->logging = $logging; } public function getLogging() { return $this->logging; } public function setMetageneration($metageneration) { $this->metageneration = $metageneration; } public function getMetageneration() { return $this->metageneration; } public function setName($name) { $this->name = $name; } public function getName() { return $this->name; } public function setOwner(Google_Service_Storage_BucketOwner $owner) { $this->owner = $owner; } public function getOwner() { return $this->owner; } public function setProjectNumber($projectNumber) { $this->projectNumber = $projectNumber; } public function getProjectNumber() { return $this->projectNumber; } public function setSelfLink($selfLink) { $this->selfLink = $selfLink; } public function getSelfLink() { return $this->selfLink; } public function setStorageClass($storageClass) { $this->storageClass = $storageClass; } public function getStorageClass() { return $this->storageClass; } public function setTimeCreated($timeCreated) { $this->timeCreated = $timeCreated; } public function getTimeCreated() { return $this->timeCreated; } public function setVersioning(Google_Service_Storage_BucketVersioning $versioning) { $this->versioning = $versioning; } public function getVersioning() { return $this->versioning; } public function setWebsite(Google_Service_Storage_BucketWebsite $website) { $this->website = $website; } public function getWebsite() { return $this->website; } } class Google_Service_Storage_BucketAccessControl extends Google_Model { protected $internal_gapi_mappings = array( ); public $bucket; public $domain; public $email; public $entity; public $entityId; public $etag; public $id; public $kind; protected $projectTeamType = 'Google_Service_Storage_BucketAccessControlProjectTeam'; protected $projectTeamDataType = ''; public $role; public $selfLink; public function setBucket($bucket) { $this->bucket = $bucket; } public function getBucket() { return $this->bucket; } public function setDomain($domain) { $this->domain = $domain; } public function getDomain() { return $this->domain; } public function setEmail($email) { $this->email = $email; } public function getEmail() { return $this->email; } public function setEntity($entity) { $this->entity = $entity; } public function getEntity() { return $this->entity; } public function setEntityId($entityId) { $this->entityId = $entityId; } public function getEntityId() { return $this->entityId; } public function setEtag($etag) { $this->etag = $etag; } public function getEtag() { return $this->etag; } public function setId($id) { $this->id = $id; } public function getId() { return $this->id; } public function setKind($kind) { $this->kind = $kind; } public function getKind() { return $this->kind; } public function setProjectTeam(Google_Service_Storage_BucketAccessControlProjectTeam $projectTeam) { $this->projectTeam = $projectTeam; } public function getProjectTeam() { return $this->projectTeam; } public function setRole($role) { $this->role = $role; } public function getRole() { return $this->role; } public function setSelfLink($selfLink) { $this->selfLink = $selfLink; } public function getSelfLink() { return $this->selfLink; } } class Google_Service_Storage_BucketAccessControlProjectTeam extends Google_Model { protected $internal_gapi_mappings = array( ); public $projectNumber; public $team; public function setProjectNumber($projectNumber) { $this->projectNumber = $projectNumber; } public function getProjectNumber() { return $this->projectNumber; } public function setTeam($team) { $this->team = $team; } public function getTeam() { return $this->team; } } class Google_Service_Storage_BucketAccessControls extends Google_Collection { protected $collection_key = 'items'; protected $internal_gapi_mappings = array( ); protected $itemsType = 'Google_Service_Storage_BucketAccessControl'; protected $itemsDataType = 'array'; public $kind; public function setItems($items) { $this->items = $items; } public function getItems() { return $this->items; } public function setKind($kind) { $this->kind = $kind; } public function getKind() { return $this->kind; } } class Google_Service_Storage_BucketCors extends Google_Collection { protected $collection_key = 'responseHeader'; protected $internal_gapi_mappings = array( ); public $maxAgeSeconds; public $method; public $origin; public $responseHeader; public function setMaxAgeSeconds($maxAgeSeconds) { $this->maxAgeSeconds = $maxAgeSeconds; } public function getMaxAgeSeconds() { return $this->maxAgeSeconds; } public function setMethod($method) { $this->method = $method; } public function getMethod() { return $this->method; } public function setOrigin($origin) { $this->origin = $origin; } public function getOrigin() { return $this->origin; } public function setResponseHeader($responseHeader) { $this->responseHeader = $responseHeader; } public function getResponseHeader() { return $this->responseHeader; } } class Google_Service_Storage_BucketLifecycle extends Google_Collection { protected $collection_key = 'rule'; protected $internal_gapi_mappings = array( ); protected $ruleType = 'Google_Service_Storage_BucketLifecycleRule'; protected $ruleDataType = 'array'; public function setRule($rule) { $this->rule = $rule; } public function getRule() { return $this->rule; } } class Google_Service_Storage_BucketLifecycleRule extends Google_Model { protected $internal_gapi_mappings = array( ); protected $actionType = 'Google_Service_Storage_BucketLifecycleRuleAction'; protected $actionDataType = ''; protected $conditionType = 'Google_Service_Storage_BucketLifecycleRuleCondition'; protected $conditionDataType = ''; public function setAction(Google_Service_Storage_BucketLifecycleRuleAction $action) { $this->action = $action; } public function getAction() { return $this->action; } public function setCondition(Google_Service_Storage_BucketLifecycleRuleCondition $condition) { $this->condition = $condition; } public function getCondition() { return $this->condition; } } class Google_Service_Storage_BucketLifecycleRuleAction extends Google_Model { protected $internal_gapi_mappings = array( ); public $type; public function setType($type) { $this->type = $type; } public function getType() { return $this->type; } } class Google_Service_Storage_BucketLifecycleRuleCondition extends Google_Model { protected $internal_gapi_mappings = array( ); public $age; public $createdBefore; public $isLive; public $numNewerVersions; public function setAge($age) { $this->age = $age; } public function getAge() { return $this->age; } public function setCreatedBefore($createdBefore) { $this->createdBefore = $createdBefore; } public function getCreatedBefore() { return $this->createdBefore; } public function setIsLive($isLive) { $this->isLive = $isLive; } public function getIsLive() { return $this->isLive; } public function setNumNewerVersions($numNewerVersions) { $this->numNewerVersions = $numNewerVersions; } public function getNumNewerVersions() { return $this->numNewerVersions; } } class Google_Service_Storage_BucketLogging extends Google_Model { protected $internal_gapi_mappings = array( ); public $logBucket; public $logObjectPrefix; public function setLogBucket($logBucket) { $this->logBucket = $logBucket; } public function getLogBucket() { return $this->logBucket; } public function setLogObjectPrefix($logObjectPrefix) { $this->logObjectPrefix = $logObjectPrefix; } public function getLogObjectPrefix() { return $this->logObjectPrefix; } } class Google_Service_Storage_BucketOwner extends Google_Model { protected $internal_gapi_mappings = array( ); public $entity; public $entityId; public function setEntity($entity) { $this->entity = $entity; } public function getEntity() { return $this->entity; } public function setEntityId($entityId) { $this->entityId = $entityId; } public function getEntityId() { return $this->entityId; } } class Google_Service_Storage_BucketVersioning extends Google_Model { protected $internal_gapi_mappings = array( ); public $enabled; public function setEnabled($enabled) { $this->enabled = $enabled; } public function getEnabled() { return $this->enabled; } } class Google_Service_Storage_BucketWebsite extends Google_Model { protected $internal_gapi_mappings = array( ); public $mainPageSuffix; public $notFoundPage; public function setMainPageSuffix($mainPageSuffix) { $this->mainPageSuffix = $mainPageSuffix; } public function getMainPageSuffix() { return $this->mainPageSuffix; } public function setNotFoundPage($notFoundPage) { $this->notFoundPage = $notFoundPage; } public function getNotFoundPage() { return $this->notFoundPage; } } class Google_Service_Storage_Buckets extends Google_Collection { protected $collection_key = 'items'; protected $internal_gapi_mappings = array( ); protected $itemsType = 'UDP_Google_Service_Storage_Bucket'; protected $itemsDataType = 'array'; public $kind; public $nextPageToken; public function setItems($items) { $this->items = $items; } public function getItems() { return $this->items; } public function setKind($kind) { $this->kind = $kind; } public function getKind() { return $this->kind; } public function setNextPageToken($nextPageToken) { $this->nextPageToken = $nextPageToken; } public function getNextPageToken() { return $this->nextPageToken; } } class Google_Service_Storage_Channel extends Google_Model { protected $internal_gapi_mappings = array( ); public $address; public $expiration; public $id; public $kind; public $params; public $payload; public $resourceId; public $resourceUri; public $token; public $type; public function setAddress($address) { $this->address = $address; } public function getAddress() { return $this->address; } public function setExpiration($expiration) { $this->expiration = $expiration; } public function getExpiration() { return $this->expiration; } public function setId($id) { $this->id = $id; } public function getId() { return $this->id; } public function setKind($kind) { $this->kind = $kind; } public function getKind() { return $this->kind; } public function setParams($params) { $this->params = $params; } public function getParams() { return $this->params; } public function setPayload($payload) { $this->payload = $payload; } public function getPayload() { return $this->payload; } public function setResourceId($resourceId) { $this->resourceId = $resourceId; } public function getResourceId() { return $this->resourceId; } public function setResourceUri($resourceUri) { $this->resourceUri = $resourceUri; } public function getResourceUri() { return $this->resourceUri; } public function setToken($token) { $this->token = $token; } public function getToken() { return $this->token; } public function setType($type) { $this->type = $type; } public function getType() { return $this->type; } } class Google_Service_Storage_ChannelParams extends Google_Model { } class Google_Service_Storage_ComposeRequest extends Google_Collection { protected $collection_key = 'sourceObjects'; protected $internal_gapi_mappings = array( ); protected $destinationType = 'UDP_Google_Service_Storage_StorageObject'; protected $destinationDataType = ''; public $kind; protected $sourceObjectsType = 'Google_Service_Storage_ComposeRequestSourceObjects'; protected $sourceObjectsDataType = 'array'; public function setDestination(UDP_Google_Service_Storage_StorageObject $destination) { $this->destination = $destination; } public function getDestination() { return $this->destination; } public function setKind($kind) { $this->kind = $kind; } public function getKind() { return $this->kind; } public function setSourceObjects($sourceObjects) { $this->sourceObjects = $sourceObjects; } public function getSourceObjects() { return $this->sourceObjects; } } class Google_Service_Storage_ComposeRequestSourceObjects extends Google_Model { protected $internal_gapi_mappings = array( ); public $generation; public $name; protected $objectPreconditionsType = 'Google_Service_Storage_ComposeRequestSourceObjectsObjectPreconditions'; protected $objectPreconditionsDataType = ''; public function setGeneration($generation) { $this->generation = $generation; } public function getGeneration() { return $this->generation; } public function setName($name) { $this->name = $name; } public function getName() { return $this->name; } public function setObjectPreconditions(Google_Service_Storage_ComposeRequestSourceObjectsObjectPreconditions $objectPreconditions) { $this->objectPreconditions = $objectPreconditions; } public function getObjectPreconditions() { return $this->objectPreconditions; } } class Google_Service_Storage_ComposeRequestSourceObjectsObjectPreconditions extends Google_Model { protected $internal_gapi_mappings = array( ); public $ifGenerationMatch; public function setIfGenerationMatch($ifGenerationMatch) { $this->ifGenerationMatch = $ifGenerationMatch; } public function getIfGenerationMatch() { return $this->ifGenerationMatch; } } class Google_Service_Storage_ObjectAccessControl extends Google_Model { protected $internal_gapi_mappings = array( ); public $bucket; public $domain; public $email; public $entity; public $entityId; public $etag; public $generation; public $id; public $kind; public $object; protected $projectTeamType = 'Google_Service_Storage_ObjectAccessControlProjectTeam'; protected $projectTeamDataType = ''; public $role; public $selfLink; public function setBucket($bucket) { $this->bucket = $bucket; } public function getBucket() { return $this->bucket; } public function setDomain($domain) { $this->domain = $domain; } public function getDomain() { return $this->domain; } public function setEmail($email) { $this->email = $email; } public function getEmail() { return $this->email; } public function setEntity($entity) { $this->entity = $entity; } public function getEntity() { return $this->entity; } public function setEntityId($entityId) { $this->entityId = $entityId; } public function getEntityId() { return $this->entityId; } public function setEtag($etag) { $this->etag = $etag; } public function getEtag() { return $this->etag; } public function setGeneration($generation) { $this->generation = $generation; } public function getGeneration() { return $this->generation; } public function setId($id) { $this->id = $id; } public function getId() { return $this->id; } public function setKind($kind) { $this->kind = $kind; } public function getKind() { return $this->kind; } public function setObject($object) { $this->object = $object; } public function getObject() { return $this->object; } public function setProjectTeam(Google_Service_Storage_ObjectAccessControlProjectTeam $projectTeam) { $this->projectTeam = $projectTeam; } public function getProjectTeam() { return $this->projectTeam; } public function setRole($role) { $this->role = $role; } public function getRole() { return $this->role; } public function setSelfLink($selfLink) { $this->selfLink = $selfLink; } public function getSelfLink() { return $this->selfLink; } } class Google_Service_Storage_ObjectAccessControlProjectTeam extends Google_Model { protected $internal_gapi_mappings = array( ); public $projectNumber; public $team; public function setProjectNumber($projectNumber) { $this->projectNumber = $projectNumber; } public function getProjectNumber() { return $this->projectNumber; } public function setTeam($team) { $this->team = $team; } public function getTeam() { return $this->team; } } class Google_Service_Storage_ObjectAccessControls extends Google_Collection { protected $collection_key = 'items'; protected $internal_gapi_mappings = array( ); public $items; public $kind; public function setItems($items) { $this->items = $items; } public function getItems() { return $this->items; } public function setKind($kind) { $this->kind = $kind; } public function getKind() { return $this->kind; } } class Google_Service_Storage_Objects extends Google_Collection { protected $collection_key = 'prefixes'; protected $internal_gapi_mappings = array( ); protected $itemsType = 'UDP_Google_Service_Storage_StorageObject'; protected $itemsDataType = 'array'; public $kind; public $nextPageToken; public $prefixes; public function setItems($items) { $this->items = $items; } public function getItems() { return $this->items; } public function setKind($kind) { $this->kind = $kind; } public function getKind() { return $this->kind; } public function setNextPageToken($nextPageToken) { $this->nextPageToken = $nextPageToken; } public function getNextPageToken() { return $this->nextPageToken; } public function setPrefixes($prefixes) { $this->prefixes = $prefixes; } public function getPrefixes() { return $this->prefixes; } } class Google_Service_Storage_RewriteResponse extends Google_Model { protected $internal_gapi_mappings = array( ); public $done; public $kind; public $objectSize; protected $resourceType = 'UDP_Google_Service_Storage_StorageObject'; protected $resourceDataType = ''; public $rewriteToken; public $totalBytesRewritten; public function setDone($done) { $this->done = $done; } public function getDone() { return $this->done; } public function setKind($kind) { $this->kind = $kind; } public function getKind() { return $this->kind; } public function setObjectSize($objectSize) { $this->objectSize = $objectSize; } public function getObjectSize() { return $this->objectSize; } public function setResource(UDP_Google_Service_Storage_StorageObject $resource) { $this->resource = $resource; } public function getResource() { return $this->resource; } public function setRewriteToken($rewriteToken) { $this->rewriteToken = $rewriteToken; } public function getRewriteToken() { return $this->rewriteToken; } public function setTotalBytesRewritten($totalBytesRewritten) { $this->totalBytesRewritten = $totalBytesRewritten; } public function getTotalBytesRewritten() { return $this->totalBytesRewritten; } } class UDP_Google_Service_Storage_StorageObject extends Google_Collection { protected $collection_key = 'acl'; protected $internal_gapi_mappings = array( ); protected $aclType = 'Google_Service_Storage_ObjectAccessControl'; protected $aclDataType = 'array'; public $bucket; public $cacheControl; public $componentCount; public $contentDisposition; public $contentEncoding; public $contentLanguage; public $contentType; public $crc32c; public $etag; public $generation; public $id; public $kind; public $md5Hash; public $mediaLink; public $metadata; public $metageneration; public $name; protected $ownerType = 'Google_Service_Storage_StorageObjectOwner'; protected $ownerDataType = ''; public $selfLink; public $size; public $storageClass; public $timeDeleted; public $updated; public function setAcl($acl) { $this->acl = $acl; } public function getAcl() { return $this->acl; } public function setBucket($bucket) { $this->bucket = $bucket; } public function getBucket() { return $this->bucket; } public function setCacheControl($cacheControl) { $this->cacheControl = $cacheControl; } public function getCacheControl() { return $this->cacheControl; } public function setComponentCount($componentCount) { $this->componentCount = $componentCount; } public function getComponentCount() { return $this->componentCount; } public function setContentDisposition($contentDisposition) { $this->contentDisposition = $contentDisposition; } public function getContentDisposition() { return $this->contentDisposition; } public function setContentEncoding($contentEncoding) { $this->contentEncoding = $contentEncoding; } public function getContentEncoding() { return $this->contentEncoding; } public function setContentLanguage($contentLanguage) { $this->contentLanguage = $contentLanguage; } public function getContentLanguage() { return $this->contentLanguage; } public function setContentType($contentType) { $this->contentType = $contentType; } public function getContentType() { return $this->contentType; } public function setCrc32c($crc32c) { $this->crc32c = $crc32c; } public function getCrc32c() { return $this->crc32c; } public function setEtag($etag) { $this->etag = $etag; } public function getEtag() { return $this->etag; } public function setGeneration($generation) { $this->generation = $generation; } public function getGeneration() { return $this->generation; } public function setId($id) { $this->id = $id; } public function getId() { return $this->id; } public function setKind($kind) { $this->kind = $kind; } public function getKind() { return $this->kind; } public function setMd5Hash($md5Hash) { $this->md5Hash = $md5Hash; } public function getMd5Hash() { return $this->md5Hash; } public function setMediaLink($mediaLink) { $this->mediaLink = $mediaLink; } public function getMediaLink() { return $this->mediaLink; } public function setMetadata($metadata) { $this->metadata = $metadata; } public function getMetadata() { return $this->metadata; } public function setMetageneration($metageneration) { $this->metageneration = $metageneration; } public function getMetageneration() { return $this->metageneration; } public function setName($name) { $this->name = $name; } public function getName() { return $this->name; } public function setOwner(Google_Service_Storage_StorageObjectOwner $owner) { $this->owner = $owner; } public function getOwner() { return $this->owner; } public function setSelfLink($selfLink) { $this->selfLink = $selfLink; } public function getSelfLink() { return $this->selfLink; } public function setSize($size) { $this->size = $size; } public function getSize() { return $this->size; } public function setStorageClass($storageClass) { $this->storageClass = $storageClass; } public function getStorageClass() { return $this->storageClass; } public function setTimeDeleted($timeDeleted) { $this->timeDeleted = $timeDeleted; } public function getTimeDeleted() { return $this->timeDeleted; } public function setUpdated($updated) { $this->updated = $updated; } public function getUpdated() { return $this->updated; } } class Google_Service_Storage_StorageObjectMetadata extends Google_Model { } class Google_Service_Storage_StorageObjectOwner extends Google_Model { protected $internal_gapi_mappings = array( ); public $entity; public $entityId; public function setEntity($entity) { $this->entity = $entity; } public function getEntity() { return $this->entity; } public function setEntityId($entityId) { $this->entityId = $entityId; } public function getEntityId() { return $this->entityId; } } includes/Google/Service/Exception.php000064400000005314152214270100013632 0ustar00= 0) { parent::__construct($message, $code, $previous); } else { parent::__construct($message, $code); } $this->errors = $errors; if (is_array($retryMap)) { $this->retryMap = $retryMap; } } /** * An example of the possible errors returned. * * { * "domain": "global", * "reason": "authError", * "message": "Invalid Credentials", * "locationType": "header", * "location": "Authorization", * } * * @return [{string, string}] List of errors return in an HTTP response or []. */ public function getErrors() { return $this->errors; } /** * Gets the number of times the associated task can be retried. * * NOTE: -1 is returned if the task can be retried indefinitely * * @return integer */ public function allowedRetries() { if (isset($this->retryMap[$this->code])) { return $this->retryMap[$this->code]; } $errors = $this->getErrors(); if (!empty($errors) && isset($errors[0]['reason']) && isset($this->retryMap[$errors[0]['reason']])) { return $this->retryMap[$errors[0]['reason']]; } return 0; } } includes/Google/Service/Datastore.php000064400000110124152214270100013616 0ustar00 * API for accessing Google Cloud Datastore.

* *

* For more information about this service, see the API * Documentation *

* * @author Google, Inc. */ class Google_Service_Datastore extends UDP_Google_Service { /** View and manage your data across Google Cloud Platform services. */ const CLOUD_PLATFORM = "https://www.googleapis.com/auth/cloud-platform"; /** View and manage your Google Cloud Datastore data. */ const DATASTORE = "https://www.googleapis.com/auth/datastore"; /** View your email address. */ const USERINFO_EMAIL = "https://www.googleapis.com/auth/userinfo.email"; public $datasets; /** * Constructs the internal representation of the Datastore service. * * @param Google_Client $client */ public function __construct(UDP_Google_Client $client) { parent::__construct($client); $this->servicePath = 'datastore/v1beta2/datasets/'; $this->version = 'v1beta2'; $this->serviceName = 'datastore'; $this->datasets = new Google_Service_Datastore_Datasets_Resource( $this, $this->serviceName, 'datasets', array( 'methods' => array( 'allocateIds' => array( 'path' => '{datasetId}/allocateIds', 'httpMethod' => 'POST', 'parameters' => array( 'datasetId' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), ), ),'beginTransaction' => array( 'path' => '{datasetId}/beginTransaction', 'httpMethod' => 'POST', 'parameters' => array( 'datasetId' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), ), ),'commit' => array( 'path' => '{datasetId}/commit', 'httpMethod' => 'POST', 'parameters' => array( 'datasetId' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), ), ),'lookup' => array( 'path' => '{datasetId}/lookup', 'httpMethod' => 'POST', 'parameters' => array( 'datasetId' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), ), ),'rollback' => array( 'path' => '{datasetId}/rollback', 'httpMethod' => 'POST', 'parameters' => array( 'datasetId' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), ), ),'runQuery' => array( 'path' => '{datasetId}/runQuery', 'httpMethod' => 'POST', 'parameters' => array( 'datasetId' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), ), ), ) ) ); } } /** * The "datasets" collection of methods. * Typical usage is: * * $datastoreService = new Google_Service_Datastore(...); * $datasets = $datastoreService->datasets; * */ class Google_Service_Datastore_Datasets_Resource extends UDP_Google_Service_Resource { /** * Allocate IDs for incomplete keys (useful for referencing an entity before it * is inserted). (datasets.allocateIds) * * @param string $datasetId Identifies the dataset. * @param Google_AllocateIdsRequest $postBody * @param array $optParams Optional parameters. * @return Google_Service_Datastore_AllocateIdsResponse */ public function allocateIds($datasetId, Google_Service_Datastore_AllocateIdsRequest $postBody, $optParams = array()) { $params = array('datasetId' => $datasetId, 'postBody' => $postBody); $params = array_merge($params, $optParams); return $this->call('allocateIds', array($params), "Google_Service_Datastore_AllocateIdsResponse"); } /** * Begin a new transaction. (datasets.beginTransaction) * * @param string $datasetId Identifies the dataset. * @param Google_BeginTransactionRequest $postBody * @param array $optParams Optional parameters. * @return Google_Service_Datastore_BeginTransactionResponse */ public function beginTransaction($datasetId, Google_Service_Datastore_BeginTransactionRequest $postBody, $optParams = array()) { $params = array('datasetId' => $datasetId, 'postBody' => $postBody); $params = array_merge($params, $optParams); return $this->call('beginTransaction', array($params), "Google_Service_Datastore_BeginTransactionResponse"); } /** * Commit a transaction, optionally creating, deleting or modifying some * entities. (datasets.commit) * * @param string $datasetId Identifies the dataset. * @param Google_CommitRequest $postBody * @param array $optParams Optional parameters. * @return Google_Service_Datastore_CommitResponse */ public function commit($datasetId, Google_Service_Datastore_CommitRequest $postBody, $optParams = array()) { $params = array('datasetId' => $datasetId, 'postBody' => $postBody); $params = array_merge($params, $optParams); return $this->call('commit', array($params), "Google_Service_Datastore_CommitResponse"); } /** * Look up some entities by key. (datasets.lookup) * * @param string $datasetId Identifies the dataset. * @param Google_LookupRequest $postBody * @param array $optParams Optional parameters. * @return Google_Service_Datastore_LookupResponse */ public function lookup($datasetId, Google_Service_Datastore_LookupRequest $postBody, $optParams = array()) { $params = array('datasetId' => $datasetId, 'postBody' => $postBody); $params = array_merge($params, $optParams); return $this->call('lookup', array($params), "Google_Service_Datastore_LookupResponse"); } /** * Roll back a transaction. (datasets.rollback) * * @param string $datasetId Identifies the dataset. * @param Google_RollbackRequest $postBody * @param array $optParams Optional parameters. * @return Google_Service_Datastore_RollbackResponse */ public function rollback($datasetId, Google_Service_Datastore_RollbackRequest $postBody, $optParams = array()) { $params = array('datasetId' => $datasetId, 'postBody' => $postBody); $params = array_merge($params, $optParams); return $this->call('rollback', array($params), "Google_Service_Datastore_RollbackResponse"); } /** * Query for entities. (datasets.runQuery) * * @param string $datasetId Identifies the dataset. * @param Google_RunQueryRequest $postBody * @param array $optParams Optional parameters. * @return Google_Service_Datastore_RunQueryResponse */ public function runQuery($datasetId, Google_Service_Datastore_RunQueryRequest $postBody, $optParams = array()) { $params = array('datasetId' => $datasetId, 'postBody' => $postBody); $params = array_merge($params, $optParams); return $this->call('runQuery', array($params), "Google_Service_Datastore_RunQueryResponse"); } } class Google_Service_Datastore_AllocateIdsRequest extends Google_Collection { protected $collection_key = 'keys'; protected $internal_gapi_mappings = array( ); protected $keysType = 'Google_Service_Datastore_Key'; protected $keysDataType = 'array'; public function setKeys($keys) { $this->keys = $keys; } public function getKeys() { return $this->keys; } } class Google_Service_Datastore_AllocateIdsResponse extends Google_Collection { protected $collection_key = 'keys'; protected $internal_gapi_mappings = array( ); protected $headerType = 'Google_Service_Datastore_ResponseHeader'; protected $headerDataType = ''; protected $keysType = 'Google_Service_Datastore_Key'; protected $keysDataType = 'array'; public function setHeader(Google_Service_Datastore_ResponseHeader $header) { $this->header = $header; } public function getHeader() { return $this->header; } public function setKeys($keys) { $this->keys = $keys; } public function getKeys() { return $this->keys; } } class Google_Service_Datastore_BeginTransactionRequest extends Google_Model { protected $internal_gapi_mappings = array( ); public $isolationLevel; public function setIsolationLevel($isolationLevel) { $this->isolationLevel = $isolationLevel; } public function getIsolationLevel() { return $this->isolationLevel; } } class Google_Service_Datastore_BeginTransactionResponse extends Google_Model { protected $internal_gapi_mappings = array( ); protected $headerType = 'Google_Service_Datastore_ResponseHeader'; protected $headerDataType = ''; public $transaction; public function setHeader(Google_Service_Datastore_ResponseHeader $header) { $this->header = $header; } public function getHeader() { return $this->header; } public function setTransaction($transaction) { $this->transaction = $transaction; } public function getTransaction() { return $this->transaction; } } class Google_Service_Datastore_CommitRequest extends Google_Model { protected $internal_gapi_mappings = array( ); public $ignoreReadOnly; public $mode; protected $mutationType = 'Google_Service_Datastore_Mutation'; protected $mutationDataType = ''; public $transaction; public function setIgnoreReadOnly($ignoreReadOnly) { $this->ignoreReadOnly = $ignoreReadOnly; } public function getIgnoreReadOnly() { return $this->ignoreReadOnly; } public function setMode($mode) { $this->mode = $mode; } public function getMode() { return $this->mode; } public function setMutation(Google_Service_Datastore_Mutation $mutation) { $this->mutation = $mutation; } public function getMutation() { return $this->mutation; } public function setTransaction($transaction) { $this->transaction = $transaction; } public function getTransaction() { return $this->transaction; } } class Google_Service_Datastore_CommitResponse extends Google_Model { protected $internal_gapi_mappings = array( ); protected $headerType = 'Google_Service_Datastore_ResponseHeader'; protected $headerDataType = ''; protected $mutationResultType = 'Google_Service_Datastore_MutationResult'; protected $mutationResultDataType = ''; public function setHeader(Google_Service_Datastore_ResponseHeader $header) { $this->header = $header; } public function getHeader() { return $this->header; } public function setMutationResult(Google_Service_Datastore_MutationResult $mutationResult) { $this->mutationResult = $mutationResult; } public function getMutationResult() { return $this->mutationResult; } } class Google_Service_Datastore_CompositeFilter extends Google_Collection { protected $collection_key = 'filters'; protected $internal_gapi_mappings = array( ); protected $filtersType = 'Google_Service_Datastore_Filter'; protected $filtersDataType = 'array'; public $operator; public function setFilters($filters) { $this->filters = $filters; } public function getFilters() { return $this->filters; } public function setOperator($operator) { $this->operator = $operator; } public function getOperator() { return $this->operator; } } class Google_Service_Datastore_Entity extends Google_Model { protected $internal_gapi_mappings = array( ); protected $keyType = 'Google_Service_Datastore_Key'; protected $keyDataType = ''; protected $propertiesType = 'Google_Service_Datastore_Property'; protected $propertiesDataType = 'map'; public function setKey(Google_Service_Datastore_Key $key) { $this->key = $key; } public function getKey() { return $this->key; } public function setProperties($properties) { $this->properties = $properties; } public function getProperties() { return $this->properties; } } class Google_Service_Datastore_EntityProperties extends Google_Model { } class Google_Service_Datastore_EntityResult extends Google_Model { protected $internal_gapi_mappings = array( ); protected $entityType = 'Google_Service_Datastore_Entity'; protected $entityDataType = ''; public function setEntity(Google_Service_Datastore_Entity $entity) { $this->entity = $entity; } public function getEntity() { return $this->entity; } } class Google_Service_Datastore_Filter extends Google_Model { protected $internal_gapi_mappings = array( ); protected $compositeFilterType = 'Google_Service_Datastore_CompositeFilter'; protected $compositeFilterDataType = ''; protected $propertyFilterType = 'Google_Service_Datastore_PropertyFilter'; protected $propertyFilterDataType = ''; public function setCompositeFilter(Google_Service_Datastore_CompositeFilter $compositeFilter) { $this->compositeFilter = $compositeFilter; } public function getCompositeFilter() { return $this->compositeFilter; } public function setPropertyFilter(Google_Service_Datastore_PropertyFilter $propertyFilter) { $this->propertyFilter = $propertyFilter; } public function getPropertyFilter() { return $this->propertyFilter; } } class Google_Service_Datastore_GqlQuery extends Google_Collection { protected $collection_key = 'numberArgs'; protected $internal_gapi_mappings = array( ); public $allowLiteral; protected $nameArgsType = 'Google_Service_Datastore_GqlQueryArg'; protected $nameArgsDataType = 'array'; protected $numberArgsType = 'Google_Service_Datastore_GqlQueryArg'; protected $numberArgsDataType = 'array'; public $queryString; public function setAllowLiteral($allowLiteral) { $this->allowLiteral = $allowLiteral; } public function getAllowLiteral() { return $this->allowLiteral; } public function setNameArgs($nameArgs) { $this->nameArgs = $nameArgs; } public function getNameArgs() { return $this->nameArgs; } public function setNumberArgs($numberArgs) { $this->numberArgs = $numberArgs; } public function getNumberArgs() { return $this->numberArgs; } public function setQueryString($queryString) { $this->queryString = $queryString; } public function getQueryString() { return $this->queryString; } } class Google_Service_Datastore_GqlQueryArg extends Google_Model { protected $internal_gapi_mappings = array( ); public $cursor; public $name; protected $valueType = 'Google_Service_Datastore_Value'; protected $valueDataType = ''; public function setCursor($cursor) { $this->cursor = $cursor; } public function getCursor() { return $this->cursor; } public function setName($name) { $this->name = $name; } public function getName() { return $this->name; } public function setValue(Google_Service_Datastore_Value $value) { $this->value = $value; } public function getValue() { return $this->value; } } class Google_Service_Datastore_Key extends Google_Collection { protected $collection_key = 'path'; protected $internal_gapi_mappings = array( ); protected $partitionIdType = 'Google_Service_Datastore_PartitionId'; protected $partitionIdDataType = ''; protected $pathType = 'Google_Service_Datastore_KeyPathElement'; protected $pathDataType = 'array'; public function setPartitionId(Google_Service_Datastore_PartitionId $partitionId) { $this->partitionId = $partitionId; } public function getPartitionId() { return $this->partitionId; } public function setPath($path) { $this->path = $path; } public function getPath() { return $this->path; } } class Google_Service_Datastore_KeyPathElement extends Google_Model { protected $internal_gapi_mappings = array( ); public $id; public $kind; public $name; public function setId($id) { $this->id = $id; } public function getId() { return $this->id; } public function setKind($kind) { $this->kind = $kind; } public function getKind() { return $this->kind; } public function setName($name) { $this->name = $name; } public function getName() { return $this->name; } } class Google_Service_Datastore_KindExpression extends Google_Model { protected $internal_gapi_mappings = array( ); public $name; public function setName($name) { $this->name = $name; } public function getName() { return $this->name; } } class Google_Service_Datastore_LookupRequest extends Google_Collection { protected $collection_key = 'keys'; protected $internal_gapi_mappings = array( ); protected $keysType = 'Google_Service_Datastore_Key'; protected $keysDataType = 'array'; protected $readOptionsType = 'Google_Service_Datastore_ReadOptions'; protected $readOptionsDataType = ''; public function setKeys($keys) { $this->keys = $keys; } public function getKeys() { return $this->keys; } public function setReadOptions(Google_Service_Datastore_ReadOptions $readOptions) { $this->readOptions = $readOptions; } public function getReadOptions() { return $this->readOptions; } } class Google_Service_Datastore_LookupResponse extends Google_Collection { protected $collection_key = 'missing'; protected $internal_gapi_mappings = array( ); protected $deferredType = 'Google_Service_Datastore_Key'; protected $deferredDataType = 'array'; protected $foundType = 'Google_Service_Datastore_EntityResult'; protected $foundDataType = 'array'; protected $headerType = 'Google_Service_Datastore_ResponseHeader'; protected $headerDataType = ''; protected $missingType = 'Google_Service_Datastore_EntityResult'; protected $missingDataType = 'array'; public function setDeferred($deferred) { $this->deferred = $deferred; } public function getDeferred() { return $this->deferred; } public function setFound($found) { $this->found = $found; } public function getFound() { return $this->found; } public function setHeader(Google_Service_Datastore_ResponseHeader $header) { $this->header = $header; } public function getHeader() { return $this->header; } public function setMissing($missing) { $this->missing = $missing; } public function getMissing() { return $this->missing; } } class Google_Service_Datastore_Mutation extends Google_Collection { protected $collection_key = 'upsert'; protected $internal_gapi_mappings = array( ); protected $deleteType = 'Google_Service_Datastore_Key'; protected $deleteDataType = 'array'; public $force; protected $insertType = 'Google_Service_Datastore_Entity'; protected $insertDataType = 'array'; protected $insertAutoIdType = 'Google_Service_Datastore_Entity'; protected $insertAutoIdDataType = 'array'; protected $updateType = 'Google_Service_Datastore_Entity'; protected $updateDataType = 'array'; protected $upsertType = 'Google_Service_Datastore_Entity'; protected $upsertDataType = 'array'; public function setDelete($delete) { $this->delete = $delete; } public function getDelete() { return $this->delete; } public function setForce($force) { $this->force = $force; } public function getForce() { return $this->force; } public function setInsert($insert) { $this->insert = $insert; } public function getInsert() { return $this->insert; } public function setInsertAutoId($insertAutoId) { $this->insertAutoId = $insertAutoId; } public function getInsertAutoId() { return $this->insertAutoId; } public function setUpdate($update) { $this->update = $update; } public function getUpdate() { return $this->update; } public function setUpsert($upsert) { $this->upsert = $upsert; } public function getUpsert() { return $this->upsert; } } class Google_Service_Datastore_MutationResult extends Google_Collection { protected $collection_key = 'insertAutoIdKeys'; protected $internal_gapi_mappings = array( ); public $indexUpdates; protected $insertAutoIdKeysType = 'Google_Service_Datastore_Key'; protected $insertAutoIdKeysDataType = 'array'; public function setIndexUpdates($indexUpdates) { $this->indexUpdates = $indexUpdates; } public function getIndexUpdates() { return $this->indexUpdates; } public function setInsertAutoIdKeys($insertAutoIdKeys) { $this->insertAutoIdKeys = $insertAutoIdKeys; } public function getInsertAutoIdKeys() { return $this->insertAutoIdKeys; } } class Google_Service_Datastore_PartitionId extends Google_Model { protected $internal_gapi_mappings = array( ); public $datasetId; public $namespace; public function setDatasetId($datasetId) { $this->datasetId = $datasetId; } public function getDatasetId() { return $this->datasetId; } public function setNamespace($namespace) { $this->namespace = $namespace; } public function getNamespace() { return $this->namespace; } } class Google_Service_Datastore_Property extends Google_Collection { protected $collection_key = 'listValue'; protected $internal_gapi_mappings = array( ); public $blobKeyValue; public $blobValue; public $booleanValue; public $dateTimeValue; public $doubleValue; protected $entityValueType = 'Google_Service_Datastore_Entity'; protected $entityValueDataType = ''; public $indexed; public $integerValue; protected $keyValueType = 'Google_Service_Datastore_Key'; protected $keyValueDataType = ''; protected $listValueType = 'Google_Service_Datastore_Value'; protected $listValueDataType = 'array'; public $meaning; public $stringValue; public function setBlobKeyValue($blobKeyValue) { $this->blobKeyValue = $blobKeyValue; } public function getBlobKeyValue() { return $this->blobKeyValue; } public function setBlobValue($blobValue) { $this->blobValue = $blobValue; } public function getBlobValue() { return $this->blobValue; } public function setBooleanValue($booleanValue) { $this->booleanValue = $booleanValue; } public function getBooleanValue() { return $this->booleanValue; } public function setDateTimeValue($dateTimeValue) { $this->dateTimeValue = $dateTimeValue; } public function getDateTimeValue() { return $this->dateTimeValue; } public function setDoubleValue($doubleValue) { $this->doubleValue = $doubleValue; } public function getDoubleValue() { return $this->doubleValue; } public function setEntityValue(Google_Service_Datastore_Entity $entityValue) { $this->entityValue = $entityValue; } public function getEntityValue() { return $this->entityValue; } public function setIndexed($indexed) { $this->indexed = $indexed; } public function getIndexed() { return $this->indexed; } public function setIntegerValue($integerValue) { $this->integerValue = $integerValue; } public function getIntegerValue() { return $this->integerValue; } public function setKeyValue(Google_Service_Datastore_Key $keyValue) { $this->keyValue = $keyValue; } public function getKeyValue() { return $this->keyValue; } public function setListValue($listValue) { $this->listValue = $listValue; } public function getListValue() { return $this->listValue; } public function setMeaning($meaning) { $this->meaning = $meaning; } public function getMeaning() { return $this->meaning; } public function setStringValue($stringValue) { $this->stringValue = $stringValue; } public function getStringValue() { return $this->stringValue; } } class Google_Service_Datastore_PropertyExpression extends Google_Model { protected $internal_gapi_mappings = array( ); public $aggregationFunction; protected $propertyType = 'Google_Service_Datastore_PropertyReference'; protected $propertyDataType = ''; public function setAggregationFunction($aggregationFunction) { $this->aggregationFunction = $aggregationFunction; } public function getAggregationFunction() { return $this->aggregationFunction; } public function setProperty(Google_Service_Datastore_PropertyReference $property) { $this->property = $property; } public function getProperty() { return $this->property; } } class Google_Service_Datastore_PropertyFilter extends Google_Model { protected $internal_gapi_mappings = array( ); public $operator; protected $propertyType = 'Google_Service_Datastore_PropertyReference'; protected $propertyDataType = ''; protected $valueType = 'Google_Service_Datastore_Value'; protected $valueDataType = ''; public function setOperator($operator) { $this->operator = $operator; } public function getOperator() { return $this->operator; } public function setProperty(Google_Service_Datastore_PropertyReference $property) { $this->property = $property; } public function getProperty() { return $this->property; } public function setValue(Google_Service_Datastore_Value $value) { $this->value = $value; } public function getValue() { return $this->value; } } class Google_Service_Datastore_PropertyOrder extends Google_Model { protected $internal_gapi_mappings = array( ); public $direction; protected $propertyType = 'Google_Service_Datastore_PropertyReference'; protected $propertyDataType = ''; public function setDirection($direction) { $this->direction = $direction; } public function getDirection() { return $this->direction; } public function setProperty(Google_Service_Datastore_PropertyReference $property) { $this->property = $property; } public function getProperty() { return $this->property; } } class Google_Service_Datastore_PropertyReference extends Google_Model { protected $internal_gapi_mappings = array( ); public $name; public function setName($name) { $this->name = $name; } public function getName() { return $this->name; } } class Google_Service_Datastore_Query extends Google_Collection { protected $collection_key = 'projection'; protected $internal_gapi_mappings = array( ); public $endCursor; protected $filterType = 'Google_Service_Datastore_Filter'; protected $filterDataType = ''; protected $groupByType = 'Google_Service_Datastore_PropertyReference'; protected $groupByDataType = 'array'; protected $kindsType = 'Google_Service_Datastore_KindExpression'; protected $kindsDataType = 'array'; public $limit; public $offset; protected $orderType = 'Google_Service_Datastore_PropertyOrder'; protected $orderDataType = 'array'; protected $projectionType = 'Google_Service_Datastore_PropertyExpression'; protected $projectionDataType = 'array'; public $startCursor; public function setEndCursor($endCursor) { $this->endCursor = $endCursor; } public function getEndCursor() { return $this->endCursor; } public function setFilter(Google_Service_Datastore_Filter $filter) { $this->filter = $filter; } public function getFilter() { return $this->filter; } public function setGroupBy($groupBy) { $this->groupBy = $groupBy; } public function getGroupBy() { return $this->groupBy; } public function setKinds($kinds) { $this->kinds = $kinds; } public function getKinds() { return $this->kinds; } public function setLimit($limit) { $this->limit = $limit; } public function getLimit() { return $this->limit; } public function setOffset($offset) { $this->offset = $offset; } public function getOffset() { return $this->offset; } public function setOrder($order) { $this->order = $order; } public function getOrder() { return $this->order; } public function setProjection($projection) { $this->projection = $projection; } public function getProjection() { return $this->projection; } public function setStartCursor($startCursor) { $this->startCursor = $startCursor; } public function getStartCursor() { return $this->startCursor; } } class Google_Service_Datastore_QueryResultBatch extends Google_Collection { protected $collection_key = 'entityResults'; protected $internal_gapi_mappings = array( ); public $endCursor; public $entityResultType; protected $entityResultsType = 'Google_Service_Datastore_EntityResult'; protected $entityResultsDataType = 'array'; public $moreResults; public $skippedResults; public function setEndCursor($endCursor) { $this->endCursor = $endCursor; } public function getEndCursor() { return $this->endCursor; } public function setEntityResultType($entityResultType) { $this->entityResultType = $entityResultType; } public function getEntityResultType() { return $this->entityResultType; } public function setEntityResults($entityResults) { $this->entityResults = $entityResults; } public function getEntityResults() { return $this->entityResults; } public function setMoreResults($moreResults) { $this->moreResults = $moreResults; } public function getMoreResults() { return $this->moreResults; } public function setSkippedResults($skippedResults) { $this->skippedResults = $skippedResults; } public function getSkippedResults() { return $this->skippedResults; } } class Google_Service_Datastore_ReadOptions extends Google_Model { protected $internal_gapi_mappings = array( ); public $readConsistency; public $transaction; public function setReadConsistency($readConsistency) { $this->readConsistency = $readConsistency; } public function getReadConsistency() { return $this->readConsistency; } public function setTransaction($transaction) { $this->transaction = $transaction; } public function getTransaction() { return $this->transaction; } } class Google_Service_Datastore_ResponseHeader extends Google_Model { protected $internal_gapi_mappings = array( ); public $kind; public function setKind($kind) { $this->kind = $kind; } public function getKind() { return $this->kind; } } class Google_Service_Datastore_RollbackRequest extends Google_Model { protected $internal_gapi_mappings = array( ); public $transaction; public function setTransaction($transaction) { $this->transaction = $transaction; } public function getTransaction() { return $this->transaction; } } class Google_Service_Datastore_RollbackResponse extends Google_Model { protected $internal_gapi_mappings = array( ); protected $headerType = 'Google_Service_Datastore_ResponseHeader'; protected $headerDataType = ''; public function setHeader(Google_Service_Datastore_ResponseHeader $header) { $this->header = $header; } public function getHeader() { return $this->header; } } class Google_Service_Datastore_RunQueryRequest extends Google_Model { protected $internal_gapi_mappings = array( ); protected $gqlQueryType = 'Google_Service_Datastore_GqlQuery'; protected $gqlQueryDataType = ''; protected $partitionIdType = 'Google_Service_Datastore_PartitionId'; protected $partitionIdDataType = ''; protected $queryType = 'Google_Service_Datastore_Query'; protected $queryDataType = ''; protected $readOptionsType = 'Google_Service_Datastore_ReadOptions'; protected $readOptionsDataType = ''; public function setGqlQuery(Google_Service_Datastore_GqlQuery $gqlQuery) { $this->gqlQuery = $gqlQuery; } public function getGqlQuery() { return $this->gqlQuery; } public function setPartitionId(Google_Service_Datastore_PartitionId $partitionId) { $this->partitionId = $partitionId; } public function getPartitionId() { return $this->partitionId; } public function setQuery(Google_Service_Datastore_Query $query) { $this->query = $query; } public function getQuery() { return $this->query; } public function setReadOptions(Google_Service_Datastore_ReadOptions $readOptions) { $this->readOptions = $readOptions; } public function getReadOptions() { return $this->readOptions; } } class Google_Service_Datastore_RunQueryResponse extends Google_Model { protected $internal_gapi_mappings = array( ); protected $batchType = 'Google_Service_Datastore_QueryResultBatch'; protected $batchDataType = ''; protected $headerType = 'Google_Service_Datastore_ResponseHeader'; protected $headerDataType = ''; public function setBatch(Google_Service_Datastore_QueryResultBatch $batch) { $this->batch = $batch; } public function getBatch() { return $this->batch; } public function setHeader(Google_Service_Datastore_ResponseHeader $header) { $this->header = $header; } public function getHeader() { return $this->header; } } class Google_Service_Datastore_Value extends Google_Collection { protected $collection_key = 'listValue'; protected $internal_gapi_mappings = array( ); public $blobKeyValue; public $blobValue; public $booleanValue; public $dateTimeValue; public $doubleValue; protected $entityValueType = 'Google_Service_Datastore_Entity'; protected $entityValueDataType = ''; public $indexed; public $integerValue; protected $keyValueType = 'Google_Service_Datastore_Key'; protected $keyValueDataType = ''; protected $listValueType = 'Google_Service_Datastore_Value'; protected $listValueDataType = 'array'; public $meaning; public $stringValue; public function setBlobKeyValue($blobKeyValue) { $this->blobKeyValue = $blobKeyValue; } public function getBlobKeyValue() { return $this->blobKeyValue; } public function setBlobValue($blobValue) { $this->blobValue = $blobValue; } public function getBlobValue() { return $this->blobValue; } public function setBooleanValue($booleanValue) { $this->booleanValue = $booleanValue; } public function getBooleanValue() { return $this->booleanValue; } public function setDateTimeValue($dateTimeValue) { $this->dateTimeValue = $dateTimeValue; } public function getDateTimeValue() { return $this->dateTimeValue; } public function setDoubleValue($doubleValue) { $this->doubleValue = $doubleValue; } public function getDoubleValue() { return $this->doubleValue; } public function setEntityValue(Google_Service_Datastore_Entity $entityValue) { $this->entityValue = $entityValue; } public function getEntityValue() { return $this->entityValue; } public function setIndexed($indexed) { $this->indexed = $indexed; } public function getIndexed() { return $this->indexed; } public function setIntegerValue($integerValue) { $this->integerValue = $integerValue; } public function getIntegerValue() { return $this->integerValue; } public function setKeyValue(Google_Service_Datastore_Key $keyValue) { $this->keyValue = $keyValue; } public function getKeyValue() { return $this->keyValue; } public function setListValue($listValue) { $this->listValue = $listValue; } public function getListValue() { return $this->listValue; } public function setMeaning($meaning) { $this->meaning = $meaning; } public function getMeaning() { return $this->meaning; } public function setStringValue($stringValue) { $this->stringValue = $stringValue; } public function getStringValue() { return $this->stringValue; } } includes/Google/Service/Deploymentmanager.php000064400000100376152214270100015353 0ustar00 * The Deployment Manager API allows users to declaratively configure, deploy * and run complex solutions on the Google Cloud Platform.

* *

* For more information about this service, see the API * Documentation *

* * @author Google, Inc. */ class Google_Service_Deploymentmanager extends UDP_Google_Service { /** View and manage your data across Google Cloud Platform services. */ const CLOUD_PLATFORM = "https://www.googleapis.com/auth/cloud-platform"; /** View and manage your Google Cloud Platform management resources and deployment status information. */ const NDEV_CLOUDMAN = "https://www.googleapis.com/auth/ndev.cloudman"; /** View your Google Cloud Platform management resources and deployment status information. */ const NDEV_CLOUDMAN_READONLY = "https://www.googleapis.com/auth/ndev.cloudman.readonly"; public $deployments; public $manifests; public $operations; public $resources; public $types; /** * Constructs the internal representation of the Deploymentmanager service. * * @param Google_Client $client */ public function __construct(UDP_Google_Client $client) { parent::__construct($client); $this->servicePath = 'deploymentmanager/v2beta1/projects/'; $this->version = 'v2beta1'; $this->serviceName = 'deploymentmanager'; $this->deployments = new Google_Service_Deploymentmanager_Deployments_Resource( $this, $this->serviceName, 'deployments', array( 'methods' => array( 'delete' => array( 'path' => '{project}/global/deployments/{deployment}', 'httpMethod' => 'DELETE', 'parameters' => array( 'project' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'deployment' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), ), ),'get' => array( 'path' => '{project}/global/deployments/{deployment}', 'httpMethod' => 'GET', 'parameters' => array( 'project' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'deployment' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), ), ),'insert' => array( 'path' => '{project}/global/deployments', 'httpMethod' => 'POST', 'parameters' => array( 'project' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), ), ),'list' => array( 'path' => '{project}/global/deployments', 'httpMethod' => 'GET', 'parameters' => array( 'project' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'pageToken' => array( 'location' => 'query', 'type' => 'string', ), 'maxResults' => array( 'location' => 'query', 'type' => 'integer', ), ), ), ) ) ); $this->manifests = new Google_Service_Deploymentmanager_Manifests_Resource( $this, $this->serviceName, 'manifests', array( 'methods' => array( 'get' => array( 'path' => '{project}/global/deployments/{deployment}/manifests/{manifest}', 'httpMethod' => 'GET', 'parameters' => array( 'project' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'deployment' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'manifest' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), ), ),'list' => array( 'path' => '{project}/global/deployments/{deployment}/manifests', 'httpMethod' => 'GET', 'parameters' => array( 'project' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'deployment' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'pageToken' => array( 'location' => 'query', 'type' => 'string', ), 'maxResults' => array( 'location' => 'query', 'type' => 'integer', ), ), ), ) ) ); $this->operations = new Google_Service_Deploymentmanager_Operations_Resource( $this, $this->serviceName, 'operations', array( 'methods' => array( 'get' => array( 'path' => '{project}/global/operations/{operation}', 'httpMethod' => 'GET', 'parameters' => array( 'project' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'operation' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), ), ),'list' => array( 'path' => '{project}/global/operations', 'httpMethod' => 'GET', 'parameters' => array( 'project' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'pageToken' => array( 'location' => 'query', 'type' => 'string', ), 'maxResults' => array( 'location' => 'query', 'type' => 'integer', ), ), ), ) ) ); $this->resources = new Google_Service_Deploymentmanager_Resources_Resource( $this, $this->serviceName, 'resources', array( 'methods' => array( 'get' => array( 'path' => '{project}/global/deployments/{deployment}/resources/{resource}', 'httpMethod' => 'GET', 'parameters' => array( 'project' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'deployment' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'resource' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), ), ),'list' => array( 'path' => '{project}/global/deployments/{deployment}/resources', 'httpMethod' => 'GET', 'parameters' => array( 'project' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'deployment' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'pageToken' => array( 'location' => 'query', 'type' => 'string', ), 'maxResults' => array( 'location' => 'query', 'type' => 'integer', ), ), ), ) ) ); $this->types = new Google_Service_Deploymentmanager_Types_Resource( $this, $this->serviceName, 'types', array( 'methods' => array( 'list' => array( 'path' => '{project}/global/types', 'httpMethod' => 'GET', 'parameters' => array( 'project' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'pageToken' => array( 'location' => 'query', 'type' => 'string', ), 'maxResults' => array( 'location' => 'query', 'type' => 'integer', ), ), ), ) ) ); } } /** * The "deployments" collection of methods. * Typical usage is: * * $deploymentmanagerService = new Google_Service_Deploymentmanager(...); * $deployments = $deploymentmanagerService->deployments; * */ class Google_Service_Deploymentmanager_Deployments_Resource extends UDP_Google_Service_Resource { /** * ! Deletes a deployment and all of the resources in the deployment. * (deployments.delete) * * @param string $project ! The project ID for this request. * @param string $deployment ! The name of the deployment for this request. * @param array $optParams Optional parameters. * @return Google_Service_Deploymentmanager_Operation */ public function delete($project, $deployment, $optParams = array()) { $params = array('project' => $project, 'deployment' => $deployment); $params = array_merge($params, $optParams); return $this->call('delete', array($params), "Google_Service_Deploymentmanager_Operation"); } /** * ! Gets information about a specific deployment. (deployments.get) * * @param string $project ! The project ID for this request. * @param string $deployment ! The name of the deployment for this request. * @param array $optParams Optional parameters. * @return Google_Service_Deploymentmanager_Deployment */ public function get($project, $deployment, $optParams = array()) { $params = array('project' => $project, 'deployment' => $deployment); $params = array_merge($params, $optParams); return $this->call('get', array($params), "Google_Service_Deploymentmanager_Deployment"); } /** * ! Creates a deployment and all of the resources described by the ! deployment * manifest. (deployments.insert) * * @param string $project ! The project ID for this request. * @param Google_Deployment $postBody * @param array $optParams Optional parameters. * @return Google_Service_Deploymentmanager_Operation */ public function insert($project, Google_Service_Deploymentmanager_Deployment $postBody, $optParams = array()) { $params = array('project' => $project, 'postBody' => $postBody); $params = array_merge($params, $optParams); return $this->call('insert', array($params), "Google_Service_Deploymentmanager_Operation"); } /** * ! Lists all deployments for a given project. (deployments.listDeployments) * * @param string $project ! The project ID for this request. * @param array $optParams Optional parameters. * * @opt_param string pageToken ! Specifies a nextPageToken returned by a * previous list request. This ! token can be used to request the next page of * results from a previous ! list request. * @opt_param int maxResults ! Maximum count of results to be returned. ! * Acceptable values are 0 to 100, inclusive. (Default: 50) * @return Google_Service_Deploymentmanager_DeploymentsListResponse */ public function listDeployments($project, $optParams = array()) { $params = array('project' => $project); $params = array_merge($params, $optParams); return $this->call('list', array($params), "Google_Service_Deploymentmanager_DeploymentsListResponse"); } } /** * The "manifests" collection of methods. * Typical usage is: * * $deploymentmanagerService = new Google_Service_Deploymentmanager(...); * $manifests = $deploymentmanagerService->manifests; * */ class Google_Service_Deploymentmanager_Manifests_Resource extends UDP_Google_Service_Resource { /** * ! Gets information about a specific manifest. (manifests.get) * * @param string $project ! The project ID for this request. * @param string $deployment ! The name of the deployment for this request. * @param string $manifest ! The name of the manifest for this request. * @param array $optParams Optional parameters. * @return Google_Service_Deploymentmanager_Manifest */ public function get($project, $deployment, $manifest, $optParams = array()) { $params = array('project' => $project, 'deployment' => $deployment, 'manifest' => $manifest); $params = array_merge($params, $optParams); return $this->call('get', array($params), "Google_Service_Deploymentmanager_Manifest"); } /** * ! Lists all manifests for a given deployment. (manifests.listManifests) * * @param string $project ! The project ID for this request. * @param string $deployment ! The name of the deployment for this request. * @param array $optParams Optional parameters. * * @opt_param string pageToken ! Specifies a nextPageToken returned by a * previous list request. This ! token can be used to request the next page of * results from a previous ! list request. * @opt_param int maxResults ! Maximum count of results to be returned. ! * Acceptable values are 0 to 100, inclusive. (Default: 50) * @return Google_Service_Deploymentmanager_ManifestsListResponse */ public function listManifests($project, $deployment, $optParams = array()) { $params = array('project' => $project, 'deployment' => $deployment); $params = array_merge($params, $optParams); return $this->call('list', array($params), "Google_Service_Deploymentmanager_ManifestsListResponse"); } } /** * The "operations" collection of methods. * Typical usage is: * * $deploymentmanagerService = new Google_Service_Deploymentmanager(...); * $operations = $deploymentmanagerService->operations; * */ class Google_Service_Deploymentmanager_Operations_Resource extends UDP_Google_Service_Resource { /** * ! Gets information about a specific Operation. (operations.get) * * @param string $project ! The project ID for this request. * @param string $operation ! The name of the operation for this request. * @param array $optParams Optional parameters. * @return Google_Service_Deploymentmanager_Operation */ public function get($project, $operation, $optParams = array()) { $params = array('project' => $project, 'operation' => $operation); $params = array_merge($params, $optParams); return $this->call('get', array($params), "Google_Service_Deploymentmanager_Operation"); } /** * ! Lists all Operations for a project. (operations.listOperations) * * @param string $project ! The project ID for this request. * @param array $optParams Optional parameters. * * @opt_param string pageToken ! Specifies a nextPageToken returned by a * previous list request. This ! token can be used to request the next page of * results from a previous ! list request. * @opt_param int maxResults ! Maximum count of results to be returned. ! * Acceptable values are 0 to 100, inclusive. (Default: 50) * @return Google_Service_Deploymentmanager_OperationsListResponse */ public function listOperations($project, $optParams = array()) { $params = array('project' => $project); $params = array_merge($params, $optParams); return $this->call('list', array($params), "Google_Service_Deploymentmanager_OperationsListResponse"); } } /** * The "resources" collection of methods. * Typical usage is: * * $deploymentmanagerService = new Google_Service_Deploymentmanager(...); * $resources = $deploymentmanagerService->resources; * */ class Google_Service_Deploymentmanager_Resources_Resource extends UDP_Google_Service_Resource { /** * ! Gets information about a single resource. (resources.get) * * @param string $project ! The project ID for this request. * @param string $deployment ! The name of the deployment for this request. * @param string $resource ! The name of the resource for this request. * @param array $optParams Optional parameters. * @return Google_Service_Deploymentmanager_DeploymentmanagerResource */ public function get($project, $deployment, $resource, $optParams = array()) { $params = array('project' => $project, 'deployment' => $deployment, 'resource' => $resource); $params = array_merge($params, $optParams); return $this->call('get', array($params), "Google_Service_Deploymentmanager_DeploymentmanagerResource"); } /** * ! Lists all resources in a given deployment. (resources.listResources) * * @param string $project ! The project ID for this request. * @param string $deployment ! The name of the deployment for this request. * @param array $optParams Optional parameters. * * @opt_param string pageToken ! Specifies a nextPageToken returned by a * previous list request. This ! token can be used to request the next page of * results from a previous ! list request. * @opt_param int maxResults ! Maximum count of results to be returned. ! * Acceptable values are 0 to 100, inclusive. (Default: 50) * @return Google_Service_Deploymentmanager_ResourcesListResponse */ public function listResources($project, $deployment, $optParams = array()) { $params = array('project' => $project, 'deployment' => $deployment); $params = array_merge($params, $optParams); return $this->call('list', array($params), "Google_Service_Deploymentmanager_ResourcesListResponse"); } } /** * The "types" collection of methods. * Typical usage is: * * $deploymentmanagerService = new Google_Service_Deploymentmanager(...); * $types = $deploymentmanagerService->types; * */ class Google_Service_Deploymentmanager_Types_Resource extends UDP_Google_Service_Resource { /** * ! Lists all Types for Deployment Manager. (types.listTypes) * * @param string $project ! The project ID for this request. * @param array $optParams Optional parameters. * * @opt_param string pageToken ! Specifies a nextPageToken returned by a * previous list request. This ! token can be used to request the next page of * results from a previous ! list request. * @opt_param int maxResults ! Maximum count of results to be returned. ! * Acceptable values are 0 to 100, inclusive. (Default: 50) * @return Google_Service_Deploymentmanager_TypesListResponse */ public function listTypes($project, $optParams = array()) { $params = array('project' => $project); $params = array_merge($params, $optParams); return $this->call('list', array($params), "Google_Service_Deploymentmanager_TypesListResponse"); } } class Google_Service_Deploymentmanager_Deployment extends Google_Model { protected $internal_gapi_mappings = array( ); public $description; public $id; public $manifest; public $name; public $targetConfig; public function setDescription($description) { $this->description = $description; } public function getDescription() { return $this->description; } public function setId($id) { $this->id = $id; } public function getId() { return $this->id; } public function setManifest($manifest) { $this->manifest = $manifest; } public function getManifest() { return $this->manifest; } public function setName($name) { $this->name = $name; } public function getName() { return $this->name; } public function setTargetConfig($targetConfig) { $this->targetConfig = $targetConfig; } public function getTargetConfig() { return $this->targetConfig; } } class Google_Service_Deploymentmanager_DeploymentmanagerResource extends Google_Collection { protected $collection_key = 'errors'; protected $internal_gapi_mappings = array( ); public $errors; public $id; public $intent; public $manifest; public $name; public $state; public $type; public $url; public function setErrors($errors) { $this->errors = $errors; } public function getErrors() { return $this->errors; } public function setId($id) { $this->id = $id; } public function getId() { return $this->id; } public function setIntent($intent) { $this->intent = $intent; } public function getIntent() { return $this->intent; } public function setManifest($manifest) { $this->manifest = $manifest; } public function getManifest() { return $this->manifest; } public function setName($name) { $this->name = $name; } public function getName() { return $this->name; } public function setState($state) { $this->state = $state; } public function getState() { return $this->state; } public function setType($type) { $this->type = $type; } public function getType() { return $this->type; } public function setUrl($url) { $this->url = $url; } public function getUrl() { return $this->url; } } class Google_Service_Deploymentmanager_DeploymentsListResponse extends Google_Collection { protected $collection_key = 'deployments'; protected $internal_gapi_mappings = array( ); protected $deploymentsType = 'Google_Service_Deploymentmanager_Deployment'; protected $deploymentsDataType = 'array'; public $nextPageToken; public function setDeployments($deployments) { $this->deployments = $deployments; } public function getDeployments() { return $this->deployments; } public function setNextPageToken($nextPageToken) { $this->nextPageToken = $nextPageToken; } public function getNextPageToken() { return $this->nextPageToken; } } class Google_Service_Deploymentmanager_Manifest extends Google_Model { protected $internal_gapi_mappings = array( ); public $config; public $evaluatedConfig; public $id; public $name; public $selfLink; public function setConfig($config) { $this->config = $config; } public function getConfig() { return $this->config; } public function setEvaluatedConfig($evaluatedConfig) { $this->evaluatedConfig = $evaluatedConfig; } public function getEvaluatedConfig() { return $this->evaluatedConfig; } public function setId($id) { $this->id = $id; } public function getId() { return $this->id; } public function setName($name) { $this->name = $name; } public function getName() { return $this->name; } public function setSelfLink($selfLink) { $this->selfLink = $selfLink; } public function getSelfLink() { return $this->selfLink; } } class Google_Service_Deploymentmanager_ManifestsListResponse extends Google_Collection { protected $collection_key = 'manifests'; protected $internal_gapi_mappings = array( ); protected $manifestsType = 'Google_Service_Deploymentmanager_Manifest'; protected $manifestsDataType = 'array'; public $nextPageToken; public function setManifests($manifests) { $this->manifests = $manifests; } public function getManifests() { return $this->manifests; } public function setNextPageToken($nextPageToken) { $this->nextPageToken = $nextPageToken; } public function getNextPageToken() { return $this->nextPageToken; } } class Google_Service_Deploymentmanager_Operation extends Google_Collection { protected $collection_key = 'warnings'; protected $internal_gapi_mappings = array( ); public $creationTimestamp; public $endTime; protected $errorType = 'Google_Service_Deploymentmanager_OperationError'; protected $errorDataType = ''; public $httpErrorMessage; public $httpErrorStatusCode; public $id; public $insertTime; public $name; public $operationType; public $progress; public $selfLink; public $startTime; public $status; public $statusMessage; public $targetId; public $targetLink; public $user; protected $warningsType = 'Google_Service_Deploymentmanager_OperationWarnings'; protected $warningsDataType = 'array'; public function setCreationTimestamp($creationTimestamp) { $this->creationTimestamp = $creationTimestamp; } public function getCreationTimestamp() { return $this->creationTimestamp; } public function setEndTime($endTime) { $this->endTime = $endTime; } public function getEndTime() { return $this->endTime; } public function setError(Google_Service_Deploymentmanager_OperationError $error) { $this->error = $error; } public function getError() { return $this->error; } public function setHttpErrorMessage($httpErrorMessage) { $this->httpErrorMessage = $httpErrorMessage; } public function getHttpErrorMessage() { return $this->httpErrorMessage; } public function setHttpErrorStatusCode($httpErrorStatusCode) { $this->httpErrorStatusCode = $httpErrorStatusCode; } public function getHttpErrorStatusCode() { return $this->httpErrorStatusCode; } public function setId($id) { $this->id = $id; } public function getId() { return $this->id; } public function setInsertTime($insertTime) { $this->insertTime = $insertTime; } public function getInsertTime() { return $this->insertTime; } public function setName($name) { $this->name = $name; } public function getName() { return $this->name; } public function setOperationType($operationType) { $this->operationType = $operationType; } public function getOperationType() { return $this->operationType; } public function setProgress($progress) { $this->progress = $progress; } public function getProgress() { return $this->progress; } public function setSelfLink($selfLink) { $this->selfLink = $selfLink; } public function getSelfLink() { return $this->selfLink; } public function setStartTime($startTime) { $this->startTime = $startTime; } public function getStartTime() { return $this->startTime; } public function setStatus($status) { $this->status = $status; } public function getStatus() { return $this->status; } public function setStatusMessage($statusMessage) { $this->statusMessage = $statusMessage; } public function getStatusMessage() { return $this->statusMessage; } public function setTargetId($targetId) { $this->targetId = $targetId; } public function getTargetId() { return $this->targetId; } public function setTargetLink($targetLink) { $this->targetLink = $targetLink; } public function getTargetLink() { return $this->targetLink; } public function setUser($user) { $this->user = $user; } public function getUser() { return $this->user; } public function setWarnings($warnings) { $this->warnings = $warnings; } public function getWarnings() { return $this->warnings; } } class Google_Service_Deploymentmanager_OperationError extends Google_Collection { protected $collection_key = 'errors'; protected $internal_gapi_mappings = array( ); protected $errorsType = 'Google_Service_Deploymentmanager_OperationErrorErrors'; protected $errorsDataType = 'array'; public function setErrors($errors) { $this->errors = $errors; } public function getErrors() { return $this->errors; } } class Google_Service_Deploymentmanager_OperationErrorErrors extends Google_Model { protected $internal_gapi_mappings = array( ); public $code; public $location; public $message; public function setCode($code) { $this->code = $code; } public function getCode() { return $this->code; } public function setLocation($location) { $this->location = $location; } public function getLocation() { return $this->location; } public function setMessage($message) { $this->message = $message; } public function getMessage() { return $this->message; } } class Google_Service_Deploymentmanager_OperationWarnings extends Google_Collection { protected $collection_key = 'data'; protected $internal_gapi_mappings = array( ); public $code; protected $dataType = 'Google_Service_Deploymentmanager_OperationWarningsData'; protected $dataDataType = 'array'; public $message; public function setCode($code) { $this->code = $code; } public function getCode() { return $this->code; } public function setData($data) { $this->data = $data; } public function getData() { return $this->data; } public function setMessage($message) { $this->message = $message; } public function getMessage() { return $this->message; } } class Google_Service_Deploymentmanager_OperationWarningsData extends Google_Model { protected $internal_gapi_mappings = array( ); public $key; public $value; public function setKey($key) { $this->key = $key; } public function getKey() { return $this->key; } public function setValue($value) { $this->value = $value; } public function getValue() { return $this->value; } } class Google_Service_Deploymentmanager_OperationsListResponse extends Google_Collection { protected $collection_key = 'operations'; protected $internal_gapi_mappings = array( ); public $nextPageToken; protected $operationsType = 'Google_Service_Deploymentmanager_Operation'; protected $operationsDataType = 'array'; public function setNextPageToken($nextPageToken) { $this->nextPageToken = $nextPageToken; } public function getNextPageToken() { return $this->nextPageToken; } public function setOperations($operations) { $this->operations = $operations; } public function getOperations() { return $this->operations; } } class Google_Service_Deploymentmanager_ResourcesListResponse extends Google_Collection { protected $collection_key = 'resources'; protected $internal_gapi_mappings = array( ); public $nextPageToken; protected $resourcesType = 'Google_Service_Deploymentmanager_DeploymentmanagerResource'; protected $resourcesDataType = 'array'; public function setNextPageToken($nextPageToken) { $this->nextPageToken = $nextPageToken; } public function getNextPageToken() { return $this->nextPageToken; } public function setResources($resources) { $this->resources = $resources; } public function getResources() { return $this->resources; } } class Google_Service_Deploymentmanager_Type extends Google_Model { protected $internal_gapi_mappings = array( ); public $name; public function setName($name) { $this->name = $name; } public function getName() { return $this->name; } } class Google_Service_Deploymentmanager_TypesListResponse extends Google_Collection { protected $collection_key = 'types'; protected $internal_gapi_mappings = array( ); protected $typesType = 'Google_Service_Deploymentmanager_Type'; protected $typesDataType = 'array'; public function setTypes($types) { $this->types = $types; } public function getTypes() { return $this->types; } } includes/Google/Service/CloudMonitoring.php000064400000103365152214270100015015 0ustar00 * API for accessing Google Cloud and API monitoring data.

* *

* For more information about this service, see the API * Documentation *

* * @author Google, Inc. */ class Google_Service_CloudMonitoring extends UDP_Google_Service { /** View and write monitoring data for all of your Google and third-party Cloud and API projects. */ const MONITORING = "https://www.googleapis.com/auth/monitoring"; public $metricDescriptors; public $timeseries; public $timeseriesDescriptors; /** * Constructs the internal representation of the CloudMonitoring service. * * @param Google_Client $client */ public function __construct(UDP_Google_Client $client) { parent::__construct($client); $this->servicePath = 'cloudmonitoring/v2beta2/projects/'; $this->version = 'v2beta2'; $this->serviceName = 'cloudmonitoring'; $this->metricDescriptors = new Google_Service_CloudMonitoring_MetricDescriptors_Resource( $this, $this->serviceName, 'metricDescriptors', array( 'methods' => array( 'create' => array( 'path' => '{project}/metricDescriptors', 'httpMethod' => 'POST', 'parameters' => array( 'project' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), ), ),'delete' => array( 'path' => '{project}/metricDescriptors/{metric}', 'httpMethod' => 'DELETE', 'parameters' => array( 'project' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'metric' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), ), ),'list' => array( 'path' => '{project}/metricDescriptors', 'httpMethod' => 'GET', 'parameters' => array( 'project' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'count' => array( 'location' => 'query', 'type' => 'integer', ), 'pageToken' => array( 'location' => 'query', 'type' => 'string', ), 'query' => array( 'location' => 'query', 'type' => 'string', ), ), ), ) ) ); $this->timeseries = new Google_Service_CloudMonitoring_Timeseries_Resource( $this, $this->serviceName, 'timeseries', array( 'methods' => array( 'list' => array( 'path' => '{project}/timeseries/{metric}', 'httpMethod' => 'GET', 'parameters' => array( 'project' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'metric' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'youngest' => array( 'location' => 'query', 'type' => 'string', 'required' => true, ), 'count' => array( 'location' => 'query', 'type' => 'integer', ), 'timespan' => array( 'location' => 'query', 'type' => 'string', ), 'aggregator' => array( 'location' => 'query', 'type' => 'string', ), 'labels' => array( 'location' => 'query', 'type' => 'string', 'repeated' => true, ), 'pageToken' => array( 'location' => 'query', 'type' => 'string', ), 'window' => array( 'location' => 'query', 'type' => 'string', ), 'oldest' => array( 'location' => 'query', 'type' => 'string', ), ), ),'write' => array( 'path' => '{project}/timeseries:write', 'httpMethod' => 'POST', 'parameters' => array( 'project' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), ), ), ) ) ); $this->timeseriesDescriptors = new Google_Service_CloudMonitoring_TimeseriesDescriptors_Resource( $this, $this->serviceName, 'timeseriesDescriptors', array( 'methods' => array( 'list' => array( 'path' => '{project}/timeseriesDescriptors/{metric}', 'httpMethod' => 'GET', 'parameters' => array( 'project' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'metric' => array( 'location' => 'path', 'type' => 'string', 'required' => true, ), 'youngest' => array( 'location' => 'query', 'type' => 'string', 'required' => true, ), 'count' => array( 'location' => 'query', 'type' => 'integer', ), 'timespan' => array( 'location' => 'query', 'type' => 'string', ), 'aggregator' => array( 'location' => 'query', 'type' => 'string', ), 'labels' => array( 'location' => 'query', 'type' => 'string', 'repeated' => true, ), 'pageToken' => array( 'location' => 'query', 'type' => 'string', ), 'window' => array( 'location' => 'query', 'type' => 'string', ), 'oldest' => array( 'location' => 'query', 'type' => 'string', ), ), ), ) ) ); } } /** * The "metricDescriptors" collection of methods. * Typical usage is: * * $cloudmonitoringService = new Google_Service_CloudMonitoring(...); * $metricDescriptors = $cloudmonitoringService->metricDescriptors; * */ class Google_Service_CloudMonitoring_MetricDescriptors_Resource extends UDP_Google_Service_Resource { /** * Create a new metric. (metricDescriptors.create) * * @param string $project The project id. The value can be the numeric project * ID or string-based project name. * @param Google_MetricDescriptor $postBody * @param array $optParams Optional parameters. * @return Google_Service_CloudMonitoring_MetricDescriptor */ public function create($project, Google_Service_CloudMonitoring_MetricDescriptor $postBody, $optParams = array()) { $params = array('project' => $project, 'postBody' => $postBody); $params = array_merge($params, $optParams); return $this->call('create', array($params), "Google_Service_CloudMonitoring_MetricDescriptor"); } /** * Delete an existing metric. (metricDescriptors.delete) * * @param string $project The project ID to which the metric belongs. * @param string $metric Name of the metric. * @param array $optParams Optional parameters. * @return Google_Service_CloudMonitoring_DeleteMetricDescriptorResponse */ public function delete($project, $metric, $optParams = array()) { $params = array('project' => $project, 'metric' => $metric); $params = array_merge($params, $optParams); return $this->call('delete', array($params), "Google_Service_CloudMonitoring_DeleteMetricDescriptorResponse"); } /** * List metric descriptors that match the query. If the query is not set, then * all of the metric descriptors will be returned. Large responses will be * paginated, use the nextPageToken returned in the response to request * subsequent pages of results by setting the pageToken query parameter to the * value of the nextPageToken. (metricDescriptors.listMetricDescriptors) * * @param string $project The project id. The value can be the numeric project * ID or string-based project name. * @param array $optParams Optional parameters. * * @opt_param int count Maximum number of metric descriptors per page. Used for * pagination. If not specified, count = 100. * @opt_param string pageToken The pagination token, which is used to page * through large result sets. Set this value to the value of the nextPageToken * to retrieve the next page of results. * @opt_param string query The query used to search against existing metrics. * Separate keywords with a space; the service joins all keywords with AND, * meaning that all keywords must match for a metric to be returned. If this * field is omitted, all metrics are returned. If an empty string is passed with * this field, no metrics are returned. * @return Google_Service_CloudMonitoring_ListMetricDescriptorsResponse */ public function listMetricDescriptors($project, $optParams = array()) { $params = array('project' => $project); $params = array_merge($params, $optParams); return $this->call('list', array($params), "Google_Service_CloudMonitoring_ListMetricDescriptorsResponse"); } } /** * The "timeseries" collection of methods. * Typical usage is: * * $cloudmonitoringService = new Google_Service_CloudMonitoring(...); * $timeseries = $cloudmonitoringService->timeseries; * */ class Google_Service_CloudMonitoring_Timeseries_Resource extends UDP_Google_Service_Resource { /** * List the data points of the time series that match the metric and labels * values and that have data points in the interval. Large responses are * paginated; use the nextPageToken returned in the response to request * subsequent pages of results by setting the pageToken query parameter to the * value of the nextPageToken. (timeseries.listTimeseries) * * @param string $project The project ID to which this time series belongs. The * value can be the numeric project ID or string-based project name. * @param string $metric Metric names are protocol-free URLs as listed in the * Supported Metrics page. For example, * compute.googleapis.com/instance/disk/read_ops_count. * @param string $youngest End of the time interval (inclusive), which is * expressed as an RFC 3339 timestamp. * @param array $optParams Optional parameters. * * @opt_param int count Maximum number of data points per page, which is used * for pagination of results. * @opt_param string timespan Length of the time interval to query, which is an * alternative way to declare the interval: (youngest - timespan, youngest]. The * timespan and oldest parameters should not be used together. Units: - s: * second - m: minute - h: hour - d: day - w: week Examples: 2s, 3m, 4w. * Only one unit is allowed, for example: 2w3d is not allowed; you should use * 17d instead. * * If neither oldest nor timespan is specified, the default time interval will * be (youngest - 4 hours, youngest]. * @opt_param string aggregator The aggregation function that will reduce the * data points in each window to a single point. This parameter is only valid * for non-cumulative metrics with a value type of INT64 or DOUBLE. * @opt_param string labels A collection of labels for the matching time series, * which are represented as: - key==value: key equals the value - key=~value: * key regex matches the value - key!=value: key does not equal the value - * key!~value: key regex does not match the value For example, to list all of * the time series descriptors for the region us-central1, you could specify: * label=cloud.googleapis.com%2Flocation=~us-central1.* * @opt_param string pageToken The pagination token, which is used to page * through large result sets. Set this value to the value of the nextPageToken * to retrieve the next page of results. * @opt_param string window The sampling window. At most one data point will be * returned for each window in the requested time interval. This parameter is * only valid for non-cumulative metric types. Units: - m: minute - h: hour - * d: day - w: week Examples: 3m, 4w. Only one unit is allowed, for example: * 2w3d is not allowed; you should use 17d instead. * @opt_param string oldest Start of the time interval (exclusive), which is * expressed as an RFC 3339 timestamp. If neither oldest nor timespan is * specified, the default time interval will be (youngest - 4 hours, youngest] * @return Google_Service_CloudMonitoring_ListTimeseriesResponse */ public function listTimeseries($project, $metric, $youngest, $optParams = array()) { $params = array('project' => $project, 'metric' => $metric, 'youngest' => $youngest); $params = array_merge($params, $optParams); return $this->call('list', array($params), "Google_Service_CloudMonitoring_ListTimeseriesResponse"); } /** * Put data points to one or more time series for one or more metrics. If a time * series does not exist, a new time series will be created. It is not allowed * to write a time series point that is older than the existing youngest point * of that time series. Points that are older than the existing youngest point * of that time series will be discarded silently. Therefore, users should make * sure that points of a time series are written sequentially in the order of * their end time. (timeseries.write) * * @param string $project The project ID. The value can be the numeric project * ID or string-based project name. * @param Google_WriteTimeseriesRequest $postBody * @param array $optParams Optional parameters. * @return Google_Service_CloudMonitoring_WriteTimeseriesResponse */ public function write($project, Google_Service_CloudMonitoring_WriteTimeseriesRequest $postBody, $optParams = array()) { $params = array('project' => $project, 'postBody' => $postBody); $params = array_merge($params, $optParams); return $this->call('write', array($params), "Google_Service_CloudMonitoring_WriteTimeseriesResponse"); } } /** * The "timeseriesDescriptors" collection of methods. * Typical usage is: * * $cloudmonitoringService = new Google_Service_CloudMonitoring(...); * $timeseriesDescriptors = $cloudmonitoringService->timeseriesDescriptors; * */ class Google_Service_CloudMonitoring_TimeseriesDescriptors_Resource extends UDP_Google_Service_Resource { /** * List the descriptors of the time series that match the metric and labels * values and that have data points in the interval. Large responses are * paginated; use the nextPageToken returned in the response to request * subsequent pages of results by setting the pageToken query parameter to the * value of the nextPageToken. (timeseriesDescriptors.listTimeseriesDescriptors) * * @param string $project The project ID to which this time series belongs. The * value can be the numeric project ID or string-based project name. * @param string $metric Metric names are protocol-free URLs as listed in the * Supported Metrics page. For example, * compute.googleapis.com/instance/disk/read_ops_count. * @param string $youngest End of the time interval (inclusive), which is * expressed as an RFC 3339 timestamp. * @param array $optParams Optional parameters. * * @opt_param int count Maximum number of time series descriptors per page. Used * for pagination. If not specified, count = 100. * @opt_param string timespan Length of the time interval to query, which is an * alternative way to declare the interval: (youngest - timespan, youngest]. The * timespan and oldest parameters should not be used together. Units: - s: * second - m: minute - h: hour - d: day - w: week Examples: 2s, 3m, 4w. * Only one unit is allowed, for example: 2w3d is not allowed; you should use * 17d instead. * * If neither oldest nor timespan is specified, the default time interval will * be (youngest - 4 hours, youngest]. * @opt_param string aggregator The aggregation function that will reduce the * data points in each window to a single point. This parameter is only valid * for non-cumulative metrics with a value type of INT64 or DOUBLE. * @opt_param string labels A collection of labels for the matching time series, * which are represented as: - key==value: key equals the value - key=~value: * key regex matches the value - key!=value: key does not equal the value - * key!~value: key regex does not match the value For example, to list all of * the time series descriptors for the region us-central1, you could specify: * label=cloud.googleapis.com%2Flocation=~us-central1.* * @opt_param string pageToken The pagination token, which is used to page * through large result sets. Set this value to the value of the nextPageToken * to retrieve the next page of results. * @opt_param string window The sampling window. At most one data point will be * returned for each window in the requested time interval. This parameter is * only valid for non-cumulative metric types. Units: - m: minute - h: hour - * d: day - w: week Examples: 3m, 4w. Only one unit is allowed, for example: * 2w3d is not allowed; you should use 17d instead. * @opt_param string oldest Start of the time interval (exclusive), which is * expressed as an RFC 3339 timestamp. If neither oldest nor timespan is * specified, the default time interval will be (youngest - 4 hours, youngest] * @return Google_Service_CloudMonitoring_ListTimeseriesDescriptorsResponse */ public function listTimeseriesDescriptors($project, $metric, $youngest, $optParams = array()) { $params = array('project' => $project, 'metric' => $metric, 'youngest' => $youngest); $params = array_merge($params, $optParams); return $this->call('list', array($params), "Google_Service_CloudMonitoring_ListTimeseriesDescriptorsResponse"); } } class Google_Service_CloudMonitoring_DeleteMetricDescriptorResponse extends Google_Model { protected $internal_gapi_mappings = array( ); public $kind; public function setKind($kind) { $this->kind = $kind; } public function getKind() { return $this->kind; } } class Google_Service_CloudMonitoring_ListMetricDescriptorsRequest extends Google_Model { protected $internal_gapi_mappings = array( ); public $kind; public function setKind($kind) { $this->kind = $kind; } public function getKind() { return $this->kind; } } class Google_Service_CloudMonitoring_ListMetricDescriptorsResponse extends Google_Collection { protected $collection_key = 'metrics'; protected $internal_gapi_mappings = array( ); public $kind; protected $metricsType = 'Google_Service_CloudMonitoring_MetricDescriptor'; protected $metricsDataType = 'array'; public $nextPageToken; public function setKind($kind) { $this->kind = $kind; } public function getKind() { return $this->kind; } public function setMetrics($metrics) { $this->metrics = $metrics; } public function getMetrics() { return $this->metrics; } public function setNextPageToken($nextPageToken) { $this->nextPageToken = $nextPageToken; } public function getNextPageToken() { return $this->nextPageToken; } } class Google_Service_CloudMonitoring_ListTimeseriesDescriptorsRequest extends Google_Model { protected $internal_gapi_mappings = array( ); public $kind; public function setKind($kind) { $this->kind = $kind; } public function getKind() { return $this->kind; } } class Google_Service_CloudMonitoring_ListTimeseriesDescriptorsResponse extends Google_Collection { protected $collection_key = 'timeseries'; protected $internal_gapi_mappings = array( ); public $kind; public $nextPageToken; public $oldest; protected $timeseriesType = 'Google_Service_CloudMonitoring_TimeseriesDescriptor'; protected $timeseriesDataType = 'array'; public $youngest; public function setKind($kind) { $this->kind = $kind; } public function getKind() { return $this->kind; } public function setNextPageToken($nextPageToken) { $this->nextPageToken = $nextPageToken; } public function getNextPageToken() { return $this->nextPageToken; } public function setOldest($oldest) { $this->oldest = $oldest; } public function getOldest() { return $this->oldest; } public function setTimeseries($timeseries) { $this->timeseries = $timeseries; } public function getTimeseries() { return $this->timeseries; } public function setYoungest($youngest) { $this->youngest = $youngest; } public function getYoungest() { return $this->youngest; } } class Google_Service_CloudMonitoring_ListTimeseriesRequest extends Google_Model { protected $internal_gapi_mappings = array( ); public $kind; public function setKind($kind) { $this->kind = $kind; } public function getKind() { return $this->kind; } } class Google_Service_CloudMonitoring_ListTimeseriesResponse extends Google_Collection { protected $collection_key = 'timeseries'; protected $internal_gapi_mappings = array( ); public $kind; public $nextPageToken; public $oldest; protected $timeseriesType = 'Google_Service_CloudMonitoring_Timeseries'; protected $timeseriesDataType = 'array'; public $youngest; public function setKind($kind) { $this->kind = $kind; } public function getKind() { return $this->kind; } public function setNextPageToken($nextPageToken) { $this->nextPageToken = $nextPageToken; } public function getNextPageToken() { return $this->nextPageToken; } public function setOldest($oldest) { $this->oldest = $oldest; } public function getOldest() { return $this->oldest; } public function setTimeseries($timeseries) { $this->timeseries = $timeseries; } public function getTimeseries() { return $this->timeseries; } public function setYoungest($youngest) { $this->youngest = $youngest; } public function getYoungest() { return $this->youngest; } } class Google_Service_CloudMonitoring_MetricDescriptor extends Google_Collection { protected $collection_key = 'labels'; protected $internal_gapi_mappings = array( ); public $description; protected $labelsType = 'Google_Service_CloudMonitoring_MetricDescriptorLabelDescriptor'; protected $labelsDataType = 'array'; public $name; public $project; protected $typeDescriptorType = 'Google_Service_CloudMonitoring_MetricDescriptorTypeDescriptor'; protected $typeDescriptorDataType = ''; public function setDescription($description) { $this->description = $description; } public function getDescription() { return $this->description; } public function setLabels($labels) { $this->labels = $labels; } public function getLabels() { return $this->labels; } public function setName($name) { $this->name = $name; } public function getName() { return $this->name; } public function setProject($project) { $this->project = $project; } public function getProject() { return $this->project; } public function setTypeDescriptor(Google_Service_CloudMonitoring_MetricDescriptorTypeDescriptor $typeDescriptor) { $this->typeDescriptor = $typeDescriptor; } public function getTypeDescriptor() { return $this->typeDescriptor; } } class Google_Service_CloudMonitoring_MetricDescriptorLabelDescriptor extends Google_Model { protected $internal_gapi_mappings = array( ); public $description; public $key; public function setDescription($description) { $this->description = $description; } public function getDescription() { return $this->description; } public function setKey($key) { $this->key = $key; } public function getKey() { return $this->key; } } class Google_Service_CloudMonitoring_MetricDescriptorTypeDescriptor extends Google_Model { protected $internal_gapi_mappings = array( ); public $metricType; public $valueType; public function setMetricType($metricType) { $this->metricType = $metricType; } public function getMetricType() { return $this->metricType; } public function setValueType($valueType) { $this->valueType = $valueType; } public function getValueType() { return $this->valueType; } } class Google_Service_CloudMonitoring_Point extends Google_Model { protected $internal_gapi_mappings = array( ); public $boolValue; protected $distributionValueType = 'Google_Service_CloudMonitoring_PointDistribution'; protected $distributionValueDataType = ''; public $doubleValue; public $end; public $int64Value; public $start; public $stringValue; public function setBoolValue($boolValue) { $this->boolValue = $boolValue; } public function getBoolValue() { return $this->boolValue; } public function setDistributionValue(Google_Service_CloudMonitoring_PointDistribution $distributionValue) { $this->distributionValue = $distributionValue; } public function getDistributionValue() { return $this->distributionValue; } public function setDoubleValue($doubleValue) { $this->doubleValue = $doubleValue; } public function getDoubleValue() { return $this->doubleValue; } public function setEnd($end) { $this->end = $end; } public function getEnd() { return $this->end; } public function setInt64Value($int64Value) { $this->int64Value = $int64Value; } public function getInt64Value() { return $this->int64Value; } public function setStart($start) { $this->start = $start; } public function getStart() { return $this->start; } public function setStringValue($stringValue) { $this->stringValue = $stringValue; } public function getStringValue() { return $this->stringValue; } } class Google_Service_CloudMonitoring_PointDistribution extends Google_Collection { protected $collection_key = 'buckets'; protected $internal_gapi_mappings = array( ); protected $bucketsType = 'Google_Service_CloudMonitoring_PointDistributionBucket'; protected $bucketsDataType = 'array'; protected $overflowBucketType = 'Google_Service_CloudMonitoring_PointDistributionOverflowBucket'; protected $overflowBucketDataType = ''; protected $underflowBucketType = 'Google_Service_CloudMonitoring_PointDistributionUnderflowBucket'; protected $underflowBucketDataType = ''; public function setBuckets($buckets) { $this->buckets = $buckets; } public function getBuckets() { return $this->buckets; } public function setOverflowBucket(Google_Service_CloudMonitoring_PointDistributionOverflowBucket $overflowBucket) { $this->overflowBucket = $overflowBucket; } public function getOverflowBucket() { return $this->overflowBucket; } public function setUnderflowBucket(Google_Service_CloudMonitoring_PointDistributionUnderflowBucket $underflowBucket) { $this->underflowBucket = $underflowBucket; } public function getUnderflowBucket() { return $this->underflowBucket; } } class Google_Service_CloudMonitoring_PointDistributionBucket extends Google_Model { protected $internal_gapi_mappings = array( ); public $count; public $lowerBound; public $upperBound; public function setCount($count) { $this->count = $count; } public function getCount() { return $this->count; } public function setLowerBound($lowerBound) { $this->lowerBound = $lowerBound; } public function getLowerBound() { return $this->lowerBound; } public function setUpperBound($upperBound) { $this->upperBound = $upperBound; } public function getUpperBound() { return $this->upperBound; } } class Google_Service_CloudMonitoring_PointDistributionOverflowBucket extends Google_Model { protected $internal_gapi_mappings = array( ); public $count; public $lowerBound; public function setCount($count) { $this->count = $count; } public function getCount() { return $this->count; } public function setLowerBound($lowerBound) { $this->lowerBound = $lowerBound; } public function getLowerBound() { return $this->lowerBound; } } class Google_Service_CloudMonitoring_PointDistributionUnderflowBucket extends Google_Model { protected $internal_gapi_mappings = array( ); public $count; public $upperBound; public function setCount($count) { $this->count = $count; } public function getCount() { return $this->count; } public function setUpperBound($upperBound) { $this->upperBound = $upperBound; } public function getUpperBound() { return $this->upperBound; } } class Google_Service_CloudMonitoring_Timeseries extends Google_Collection { protected $collection_key = 'points'; protected $internal_gapi_mappings = array( ); protected $pointsType = 'Google_Service_CloudMonitoring_Point'; protected $pointsDataType = 'array'; protected $timeseriesDescType = 'Google_Service_CloudMonitoring_TimeseriesDescriptor'; protected $timeseriesDescDataType = ''; public function setPoints($points) { $this->points = $points; } public function getPoints() { return $this->points; } public function setTimeseriesDesc(Google_Service_CloudMonitoring_TimeseriesDescriptor $timeseriesDesc) { $this->timeseriesDesc = $timeseriesDesc; } public function getTimeseriesDesc() { return $this->timeseriesDesc; } } class Google_Service_CloudMonitoring_TimeseriesDescriptor extends Google_Model { protected $internal_gapi_mappings = array( ); public $labels; public $metric; public $project; public function setLabels($labels) { $this->labels = $labels; } public function getLabels() { return $this->labels; } public function setMetric($metric) { $this->metric = $metric; } public function getMetric() { return $this->metric; } public function setProject($project) { $this->project = $project; } public function getProject() { return $this->project; } } class Google_Service_CloudMonitoring_TimeseriesDescriptorLabel extends Google_Model { protected $internal_gapi_mappings = array( ); public $key; public $value; public function setKey($key) { $this->key = $key; } public function getKey() { return $this->key; } public function setValue($value) { $this->value = $value; } public function getValue() { return $this->value; } } class Google_Service_CloudMonitoring_TimeseriesDescriptorLabels extends Google_Model { } class Google_Service_CloudMonitoring_TimeseriesPoint extends Google_Model { protected $internal_gapi_mappings = array( ); protected $pointType = 'Google_Service_CloudMonitoring_Point'; protected $pointDataType = ''; protected $timeseriesDescType = 'Google_Service_CloudMonitoring_TimeseriesDescriptor'; protected $timeseriesDescDataType = ''; public function setPoint(Google_Service_CloudMonitoring_Point $point) { $this->point = $point; } public function getPoint() { return $this->point; } public function setTimeseriesDesc(Google_Service_CloudMonitoring_TimeseriesDescriptor $timeseriesDesc) { $this->timeseriesDesc = $timeseriesDesc; } public function getTimeseriesDesc() { return $this->timeseriesDesc; } } class Google_Service_CloudMonitoring_WriteTimeseriesRequest extends Google_Collection { protected $collection_key = 'timeseries'; protected $internal_gapi_mappings = array( ); public $commonLabels; protected $timeseriesType = 'Google_Service_CloudMonitoring_TimeseriesPoint'; protected $timeseriesDataType = 'array'; public function setCommonLabels($commonLabels) { $this->commonLabels = $commonLabels; } public function getCommonLabels() { return $this->commonLabels; } public function setTimeseries($timeseries) { $this->timeseries = $timeseries; } public function getTimeseries() { return $this->timeseries; } } class Google_Service_CloudMonitoring_WriteTimeseriesRequestCommonLabels extends Google_Model { } class Google_Service_CloudMonitoring_WriteTimeseriesResponse extends Google_Model { protected $internal_gapi_mappings = array( ); public $kind; public function setKind($kind) { $this->kind = $kind; } public function getKind() { return $this->kind; } } includes/Google/Signer/Abstract.php000064400000001464152214270100013270 0ustar00 */ abstract class Google_Signer_Abstract { /** * Signs data, returns the signature as binary data. */ abstract public function sign($data); } includes/Google/Signer/P12.php000064400000006154152214270100012070 0ustar00 */ class Google_Signer_P12 extends Google_Signer_Abstract { // OpenSSL private key resource private $privateKey; // Creates a new signer from a .p12 file. public function __construct($p12, $password) { if (!function_exists('openssl_x509_read')) { throw new Google_Exception( 'The Google PHP API library needs the openssl PHP extension' ); } // If the private key is provided directly, then this isn't in the p12 // format. Different versions of openssl support different p12 formats // and the key from google wasn't being accepted by the version available // at the time. if (!$password && strpos($p12, "-----BEGIN RSA PRIVATE KEY-----") !== false) { $this->privateKey = openssl_pkey_get_private($p12); } elseif($password === 'notasecret' && strpos($p12, "-----BEGIN PRIVATE KEY-----") !== false) { $this->privateKey = openssl_pkey_get_private($p12); } else { // This throws on error $certs = array(); if (!openssl_pkcs12_read($p12, $certs, $password)) { throw new Google_Auth_Exception( "Unable to parse the p12 file. " . "Is this a .p12 file? Is the password correct? OpenSSL error: " . openssl_error_string() ); } // TODO(beaton): is this part of the contract for the openssl_pkcs12_read // method? What happens if there are multiple private keys? Do we care? if (!array_key_exists("pkey", $certs) || !$certs["pkey"]) { throw new Google_Auth_Exception("No private key found in p12 file."); } $this->privateKey = openssl_pkey_get_private($certs['pkey']); } if (!$this->privateKey) { throw new Google_Auth_Exception("Unable to load private key"); } } public function __destruct() { if ($this->privateKey) { openssl_pkey_free($this->privateKey); } } public function sign($data) { if (version_compare(PHP_VERSION, '5.3.0') < 0) { throw new Google_Auth_Exception( "PHP 5.3.0 or higher is required to use service accounts." ); } // @codingStandardsIgnoreLine $hash = defined("OPENSSL_ALGO_SHA256") ? OPENSSL_ALGO_SHA256 : "sha256"; if (!openssl_sign($data, $signature, $this->privateKey, $hash)) { throw new Google_Auth_Exception("Unable to sign data"); } return $signature; } } includes/Google/Task/Retryable.php000064400000002032152214270100013121 0ustar00getClassConfig('UDP_Google_Task_Runner'); if (isset($config['initial_delay'])) { if ($config['initial_delay'] < 0) { throw new Google_Task_Exception( 'Task configuration `initial_delay` must not be negative.' ); } $this->delay = $config['initial_delay']; } if (isset($config['max_delay'])) { if ($config['max_delay'] <= 0) { throw new Google_Task_Exception( 'Task configuration `max_delay` must be greater than 0.' ); } $this->maxDelay = $config['max_delay']; } if (isset($config['factor'])) { if ($config['factor'] <= 0) { throw new Google_Task_Exception( 'Task configuration `factor` must be greater than 0.' ); } $this->factor = $config['factor']; } if (isset($config['jitter'])) { if ($config['jitter'] <= 0) { throw new Google_Task_Exception( 'Task configuration `jitter` must be greater than 0.' ); } $this->jitter = $config['jitter']; } if (isset($config['retries'])) { if ($config['retries'] < 0) { throw new Google_Task_Exception( 'Task configuration `retries` must not be negative.' ); } $this->maxAttempts += $config['retries']; } if (!is_callable($action)) { throw new Google_Task_Exception( 'Task argument `$action` must be a valid callable.' ); } $this->name = $name; $this->client = $client; $this->action = $action; $this->arguments = $arguments; } /** * Checks if a retry can be attempted. * * @return boolean */ public function canAttmpt() { return $this->attempts < $this->maxAttempts; } /** * Runs the task and (if applicable) automatically retries when errors occur. * * @return mixed * @throws Google_Task_Retryable on failure when no retries are available. */ public function run() { while ($this->attempt()) { try { return call_user_func_array($this->action, $this->arguments); } catch (Google_Task_Retryable $exception) { $allowedRetries = $exception->allowedRetries(); if (!$this->canAttmpt() || !$allowedRetries) { throw $exception; } if ($allowedRetries > 0) { $this->maxAttempts = min( $this->maxAttempts, $this->attempts + $allowedRetries ); } } } } /** * Runs a task once, if possible. This is useful for bypassing the `run()` * loop. * * NOTE: If this is not the first attempt, this function will sleep in * accordance to the backoff configurations before running the task. * * @return boolean */ public function attempt() { if (!$this->canAttmpt()) { return false; } if ($this->attempts > 0) { $this->backOff(); } $this->attempts++; return true; } /** * Sleeps in accordance to the backoff configurations. */ private function backOff() { $delay = $this->getDelay(); $this->client->getLogger()->debug( 'Retrying task with backoff', array( 'request' => $this->name, 'retry' => $this->attempts, 'backoff_seconds' => $delay ) ); usleep($delay * 1000000); } /** * Gets the delay (in seconds) for the current backoff period. * * @return float */ private function getDelay() { $jitter = $this->getJitter(); $factor = $this->attempts > 1 ? $this->factor + $jitter : 1 + abs($jitter); return $this->delay = min($this->maxDelay, $this->delay * $factor); } /** * Gets the current jitter (random number between -$this->jitter and * $this->jitter). * * @return float */ private function getJitter() { return $this->jitter * 2 * mt_rand() / mt_getrandmax() - $this->jitter; } } includes/Google/Task/Exception.php000064400000001367152214270100013140 0ustar00 "reserved", "/" => "segments", "." => "dotprefix", "#" => "fragment", ";" => "semicolon", "?" => "form", "&" => "continuation" ); /** * @var reserved array * These are the characters which should not be URL encoded in reserved * strings. */ private $reserved = array( "=", ",", "!", "@", "|", ":", "/", "?", "#", "[", "]",'$', "&", "'", "(", ")", "*", "+", ";" ); private $reservedEncoded = array( "%3D", "%2C", "%21", "%40", "%7C", "%3A", "%2F", "%3F", "%23", "%5B", "%5D", "%24", "%26", "%27", "%28", "%29", "%2A", "%2B", "%3B" ); public function parse($string, array $parameters) { return $this->resolveNextSection($string, $parameters); } /** * This function finds the first matching {...} block and * executes the replacement. It then calls itself to find * subsequent blocks, if any. */ private function resolveNextSection($string, $parameters) { $start = strpos($string, "{"); if ($start === false) { return $string; } $end = strpos($string, "}"); if ($end === false) { return $string; } $string = $this->replace($string, $start, $end, $parameters); return $this->resolveNextSection($string, $parameters); } private function replace($string, $start, $end, $parameters) { // We know a data block will have {} round it, so we can strip that. $data = substr($string, $start + 1, $end - $start - 1); // If the first character is one of the reserved operators, it effects // the processing of the stream. if (isset($this->operators[$data[0]])) { $op = $this->operators[$data[0]]; $data = substr($data, 1); $prefix = ""; $prefix_on_missing = false; switch ($op) { case "reserved": // Reserved means certain characters should not be URL encoded $data = $this->replaceVars($data, $parameters, ",", null, true); break; case "fragment": // Comma separated with fragment prefix. Bare values only. $prefix = "#"; $prefix_on_missing = true; $data = $this->replaceVars($data, $parameters, ",", null, true); break; case "segments": // Slash separated data. Bare values only. $prefix = "/"; $data =$this->replaceVars($data, $parameters, "/"); break; case "dotprefix": // Dot separated data. Bare values only. $prefix = "."; $prefix_on_missing = true; $data = $this->replaceVars($data, $parameters, "."); break; case "semicolon": // Semicolon prefixed and separated. Uses the key name $prefix = ";"; $data = $this->replaceVars($data, $parameters, ";", "=", false, true, false); break; case "form": // Standard URL format. Uses the key name $prefix = "?"; $data = $this->replaceVars($data, $parameters, "&", "="); break; case "continuation": // Standard URL, but with leading ampersand. Uses key name. $prefix = "&"; $data = $this->replaceVars($data, $parameters, "&", "="); break; } // Add the initial prefix character if data is valid. if ($data || ($data !== false && $prefix_on_missing)) { $data = $prefix . $data; } } else { // If no operator we replace with the defaults. $data = $this->replaceVars($data, $parameters); } // This is chops out the {...} and replaces with the new section. return substr($string, 0, $start) . $data . substr($string, $end + 1); } private function replaceVars( $section, $parameters, $sep = ",", $combine = null, $reserved = false, $tag_empty = false, $combine_on_empty = true ) { if (strpos($section, ",") === false) { // If we only have a single value, we can immediately process. return $this->combine( $section, $parameters, $sep, $combine, $reserved, $tag_empty, $combine_on_empty ); } else { // If we have multiple values, we need to split and loop over them. // Each is treated individually, then glued together with the // separator character. $vars = explode(",", $section); return $this->combineList( $vars, $sep, $parameters, $combine, $reserved, false, // Never emit empty strings in multi-param replacements $combine_on_empty ); } } public function combine( $key, $parameters, $sep, $combine, $reserved, $tag_empty, $combine_on_empty ) { $length = false; $explode = false; $skip_final_combine = false; $value = false; // Check for length restriction. if (strpos($key, ":") !== false) { list($key, $length) = explode(":", $key); } // Check for explode parameter. if ($key[strlen($key) - 1] == "*") { $explode = true; $key = substr($key, 0, -1); $skip_final_combine = true; } // Define the list separator. $list_sep = $explode ? $sep : ","; if (isset($parameters[$key])) { $data_type = $this->getDataType($parameters[$key]); switch($data_type) { case self::TYPE_SCALAR: $value = $this->getValue($parameters[$key], $length); break; case self::TYPE_LIST: $values = array(); foreach ($parameters[$key] as $pkey => $pvalue) { $pvalue = $this->getValue($pvalue, $length); if ($combine && $explode) { $values[$pkey] = $key . $combine . $pvalue; } else { $values[$pkey] = $pvalue; } } $value = implode($list_sep, $values); if ($value == '') { return ''; } break; case self::TYPE_MAP: $values = array(); foreach ($parameters[$key] as $pkey => $pvalue) { $pvalue = $this->getValue($pvalue, $length); if ($explode) { $pkey = $this->getValue($pkey, $length); $values[] = $pkey . "=" . $pvalue; // Explode triggers = combine. } else { $values[] = $pkey; $values[] = $pvalue; } } $value = implode($list_sep, $values); if ($value == '') { return false; } break; } } else if ($tag_empty) { // If we are just indicating empty values with their key name, return that. return $key; } else { // Otherwise we can skip this variable due to not being defined. return false; } if ($reserved) { $value = str_replace($this->reservedEncoded, $this->reserved, $value); } // If we do not need to include the key name, we just return the raw // value. if (!$combine || $skip_final_combine) { return $value; } // Else we combine the key name: foo=bar, if value is not the empty string. return $key . ($value != '' || $combine_on_empty ? $combine . $value : ''); } /** * Return the type of a passed in value */ private function getDataType($data) { if (is_array($data)) { reset($data); if (key($data) !== 0) { return self::TYPE_MAP; } return self::TYPE_LIST; } return self::TYPE_SCALAR; } /** * Utility function that merges multiple combine calls * for multi-key templates. */ private function combineList( $vars, $sep, $parameters, $combine, $reserved, $tag_empty, $combine_on_empty ) { $ret = array(); foreach ($vars as $var) { $response = $this->combine( $var, $parameters, $sep, $combine, $reserved, $tag_empty, $combine_on_empty ); if ($response === false) { continue; } $ret[] = $response; } return implode($sep, $ret); } /** * Utility function to encode and trim values */ private function getValue($value, $length) { if ($length) { $value = substr($value, 0, $length); } $value = rawurlencode($value); return $value; } } includes/Google/Verifier/Pem.php000064400000004204152214270100012565 0ustar00 */ class Google_Verifier_Pem extends Google_Verifier_Abstract { private $publicKey; /** * Constructs a verifier from the supplied PEM-encoded certificate. * * $pem: a PEM encoded certificate (not a file). * @param $pem * @throws Google_Auth_Exception * @throws Google_Exception */ public function __construct($pem) { if (!function_exists('openssl_x509_read')) { throw new Google_Exception('Google API PHP client needs the openssl PHP extension'); } $this->publicKey = openssl_x509_read($pem); if (!$this->publicKey) { throw new Google_Auth_Exception("Unable to parse PEM: $pem"); } } public function __destruct() { if ($this->publicKey) { openssl_x509_free($this->publicKey); } } /** * Verifies the signature on data. * * Returns true if the signature is valid, false otherwise. * @param $data * @param $signature * @throws Google_Auth_Exception * @return bool */ public function verify($data, $signature) { // @codingStandardsIgnoreLine $hash = defined("OPENSSL_ALGO_SHA256") ? OPENSSL_ALGO_SHA256 : "sha256"; $status = openssl_verify($data, $signature, $this->publicKey, $hash); if ($status === -1) { throw new Google_Auth_Exception('Signature verification error: ' . openssl_error_string()); } return $status === 1; } } includes/Google/Verifier/Abstract.php000064400000001557152214270100013617 0ustar00 */ abstract class Google_Verifier_Abstract { /** * Checks a signature, returns true if the signature is correct, * false otherwise. */ abstract public function verify($data, $signature); } includes/Google/Service.php000064400000001765152214270100011702 0ustar00client = $client; } /** * Return the associated UDP_Google_Client class. * @return UDP_Google_Client */ public function getClient() { return $this->client; } } includes/Google/Config.php000064400000033244152214270100011504 0ustar00configuration = array( // The application_name is included in the User-Agent HTTP header. 'application_name' => '', // Which Authentication, Storage and HTTP IO classes to use. 'auth_class' => 'Google_Auth_OAuth2', 'io_class' => self::USE_AUTO_IO_SELECTION, 'cache_class' => 'Google_Cache_File', 'logger_class' => 'Google_Logger_Null', // Don't change these unless you're working against a special development // or testing environment. 'base_path' => 'https://www.googleapis.com', // Definition of class specific values, like file paths and so on. 'classes' => array( 'UDP_Google_IO_Abstract' => array( 'request_timeout_seconds' => 100, ), 'Google_Logger_Abstract' => array( 'level' => 'debug', 'log_format' => "[%datetime%] %level%: %message% %context%\n", 'date_format' => 'd/M/Y:H:i:s O', 'allow_newlines' => true ), 'Google_Logger_File' => array( 'file' => 'php://stdout', 'mode' => 0640, 'lock' => false, ), 'UDP_Google_Http_Request' => array( // Disable the use of gzip on calls if set to true. Defaults to false. 'disable_gzip' => self::GZIP_ENABLED, // We default gzip to disabled on uploads even if gzip is otherwise // enabled, due to some issues seen with small packet sizes for uploads. // Please test with this option before enabling gzip for uploads in // a production environment. 'enable_gzip_for_uploads' => self::GZIP_UPLOADS_DISABLED, ), // If you want to pass in OAuth 2.0 settings, they will need to be // structured like this. 'Google_Auth_OAuth2' => array( // Keys for OAuth 2.0 access, see the API console at // https://developers.google.com/console 'client_id' => '', 'client_secret' => '', 'redirect_uri' => '', // Simple API access key, also from the API console. Ensure you get // a Server key, and not a Browser key. 'developer_key' => '', // Other parameters. 'hd' => '', 'prompt' => '', 'openid.realm' => '', 'include_granted_scopes' => '', 'login_hint' => '', 'request_visible_actions' => '', 'access_type' => 'online', 'approval_prompt' => 'auto', 'federated_signon_certs_url' => 'https://www.googleapis.com/oauth2/v1/certs', ), 'Google_Task_Runner' => array( // Delays are specified in seconds 'initial_delay' => 1, 'max_delay' => 60, // Base number for exponential backoff 'factor' => 2, // A random number between -jitter and jitter will be added to the // factor on each iteration to allow for better distribution of // retries. 'jitter' => .5, // Maximum number of retries allowed 'retries' => 0 ), 'UDP_Google_Service_Exception' => array( 'retry_map' => array( '500' => self::TASK_RETRY_ALWAYS, '503' => self::TASK_RETRY_ALWAYS, 'rateLimitExceeded' => self::TASK_RETRY_ALWAYS, 'userRateLimitExceeded' => self::TASK_RETRY_ALWAYS ) ), 'UDP_Google_IO_Exception' => array( 'retry_map' => !extension_loaded('curl') ? array() : array( CURLE_COULDNT_RESOLVE_HOST => self::TASK_RETRY_ALWAYS, CURLE_COULDNT_CONNECT => self::TASK_RETRY_ALWAYS, CURLE_OPERATION_TIMEOUTED => self::TASK_RETRY_ALWAYS, CURLE_SSL_CONNECT_ERROR => self::TASK_RETRY_ALWAYS, CURLE_GOT_NOTHING => self::TASK_RETRY_ALWAYS ) ), // Set a default directory for the file cache. 'Google_Cache_File' => array( 'directory' => sys_get_temp_dir() . '/UDP_Google_Client' ) ), ); if ($ini_file_location) { $ini = parse_ini_file($ini_file_location, true); if (is_array($ini) && count($ini)) { $merged_configuration = $ini + $this->configuration; if (isset($ini['classes']) && isset($this->configuration['classes'])) { $merged_configuration['classes'] = $ini['classes'] + $this->configuration['classes']; } $this->configuration = $merged_configuration; } } } /** * Set configuration specific to a given class. * $config->setClassConfig('Google_Cache_File', * array('directory' => '/tmp/cache')); * @param $class string The class name for the configuration * @param $config string key or an array of configuration values * @param $value string optional - if $config is a key, the value */ public function setClassConfig($class, $config, $value = null) { if (!is_array($config)) { if (!isset($this->configuration['classes'][$class])) { $this->configuration['classes'][$class] = array(); } $this->configuration['classes'][$class][$config] = $value; } else { $this->configuration['classes'][$class] = $config; } } public function getClassConfig($class, $key = null) { if (!isset($this->configuration['classes'][$class])) { return null; } if ($key === null) { return $this->configuration['classes'][$class]; } else { return $this->configuration['classes'][$class][$key]; } } /** * Return the configured cache class. * @return string */ public function getCacheClass() { return $this->configuration['cache_class']; } /** * Return the configured logger class. * @return string */ public function getLoggerClass() { return $this->configuration['logger_class']; } /** * Return the configured Auth class. * @return string */ public function getAuthClass() { return $this->configuration['auth_class']; } /** * Set the auth class. * * @param $class string the class name to set */ public function setAuthClass($class) { $prev = $this->configuration['auth_class']; if (!isset($this->configuration['classes'][$class]) && isset($this->configuration['classes'][$prev])) { $this->configuration['classes'][$class] = $this->configuration['classes'][$prev]; } $this->configuration['auth_class'] = $class; } /** * Set the IO class. * * @param $class string the class name to set */ public function setIoClass($class) { $prev = $this->configuration['io_class']; if (!isset($this->configuration['classes'][$class]) && isset($this->configuration['classes'][$prev])) { $this->configuration['classes'][$class] = $this->configuration['classes'][$prev]; } $this->configuration['io_class'] = $class; } /** * Set the cache class. * * @param $class string the class name to set */ public function setCacheClass($class) { $prev = $this->configuration['cache_class']; if (!isset($this->configuration['classes'][$class]) && isset($this->configuration['classes'][$prev])) { $this->configuration['classes'][$class] = $this->configuration['classes'][$prev]; } $this->configuration['cache_class'] = $class; } /** * Set the logger class. * * @param $class string the class name to set */ public function setLoggerClass($class) { $prev = $this->configuration['logger_class']; if (!isset($this->configuration['classes'][$class]) && isset($this->configuration['classes'][$prev])) { $this->configuration['classes'][$class] = $this->configuration['classes'][$prev]; } $this->configuration['logger_class'] = $class; } /** * Return the configured IO class. * * @return string */ public function getIoClass() { return $this->configuration['io_class']; } /** * Set the application name, this is included in the User-Agent HTTP header. * @param string $name */ public function setApplicationName($name) { $this->configuration['application_name'] = $name; } /** * @return string the name of the application */ public function getApplicationName() { return $this->configuration['application_name']; } /** * Set the client ID for the auth class. * @param $clientId string - the API console client ID */ public function setClientId($clientId) { $this->setAuthConfig('client_id', $clientId); } /** * Set the client secret for the auth class. * @param $secret string - the API console client secret */ public function setClientSecret($secret) { $this->setAuthConfig('client_secret', $secret); } /** * Set the redirect uri for the auth class. Note that if using the * Javascript based sign in flow, this should be the string 'postmessage'. * * @param $uri string - the URI that users should be redirected to */ public function setRedirectUri($uri) { $this->setAuthConfig('redirect_uri', $uri); } /** * Set the app activities for the auth class. * @param $rva string a space separated list of app activity types */ public function setRequestVisibleActions($rva) { $this->setAuthConfig('request_visible_actions', $rva); } /** * Set the the access type requested (offline or online.) * @param $access string - the access type */ public function setAccessType($access) { $this->setAuthConfig('access_type', $access); } /** * Set when to show the approval prompt (auto or force) * @param $approval string - the approval request */ public function setApprovalPrompt($approval) { $this->setAuthConfig('approval_prompt', $approval); } /** * Set the login hint (email address or sub identifier) * @param $hint string */ public function setLoginHint($hint) { $this->setAuthConfig('login_hint', $hint); } /** * Set the developer key for the auth class. Note that this is separate value * from the client ID - if it looks like a URL, its a client ID! * @param $key string - the API console developer key */ public function setDeveloperKey($key) { $this->setAuthConfig('developer_key', $key); } /** * Set the hd (hosted domain) parameter streamlines the login process for * Google Apps hosted accounts. By including the domain of the user, you * restrict sign-in to accounts at that domain. * * This should not be used to ensure security on your application - check * the hd values within an id token (@see Google_Auth_LoginTicket) after sign * in to ensure that the user is from the domain you were expecting. * * @param $hd string - the domain to use. */ public function setHostedDomain($hd) { $this->setAuthConfig('hd', $hd); } /** * Set the prompt hint. Valid values are none, consent and select_account. * If no value is specified and the user has not previously authorized * access, then the user is shown a consent screen. * @param $prompt string */ public function setPrompt($prompt) { $this->setAuthConfig('prompt', $prompt); } /** * openid.realm is a parameter from the OpenID 2.0 protocol, not from OAuth * 2.0. It is used in OpenID 2.0 requests to signify the URL-space for which * an authentication request is valid. * @param $realm string - the URL-space to use. */ public function setOpenidRealm($realm) { $this->setAuthConfig('openid.realm', $realm); } /** * If this is provided with the value true, and the authorization request is * granted, the authorization will include any previous authorizations * granted to this user/application combination for other scopes. * @param $include boolean - the URL-space to use. */ public function setIncludeGrantedScopes($include) { $this->setAuthConfig( 'include_granted_scopes', $include ? "true" : "false" ); } /** * @return string the base URL to use for API calls */ public function getBasePath() { return $this->configuration['base_path']; } /** * Set the auth configuration for the current auth class. * @param $key - the key to set * @param $value - the parameter value */ private function setAuthConfig($key, $value) { if (!isset($this->configuration['classes'][$this->getAuthClass()])) { $this->configuration['classes'][$this->getAuthClass()] = array(); } $this->configuration['classes'][$this->getAuthClass()][$key] = $value; } } includes/Google/autoload.php000064400000002765152214270100012113 0ustar00=')) { // Use the 'prepend' parameter; if other tools have registered autoloaders for incompatible versions of the Google SDK, ours should still get loaded first (since we only register our autoloader late, immediately before using it). spl_autoload_register('google_api_php_client_autoload_updraftplus', true, true); } else { spl_autoload_register('google_api_php_client_autoload_updraftplus'); } includes/Google/Model.php000064400000020127152214270100011333 0ustar00mapTypes($array); } $this->gapiInit(); } /** * Getter that handles passthrough access to the data array, and lazy object creation. * @param string $key Property name. * @return mixed The value if any, or null. */ public function __get($key) { $keyTypeName = $this->keyType($key); $keyDataType = $this->dataType($key); if (isset($this->$keyTypeName) && !isset($this->processed[$key])) { if (isset($this->modelData[$key])) { $val = $this->modelData[$key]; } else if (isset($this->$keyDataType) && ($this->$keyDataType == 'array' || $this->$keyDataType == 'map')) { $val = array(); } else { $val = null; } if ($this->isAssociativeArray($val)) { if (isset($this->$keyDataType) && 'map' == $this->$keyDataType) { foreach ($val as $arrayKey => $arrayItem) { $this->modelData[$key][$arrayKey] = $this->createObjectFromName($keyTypeName, $arrayItem); } } else { $this->modelData[$key] = $this->createObjectFromName($keyTypeName, $val); } } else if (is_array($val)) { $arrayObject = array(); foreach ($val as $arrayIndex => $arrayItem) { $arrayObject[$arrayIndex] = $this->createObjectFromName($keyTypeName, $arrayItem); } $this->modelData[$key] = $arrayObject; } $this->processed[$key] = true; } return isset($this->modelData[$key]) ? $this->modelData[$key] : null; } /** * Initialize this object's properties from an array. * * @param array $array Used to seed this object's properties. * @return void */ protected function mapTypes($array) { // Hard initialise simple types, lazy load more complex ones. foreach ($array as $key => $val) { if ( !property_exists($this, $this->keyType($key)) && property_exists($this, $key)) { $this->$key = $val; unset($array[$key]); } elseif (property_exists($this, $camelKey = Google_Utils::camelCase($key))) { // This checks if property exists as camelCase, leaving it in array as snake_case // in case of backwards compatibility issues. $this->$camelKey = $val; } } $this->modelData = $array; } /** * Blank initialiser to be used in subclasses to do post-construction initialisation - this * avoids the need for subclasses to have to implement the variadics handling in their * constructors. */ protected function gapiInit() { return; } /** * Create a simplified object suitable for straightforward * conversion to JSON. This is relatively expensive * due to the usage of reflection, but shouldn't be called * a whole lot, and is the most straightforward way to filter. */ public function toSimpleObject() { $object = new stdClass(); // Process all other data. foreach ($this->modelData as $key => $val) { $result = $this->getSimpleValue($val); if ($result !== null) { $object->$key = $this->nullPlaceholderCheck($result); } } // Process all public properties. $reflect = new ReflectionObject($this); $props = $reflect->getProperties(ReflectionProperty::IS_PUBLIC); foreach ($props as $member) { $name = $member->getName(); $result = $this->getSimpleValue($this->$name); if ($result !== null) { $name = $this->getMappedName($name); $object->$name = $this->nullPlaceholderCheck($result); } } return $object; } /** * Handle different types of values, primarily * other objects and map and array data types. */ private function getSimpleValue($value) { if ($value instanceof Google_Model) { return $value->toSimpleObject(); } else if (is_array($value)) { $return = array(); foreach ($value as $key => $a_value) { $a_value = $this->getSimpleValue($a_value); if ($a_value !== null) { $key = $this->getMappedName($key); $return[$key] = $this->nullPlaceholderCheck($a_value); } } return $return; } return $value; } /** * Check whether the value is the null placeholder and return true null. */ private function nullPlaceholderCheck($value) { if ($value === self::NULL_VALUE) { return null; } return $value; } /** * If there is an internal name mapping, use that. */ private function getMappedName($key) { if (isset($this->internal_gapi_mappings) && isset($this->internal_gapi_mappings[$key])) { $key = $this->internal_gapi_mappings[$key]; } return $key; } /** * Returns true only if the array is associative. * @param array $array * @return bool True if the array is associative. */ protected function isAssociativeArray($array) { if (!is_array($array)) { return false; } $keys = array_keys($array); foreach ($keys as $key) { if (is_string($key)) { return true; } } return false; } /** * Given a variable name, discover its type. * * @param $name * @param $item * @return object The object from the item. */ private function createObjectFromName($name, $item) { $type = $this->$name; return new $type($item); } /** * Verify if $obj is an array. * @throws Google_Exception Thrown if $obj isn't an array. * @param array $obj Items that should be validated. * @param string $method Method expecting an array as an argument. */ public function assertIsArray($obj, $method) { if ($obj && !is_array($obj)) { throw new Google_Exception( "Incorrect parameter type passed to $method(). Expected an array." ); } } #[\ReturnTypeWillChange] public function offsetExists($offset) { return isset($this->$offset) || isset($this->modelData[$offset]); } #[\ReturnTypeWillChange] public function offsetGet($offset) { return isset($this->$offset) ? $this->$offset : $this->__get($offset); } #[\ReturnTypeWillChange] public function offsetSet($offset, $value) { if (property_exists($this, $offset)) { $this->$offset = $value; } else { $this->modelData[$offset] = $value; $this->processed[$offset] = true; } } #[\ReturnTypeWillChange] public function offsetUnset($offset) { unset($this->modelData[$offset]); } protected function keyType($key) { return $key . "Type"; } protected function dataType($key) { return $key . "DataType"; } public function __isset($key) { return isset($this->modelData[$key]); } public function __unset($key) { unset($this->modelData[$key]); } } includes/Google/Client.php000064400000047415152214270100011522 0ustar00isAppEngine()) { // Automatically use Memcache if we're in AppEngine. $config->setCacheClass('Google_Cache_Memcache'); } if (version_compare(phpversion(), "5.3.4", "<=") || $this->isAppEngine()) { // Automatically disable compress.zlib, as currently unsupported. $config->setClassConfig('UDP_Google_Http_Request', 'disable_gzip', true); } } if ($config->getIoClass() == UDP_Google_Config::USE_AUTO_IO_SELECTION) { if (function_exists('curl_version') && function_exists('curl_exec') && !$this->isAppEngine()) { $config->setIoClass("UDP_Google_IO_Curl"); } else { $config->setIoClass("UDP_Google_IO_Stream"); } } $this->config = $config; } /** * Get a string containing the version of the library. * * @return string */ public function getLibraryVersion() { return self::LIBVER; } /** * Attempt to exchange a code for an valid authentication token. * Helper wrapped around the OAuth 2.0 implementation. * * @param $code string code from accounts.google.com * @return string token */ public function authenticate($code) { $this->authenticated = true; return $this->getAuth()->authenticate($code); } /** * Loads a service account key and parameters from a JSON * file from the Google Developer Console. Uses that and the * given array of scopes to return an assertion credential for * use with refreshTokenWithAssertionCredential. * * @param string $jsonLocation File location of the project-key.json. * @param array $scopes The scopes to assert. * @return Google_Auth_AssertionCredentials. * @ */ public function loadServiceAccountJson($jsonLocation, $scopes) { $data = json_decode(file_get_contents($jsonLocation)); if (isset($data->type) && $data->type == 'service_account') { // Service Account format. $cred = new Google_Auth_AssertionCredentials( $data->client_email, $scopes, $data->private_key ); return $cred; } else { throw new Google_Exception("Invalid service account JSON file."); } } /** * Set the auth config from the JSON string provided. * This structure should match the file downloaded from * the "Download JSON" button on in the Google Developer * Console. * @param string $json the configuration json * @throws Google_Exception */ public function setAuthConfig($json) { $data = json_decode($json); $key = isset($data->installed) ? 'installed' : 'web'; if (!isset($data->$key)) { throw new Google_Exception("Invalid client secret JSON file."); } $this->setClientId($data->$key->client_id); $this->setClientSecret($data->$key->client_secret); if (isset($data->$key->redirect_uris)) { $this->setRedirectUri($data->$key->redirect_uris[0]); } } /** * Set the auth config from the JSON file in the path * provided. This should match the file downloaded from * the "Download JSON" button on in the Google Developer * Console. * @param string $file the file location of the client json */ public function setAuthConfigFile($file) { $this->setAuthConfig(file_get_contents($file)); } /** * @throws Google_Auth_Exception * @return array * @visible For Testing */ public function prepareScopes() { if (empty($this->requestedScopes)) { throw new Google_Auth_Exception("No scopes specified"); } $scopes = implode(' ', $this->requestedScopes); return $scopes; } /** * Set the OAuth 2.0 access token using the string that resulted from calling createAuthUrl() * or UDP_Google_Client#getAccessToken(). * @param string $accessToken JSON encoded string containing in the following format: * {"access_token":"TOKEN", "refresh_token":"TOKEN", "token_type":"Bearer", * "expires_in":3600, "id_token":"TOKEN", "created":1320790426} */ public function setAccessToken($accessToken) { if ($accessToken == 'null') { $accessToken = null; } $this->getAuth()->setAccessToken($accessToken); } /** * Set the authenticator object * @param Google_Auth_Abstract $auth */ public function setAuth(Google_Auth_Abstract $auth) { $this->config->setAuthClass(get_class($auth)); $this->auth = $auth; } /** * Set the IO object * @param UDP_Google_IO_Abstract $io */ public function setIo(UDP_Google_IO_Abstract $io) { $this->config->setIoClass(get_class($io)); $this->io = $io; } /** * Set the Cache object * @param Google_Cache_Abstract $cache */ public function setCache(Google_Cache_Abstract $cache) { $this->config->setCacheClass(get_class($cache)); $this->cache = $cache; } /** * Set the Logger object * @param Google_Logger_Abstract $logger */ public function setLogger(Google_Logger_Abstract $logger) { $this->config->setLoggerClass(get_class($logger)); $this->logger = $logger; } /** * Construct the OAuth 2.0 authorization request URI. * @return string */ public function createAuthUrl() { $scopes = $this->prepareScopes(); return $this->getAuth()->createAuthUrl($scopes); } /** * Get the OAuth 2.0 access token. * @return string $accessToken JSON encoded string in the following format: * {"access_token":"TOKEN", "refresh_token":"TOKEN", "token_type":"Bearer", * "expires_in":3600,"id_token":"TOKEN", "created":1320790426} */ public function getAccessToken() { $token = $this->getAuth()->getAccessToken(); // The response is json encoded, so could be the string null. // It is arguable whether this check should be here or lower // in the library. return (null == $token || 'null' == $token || '[]' == $token) ? null : $token; } /** * Get the OAuth 2.0 refresh token. * @return string $refreshToken refresh token or null if not available */ public function getRefreshToken() { return $this->getAuth()->getRefreshToken(); } /** * Returns if the access_token is expired. * @return bool Returns True if the access_token is expired. */ public function isAccessTokenExpired() { return $this->getAuth()->isAccessTokenExpired(); } /** * Set OAuth 2.0 "state" parameter to achieve per-request customization. * @see http://tools.ietf.org/html/draft-ietf-oauth-v2-22#section-3.1.2.2 * @param string $state */ public function setState($state) { $this->getAuth()->setState($state); } /** * @param string $accessType Possible values for access_type include: * {@code "offline"} to request offline access from the user. * {@code "online"} to request online access from the user. */ public function setAccessType($accessType) { $this->config->setAccessType($accessType); } /** * @param string $approvalPrompt Possible values for approval_prompt include: * {@code "force"} to force the approval UI to appear. (This is the default value) * {@code "auto"} to request auto-approval when possible. */ public function setApprovalPrompt($approvalPrompt) { $this->config->setApprovalPrompt($approvalPrompt); } /** * Set the login hint, email address or sub id. * @param string $loginHint */ public function setLoginHint($loginHint) { $this->config->setLoginHint($loginHint); } /** * Set the application name, this is included in the User-Agent HTTP header. * @param string $applicationName */ public function setApplicationName($applicationName) { $this->config->setApplicationName($applicationName); } /** * Set the OAuth 2.0 Client ID. * @param string $clientId */ public function setClientId($clientId) { $this->config->setClientId($clientId); } /** * Set the OAuth 2.0 Client Secret. * @param string $clientSecret */ public function setClientSecret($clientSecret) { $this->config->setClientSecret($clientSecret); } /** * Set the OAuth 2.0 Redirect URI. * @param string $redirectUri */ public function setRedirectUri($redirectUri) { $this->config->setRedirectUri($redirectUri); } /** * If 'plus.login' is included in the list of requested scopes, you can use * this method to define types of app activities that your app will write. * You can find a list of available types here: * @link https://developers.google.com/+/api/moment-types * * @param array $requestVisibleActions Array of app activity types */ public function setRequestVisibleActions($requestVisibleActions) { if (is_array($requestVisibleActions)) { $requestVisibleActions = join(" ", $requestVisibleActions); } $this->config->setRequestVisibleActions($requestVisibleActions); } /** * Set the developer key to use, these are obtained through the API Console. * @see http://code.google.com/apis/console-help/#generatingdevkeys * @param string $developerKey */ public function setDeveloperKey($developerKey) { $this->config->setDeveloperKey($developerKey); } /** * Set the hd (hosted domain) parameter streamlines the login process for * Google Apps hosted accounts. By including the domain of the user, you * restrict sign-in to accounts at that domain. * @param $hd string - the domain to use. */ public function setHostedDomain($hd) { $this->config->setHostedDomain($hd); } /** * Set the prompt hint. Valid values are none, consent and select_account. * If no value is specified and the user has not previously authorized * access, then the user is shown a consent screen. * @param $prompt string */ public function setPrompt($prompt) { $this->config->setPrompt($prompt); } /** * openid.realm is a parameter from the OpenID 2.0 protocol, not from OAuth * 2.0. It is used in OpenID 2.0 requests to signify the URL-space for which * an authentication request is valid. * @param $realm string - the URL-space to use. */ public function setOpenidRealm($realm) { $this->config->setOpenidRealm($realm); } /** * If this is provided with the value true, and the authorization request is * granted, the authorization will include any previous authorizations * granted to this user/application combination for other scopes. * @param $include boolean - the URL-space to use. */ public function setIncludeGrantedScopes($include) { $this->config->setIncludeGrantedScopes($include); } /** * Fetches a fresh OAuth 2.0 access token with the given refresh token. * @param string $refreshToken */ public function refreshToken($refreshToken) { $this->getAuth()->refreshToken($refreshToken); } /** * Revoke an OAuth2 access token or refresh token. This method will revoke the current access * token, if a token isn't provided. * @throws Google_Auth_Exception * @param string|null $token The token (access token or a refresh token) that should be revoked. * @return boolean Returns True if the revocation was successful, otherwise False. */ public function revokeToken($token = null) { return $this->getAuth()->revokeToken($token); } /** * Verify an id_token. This method will verify the current id_token, if one * isn't provided. * @throws Google_Auth_Exception * @param string|null $token The token (id_token) that should be verified. * @return Google_Auth_LoginTicket Returns an apiLoginTicket if the verification was * successful. */ public function verifyIdToken($token = null) { return $this->getAuth()->verifyIdToken($token); } /** * Verify a JWT that was signed with your own certificates. * * @param $id_token string The JWT token * @param $cert_location array of certificates * @param $audience string the expected consumer of the token * @param $issuer string the expected issuer, defaults to Google * @param [$max_expiry] the max lifetime of a token, defaults to MAX_TOKEN_LIFETIME_SECS * @return mixed token information if valid, false if not */ public function verifySignedJwt($id_token, $cert_location, $audience, $issuer, $max_expiry = null) { $auth = new Google_Auth_OAuth2($this); $certs = $auth->retrieveCertsFromLocation($cert_location); return $auth->verifySignedJwtWithCerts($id_token, $certs, $audience, $issuer, $max_expiry); } /** * @param $creds Google_Auth_AssertionCredentials */ public function setAssertionCredentials(Google_Auth_AssertionCredentials $creds) { $this->getAuth()->setAssertionCredentials($creds); } /** * Set the scopes to be requested. Must be called before createAuthUrl(). * Will remove any previously configured scopes. * @param array $scopes, ie: array('https://www.googleapis.com/auth/plus.login', * 'https://www.googleapis.com/auth/moderator') */ public function setScopes($scopes) { $this->requestedScopes = array(); $this->addScope($scopes); } /** * This functions adds a scope to be requested as part of the OAuth2.0 flow. * Will append any scopes not previously requested to the scope parameter. * A single string will be treated as a scope to request. An array of strings * will each be appended. * @param $scope_or_scopes string|array e.g. "profile" */ public function addScope($scope_or_scopes) { if (is_string($scope_or_scopes) && !in_array($scope_or_scopes, $this->requestedScopes)) { $this->requestedScopes[] = $scope_or_scopes; } else if (is_array($scope_or_scopes)) { foreach ($scope_or_scopes as $scope) { $this->addScope($scope); } } } /** * Returns the list of scopes requested by the client * @return array the list of scopes * */ public function getScopes() { return $this->requestedScopes; } /** * Declare whether batch calls should be used. This may increase throughput * by making multiple requests in one connection. * * @param boolean $useBatch True if the batch support should * be enabled. Defaults to False. */ public function setUseBatch($useBatch) { // This is actually an alias for setDefer. $this->setDefer($useBatch); } /** * Declare whether making API calls should make the call immediately, or * return a request which can be called with ->execute(); * * @param boolean $defer True if calls should not be executed right away. */ public function setDefer($defer) { $this->deferExecution = $defer; } /** * Helper method to execute deferred HTTP requests. * * @param $request Google_Http_Request|Google_Http_Batch * @throws Google_Exception * @return object of the type of the expected class or array. */ public function execute($request) { if ($request instanceof UDP_Google_Http_Request) { $request->setUserAgent( $this->getApplicationName() . " " . self::USER_AGENT_SUFFIX . $this->getLibraryVersion() ); if (!$this->getClassConfig("UDP_Google_Http_Request", "disable_gzip")) { $request->enableGzip(); } $request->maybeMoveParametersToBody(); return UDP_Google_Http_REST::execute($this, $request); } else if ($request instanceof Google_Http_Batch) { return $request->execute(); } else { throw new Google_Exception("Do not know how to execute this type of object."); } } /** * Whether or not to return raw requests * @return boolean */ public function shouldDefer() { return $this->deferExecution; } /** * @return Google_Auth_Abstract Authentication implementation */ public function getAuth() { if (!isset($this->auth)) { $class = $this->config->getAuthClass(); $this->auth = new $class($this); } return $this->auth; } /** * @return UDP_Google_IO_Abstract IO implementation */ public function getIo() { if (!isset($this->io)) { $class = $this->config->getIoClass(); $this->io = new $class($this); } return $this->io; } /** * @return Google_Cache_Abstract Cache implementation */ public function getCache() { if (!isset($this->cache)) { $class = $this->config->getCacheClass(); $this->cache = new $class($this); } return $this->cache; } /** * @return Google_Logger_Abstract Logger implementation */ public function getLogger() { if (!isset($this->logger)) { $class = $this->config->getLoggerClass(); $this->logger = new $class($this); } return $this->logger; } /** * Retrieve custom configuration for a specific class. * @param $class string|object - class or instance of class to retrieve * @param $key string optional - key to retrieve * @return array */ public function getClassConfig($class, $key = null) { if (!is_string($class)) { $class = get_class($class); } return $this->config->getClassConfig($class, $key); } /** * Set configuration specific to a given class. * $config->setClassConfig('Google_Cache_File', * array('directory' => '/tmp/cache')); * @param $class string|object - The class name for the configuration * @param $config string key or an array of configuration values * @param $value string optional - if $config is a key, the value * */ public function setClassConfig($class, $config, $value = null) { if (!is_string($class)) { $class = get_class($class); } $this->config->setClassConfig($class, $config, $value); } /** * @return string the base URL to use for calls to the APIs */ public function getBasePath() { return $this->config->getBasePath(); } /** * @return string the name of the application */ public function getApplicationName() { return $this->config->getApplicationName(); } /** * Are we running in Google AppEngine? * return bool */ public function isAppEngine() { return (isset($_SERVER['SERVER_SOFTWARE']) && strpos($_SERVER['SERVER_SOFTWARE'], 'Google App Engine') !== false); } } includes/Google/Collection.php000064400000005305152214270100012367 0ustar00modelData[$this->collection_key]) && is_array($this->modelData[$this->collection_key])) { reset($this->modelData[$this->collection_key]); } } #[\ReturnTypeWillChange] public function current() { $this->coerceType($this->key()); if (is_array($this->modelData[$this->collection_key])) { return current($this->modelData[$this->collection_key]); } } #[\ReturnTypeWillChange] public function key() { if (isset($this->modelData[$this->collection_key]) && is_array($this->modelData[$this->collection_key])) { return key($this->modelData[$this->collection_key]); } } #[\ReturnTypeWillChange] public function next() { return next($this->modelData[$this->collection_key]); } #[\ReturnTypeWillChange] public function valid() { $key = $this->key(); return $key !== null && $key !== false; } #[\ReturnTypeWillChange] public function count() { if (!isset($this->modelData[$this->collection_key])) { return 0; } return count($this->modelData[$this->collection_key]); } public function offsetExists ($offset) { if (!is_numeric($offset)) { return parent::offsetExists($offset); } return isset($this->modelData[$this->collection_key][$offset]); } public function offsetGet($offset) { if (!is_numeric($offset)) { return parent::offsetGet($offset); } $this->coerceType($offset); return $this->modelData[$this->collection_key][$offset]; } public function offsetSet($offset, $value) { if (!is_numeric($offset)) { return parent::offsetSet($offset, $value); } $this->modelData[$this->collection_key][$offset] = $value; } public function offsetUnset($offset) { if (!is_numeric($offset)) { return parent::offsetUnset($offset); } unset($this->modelData[$this->collection_key][$offset]); } private function coerceType($offset) { $typeKey = $this->keyType($this->collection_key); if (isset($this->$typeKey) && !is_object($this->modelData[$this->collection_key][$offset])) { $type = $this->$typeKey; $this->modelData[$this->collection_key][$offset] = new $type($this->modelData[$this->collection_key][$offset]); } } } includes/Google/Utils.php000064400000007552152214270100011402 0ustar00= 0x20) && ($ordinalValue <= 0x7F)): // characters U-00000000 - U-0000007F (same as ASCII) $ret ++; break; case (($ordinalValue & 0xE0) == 0xC0): // characters U-00000080 - U-000007FF, mask 110XXXXX // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 $ret += 2; break; case (($ordinalValue & 0xF0) == 0xE0): // characters U-00000800 - U-0000FFFF, mask 1110XXXX // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 $ret += 3; break; case (($ordinalValue & 0xF8) == 0xF0): // characters U-00010000 - U-001FFFFF, mask 11110XXX // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 $ret += 4; break; case (($ordinalValue & 0xFC) == 0xF8): // characters U-00200000 - U-03FFFFFF, mask 111110XX // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 $ret += 5; break; case (($ordinalValue & 0xFE) == 0xFC): // characters U-04000000 - U-7FFFFFFF, mask 1111110X // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 $ret += 6; break; default: $ret ++; } } return $ret; } /** * Normalize all keys in an array to lower-case. * @param array $arr * @return array Normalized array. */ public static function normalize($arr) { if (!is_array($arr)) { return array(); } $normalized = array(); foreach ($arr as $key => $val) { $normalized[strtolower($key)] = $val; } return $normalized; } /** * Convert a string to camelCase * @param string $value * @return string */ public static function camelCase($value) { $value = ucwords(str_replace(array('-', '_'), ' ', $value)); $value = str_replace(' ', '', $value); $value[0] = strtolower($value[0]); return $value; } } includes/Google/Exception.php000064400000001207152214270100012227 0ustar00 * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * @category File_Formats * @package Archive_Tar * @author Vincent Blavet * @copyright 1997-2010 The Authors * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @version CVS: $Id$ * @link http://pear.php.net/package/Archive_Tar */ // If the PEAR class cannot be loaded via the autoloader, // then try to require_once it from the PHP include path. if (!class_exists('PEAR')) { require_once 'PEAR.php'; } define('ARCHIVE_TAR_ATT_SEPARATOR', 90001); define('ARCHIVE_TAR_END_BLOCK', pack("a512", '')); if (!function_exists('gzopen') && function_exists('gzopen64')) { function gzopen($filename, $mode, $use_include_path = 0) { return gzopen64($filename, $mode, $use_include_path); } } if (!function_exists('gztell') && function_exists('gztell64')) { function gztell($zp) { return gztell64($zp); } } if (!function_exists('gzseek') && function_exists('gzseek64')) { function gzseek($zp, $offset, $whence = SEEK_SET) { return gzseek64($zp, $offset, $whence); } } /** * Creates a (compressed) Tar archive * * @package Archive_Tar * @author Vincent Blavet * @license http://www.opensource.org/licenses/bsd-license.php New BSD License * @version $Revision$ */ class Archive_Tar extends PEAR { /** * @var string Name of the Tar */ public $_tarname = ''; /** * @var boolean if true, the Tar file will be gzipped */ public $_compress = false; /** * @var string Type of compression : 'none', 'gz', 'bz2' or 'lzma2' */ public $_compress_type = 'none'; /** * @var string Explode separator */ public $_separator = ' '; /** * @var file descriptor */ public $_file = 0; /** * @var string Local Tar name of a remote Tar (http:// or ftp://) */ public $_temp_tarname = ''; /** * @var string regular expression for ignoring files or directories */ public $_ignore_regexp = ''; /** * @var object PEAR_Error object */ public $error_object = null; /** * Format for data extraction * * @var string */ public $_fmt =''; /** * Archive_Tar Class constructor. This flavour of the constructor only * declare a new Archive_Tar object, identifying it by the name of the * tar file. * If the compress argument is set the tar will be read or created as a * gzip or bz2 compressed TAR file. * * @param string $p_tarname The name of the tar archive to create * @param string $p_compress can be null, 'gz', 'bz2' or 'lzma2'. This * parameter indicates if gzip, bz2 or lzma2 compression * is required. For compatibility reason the * boolean value 'true' means 'gz'. * * @return bool */ public function __construct($p_tarname, $p_compress = null) { parent::__construct(); $this->_compress = false; $this->_compress_type = 'none'; if (($p_compress === null) || ($p_compress == '')) { if (@file_exists($p_tarname)) { if ($fp = @fopen($p_tarname, "rb")) { // look for gzip magic cookie $data = fread($fp, 2); fclose($fp); if ($data == "\37\213") { $this->_compress = true; $this->_compress_type = 'gz'; // No sure it's enought for a magic code .... } elseif ($data == "BZ") { $this->_compress = true; $this->_compress_type = 'bz2'; } elseif (file_get_contents($p_tarname, false, null, 1, 4) == '7zXZ') { $this->_compress = true; $this->_compress_type = 'lzma2'; } } } else { // probably a remote file or some file accessible // through a stream interface if (substr($p_tarname, -2) == 'gz') { $this->_compress = true; $this->_compress_type = 'gz'; } elseif ((substr($p_tarname, -3) == 'bz2') || (substr($p_tarname, -2) == 'bz') ) { $this->_compress = true; $this->_compress_type = 'bz2'; } else { if (substr($p_tarname, -2) == 'xz') { $this->_compress = true; $this->_compress_type = 'lzma2'; } } } } else { if (($p_compress === true) || ($p_compress == 'gz')) { $this->_compress = true; $this->_compress_type = 'gz'; } else { if ($p_compress == 'bz2') { $this->_compress = true; $this->_compress_type = 'bz2'; } else { if ($p_compress == 'lzma2') { $this->_compress = true; $this->_compress_type = 'lzma2'; } else { $this->_error( "Unsupported compression type '$p_compress'\n" . "Supported types are 'gz', 'bz2' and 'lzma2'.\n" ); return false; } } } } $this->_tarname = $p_tarname; if ($this->_compress) { // assert zlib or bz2 or xz extension support if ($this->_compress_type == 'gz') { $extname = 'zlib'; } else { if ($this->_compress_type == 'bz2') { $extname = 'bz2'; } else { if ($this->_compress_type == 'lzma2') { $extname = 'xz'; } } } if (!extension_loaded($extname)) { PEAR::loadExtension($extname); } if (!extension_loaded($extname)) { $this->_error( "The extension '$extname' couldn't be found.\n" . "Please make sure your version of PHP was built " . "with '$extname' support.\n" ); return false; } } if (version_compare(PHP_VERSION, "5.5.0-dev") < 0) { $this->_fmt = "a100filename/a8mode/a8uid/a8gid/a12size/a12mtime/" . "a8checksum/a1typeflag/a100link/a6magic/a2version/" . "a32uname/a32gname/a8devmajor/a8devminor/a131prefix"; } else { $this->_fmt = "Z100filename/Z8mode/Z8uid/Z8gid/Z12size/Z12mtime/" . "Z8checksum/Z1typeflag/Z100link/Z6magic/Z2version/" . "Z32uname/Z32gname/Z8devmajor/Z8devminor/Z131prefix"; } } public function __destruct() { $this->_close(); // ----- Look for a local copy to delete if ($this->_temp_tarname != '') { @unlink($this->_temp_tarname); } } /** * This method creates the archive file and add the files / directories * that are listed in $p_filelist. * If a file with the same name exist and is writable, it is replaced * by the new tar. * The method return false and a PEAR error text. * The $p_filelist parameter can be an array of string, each string * representing a filename or a directory name with their path if * needed. It can also be a single string with names separated by a * single blank. * For each directory added in the archive, the files and * sub-directories are also added. * See also createModify() method for more details. * * @param array $p_filelist An array of filenames and directory names, or a * single string with names separated by a single * blank space. * * @return true on success, false on error. * @see createModify() */ public function create($p_filelist) { return $this->createModify($p_filelist, '', ''); } /** * This method add the files / directories that are listed in $p_filelist in * the archive. If the archive does not exist it is created. * The method return false and a PEAR error text. * The files and directories listed are only added at the end of the archive, * even if a file with the same name is already archived. * See also createModify() method for more details. * * @param array $p_filelist An array of filenames and directory names, or a * single string with names separated by a single * blank space. * * @return true on success, false on error. * @see createModify() * @access public */ public function add($p_filelist) { return $this->addModify($p_filelist, '', ''); } /** * @param string $p_path * @param bool $p_preserve * @return bool */ public function extract($p_path = '', $p_preserve = false) { return $this->extractModify($p_path, '', $p_preserve); } /** * @return array|int */ public function listContent() { $v_list_detail = array(); if ($this->_openRead()) { if (!$this->_extractList('', $v_list_detail, "list", '', '')) { unset($v_list_detail); $v_list_detail = 0; } $this->_close(); } return $v_list_detail; } /** * This method creates the archive file and add the files / directories * that are listed in $p_filelist. * If the file already exists and is writable, it is replaced by the * new tar. It is a create and not an add. If the file exists and is * read-only or is a directory it is not replaced. The method return * false and a PEAR error text. * The $p_filelist parameter can be an array of string, each string * representing a filename or a directory name with their path if * needed. It can also be a single string with names separated by a * single blank. * The path indicated in $p_remove_dir will be removed from the * memorized path of each file / directory listed when this path * exists. By default nothing is removed (empty path '') * The path indicated in $p_add_dir will be added at the beginning of * the memorized path of each file / directory listed. However it can * be set to empty ''. The adding of a path is done after the removing * of path. * The path add/remove ability enables the user to prepare an archive * for extraction in a different path than the origin files are. * See also addModify() method for file adding properties. * * @param array $p_filelist An array of filenames and directory names, * or a single string with names separated by * a single blank space. * @param string $p_add_dir A string which contains a path to be added * to the memorized path of each element in * the list. * @param string $p_remove_dir A string which contains a path to be * removed from the memorized path of each * element in the list, when relevant. * * @return boolean true on success, false on error. * @see addModify() */ public function createModify($p_filelist, $p_add_dir, $p_remove_dir = '') { $v_result = true; if (!$this->_openWrite()) { return false; } if ($p_filelist != '') { if (is_array($p_filelist)) { $v_list = $p_filelist; } elseif (is_string($p_filelist)) { $v_list = explode($this->_separator, $p_filelist); } else { $this->_cleanFile(); $this->_error('Invalid file list'); return false; } $v_result = $this->_addList($v_list, $p_add_dir, $p_remove_dir); } if ($v_result) { $this->_writeFooter(); $this->_close(); } else { $this->_cleanFile(); } return $v_result; } /** * This method add the files / directories listed in $p_filelist at the * end of the existing archive. If the archive does not yet exists it * is created. * The $p_filelist parameter can be an array of string, each string * representing a filename or a directory name with their path if * needed. It can also be a single string with names separated by a * single blank. * The path indicated in $p_remove_dir will be removed from the * memorized path of each file / directory listed when this path * exists. By default nothing is removed (empty path '') * The path indicated in $p_add_dir will be added at the beginning of * the memorized path of each file / directory listed. However it can * be set to empty ''. The adding of a path is done after the removing * of path. * The path add/remove ability enables the user to prepare an archive * for extraction in a different path than the origin files are. * If a file/dir is already in the archive it will only be added at the * end of the archive. There is no update of the existing archived * file/dir. However while extracting the archive, the last file will * replace the first one. This results in a none optimization of the * archive size. * If a file/dir does not exist the file/dir is ignored. However an * error text is send to PEAR error. * If a file/dir is not readable the file/dir is ignored. However an * error text is send to PEAR error. * * @param array $p_filelist An array of filenames and directory * names, or a single string with names * separated by a single blank space. * @param string $p_add_dir A string which contains a path to be * added to the memorized path of each * element in the list. * @param string $p_remove_dir A string which contains a path to be * removed from the memorized path of * each element in the list, when * relevant. * * @return true on success, false on error. */ public function addModify($p_filelist, $p_add_dir, $p_remove_dir = '') { $v_result = true; if (!$this->_isArchive()) { $v_result = $this->createModify( $p_filelist, $p_add_dir, $p_remove_dir ); } else { if (is_array($p_filelist)) { $v_list = $p_filelist; } elseif (is_string($p_filelist)) { $v_list = explode($this->_separator, $p_filelist); } else { $this->_error('Invalid file list'); return false; } $v_result = $this->_append($v_list, $p_add_dir, $p_remove_dir); } return $v_result; } /** * This method add a single string as a file at the * end of the existing archive. If the archive does not yet exists it * is created. * * @param string $p_filename A string which contains the full * filename path that will be associated * with the string. * @param string $p_string The content of the file added in * the archive. * @param bool|int $p_datetime A custom date/time (unix timestamp) * for the file (optional). * @param array $p_params An array of optional params: * stamp => the datetime (replaces * datetime above if it exists) * mode => the permissions on the * file (600 by default) * type => is this a link? See the * tar specification for details. * (default = regular file) * uid => the user ID of the file * (default = 0 = root) * gid => the group ID of the file * (default = 0 = root) * * @return true on success, false on error. */ public function addString($p_filename, $p_string, $p_datetime = false, $p_params = array()) { $p_stamp = @$p_params["stamp"] ? $p_params["stamp"] : ($p_datetime ? $p_datetime : time()); $p_mode = @$p_params["mode"] ? $p_params["mode"] : 0600; $p_type = @$p_params["type"] ? $p_params["type"] : ""; $p_uid = @$p_params["uid"] ? $p_params["uid"] : ""; $p_gid = @$p_params["gid"] ? $p_params["gid"] : ""; $v_result = true; if (!$this->_isArchive()) { if (!$this->_openWrite()) { return false; } $this->_close(); } if (!$this->_openAppend()) { return false; } // Need to check the get back to the temporary file ? .... $v_result = $this->_addString($p_filename, $p_string, $p_datetime, $p_params); $this->_writeFooter(); $this->_close(); return $v_result; } /** * This method extract all the content of the archive in the directory * indicated by $p_path. When relevant the memorized path of the * files/dir can be modified by removing the $p_remove_path path at the * beginning of the file/dir path. * While extracting a file, if the directory path does not exists it is * created. * While extracting a file, if the file already exists it is replaced * without looking for last modification date. * While extracting a file, if the file already exists and is write * protected, the extraction is aborted. * While extracting a file, if a directory with the same name already * exists, the extraction is aborted. * While extracting a directory, if a file with the same name already * exists, the extraction is aborted. * While extracting a file/directory if the destination directory exist * and is write protected, or does not exist but can not be created, * the extraction is aborted. * If after extraction an extracted file does not show the correct * stored file size, the extraction is aborted. * When the extraction is aborted, a PEAR error text is set and false * is returned. However the result can be a partial extraction that may * need to be manually cleaned. * * @param string $p_path The path of the directory where the * files/dir need to by extracted. * @param string $p_remove_path Part of the memorized path that can be * removed if present at the beginning of * the file/dir path. * @param boolean $p_preserve Preserve user/group ownership of files * * @return boolean true on success, false on error. * @see extractList() */ public function extractModify($p_path, $p_remove_path, $p_preserve = false) { $v_result = true; $v_list_detail = array(); if ($v_result = $this->_openRead()) { $v_result = $this->_extractList( $p_path, $v_list_detail, "complete", 0, $p_remove_path, $p_preserve ); $this->_close(); } return $v_result; } /** * This method extract from the archive one file identified by $p_filename. * The return value is a string with the file content, or NULL on error. * * @param string $p_filename The path of the file to extract in a string. * * @return a string with the file content or NULL. */ public function extractInString($p_filename) { if ($this->_openRead()) { $v_result = $this->_extractInString($p_filename); $this->_close(); } else { $v_result = null; } return $v_result; } /** * This method extract from the archive only the files indicated in the * $p_filelist. These files are extracted in the current directory or * in the directory indicated by the optional $p_path parameter. * If indicated the $p_remove_path can be used in the same way as it is * used in extractModify() method. * * @param array $p_filelist An array of filenames and directory names, * or a single string with names separated * by a single blank space. * @param string $p_path The path of the directory where the * files/dir need to by extracted. * @param string $p_remove_path Part of the memorized path that can be * removed if present at the beginning of * the file/dir path. * @param boolean $p_preserve Preserve user/group ownership of files * * @return true on success, false on error. * @see extractModify() */ public function extractList($p_filelist, $p_path = '', $p_remove_path = '', $p_preserve = false) { $v_result = true; $v_list_detail = array(); if (is_array($p_filelist)) { $v_list = $p_filelist; } elseif (is_string($p_filelist)) { $v_list = explode($this->_separator, $p_filelist); } else { $this->_error('Invalid string list'); return false; } if ($v_result = $this->_openRead()) { $v_result = $this->_extractList( $p_path, $v_list_detail, "partial", $v_list, $p_remove_path, $p_preserve ); $this->_close(); } return $v_result; } /** * This method set specific attributes of the archive. It uses a variable * list of parameters, in the format attribute code + attribute values : * $arch->setAttribute(ARCHIVE_TAR_ATT_SEPARATOR, ','); * * @return true on success, false on error. */ public function setAttribute() { $v_result = true; // ----- Get the number of variable list of arguments if (($v_size = func_num_args()) == 0) { return true; } // ----- Get the arguments $v_att_list = func_get_args(); // ----- Read the attributes $i = 0; while ($i < $v_size) { // ----- Look for next option switch ($v_att_list[$i]) { // ----- Look for options that request a string value case ARCHIVE_TAR_ATT_SEPARATOR : // ----- Check the number of parameters if (($i + 1) >= $v_size) { $this->_error( 'Invalid number of parameters for ' . 'attribute ARCHIVE_TAR_ATT_SEPARATOR' ); return false; } // ----- Get the value $this->_separator = $v_att_list[$i + 1]; $i++; break; default : $this->_error('Unknown attribute code ' . $v_att_list[$i] . ''); return false; } // ----- Next attribute $i++; } return $v_result; } /** * This method sets the regular expression for ignoring files and directories * at import, for example: * $arch->setIgnoreRegexp("#CVS|\.svn#"); * * @param string $regexp regular expression defining which files or directories to ignore */ public function setIgnoreRegexp($regexp) { $this->_ignore_regexp = $regexp; } /** * This method sets the regular expression for ignoring all files and directories * matching the filenames in the array list at import, for example: * $arch->setIgnoreList(array('CVS', '.svn', 'bin/tool')); * * @param array $list a list of file or directory names to ignore * * @access public */ public function setIgnoreList($list) { $regexp = str_replace(array('#', '.', '^', '$'), array('\#', '\.', '\^', '\$'), $list); $regexp = '#/' . join('$|/', $list) . '#'; $this->setIgnoreRegexp($regexp); } /** * @param string $p_message */ public function _error($p_message) { $this->error_object = $this->raiseError($p_message); } /** * @param string $p_message */ public function _warning($p_message) { $this->error_object = $this->raiseError($p_message); } /** * @param string $p_filename * @return bool */ public function _isArchive($p_filename = null) { if ($p_filename == null) { $p_filename = $this->_tarname; } clearstatcache(); return @is_file($p_filename) && !@is_link($p_filename); } /** * @return bool */ public function _openWrite() { if ($this->_compress_type == 'gz' && function_exists('gzopen')) { $this->_file = @gzopen($this->_tarname, "wb9"); } else { if ($this->_compress_type == 'bz2' && function_exists('bzopen')) { $this->_file = @bzopen($this->_tarname, "w"); } else { if ($this->_compress_type == 'lzma2' && function_exists('xzopen')) { $this->_file = @xzopen($this->_tarname, 'w'); } else { if ($this->_compress_type == 'none') { $this->_file = @fopen($this->_tarname, "wb"); } else { $this->_error( 'Unknown or missing compression type (' . $this->_compress_type . ')' ); return false; } } } } if ($this->_file == 0) { $this->_error( 'Unable to open in write mode \'' . $this->_tarname . '\'' ); return false; } return true; } /** * @return bool */ public function _openRead() { if (strtolower(substr($this->_tarname, 0, 7)) == 'http://') { // ----- Look if a local copy need to be done if ($this->_temp_tarname == '') { $this->_temp_tarname = uniqid('tar') . '.tmp'; if (!$v_file_from = @fopen($this->_tarname, 'rb')) { $this->_error( 'Unable to open in read mode \'' . $this->_tarname . '\'' ); $this->_temp_tarname = ''; return false; } if (!$v_file_to = @fopen($this->_temp_tarname, 'wb')) { $this->_error( 'Unable to open in write mode \'' . $this->_temp_tarname . '\'' ); $this->_temp_tarname = ''; return false; } while ($v_data = @fread($v_file_from, 1024)) { @fwrite($v_file_to, $v_data); } @fclose($v_file_from); @fclose($v_file_to); } // ----- File to open if the local copy $v_filename = $this->_temp_tarname; } else { // ----- File to open if the normal Tar file $v_filename = $this->_tarname; } if ($this->_compress_type == 'gz' && function_exists('gzopen')) { $this->_file = @gzopen($v_filename, "rb"); } else { if ($this->_compress_type == 'bz2' && function_exists('bzopen')) { $this->_file = @bzopen($v_filename, "r"); } else { if ($this->_compress_type == 'lzma2' && function_exists('xzopen')) { $this->_file = @xzopen($v_filename, "r"); } else { if ($this->_compress_type == 'none') { $this->_file = @fopen($v_filename, "rb"); } else { $this->_error( 'Unknown or missing compression type (' . $this->_compress_type . ')' ); return false; } } } } if ($this->_file == 0) { $this->_error('Unable to open in read mode \'' . $v_filename . '\''); return false; } return true; } /** * @return bool */ public function _openReadWrite() { if ($this->_compress_type == 'gz') { $this->_file = @gzopen($this->_tarname, "r+b"); } else { if ($this->_compress_type == 'bz2') { $this->_error( 'Unable to open bz2 in read/write mode \'' . $this->_tarname . '\' (limitation of bz2 extension)' ); return false; } else { if ($this->_compress_type == 'lzma2') { $this->_error( 'Unable to open lzma2 in read/write mode \'' . $this->_tarname . '\' (limitation of lzma2 extension)' ); return false; } else { if ($this->_compress_type == 'none') { $this->_file = @fopen($this->_tarname, "r+b"); } else { $this->_error( 'Unknown or missing compression type (' . $this->_compress_type . ')' ); return false; } } } } if ($this->_file == 0) { $this->_error( 'Unable to open in read/write mode \'' . $this->_tarname . '\'' ); return false; } return true; } /** * @return bool */ public function _close() { //if (isset($this->_file)) { if (is_resource($this->_file)) { if ($this->_compress_type == 'gz') { @gzclose($this->_file); } else { if ($this->_compress_type == 'bz2') { @bzclose($this->_file); } else { if ($this->_compress_type == 'lzma2') { @xzclose($this->_file); } else { if ($this->_compress_type == 'none') { @fclose($this->_file); } else { $this->_error( 'Unknown or missing compression type (' . $this->_compress_type . ')' ); } } } } $this->_file = 0; } // ----- Look if a local copy need to be erase // Note that it might be interesting to keep the url for a time : ToDo if ($this->_temp_tarname != '') { @unlink($this->_temp_tarname); $this->_temp_tarname = ''; } return true; } /** * @return bool */ public function _cleanFile() { $this->_close(); // ----- Look for a local copy if ($this->_temp_tarname != '') { // ----- Remove the local copy but not the remote tarname @unlink($this->_temp_tarname); $this->_temp_tarname = ''; } else { // ----- Remove the local tarname file @unlink($this->_tarname); } $this->_tarname = ''; return true; } /** * @param mixed $p_binary_data * @param integer $p_len * @return bool */ public function _writeBlock($p_binary_data, $p_len = null) { if (is_resource($this->_file)) { if ($p_len === null) { if ($this->_compress_type == 'gz') { @gzputs($this->_file, $p_binary_data); } else { if ($this->_compress_type == 'bz2') { @bzwrite($this->_file, $p_binary_data); } else { if ($this->_compress_type == 'lzma2') { @xzwrite($this->_file, $p_binary_data); } else { if ($this->_compress_type == 'none') { @fputs($this->_file, $p_binary_data); } else { $this->_error( 'Unknown or missing compression type (' . $this->_compress_type . ')' ); } } } } } else { if ($this->_compress_type == 'gz') { @gzputs($this->_file, $p_binary_data, $p_len); } else { if ($this->_compress_type == 'bz2') { @bzwrite($this->_file, $p_binary_data, $p_len); } else { if ($this->_compress_type == 'lzma2') { @xzwrite($this->_file, $p_binary_data, $p_len); } else { if ($this->_compress_type == 'none') { @fputs($this->_file, $p_binary_data, $p_len); } else { $this->_error( 'Unknown or missing compression type (' . $this->_compress_type . ')' ); } } } } } } return true; } /** * @return null|string */ public function _readBlock() { $v_block = null; if (is_resource($this->_file)) { if ($this->_compress_type == 'gz') { $v_block = @gzread($this->_file, 512); } else { if ($this->_compress_type == 'bz2') { $v_block = @bzread($this->_file, 512); } else { if ($this->_compress_type == 'lzma2') { $v_block = @xzread($this->_file, 512); } else { if ($this->_compress_type == 'none') { $v_block = @fread($this->_file, 512); } else { $this->_error( 'Unknown or missing compression type (' . $this->_compress_type . ')' ); } } } } } return $v_block; } /** * @param null $p_len * @return bool */ public function _jumpBlock($p_len = null) { if (is_resource($this->_file)) { if ($p_len === null) { $p_len = 1; } if ($this->_compress_type == 'gz') { @gzseek($this->_file, gztell($this->_file) + ($p_len * 512)); } else { if ($this->_compress_type == 'bz2') { // ----- Replace missing bztell() and bzseek() for ($i = 0; $i < $p_len; $i++) { $this->_readBlock(); } } else { if ($this->_compress_type == 'lzma2') { // ----- Replace missing xztell() and xzseek() for ($i = 0; $i < $p_len; $i++) { $this->_readBlock(); } } else { if ($this->_compress_type == 'none') { @fseek($this->_file, $p_len * 512, SEEK_CUR); } else { $this->_error( 'Unknown or missing compression type (' . $this->_compress_type . ')' ); } } } } } return true; } /** * @return bool */ public function _writeFooter() { if (is_resource($this->_file)) { // ----- Write the last 0 filled block for end of archive $v_binary_data = pack('a1024', ''); $this->_writeBlock($v_binary_data); } return true; } /** * @param array $p_list * @param string $p_add_dir * @param string $p_remove_dir * @return bool */ public function _addList($p_list, $p_add_dir, $p_remove_dir) { $v_result = true; $v_header = array(); // ----- Remove potential windows directory separator $p_add_dir = $this->_translateWinPath($p_add_dir); $p_remove_dir = $this->_translateWinPath($p_remove_dir, false); if (!$this->_file) { $this->_error('Invalid file descriptor'); return false; } if (sizeof($p_list) == 0) { return true; } foreach ($p_list as $v_filename) { if (!$v_result) { break; } // ----- Skip the current tar name if ($v_filename == $this->_tarname) { continue; } if ($v_filename == '') { continue; } // ----- ignore files and directories matching the ignore regular expression if ($this->_ignore_regexp && preg_match($this->_ignore_regexp, '/' . $v_filename)) { $this->_warning("File '$v_filename' ignored"); continue; } if (!file_exists($v_filename) && !is_link($v_filename)) { $this->_warning("File '$v_filename' does not exist"); continue; } // ----- Add the file or directory header if (!$this->_addFile($v_filename, $v_header, $p_add_dir, $p_remove_dir)) { return false; } if (@is_dir($v_filename) && !@is_link($v_filename)) { if (!($p_hdir = opendir($v_filename))) { $this->_warning("Directory '$v_filename' can not be read"); continue; } while (false !== ($p_hitem = readdir($p_hdir))) { if (($p_hitem != '.') && ($p_hitem != '..')) { if ($v_filename != ".") { $p_temp_list[0] = $v_filename . '/' . $p_hitem; } else { $p_temp_list[0] = $p_hitem; } $v_result = $this->_addList( $p_temp_list, $p_add_dir, $p_remove_dir ); } } unset($p_temp_list); unset($p_hdir); unset($p_hitem); } } return $v_result; } /** * @param string $p_filename * @param mixed $p_header * @param string $p_add_dir * @param string $p_remove_dir * @param null $v_stored_filename * @return bool */ public function _addFile($p_filename, &$p_header, $p_add_dir, $p_remove_dir, $v_stored_filename = null) { if (!$this->_file) { $this->_error('Invalid file descriptor'); return false; } if ($p_filename == '') { $this->_error('Invalid file name'); return false; } if (is_null($v_stored_filename)) { // ----- Calculate the stored filename $p_filename = $this->_translateWinPath($p_filename, false); $v_stored_filename = $p_filename; if (strcmp($p_filename, $p_remove_dir) == 0) { return true; } if ($p_remove_dir != '') { if (substr($p_remove_dir, -1) != '/') { $p_remove_dir .= '/'; } if (substr($p_filename, 0, strlen($p_remove_dir)) == $p_remove_dir) { $v_stored_filename = substr($p_filename, strlen($p_remove_dir)); } } $v_stored_filename = $this->_translateWinPath($v_stored_filename); if ($p_add_dir != '') { if (substr($p_add_dir, -1) == '/') { $v_stored_filename = $p_add_dir . $v_stored_filename; } else { $v_stored_filename = $p_add_dir . '/' . $v_stored_filename; } } $v_stored_filename = $this->_pathReduction($v_stored_filename); } if ($this->_isArchive($p_filename)) { if (($v_file = @fopen($p_filename, "rb")) == 0) { $this->_warning( "Unable to open file '" . $p_filename . "' in binary read mode" ); return true; } if (!$this->_writeHeader($p_filename, $v_stored_filename)) { return false; } while (($v_buffer = fread($v_file, 512)) != '') { $v_binary_data = pack("a512", "$v_buffer"); $this->_writeBlock($v_binary_data); } fclose($v_file); } else { // ----- Only header for dir if (!$this->_writeHeader($p_filename, $v_stored_filename)) { return false; } } return true; } /** * @param string $p_filename * @param string $p_string * @param bool $p_datetime * @param array $p_params * @return bool */ public function _addString($p_filename, $p_string, $p_datetime = false, $p_params = array()) { $p_stamp = @$p_params["stamp"] ? $p_params["stamp"] : ($p_datetime ? $p_datetime : time()); $p_mode = @$p_params["mode"] ? $p_params["mode"] : 0600; $p_type = @$p_params["type"] ? $p_params["type"] : ""; $p_uid = @$p_params["uid"] ? $p_params["uid"] : 0; $p_gid = @$p_params["gid"] ? $p_params["gid"] : 0; if (!$this->_file) { $this->_error('Invalid file descriptor'); return false; } if ($p_filename == '') { $this->_error('Invalid file name'); return false; } // ----- Calculate the stored filename $p_filename = $this->_translateWinPath($p_filename, false); // ----- If datetime is not specified, set current time if ($p_datetime === false) { $p_datetime = time(); } if (!$this->_writeHeaderBlock( $p_filename, strlen($p_string), $p_stamp, $p_mode, $p_type, $p_uid, $p_gid ) ) { return false; } $i = 0; while (($v_buffer = substr($p_string, (($i++) * 512), 512)) != '') { $v_binary_data = pack("a512", $v_buffer); $this->_writeBlock($v_binary_data); } return true; } /** * @param string $p_filename * @param string $p_stored_filename * @return bool */ public function _writeHeader($p_filename, $p_stored_filename) { if ($p_stored_filename == '') { $p_stored_filename = $p_filename; } $v_reduce_filename = $this->_pathReduction($p_stored_filename); if (strlen($v_reduce_filename) > 99) { if (!$this->_writeLongHeader($v_reduce_filename)) { return false; } } $v_info = lstat($p_filename); $v_uid = sprintf("%07s", DecOct($v_info[4])); $v_gid = sprintf("%07s", DecOct($v_info[5])); $v_perms = sprintf("%07s", DecOct($v_info['mode'] & 000777)); $v_mtime = sprintf("%011s", DecOct($v_info['mtime'])); $v_linkname = ''; if (@is_link($p_filename)) { $v_typeflag = '2'; $v_linkname = readlink($p_filename); $v_size = sprintf("%011s", DecOct(0)); } elseif (@is_dir($p_filename)) { $v_typeflag = "5"; $v_size = sprintf("%011s", DecOct(0)); } else { $v_typeflag = '0'; clearstatcache(); $v_size = sprintf("%011s", DecOct($v_info['size'])); } $v_magic = 'ustar '; $v_version = ' '; if (function_exists('posix_getpwuid')) { $userinfo = posix_getpwuid($v_info[4]); $groupinfo = posix_getgrgid($v_info[5]); $v_uname = $userinfo['name']; $v_gname = $groupinfo['name']; } else { $v_uname = ''; $v_gname = ''; } $v_devmajor = ''; $v_devminor = ''; $v_prefix = ''; $v_binary_data_first = pack( "a100a8a8a8a12a12", $v_reduce_filename, $v_perms, $v_uid, $v_gid, $v_size, $v_mtime ); $v_binary_data_last = pack( "a1a100a6a2a32a32a8a8a155a12", $v_typeflag, $v_linkname, $v_magic, $v_version, $v_uname, $v_gname, $v_devmajor, $v_devminor, $v_prefix, '' ); // ----- Calculate the checksum $v_checksum = 0; // ..... First part of the header for ($i = 0; $i < 148; $i++) { $v_checksum += ord(substr($v_binary_data_first, $i, 1)); } // ..... Ignore the checksum value and replace it by ' ' (space) for ($i = 148; $i < 156; $i++) { $v_checksum += ord(' '); } // ..... Last part of the header for ($i = 156, $j = 0; $i < 512; $i++, $j++) { $v_checksum += ord(substr($v_binary_data_last, $j, 1)); } // ----- Write the first 148 bytes of the header in the archive $this->_writeBlock($v_binary_data_first, 148); // ----- Write the calculated checksum $v_checksum = sprintf("%06s ", DecOct($v_checksum)); $v_binary_data = pack("a8", $v_checksum); $this->_writeBlock($v_binary_data, 8); // ----- Write the last 356 bytes of the header in the archive $this->_writeBlock($v_binary_data_last, 356); return true; } /** * @param string $p_filename * @param int $p_size * @param int $p_mtime * @param int $p_perms * @param string $p_type * @param int $p_uid * @param int $p_gid * @return bool */ public function _writeHeaderBlock( $p_filename, $p_size, $p_mtime = 0, $p_perms = 0, $p_type = '', $p_uid = 0, $p_gid = 0 ) { $p_filename = $this->_pathReduction($p_filename); if (strlen($p_filename) > 99) { if (!$this->_writeLongHeader($p_filename)) { return false; } } if ($p_type == "5") { $v_size = sprintf("%011s", DecOct(0)); } else { $v_size = sprintf("%011s", DecOct($p_size)); } $v_uid = sprintf("%07s", DecOct($p_uid)); $v_gid = sprintf("%07s", DecOct($p_gid)); $v_perms = sprintf("%07s", DecOct($p_perms & 000777)); $v_mtime = sprintf("%11s", DecOct($p_mtime)); $v_linkname = ''; $v_magic = 'ustar '; $v_version = ' '; if (function_exists('posix_getpwuid')) { $userinfo = posix_getpwuid($p_uid); $groupinfo = posix_getgrgid($p_gid); $v_uname = $userinfo['name']; $v_gname = $groupinfo['name']; } else { $v_uname = ''; $v_gname = ''; } $v_devmajor = ''; $v_devminor = ''; $v_prefix = ''; $v_binary_data_first = pack( "a100a8a8a8a12A12", $p_filename, $v_perms, $v_uid, $v_gid, $v_size, $v_mtime ); $v_binary_data_last = pack( "a1a100a6a2a32a32a8a8a155a12", $p_type, $v_linkname, $v_magic, $v_version, $v_uname, $v_gname, $v_devmajor, $v_devminor, $v_prefix, '' ); // ----- Calculate the checksum $v_checksum = 0; // ..... First part of the header for ($i = 0; $i < 148; $i++) { $v_checksum += ord(substr($v_binary_data_first, $i, 1)); } // ..... Ignore the checksum value and replace it by ' ' (space) for ($i = 148; $i < 156; $i++) { $v_checksum += ord(' '); } // ..... Last part of the header for ($i = 156, $j = 0; $i < 512; $i++, $j++) { $v_checksum += ord(substr($v_binary_data_last, $j, 1)); } // ----- Write the first 148 bytes of the header in the archive $this->_writeBlock($v_binary_data_first, 148); // ----- Write the calculated checksum $v_checksum = sprintf("%06s ", DecOct($v_checksum)); $v_binary_data = pack("a8", $v_checksum); $this->_writeBlock($v_binary_data, 8); // ----- Write the last 356 bytes of the header in the archive $this->_writeBlock($v_binary_data_last, 356); return true; } /** * @param string $p_filename * @return bool */ public function _writeLongHeader($p_filename) { $v_size = sprintf("%11s ", DecOct(strlen($p_filename))); $v_typeflag = 'L'; $v_linkname = ''; $v_magic = ''; $v_version = ''; $v_uname = ''; $v_gname = ''; $v_devmajor = ''; $v_devminor = ''; $v_prefix = ''; $v_binary_data_first = pack( "a100a8a8a8a12a12", '././@LongLink', 0, 0, 0, $v_size, 0 ); $v_binary_data_last = pack( "a1a100a6a2a32a32a8a8a155a12", $v_typeflag, $v_linkname, $v_magic, $v_version, $v_uname, $v_gname, $v_devmajor, $v_devminor, $v_prefix, '' ); // ----- Calculate the checksum $v_checksum = 0; // ..... First part of the header for ($i = 0; $i < 148; $i++) { $v_checksum += ord(substr($v_binary_data_first, $i, 1)); } // ..... Ignore the checksum value and replace it by ' ' (space) for ($i = 148; $i < 156; $i++) { $v_checksum += ord(' '); } // ..... Last part of the header for ($i = 156, $j = 0; $i < 512; $i++, $j++) { $v_checksum += ord(substr($v_binary_data_last, $j, 1)); } // ----- Write the first 148 bytes of the header in the archive $this->_writeBlock($v_binary_data_first, 148); // ----- Write the calculated checksum $v_checksum = sprintf("%06s ", DecOct($v_checksum)); $v_binary_data = pack("a8", $v_checksum); $this->_writeBlock($v_binary_data, 8); // ----- Write the last 356 bytes of the header in the archive $this->_writeBlock($v_binary_data_last, 356); // ----- Write the filename as content of the block $i = 0; while (($v_buffer = substr($p_filename, (($i++) * 512), 512)) != '') { $v_binary_data = pack("a512", "$v_buffer"); $this->_writeBlock($v_binary_data); } return true; } /** * @param mixed $v_binary_data * @param mixed $v_header * @return bool */ public function _readHeader($v_binary_data, &$v_header) { if (strlen($v_binary_data) == 0) { $v_header['filename'] = ''; return true; } if (strlen($v_binary_data) != 512) { $v_header['filename'] = ''; $this->_error('Invalid block size : ' . strlen($v_binary_data)); return false; } if (!is_array($v_header)) { $v_header = array(); } // ----- Calculate the checksum $v_checksum = 0; // ..... First part of the header $v_binary_split = str_split($v_binary_data); $v_checksum += array_sum(array_map('ord', array_slice($v_binary_split, 0, 148))); $v_checksum += array_sum(array_map('ord', array(' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',))); $v_checksum += array_sum(array_map('ord', array_slice($v_binary_split, 156, 512))); $v_data = unpack($this->_fmt, $v_binary_data); if (strlen($v_data["prefix"]) > 0) { $v_data["filename"] = "$v_data[prefix]/$v_data[filename]"; } // ----- Extract the checksum $v_header['checksum'] = OctDec(trim($v_data['checksum'])); if ($v_header['checksum'] != $v_checksum) { $v_header['filename'] = ''; // ----- Look for last block (empty block) if (($v_checksum == 256) && ($v_header['checksum'] == 0)) { return true; } $this->_error( 'Invalid checksum for file "' . $v_data['filename'] . '" : ' . $v_checksum . ' calculated, ' . $v_header['checksum'] . ' expected' ); return false; } // ----- Extract the properties $v_header['filename'] = rtrim($v_data['filename'], "\0"); if ($this->_maliciousFilename($v_header['filename'])) { $this->_error( 'Malicious .tar detected, file "' . $v_header['filename'] . '" will not install in desired directory tree' ); return false; } $v_header['mode'] = OctDec(trim($v_data['mode'])); $v_header['uid'] = OctDec(trim($v_data['uid'])); $v_header['gid'] = OctDec(trim($v_data['gid'])); $v_header['size'] = $this->_tarRecToSize($v_data['size']); $v_header['mtime'] = OctDec(trim($v_data['mtime'])); if (($v_header['typeflag'] = $v_data['typeflag']) == "5") { $v_header['size'] = 0; } $v_header['link'] = trim($v_data['link']); /* ----- All these fields are removed form the header because they do not carry interesting info $v_header[magic] = trim($v_data[magic]); $v_header[version] = trim($v_data[version]); $v_header[uname] = trim($v_data[uname]); $v_header[gname] = trim($v_data[gname]); $v_header[devmajor] = trim($v_data[devmajor]); $v_header[devminor] = trim($v_data[devminor]); */ return true; } /** * Convert Tar record size to actual size * * @param string $tar_size * @return size of tar record in bytes */ private function _tarRecToSize($tar_size) { /* * First byte of size has a special meaning if bit 7 is set. * * Bit 7 indicates base-256 encoding if set. * Bit 6 is the sign bit. * Bits 5:0 are most significant value bits. */ $ch = ord($tar_size[0]); if ($ch & 0x80) { // Full 12-bytes record is required. $rec_str = $tar_size . "\x00"; $size = ($ch & 0x40) ? -1 : 0; $size = ($size << 6) | ($ch & 0x3f); for ($num_ch = 1; $num_ch < 12; ++$num_ch) { $size = ($size * 256) + ord($rec_str[$num_ch]); } return $size; } else { return OctDec(trim($tar_size)); } } /** * Detect and report a malicious file name * * @param string $file * * @return bool */ private function _maliciousFilename($file) { if (strpos($file, '/../') !== false) { return true; } if (strpos($file, '../') === 0) { return true; } return false; } /** * @param $v_header * @return bool */ public function _readLongHeader(&$v_header) { $v_filename = ''; $v_filesize = $v_header['size']; $n = floor($v_header['size'] / 512); for ($i = 0; $i < $n; $i++) { $v_content = $this->_readBlock(); $v_filename .= $v_content; } if (($v_header['size'] % 512) != 0) { $v_content = $this->_readBlock(); $v_filename .= $v_content; } // ----- Read the next header $v_binary_data = $this->_readBlock(); if (!$this->_readHeader($v_binary_data, $v_header)) { return false; } $v_filename = rtrim(substr($v_filename, 0, $v_filesize), "\0"); $v_header['filename'] = $v_filename; if ($this->_maliciousFilename($v_filename)) { $this->_error( 'Malicious .tar detected, file "' . $v_filename . '" will not install in desired directory tree' ); return false; } return true; } /** * This method extract from the archive one file identified by $p_filename. * The return value is a string with the file content, or null on error. * * @param string $p_filename The path of the file to extract in a string. * * @return a string with the file content or null. */ private function _extractInString($p_filename) { $v_result_str = ""; while (strlen($v_binary_data = $this->_readBlock()) != 0) { if (!$this->_readHeader($v_binary_data, $v_header)) { return null; } if ($v_header['filename'] == '') { continue; } // ----- Look for long filename if ($v_header['typeflag'] == 'L') { if (!$this->_readLongHeader($v_header)) { return null; } } if ($v_header['filename'] == $p_filename) { if ($v_header['typeflag'] == "5") { $this->_error( 'Unable to extract in string a directory ' . 'entry {' . $v_header['filename'] . '}' ); return null; } else { $n = floor($v_header['size'] / 512); for ($i = 0; $i < $n; $i++) { $v_result_str .= $this->_readBlock(); } if (($v_header['size'] % 512) != 0) { $v_content = $this->_readBlock(); $v_result_str .= substr( $v_content, 0, ($v_header['size'] % 512) ); } return $v_result_str; } } else { $this->_jumpBlock(ceil(($v_header['size'] / 512))); } } return null; } /** * @param string $p_path * @param string $p_list_detail * @param string $p_mode * @param string $p_file_list * @param string $p_remove_path * @param bool $p_preserve * @return bool */ public function _extractList( $p_path, &$p_list_detail, $p_mode, $p_file_list, $p_remove_path, $p_preserve = false ) { $v_result = true; $v_nb = 0; $v_extract_all = true; $v_listing = false; $p_path = $this->_translateWinPath($p_path, false); if ($p_path == '' || (substr($p_path, 0, 1) != '/' && substr($p_path, 0, 3) != "../" && !strpos($p_path, ':')) ) { $p_path = "./" . $p_path; } $p_remove_path = $this->_translateWinPath($p_remove_path); // ----- Look for path to remove format (should end by /) if (($p_remove_path != '') && (substr($p_remove_path, -1) != '/')) { $p_remove_path .= '/'; } $p_remove_path_size = strlen($p_remove_path); switch ($p_mode) { case "complete" : $v_extract_all = true; $v_listing = false; break; case "partial" : $v_extract_all = false; $v_listing = false; break; case "list" : $v_extract_all = false; $v_listing = true; break; default : $this->_error('Invalid extract mode (' . $p_mode . ')'); return false; } clearstatcache(); while (strlen($v_binary_data = $this->_readBlock()) != 0) { $v_extract_file = false; $v_extraction_stopped = 0; if (!$this->_readHeader($v_binary_data, $v_header)) { return false; } if ($v_header['filename'] == '') { continue; } // ----- Look for long filename if ($v_header['typeflag'] == 'L') { if (!$this->_readLongHeader($v_header)) { return false; } } // ignore extended / pax headers if ($v_header['typeflag'] == 'x' || $v_header['typeflag'] == 'g') { $this->_jumpBlock(ceil(($v_header['size'] / 512))); continue; } if ((!$v_extract_all) && (is_array($p_file_list))) { // ----- By default no unzip if the file is not found $v_extract_file = false; for ($i = 0; $i < sizeof($p_file_list); $i++) { // ----- Look if it is a directory if (substr($p_file_list[$i], -1) == '/') { // ----- Look if the directory is in the filename path if ((strlen($v_header['filename']) > strlen($p_file_list[$i])) && (substr($v_header['filename'], 0, strlen($p_file_list[$i])) == $p_file_list[$i]) ) { $v_extract_file = true; break; } } // ----- It is a file, so compare the file names elseif ($p_file_list[$i] == $v_header['filename']) { $v_extract_file = true; break; } } } else { $v_extract_file = true; } // ----- Look if this file need to be extracted if (($v_extract_file) && (!$v_listing)) { if (($p_remove_path != '') && (substr($v_header['filename'] . '/', 0, $p_remove_path_size) == $p_remove_path) ) { $v_header['filename'] = substr( $v_header['filename'], $p_remove_path_size ); if ($v_header['filename'] == '') { continue; } } if (($p_path != './') && ($p_path != '/')) { while (substr($p_path, -1) == '/') { $p_path = substr($p_path, 0, strlen($p_path) - 1); } if (substr($v_header['filename'], 0, 1) == '/') { $v_header['filename'] = $p_path . $v_header['filename']; } else { $v_header['filename'] = $p_path . '/' . $v_header['filename']; } } if (file_exists($v_header['filename'])) { if ((@is_dir($v_header['filename'])) && ($v_header['typeflag'] == '') ) { $this->_error( 'File ' . $v_header['filename'] . ' already exists as a directory' ); return false; } if (($this->_isArchive($v_header['filename'])) && ($v_header['typeflag'] == "5") ) { $this->_error( 'Directory ' . $v_header['filename'] . ' already exists as a file' ); return false; } if (!is_writeable($v_header['filename'])) { $this->_error( 'File ' . $v_header['filename'] . ' already exists and is write protected' ); return false; } if (filemtime($v_header['filename']) > $v_header['mtime']) { // To be completed : An error or silent no replace ? } } // ----- Check the directory availability and create it if necessary elseif (($v_result = $this->_dirCheck( ($v_header['typeflag'] == "5" ? $v_header['filename'] : dirname($v_header['filename'])) )) != 1 ) { $this->_error('Unable to create path for ' . $v_header['filename']); return false; } if ($v_extract_file) { if ($v_header['typeflag'] == "5") { if (!@file_exists($v_header['filename'])) { if (!@mkdir($v_header['filename'], 0777)) { $this->_error( 'Unable to create directory {' . $v_header['filename'] . '}' ); return false; } } } elseif ($v_header['typeflag'] == "2") { if (@file_exists($v_header['filename'])) { @unlink($v_header['filename']); } if (!@symlink($v_header['link'], $v_header['filename'])) { $this->_error( 'Unable to extract symbolic link {' . $v_header['filename'] . '}' ); return false; } } else { if (($v_dest_file = @fopen($v_header['filename'], "wb")) == 0) { $this->_error( 'Error while opening {' . $v_header['filename'] . '} in write binary mode' ); return false; } else { $n = floor($v_header['size'] / 512); for ($i = 0; $i < $n; $i++) { $v_content = $this->_readBlock(); fwrite($v_dest_file, $v_content, 512); } if (($v_header['size'] % 512) != 0) { $v_content = $this->_readBlock(); fwrite($v_dest_file, $v_content, ($v_header['size'] % 512)); } @fclose($v_dest_file); if ($p_preserve) { @chown($v_header['filename'], $v_header['uid']); @chgrp($v_header['filename'], $v_header['gid']); } // ----- Change the file mode, mtime @touch($v_header['filename'], $v_header['mtime']); if ($v_header['mode'] & 0111) { // make file executable, obey umask $mode = fileperms($v_header['filename']) | (~umask() & 0111); @chmod($v_header['filename'], $mode); } } // ----- Check the file size clearstatcache(); if (!is_file($v_header['filename'])) { $this->_error( 'Extracted file ' . $v_header['filename'] . 'does not exist. Archive may be corrupted.' ); return false; } $filesize = filesize($v_header['filename']); if ($filesize != $v_header['size']) { $this->_error( 'Extracted file ' . $v_header['filename'] . ' does not have the correct file size \'' . $filesize . '\' (' . $v_header['size'] . ' expected). Archive may be corrupted.' ); return false; } } } else { $this->_jumpBlock(ceil(($v_header['size'] / 512))); } } else { $this->_jumpBlock(ceil(($v_header['size'] / 512))); } /* TBC : Seems to be unused ... if ($this->_compress) $v_end_of_file = @gzeof($this->_file); else $v_end_of_file = @feof($this->_file); */ if ($v_listing || $v_extract_file || $v_extraction_stopped) { // ----- Log extracted files if (($v_file_dir = dirname($v_header['filename'])) == $v_header['filename'] ) { $v_file_dir = ''; } if ((substr($v_header['filename'], 0, 1) == '/') && ($v_file_dir == '')) { $v_file_dir = '/'; } $p_list_detail[$v_nb++] = $v_header; if (is_array($p_file_list) && (count($p_list_detail) == count($p_file_list))) { return true; } } } return true; } /** * @return bool */ public function _openAppend() { if (filesize($this->_tarname) == 0) { return $this->_openWrite(); } if ($this->_compress) { $this->_close(); if (!@rename($this->_tarname, $this->_tarname . ".tmp")) { $this->_error( 'Error while renaming \'' . $this->_tarname . '\' to temporary file \'' . $this->_tarname . '.tmp\'' ); return false; } if ($this->_compress_type == 'gz') { $v_temp_tar = @gzopen($this->_tarname . ".tmp", "rb"); } elseif ($this->_compress_type == 'bz2') { $v_temp_tar = @bzopen($this->_tarname . ".tmp", "r"); } elseif ($this->_compress_type == 'lzma2') { $v_temp_tar = @xzopen($this->_tarname . ".tmp", "r"); } if ($v_temp_tar == 0) { $this->_error( 'Unable to open file \'' . $this->_tarname . '.tmp\' in binary read mode' ); @rename($this->_tarname . ".tmp", $this->_tarname); return false; } if (!$this->_openWrite()) { @rename($this->_tarname . ".tmp", $this->_tarname); return false; } if ($this->_compress_type == 'gz') { $end_blocks = 0; while (!@gzeof($v_temp_tar)) { $v_buffer = @gzread($v_temp_tar, 512); if ($v_buffer == ARCHIVE_TAR_END_BLOCK || strlen($v_buffer) == 0) { $end_blocks++; // do not copy end blocks, we will re-make them // after appending continue; } elseif ($end_blocks > 0) { for ($i = 0; $i < $end_blocks; $i++) { $this->_writeBlock(ARCHIVE_TAR_END_BLOCK); } $end_blocks = 0; } $v_binary_data = pack("a512", $v_buffer); $this->_writeBlock($v_binary_data); } @gzclose($v_temp_tar); } elseif ($this->_compress_type == 'bz2') { $end_blocks = 0; while (strlen($v_buffer = @bzread($v_temp_tar, 512)) > 0) { if ($v_buffer == ARCHIVE_TAR_END_BLOCK || strlen($v_buffer) == 0) { $end_blocks++; // do not copy end blocks, we will re-make them // after appending continue; } elseif ($end_blocks > 0) { for ($i = 0; $i < $end_blocks; $i++) { $this->_writeBlock(ARCHIVE_TAR_END_BLOCK); } $end_blocks = 0; } $v_binary_data = pack("a512", $v_buffer); $this->_writeBlock($v_binary_data); } @bzclose($v_temp_tar); } elseif ($this->_compress_type == 'lzma2') { $end_blocks = 0; while (strlen($v_buffer = @xzread($v_temp_tar, 512)) > 0) { if ($v_buffer == ARCHIVE_TAR_END_BLOCK || strlen($v_buffer) == 0) { $end_blocks++; // do not copy end blocks, we will re-make them // after appending continue; } elseif ($end_blocks > 0) { for ($i = 0; $i < $end_blocks; $i++) { $this->_writeBlock(ARCHIVE_TAR_END_BLOCK); } $end_blocks = 0; } $v_binary_data = pack("a512", $v_buffer); $this->_writeBlock($v_binary_data); } @xzclose($v_temp_tar); } if (!@unlink($this->_tarname . ".tmp")) { $this->_error( 'Error while deleting temporary file \'' . $this->_tarname . '.tmp\'' ); } } else { // ----- For not compressed tar, just add files before the last // one or two 512 bytes block if (!$this->_openReadWrite()) { return false; } clearstatcache(); $v_size = filesize($this->_tarname); // We might have zero, one or two end blocks. // The standard is two, but we should try to handle // other cases. fseek($this->_file, $v_size - 1024); if (fread($this->_file, 512) == ARCHIVE_TAR_END_BLOCK) { fseek($this->_file, $v_size - 1024); } elseif (fread($this->_file, 512) == ARCHIVE_TAR_END_BLOCK) { fseek($this->_file, $v_size - 512); } } return true; } /** * @param $p_filelist * @param string $p_add_dir * @param string $p_remove_dir * @return bool */ public function _append($p_filelist, $p_add_dir = '', $p_remove_dir = '') { if (!$this->_openAppend()) { return false; } if ($this->_addList($p_filelist, $p_add_dir, $p_remove_dir)) { $this->_writeFooter(); } $this->_close(); return true; } /** * Check if a directory exists and create it (including parent * dirs) if not. * * @param string $p_dir directory to check * * @return bool true if the directory exists or was created */ public function _dirCheck($p_dir) { clearstatcache(); if ((@is_dir($p_dir)) || ($p_dir == '')) { return true; } $p_parent_dir = dirname($p_dir); if (($p_parent_dir != $p_dir) && ($p_parent_dir != '') && (!$this->_dirCheck($p_parent_dir)) ) { return false; } if (!@mkdir($p_dir, 0777)) { $this->_error("Unable to create directory '$p_dir'"); return false; } return true; } /** * Compress path by changing for example "/dir/foo/../bar" to "/dir/bar", * rand emove double slashes. * * @param string $p_dir path to reduce * * @return string reduced path */ private function _pathReduction($p_dir) { $v_result = ''; // ----- Look for not empty path if ($p_dir != '') { // ----- Explode path by directory names $v_list = explode('/', $p_dir); // ----- Study directories from last to first for ($i = sizeof($v_list) - 1; $i >= 0; $i--) { // ----- Look for current path if ($v_list[$i] == ".") { // ----- Ignore this directory // Should be the first $i=0, but no check is done } else { if ($v_list[$i] == "..") { // ----- Ignore it and ignore the $i-1 $i--; } else { if (($v_list[$i] == '') && ($i != (sizeof($v_list) - 1)) && ($i != 0) ) { // ----- Ignore only the double '//' in path, // but not the first and last / } else { $v_result = $v_list[$i] . ($i != (sizeof($v_list) - 1) ? '/' . $v_result : ''); } } } } } if (defined('OS_WINDOWS') && OS_WINDOWS) { $v_result = strtr($v_result, '\\', '/'); } return $v_result; } /** * @param $p_path * @param bool $p_remove_disk_letter * @return string */ public function _translateWinPath($p_path, $p_remove_disk_letter = true) { if (defined('OS_WINDOWS') && OS_WINDOWS) { // ----- Look for potential disk letter if (($p_remove_disk_letter) && (($v_position = strpos($p_path, ':')) != false) ) { $p_path = substr($p_path, $v_position + 1); } // ----- Change potential windows directory separator if ((strpos($p_path, '\\') > 0) || (substr($p_path, 0, 1) == '\\')) { $p_path = strtr($p_path, '\\', '/'); } } return $p_path; } } includes/PEAR/HTTP/Request2/Adapter/Socket.php000064400000125322152214270100014712 0ustar00 * @copyright 2008-2022 Alexey Borzov * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License * @link http://pear.php.net/package/HTTP_Request2 */ /** Base class for HTTP_Request2 adapters */ require_once 'HTTP/Request2/Adapter.php'; /** Socket wrapper class */ require_once 'HTTP/Request2/SocketWrapper.php'; /** * Socket-based adapter for HTTP_Request2 * * This adapter uses only PHP sockets and will work on almost any PHP * environment. Code is based on original HTTP_Request PEAR package. * * @category HTTP * @package HTTP_Request2 * @author Alexey Borzov * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License * @version Release: 2.5.1 * @link http://pear.php.net/package/HTTP_Request2 */ class HTTP_Request2_Adapter_Socket extends HTTP_Request2_Adapter { /** * Regular expression for 'token' rule from RFC 2616 */ const REGEXP_TOKEN = '[^\x00-\x1f\x7f-\xff()<>@,;:\\\\"/\[\]?={}\s]+'; /** * Regular expression for 'quoted-string' rule from RFC 2616 */ const REGEXP_QUOTED_STRING = '"(?>[^"\\\\]+|\\\\.)*"'; /** * Connected sockets, needed for Keep-Alive support * * @var array * @see connect() */ protected static $sockets = []; /** * Data for digest authentication scheme * * The keys for the array are URL prefixes. * * The values are associative arrays with data (realm, nonce, nonce-count, * opaque...) needed for digest authentication. Stored here to prevent making * duplicate requests to digest-protected resources after we have already * received the challenge. * * @var array */ protected static $challenges = []; /** * Connected socket * * @var HTTP_Request2_SocketWrapper * @see connect() */ protected $socket; /** * Challenge used for server digest authentication * * @var array */ protected $serverChallenge; /** * Challenge used for proxy digest authentication * * @var array */ protected $proxyChallenge; /** * Remaining length of the current chunk, when reading chunked response * * @var integer * @see readChunked() */ protected $chunkLength = 0; /** * Remaining amount of redirections to follow * * Starts at 'max_redirects' configuration parameter and is reduced on each * subsequent redirect. An Exception will be thrown once it reaches zero. * * @var integer */ protected $redirectCountdown = null; /** * Whether to wait for "100 Continue" response before sending request body * * @var bool */ protected $expect100Continue = false; /** * Sends request to the remote server and returns its response * * @param HTTP_Request2 $request HTTP request message * * @return HTTP_Request2_Response * @throws HTTP_Request2_Exception */ public function sendRequest(HTTP_Request2 $request) { $this->request = $request; try { $keepAlive = $this->connect(); $headers = $this->prepareHeaders(); $this->socket->write($headers); // provide request headers to the observer, see request #7633 $this->request->setLastEvent('sentHeaders', $headers); if (!$this->expect100Continue) { $this->writeBody(); $response = $this->readResponse(); } else { $response = $this->readResponse(); if (!$response || 100 == $response->getStatus()) { $this->expect100Continue = false; // either got "100 Continue" or timed out -> send body $this->writeBody(); $response = $this->readResponse(); } } if ($jar = $request->getCookieJar()) { $jar->addCookiesFromResponse($response); } if (!$this->canKeepAlive($keepAlive, $response)) { $this->disconnect(); } if ($this->shouldUseProxyDigestAuth($response)) { return $this->sendRequest($request); } if ($this->shouldUseServerDigestAuth($response)) { return $this->sendRequest($request); } if ($authInfo = $response->getHeader('authentication-info')) { $this->updateChallenge($this->serverChallenge, $authInfo); } if ($proxyInfo = $response->getHeader('proxy-authentication-info')) { $this->updateChallenge($this->proxyChallenge, $proxyInfo); } } catch (Exception $e) { $this->disconnect(); $this->redirectCountdown = null; throw $e; } finally { // phpcs:ignore PHPCompatibility.Keywords.NewKeywords.t_finallyFound unset($this->request, $this->requestBody); } if (!$request->getConfig('follow_redirects') || !$response->isRedirect()) { $this->redirectCountdown = null; return $response; } else { return $this->handleRedirect($request, $response); } } /** * Connects to the remote server * * @return bool whether the connection can be persistent * @throws HTTP_Request2_Exception */ protected function connect() { $secure = 0 == strcasecmp($this->request->getUrl()->getScheme(), 'https'); $tunnel = HTTP_Request2::METHOD_CONNECT == $this->request->getMethod(); $headers = $this->request->getHeaders(); $reqHost = $this->request->getUrl()->getHost(); if (!($reqPort = $this->request->getUrl()->getPort())) { $reqPort = $secure? 443: 80; } $httpProxy = $socksProxy = false; if (!($host = $this->request->getConfig('proxy_host'))) { $host = $reqHost; $port = $reqPort; } else { if (!($port = $this->request->getConfig('proxy_port'))) { throw new HTTP_Request2_LogicException( 'Proxy port not provided', HTTP_Request2_Exception::MISSING_VALUE ); } if ('http' == ($type = $this->request->getConfig('proxy_type'))) { $httpProxy = true; } elseif ('socks5' == $type) { $socksProxy = true; } else { throw new HTTP_Request2_NotImplementedException( "Proxy type '{$type}' is not supported" ); } } if ($tunnel && !$httpProxy) { throw new HTTP_Request2_LogicException( "Trying to perform CONNECT request without proxy", HTTP_Request2_Exception::MISSING_VALUE ); } if ($secure && !in_array('ssl', stream_get_transports())) { throw new HTTP_Request2_LogicException( 'Need OpenSSL support for https:// requests', HTTP_Request2_Exception::MISCONFIGURATION ); } // RFC 2068, section 19.7.1: A client MUST NOT send the Keep-Alive // connection token to a proxy server... if ($httpProxy && !$secure && !empty($headers['connection']) && 'Keep-Alive' == $headers['connection'] ) { $this->request->setHeader('connection'); } $keepAlive = ('1.1' == $this->request->getConfig('protocol_version') && empty($headers['connection'])) || (!empty($headers['connection']) && 'Keep-Alive' == $headers['connection']); $options = []; if ($ip = $this->request->getConfig('local_ip')) { $options['socket'] = [ 'bindto' => (false === strpos($ip, ':') ? $ip : '[' . $ip . ']') . ':0' ]; } if ($secure || $tunnel) { $options['ssl'] = []; foreach ($this->request->getConfig() as $name => $value) { if ('ssl_' == substr($name, 0, 4) && null !== $value) { if ('ssl_verify_host' == $name) { $options['ssl']['verify_peer_name'] = $value; $options['ssl']['peer_name'] = $reqHost; } else { $options['ssl'][substr($name, 4)] = $value; } } } ksort($options['ssl']); } // Use global request timeout if given, see feature requests #5735, #8964 if ($timeout = $this->request->getConfig('timeout')) { $deadline = microtime(true) + $timeout; } else { $deadline = null; } // Changing SSL context options after connection is established does *not* // work, we need a new connection if options change $remote = ((!$secure || $httpProxy || $socksProxy)? 'tcp://': 'tls://') . $host . ':' . $port; $socketKey = $remote . ( ($secure && $httpProxy || $socksProxy) ? "->{$reqHost}:{$reqPort}" : '' ) . (empty($options)? '': ':' . serialize($options)); unset($this->socket); // We use persistent connections and have a connected socket? // Ensure that the socket is still connected, see bug #16149 if ($keepAlive && !empty(self::$sockets[$socketKey]) && !self::$sockets[$socketKey]->eof() ) { $this->socket =& self::$sockets[$socketKey]; } else { if ($socksProxy) { require_once 'HTTP/Request2/SOCKS5.php'; $this->socket = new HTTP_Request2_SOCKS5( $remote, $this->request->getConfig('connect_timeout'), $options, $this->request->getConfig('proxy_user'), $this->request->getConfig('proxy_password') ); // handle request timeouts ASAP $this->socket->setDeadline($deadline, $this->request->getConfig('timeout')); $this->socket->connect($reqHost, $reqPort); if (!$secure) { $conninfo = "tcp://{$reqHost}:{$reqPort} via {$remote}"; } else { $this->socket->enableCrypto(); $conninfo = "tls://{$reqHost}:{$reqPort} via {$remote}"; } } elseif ($secure && $httpProxy && !$tunnel) { $this->establishTunnel(); $conninfo = "tls://{$reqHost}:{$reqPort} via {$remote}"; } else { $this->socket = new HTTP_Request2_SocketWrapper( $remote, $this->request->getConfig('connect_timeout'), $options ); } $this->request->setLastEvent('connect', empty($conninfo)? $remote: $conninfo); self::$sockets[$socketKey] =& $this->socket; } $this->socket->setDeadline($deadline, $this->request->getConfig('timeout')); return $keepAlive; } /** * Establishes a tunnel to a secure remote server via HTTP CONNECT request * * This method will fail if 'ssl_verify_peer' is enabled. Probably because PHP * sees that we are connected to a proxy server (duh!) rather than the server * that presents its certificate. * * @link http://tools.ietf.org/html/rfc2817#section-5.2 * * @return void * @throws HTTP_Request2_Exception */ protected function establishTunnel() { $donor = new self; $connect = new HTTP_Request2( $this->request->getUrl(), HTTP_Request2::METHOD_CONNECT, array_merge($this->request->getConfig(), ['adapter' => $donor]) ); $response = $connect->send(); // Need any successful (2XX) response if (200 > $response->getStatus() || 300 <= $response->getStatus()) { throw new HTTP_Request2_ConnectionException( 'Failed to connect via HTTPS proxy. Proxy response: ' . $response->getStatus() . ' ' . $response->getReasonPhrase() ); } $this->socket = $donor->socket; $this->socket->enableCrypto(); } /** * Checks whether current connection may be reused or should be closed * * @param boolean $requestKeepAlive whether connection could * be persistent in the first place * @param HTTP_Request2_Response $response response object to check * * @return boolean */ protected function canKeepAlive($requestKeepAlive, HTTP_Request2_Response $response) { // Do not close socket on successful CONNECT request if (HTTP_Request2::METHOD_CONNECT === $this->request->getMethod() && 200 <= $response->getStatus() && 300 > $response->getStatus() ) { return true; } $lengthKnown = 'chunked' === strtolower($response->getHeader('transfer-encoding') ?: '') || null !== $response->getHeader('content-length') // no body possible for such responses, see also request #17031 || HTTP_Request2::METHOD_HEAD === $this->request->getMethod() || in_array($response->getStatus(), [204, 304]); $persistent = 'keep-alive' === strtolower($response->getHeader('connection') ?: '') || (null === $response->getHeader('connection') && '1.1' === $response->getVersion()); return $requestKeepAlive && $lengthKnown && $persistent; } /** * Disconnects from the remote server * * @return void */ protected function disconnect() { if (!empty($this->socket)) { $this->socket = null; $this->request->setLastEvent('disconnect'); } } /** * Handles HTTP redirection * * This method will throw an Exception if redirect to a non-HTTP(S) location * is attempted, also if number of redirects performed already is equal to * 'max_redirects' configuration parameter. * * @param HTTP_Request2 $request Original request * @param HTTP_Request2_Response $response Response containing redirect * * @return HTTP_Request2_Response Response from a new location * @throws HTTP_Request2_Exception */ protected function handleRedirect( HTTP_Request2 $request, HTTP_Request2_Response $response ) { if (is_null($this->redirectCountdown)) { $this->redirectCountdown = $request->getConfig('max_redirects'); } if (0 == $this->redirectCountdown) { $this->redirectCountdown = null; // Copying cURL behaviour throw new HTTP_Request2_MessageException( 'Maximum (' . $request->getConfig('max_redirects') . ') redirects followed', HTTP_Request2_Exception::TOO_MANY_REDIRECTS ); } $redirectUrl = new Net_URL2( $response->getHeader('location'), [Net_URL2::OPTION_USE_BRACKETS => $request->getConfig('use_brackets')] ); // refuse non-HTTP redirect if ($redirectUrl->isAbsolute() && !in_array($redirectUrl->getScheme(), ['http', 'https']) ) { $this->redirectCountdown = null; throw new HTTP_Request2_MessageException( 'Refusing to redirect to a non-HTTP URL ' . $redirectUrl->__toString(), HTTP_Request2_Exception::NON_HTTP_REDIRECT ); } // Theoretically URL should be absolute (see http://tools.ietf.org/html/rfc2616#section-14.30), // but in practice it is often not if (!$redirectUrl->isAbsolute()) { $redirectUrl = $request->getUrl()->resolve($redirectUrl); } $redirect = clone $request; $redirect->setUrl($redirectUrl); if (303 == $response->getStatus() || (!$request->getConfig('strict_redirects') && in_array($response->getStatus(), [301, 302])) ) { $redirect->setMethod(HTTP_Request2::METHOD_GET); $redirect->setBody(''); } if (0 < $this->redirectCountdown) { $this->redirectCountdown--; } return $this->sendRequest($redirect); } /** * Checks whether another request should be performed with server digest auth * * Several conditions should be satisfied for it to return true: * - response status should be 401 * - auth credentials should be set in the request object * - response should contain WWW-Authenticate header with digest challenge * - there is either no challenge stored for this URL or new challenge * contains stale=true parameter (in other case we probably just failed * due to invalid username / password) * * The method stores challenge values in $challenges static property * * @param HTTP_Request2_Response $response response to check * * @return boolean whether another request should be performed * @throws HTTP_Request2_Exception in case of unsupported challenge parameters */ protected function shouldUseServerDigestAuth(HTTP_Request2_Response $response) { // no sense repeating a request if we don't have credentials if (401 != $response->getStatus() || !$this->request->getAuth()) { return false; } if (!$challenge = $this->parseDigestChallenge($response->getHeader('www-authenticate'))) { return false; } $url = $this->request->getUrl(); $scheme = $url->getScheme(); $host = $scheme . '://' . $url->getHost(); if ($port = $url->getPort()) { if ((0 == strcasecmp($scheme, 'http') && 80 != $port) || (0 == strcasecmp($scheme, 'https') && 443 != $port) ) { $host .= ':' . $port; } } if (!empty($challenge['domain'])) { $prefixes = []; foreach (preg_split('/\\s+/', $challenge['domain']) as $prefix) { // don't bother with different servers if ('/' == substr($prefix, 0, 1)) { $prefixes[] = $host . $prefix; } } } if (empty($prefixes)) { $prefixes = [$host . '/']; } $ret = true; foreach ($prefixes as $prefix) { if (!empty(self::$challenges[$prefix]) && (empty($challenge['stale']) || strcasecmp('true', $challenge['stale'])) ) { // probably credentials are invalid $ret = false; } self::$challenges[$prefix] =& $challenge; } return $ret; } /** * Checks whether another request should be performed with proxy digest auth * * Several conditions should be satisfied for it to return true: * - response status should be 407 * - proxy auth credentials should be set in the request object * - response should contain Proxy-Authenticate header with digest challenge * - there is either no challenge stored for this proxy or new challenge * contains stale=true parameter (in other case we probably just failed * due to invalid username / password) * * The method stores challenge values in $challenges static property * * @param HTTP_Request2_Response $response response to check * * @return boolean whether another request should be performed * @throws HTTP_Request2_Exception in case of unsupported challenge parameters */ protected function shouldUseProxyDigestAuth(HTTP_Request2_Response $response) { if (407 != $response->getStatus() || !$this->request->getConfig('proxy_user')) { return false; } if (!($challenge = $this->parseDigestChallenge($response->getHeader('proxy-authenticate')))) { return false; } $key = 'proxy://' . $this->request->getConfig('proxy_host') . ':' . $this->request->getConfig('proxy_port'); if (!empty(self::$challenges[$key]) && (empty($challenge['stale']) || strcasecmp('true', $challenge['stale'])) ) { $ret = false; } else { $ret = true; } self::$challenges[$key] = $challenge; return $ret; } /** * Extracts digest method challenge from (WWW|Proxy)-Authenticate header value * * There is a problem with implementation of RFC 2617: several of the parameters * are defined as quoted-string there and thus may contain backslash escaped * double quotes (RFC 2616, section 2.2). However, RFC 2617 defines unq(X) as * just value of quoted-string X without surrounding quotes, it doesn't speak * about removing backslash escaping. * * Now realm parameter is user-defined and human-readable, strange things * happen when it contains quotes: * - Apache allows quotes in realm, but apparently uses realm value without * backslashes for digest computation * - Squid allows (manually escaped) quotes there, but it is impossible to * authorize with either escaped or unescaped quotes used in digest, * probably it can't parse the response (?) * - Both IE and Firefox display realm value with backslashes in * the password popup and apparently use the same value for digest * * HTTP_Request2 follows IE and Firefox (and hopefully RFC 2617) in * quoted-string handling, unfortunately that means failure to authorize * sometimes * * @param string $headerValue value of WWW-Authenticate or Proxy-Authenticate header * * @return mixed associative array with challenge parameters, false if * no challenge is present in header value * @throws HTTP_Request2_NotImplementedException in case of unsupported challenge parameters */ protected function parseDigestChallenge($headerValue) { $authParam = '(' . self::REGEXP_TOKEN . ')\\s*=\\s*(' . self::REGEXP_TOKEN . '|' . self::REGEXP_QUOTED_STRING . ')'; $challenge = "!(?<=^|\\s|,)Digest ({$authParam}\\s*(,\\s*|$))+!"; if (!preg_match($challenge, $headerValue, $matches)) { return false; } preg_match_all('!' . $authParam . '!', $matches[0], $params); $paramsAry = []; $knownParams = ['realm', 'domain', 'nonce', 'opaque', 'stale', 'algorithm', 'qop']; for ($i = 0; $i < count($params[0]); $i++) { // section 3.2.1: Any unrecognized directive MUST be ignored. if (in_array($params[1][$i], $knownParams)) { if ('"' == substr($params[2][$i], 0, 1)) { $paramsAry[$params[1][$i]] = substr($params[2][$i], 1, -1); } else { $paramsAry[$params[1][$i]] = $params[2][$i]; } } } // we only support qop=auth if (!empty($paramsAry['qop']) && !in_array('auth', array_map('trim', explode(',', $paramsAry['qop']))) ) { throw new HTTP_Request2_NotImplementedException( "Only 'auth' qop is currently supported in digest authentication, " . "server requested '{$paramsAry['qop']}'" ); } // we only support algorithm=MD5 if (!empty($paramsAry['algorithm']) && 'MD5' != $paramsAry['algorithm']) { throw new HTTP_Request2_NotImplementedException( "Only 'MD5' algorithm is currently supported in digest authentication, " . "server requested '{$paramsAry['algorithm']}'" ); } return $paramsAry; } /** * Parses [Proxy-]Authentication-Info header value and updates challenge * * @param array $challenge challenge to update * @param string $headerValue value of [Proxy-]Authentication-Info header * * @return void * * @todo validate server rspauth response */ protected function updateChallenge(&$challenge, $headerValue) { $authParam = '!(' . self::REGEXP_TOKEN . ')\\s*=\\s*(' . self::REGEXP_TOKEN . '|' . self::REGEXP_QUOTED_STRING . ')!'; $paramsAry = []; preg_match_all($authParam, $headerValue, $params); for ($i = 0; $i < count($params[0]); $i++) { if ('"' == substr($params[2][$i], 0, 1)) { $paramsAry[$params[1][$i]] = substr($params[2][$i], 1, -1); } else { $paramsAry[$params[1][$i]] = $params[2][$i]; } } // for now, just update the nonce value if (!empty($paramsAry['nextnonce'])) { $challenge['nonce'] = $paramsAry['nextnonce']; $challenge['nc'] = 1; } } /** * Creates a value for [Proxy-]Authorization header when using digest authentication * * @param string $user user name * @param string $password password * @param string $url request URL * @param array $challenge digest challenge parameters * * @return string value of [Proxy-]Authorization request header * @link http://tools.ietf.org/html/rfc2617#section-3.2.2 */ protected function createDigestResponse($user, $password, $url, &$challenge) { if (false !== ($q = strpos($url, '?')) && $this->request->getConfig('digest_compat_ie') ) { $url = substr($url, 0, $q); } $a1 = md5($user . ':' . $challenge['realm'] . ':' . $password); $a2 = md5($this->request->getMethod() . ':' . $url); if (empty($challenge['qop'])) { $digest = md5($a1 . ':' . $challenge['nonce'] . ':' . $a2); } else { $challenge['cnonce'] = 'Req2.' . rand(); if (empty($challenge['nc'])) { $challenge['nc'] = 1; } $nc = sprintf('%08x', $challenge['nc']++); $digest = md5( $a1 . ':' . $challenge['nonce'] . ':' . $nc . ':' . $challenge['cnonce'] . ':auth:' . $a2 ); } return 'Digest username="' . str_replace(['\\', '"'], ['\\\\', '\\"'], $user) . '", ' . 'realm="' . $challenge['realm'] . '", ' . 'nonce="' . $challenge['nonce'] . '", ' . 'uri="' . $url . '", ' . 'response="' . $digest . '"' . (!empty($challenge['opaque'])? ', opaque="' . $challenge['opaque'] . '"': '') . (!empty($challenge['qop'])? ', qop="auth", nc=' . $nc . ', cnonce="' . $challenge['cnonce'] . '"': ''); } /** * Adds 'Authorization' header (if needed) to request headers array * * @param array $headers request headers * @param string $requestHost request host (needed for digest authentication) * @param string $requestUrl request URL (needed for digest authentication) * * @return void * @throws HTTP_Request2_NotImplementedException */ protected function addAuthorizationHeader(&$headers, $requestHost, $requestUrl) { if (!($auth = $this->request->getAuth())) { return; } switch ($auth['scheme']) { case HTTP_Request2::AUTH_BASIC: $headers['authorization'] = 'Basic ' . base64_encode( $auth['user'] . ':' . $auth['password'] ); break; case HTTP_Request2::AUTH_DIGEST: unset($this->serverChallenge); $fullUrl = ('/' == $requestUrl[0])? $this->request->getUrl()->getScheme() . '://' . $requestHost . $requestUrl: $requestUrl; foreach (array_keys(self::$challenges) as $key) { if ($key == substr($fullUrl, 0, strlen($key))) { $headers['authorization'] = $this->createDigestResponse( $auth['user'], $auth['password'], $requestUrl, self::$challenges[$key] ); $this->serverChallenge =& self::$challenges[$key]; break; } } break; default: throw new HTTP_Request2_NotImplementedException( "Unknown HTTP authentication scheme '{$auth['scheme']}'" ); } } /** * Adds 'Proxy-Authorization' header (if needed) to request headers array * * @param array $headers request headers * @param string $requestUrl request URL (needed for digest authentication) * * @return void * @throws HTTP_Request2_NotImplementedException */ protected function addProxyAuthorizationHeader(&$headers, $requestUrl) { if (!$this->request->getConfig('proxy_host') || !($user = $this->request->getConfig('proxy_user')) || (0 == strcasecmp('https', $this->request->getUrl()->getScheme()) && HTTP_Request2::METHOD_CONNECT != $this->request->getMethod()) ) { return; } $password = $this->request->getConfig('proxy_password'); switch ($this->request->getConfig('proxy_auth_scheme')) { case HTTP_Request2::AUTH_BASIC: $headers['proxy-authorization'] = 'Basic ' . base64_encode( $user . ':' . $password ); break; case HTTP_Request2::AUTH_DIGEST: unset($this->proxyChallenge); $proxyUrl = 'proxy://' . $this->request->getConfig('proxy_host') . ':' . $this->request->getConfig('proxy_port'); if (!empty(self::$challenges[$proxyUrl])) { $headers['proxy-authorization'] = $this->createDigestResponse( $user, $password, $requestUrl, self::$challenges[$proxyUrl] ); $this->proxyChallenge =& self::$challenges[$proxyUrl]; } break; default: throw new HTTP_Request2_NotImplementedException( "Unknown HTTP authentication scheme '" . $this->request->getConfig('proxy_auth_scheme') . "'" ); } } /** * Creates the string with the Request-Line and request headers * * @return string * @throws HTTP_Request2_Exception */ protected function prepareHeaders() { $headers = $this->request->getHeaders(); $url = $this->request->getUrl(); $connect = HTTP_Request2::METHOD_CONNECT == $this->request->getMethod(); $host = $url->getHost(); $defaultPort = 0 == strcasecmp($url->getScheme(), 'https')? 443: 80; if (($port = $url->getPort()) && $port != $defaultPort || $connect) { $host .= ':' . (empty($port)? $defaultPort: $port); } // Do not overwrite explicitly set 'Host' header, see bug #16146 if (!isset($headers['host'])) { $headers['host'] = $host; } if ($connect) { $requestUrl = $host; } else { if (!$this->request->getConfig('proxy_host') || 'http' != $this->request->getConfig('proxy_type') || 0 == strcasecmp($url->getScheme(), 'https') ) { $requestUrl = ''; } else { $requestUrl = $url->getScheme() . '://' . $host; } $path = $url->getPath(); $query = $url->getQuery(); $requestUrl .= (empty($path)? '/': $path) . (empty($query)? '': '?' . $query); } if ('1.1' == $this->request->getConfig('protocol_version') && extension_loaded('zlib') && !isset($headers['accept-encoding']) ) { $headers['accept-encoding'] = 'gzip, deflate'; } if (($jar = $this->request->getCookieJar()) && ($cookies = $jar->getMatching($this->request->getUrl(), true)) ) { $headers['cookie'] = (empty($headers['cookie'])? '': $headers['cookie'] . '; ') . $cookies; } $this->addAuthorizationHeader($headers, $host, $requestUrl); $this->addProxyAuthorizationHeader($headers, $requestUrl); $this->calculateRequestLength($headers); if ('1.1' == $this->request->getConfig('protocol_version')) { $this->updateExpectHeader($headers); } else { $this->expect100Continue = false; } $headersStr = $this->request->getMethod() . ' ' . $requestUrl . ' HTTP/' . $this->request->getConfig('protocol_version') . "\r\n"; foreach ($headers as $name => $value) { $canonicalName = implode('-', array_map('ucfirst', explode('-', $name))); $headersStr .= $canonicalName . ': ' . $value . "\r\n"; } return $headersStr . "\r\n"; } /** * Adds or removes 'Expect: 100-continue' header from request headers * * Also sets the $expect100Continue property. Parsing of existing header * is somewhat needed due to its complex structure and due to the * requirement in section 8.2.3 of RFC 2616: * > A client MUST NOT send an Expect request-header field (section * > 14.20) with the "100-continue" expectation if it does not intend * > to send a request body. * * @param array $headers Array of headers prepared for the request * * @return void * @throws HTTP_Request2_LogicException * * @link http://pear.php.net/bugs/bug.php?id=19233 * @link http://tools.ietf.org/html/rfc2616#section-8.2.3 */ protected function updateExpectHeader(&$headers) { $this->expect100Continue = false; $expectations = []; if (isset($headers['expect'])) { if ('' === $headers['expect']) { // empty 'Expect' header is technically invalid, so just get rid of it unset($headers['expect']); return; } // build regexp to parse the value of existing Expect header $expectParam = ';\s*' . self::REGEXP_TOKEN . '(?:\s*=\s*(?:' . self::REGEXP_TOKEN . '|' . self::REGEXP_QUOTED_STRING . '))?\s*'; $expectExtension = self::REGEXP_TOKEN . '(?:\s*=\s*(?:' . self::REGEXP_TOKEN . '|' . self::REGEXP_QUOTED_STRING . ')\s*(?:' . $expectParam . ')*)?'; $expectItem = '!(100-continue|' . $expectExtension . ')!A'; $pos = 0; $length = strlen($headers['expect']); while ($pos < $length) { $pos += strspn($headers['expect'], " \t", $pos); if (',' === substr($headers['expect'], $pos, 1)) { $pos++; continue; } elseif (!preg_match($expectItem, $headers['expect'], $m, 0, $pos)) { throw new HTTP_Request2_LogicException( "Cannot parse value '{$headers['expect']}' of Expect header", HTTP_Request2_Exception::INVALID_ARGUMENT ); } else { $pos += strlen($m[0]); if (strcasecmp('100-continue', $m[0])) { $expectations[] = $m[0]; } } } } if (1024 < $this->contentLength) { $expectations[] = '100-continue'; $this->expect100Continue = true; } if (empty($expectations)) { unset($headers['expect']); } else { $headers['expect'] = implode(',', $expectations); } } /** * Sends the request body * * @return void * @throws HTTP_Request2_MessageException */ protected function writeBody() { if (in_array($this->request->getMethod(), self::$bodyDisallowed) || 0 == $this->contentLength ) { return; } $position = 0; $bufferSize = $this->request->getConfig('buffer_size'); $headers = $this->request->getHeaders(); $chunked = isset($headers['transfer-encoding']); while ($position < $this->contentLength) { if (is_string($this->requestBody)) { $str = substr($this->requestBody, $position, $bufferSize); } elseif (is_resource($this->requestBody)) { $str = fread($this->requestBody, $bufferSize); } else { $str = $this->requestBody->read($bufferSize); } if (!$chunked) { $this->socket->write($str); } else { $this->socket->write(dechex(strlen($str)) . "\r\n{$str}\r\n"); } // Provide the length of written string to the observer, request #7630 $this->request->setLastEvent('sentBodyPart', strlen($str)); $position += strlen($str); } // write zero-length chunk if ($chunked) { $this->socket->write("0\r\n\r\n"); } $this->request->setLastEvent('sentBody', $this->contentLength); } /** * Reads the remote server's response * * @return HTTP_Request2_Response * @throws HTTP_Request2_Exception */ protected function readResponse() { $bufferSize = $this->request->getConfig('buffer_size'); // http://tools.ietf.org/html/rfc2616#section-8.2.3 // ...the client SHOULD NOT wait for an indefinite period before sending the request body $timeout = $this->expect100Continue ? 1 : null; do { try { $response = new HTTP_Request2_Response( $this->socket->readLine($bufferSize, $timeout), true, $this->request->getUrl() ); do { $headerLine = $this->socket->readLine($bufferSize); $response->parseHeaderLine($headerLine); } while ('' != $headerLine); } catch (HTTP_Request2_MessageException $e) { if (HTTP_Request2_Exception::TIMEOUT === $e->getCode() && $this->expect100Continue ) { return null; } throw $e; } if ($this->expect100Continue && 100 == $response->getStatus()) { return $response; } } while (in_array($response->getStatus(), [100, 101])); $this->request->setLastEvent('receivedHeaders', $response); // No body possible in such responses if (HTTP_Request2::METHOD_HEAD == $this->request->getMethod() || (HTTP_Request2::METHOD_CONNECT == $this->request->getMethod() && 200 <= $response->getStatus() && 300 > $response->getStatus()) || in_array($response->getStatus(), [204, 304]) ) { return $response; } $chunked = 'chunked' == $response->getHeader('transfer-encoding'); $length = $response->getHeader('content-length'); $hasBody = false; // RFC 2616, section 4.4: // 3. ... If a message is received with both a // Transfer-Encoding header field and a Content-Length header field, // the latter MUST be ignored. $toRead = ($chunked || null === $length)? null: $length; $this->chunkLength = 0; if ($chunked || null === $length || 0 < intval($length)) { while (!$this->socket->eof() && (is_null($toRead) || 0 < $toRead)) { if ($chunked) { $data = $this->readChunked($bufferSize); } elseif (is_null($toRead)) { $data = $this->socket->read($bufferSize); } else { $data = $this->socket->read(min($toRead, $bufferSize)); $toRead -= strlen($data); } if ('' == $data && (!$this->chunkLength || $this->socket->eof())) { break; } $hasBody = true; if ($this->request->getConfig('store_body')) { $response->appendBody($data); } if (!in_array($response->getHeader('content-encoding'), ['identity', null])) { $this->request->setLastEvent('receivedEncodedBodyPart', $data); } else { $this->request->setLastEvent('receivedBodyPart', $data); } } } if (0 !== $this->chunkLength || null !== $toRead && $toRead > 0) { $this->request->setLastEvent( 'warning', 'transfer closed with outstanding read data remaining' ); } if ($hasBody) { $this->request->setLastEvent('receivedBody', $response); } return $response; } /** * Reads a part of response body encoded with chunked Transfer-Encoding * * @param int $bufferSize buffer size to use for reading * * @return string * @throws HTTP_Request2_MessageException */ protected function readChunked($bufferSize) { // at start of the next chunk? if (0 == $this->chunkLength) { $line = $this->socket->readLine($bufferSize); if ('' === $line && $this->socket->eof()) { $this->chunkLength = -1; // indicate missing chunk return ''; } elseif (!preg_match('/^([0-9a-f]+)/i', $line, $matches)) { throw new HTTP_Request2_MessageException( "Cannot decode chunked response, invalid chunk length '{$line}'", HTTP_Request2_Exception::DECODE_ERROR ); } else { $this->chunkLength = hexdec($matches[1]); // Chunk with zero length indicates the end if (0 == $this->chunkLength) { $this->socket->readLine($bufferSize); return ''; } } } $data = $this->socket->read(min($this->chunkLength, $bufferSize)); $this->chunkLength -= strlen($data); if (0 == $this->chunkLength) { $this->socket->readLine($bufferSize); // Trailing CRLF } return $data; } } ?>includes/PEAR/HTTP/Request2/Adapter/Mock.php000064400000012357152214270100014356 0ustar00 * @copyright 2008-2022 Alexey Borzov * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License * @link http://pear.php.net/package/HTTP_Request2 */ /** * Base class for HTTP_Request2 adapters */ require_once 'HTTP/Request2/Adapter.php'; /** * Mock adapter intended for testing * * Can be used to test applications depending on HTTP_Request2 package without * actually performing any HTTP requests. This adapter will return responses * previously added via addResponse() * * $mock = new HTTP_Request2_Adapter_Mock(); * $mock->addResponse("HTTP/1.1 ... "); * * $request = new HTTP_Request2(); * $request->setAdapter($mock); * * // This will return the response set above * $response = $req->send(); * * * @category HTTP * @package HTTP_Request2 * @author Alexey Borzov * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License * @version Release: 2.5.1 * @link http://pear.php.net/package/HTTP_Request2 */ class HTTP_Request2_Adapter_Mock extends HTTP_Request2_Adapter { /** * A queue of responses to be returned by sendRequest() * * @var array */ protected $responses = []; /** * Returns the next response from the queue built by addResponse() * * Only responses without explicit URLs or with URLs equal to request URL * will be considered. If matching response is not found or the queue is * empty then default empty response with status 400 will be returned, * if an Exception object was added to the queue it will be thrown. * * @param HTTP_Request2 $request HTTP request message * * @return HTTP_Request2_Response * @throws Exception */ public function sendRequest(HTTP_Request2 $request) { $requestUrl = (string)$request->getUrl(); $response = null; foreach ($this->responses as $k => $v) { if (!$v[1] || $requestUrl == $v[1]) { $response = $v[0]; array_splice($this->responses, $k, 1); break; } } if (!$response) { return self::createResponseFromString("HTTP/1.1 400 Bad Request\r\n\r\n"); } elseif ($response instanceof HTTP_Request2_Response) { return $response; } else { // rethrow the exception $class = get_class($response); $message = $response->getMessage(); $code = $response->getCode(); throw new $class($message, $code); } } /** * Adds response to the queue * * @param mixed $response either a string, a pointer to an open file, * an instance of HTTP_Request2_Response or Exception * @param string $url A request URL this response should be valid for * (see {@link http://pear.php.net/bugs/bug.php?id=19276}) * * @return void * @throws HTTP_Request2_Exception */ public function addResponse($response, $url = null) { if (is_string($response)) { $response = self::createResponseFromString($response); } elseif (is_resource($response)) { $response = self::createResponseFromFile($response); } elseif (!$response instanceof HTTP_Request2_Response && !$response instanceof Exception ) { throw new HTTP_Request2_Exception('Parameter is not a valid response'); } $this->responses[] = [$response, $url]; } /** * Creates a new HTTP_Request2_Response object from a string * * @param string $str string containing HTTP response message * * @return HTTP_Request2_Response * @throws HTTP_Request2_Exception */ public static function createResponseFromString($str) { $parts = preg_split('!(\r?\n){2}!m', $str, 2); $headerLines = explode("\n", $parts[0]); $response = new HTTP_Request2_Response(array_shift($headerLines)); foreach ($headerLines as $headerLine) { $response->parseHeaderLine($headerLine); } $response->parseHeaderLine(''); if (isset($parts[1])) { $response->appendBody($parts[1]); } return $response; } /** * Creates a new HTTP_Request2_Response object from a file * * @param resource $fp file pointer returned by fopen() * * @return HTTP_Request2_Response * @throws HTTP_Request2_Exception */ public static function createResponseFromFile($fp) { $response = new HTTP_Request2_Response(fgets($fp)); do { $headerLine = fgets($fp); $response->parseHeaderLine($headerLine); } while ('' != trim($headerLine)); while (!feof($fp)) { $response->appendBody(fread($fp, 8192)); } return $response; } } ?>includes/PEAR/HTTP/Request2/Adapter/Curl.php000064400000053705152214270100014374 0ustar00 * @copyright 2008-2022 Alexey Borzov * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License * @link http://pear.php.net/package/HTTP_Request2 */ /** * Base class for HTTP_Request2 adapters */ require_once 'HTTP/Request2/Adapter.php'; /** * Adapter for HTTP_Request2 wrapping around cURL extension * * @category HTTP * @package HTTP_Request2 * @author Alexey Borzov * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License * @version Release: 2.5.1 * @link http://pear.php.net/package/HTTP_Request2 */ class HTTP_Request2_Adapter_Curl extends HTTP_Request2_Adapter { /** * Mapping of header names to cURL options * * @var array */ protected static $headerMap = [ 'accept-encoding' => CURLOPT_ENCODING, 'cookie' => CURLOPT_COOKIE, 'referer' => CURLOPT_REFERER, 'user-agent' => CURLOPT_USERAGENT ]; /** * Mapping of SSL context options to cURL options * * @var array */ protected static $sslContextMap = [ 'ssl_verify_peer' => CURLOPT_SSL_VERIFYPEER, 'ssl_cafile' => CURLOPT_CAINFO, 'ssl_capath' => CURLOPT_CAPATH, 'ssl_local_cert' => CURLOPT_SSLCERT, 'ssl_passphrase' => CURLOPT_SSLCERTPASSWD ]; /** * Mapping of CURLE_* constants to Exception subclasses and error codes * * @var array */ protected static $errorMap = [ CURLE_UNSUPPORTED_PROTOCOL => ['HTTP_Request2_MessageException', HTTP_Request2_Exception::NON_HTTP_REDIRECT], CURLE_COULDNT_RESOLVE_PROXY => ['HTTP_Request2_ConnectionException'], CURLE_COULDNT_RESOLVE_HOST => ['HTTP_Request2_ConnectionException'], CURLE_COULDNT_CONNECT => ['HTTP_Request2_ConnectionException'], // error returned from write callback CURLE_WRITE_ERROR => ['HTTP_Request2_MessageException', HTTP_Request2_Exception::NON_HTTP_REDIRECT], CURLE_OPERATION_TIMEOUTED => ['HTTP_Request2_MessageException', HTTP_Request2_Exception::TIMEOUT], CURLE_HTTP_RANGE_ERROR => ['HTTP_Request2_MessageException'], CURLE_SSL_CONNECT_ERROR => ['HTTP_Request2_ConnectionException'], CURLE_LIBRARY_NOT_FOUND => ['HTTP_Request2_LogicException', HTTP_Request2_Exception::MISCONFIGURATION], CURLE_FUNCTION_NOT_FOUND => ['HTTP_Request2_LogicException', HTTP_Request2_Exception::MISCONFIGURATION], CURLE_ABORTED_BY_CALLBACK => ['HTTP_Request2_MessageException', HTTP_Request2_Exception::NON_HTTP_REDIRECT], CURLE_TOO_MANY_REDIRECTS => ['HTTP_Request2_MessageException', HTTP_Request2_Exception::TOO_MANY_REDIRECTS], CURLE_SSL_PEER_CERTIFICATE => ['HTTP_Request2_ConnectionException'], CURLE_GOT_NOTHING => ['HTTP_Request2_MessageException'], CURLE_SSL_ENGINE_NOTFOUND => ['HTTP_Request2_LogicException', HTTP_Request2_Exception::MISCONFIGURATION], CURLE_SSL_ENGINE_SETFAILED => ['HTTP_Request2_LogicException', HTTP_Request2_Exception::MISCONFIGURATION], CURLE_SEND_ERROR => ['HTTP_Request2_MessageException'], CURLE_RECV_ERROR => ['HTTP_Request2_MessageException'], CURLE_SSL_CERTPROBLEM => ['HTTP_Request2_LogicException', HTTP_Request2_Exception::INVALID_ARGUMENT], CURLE_SSL_CIPHER => ['HTTP_Request2_ConnectionException'], CURLE_SSL_CACERT => ['HTTP_Request2_ConnectionException'], CURLE_BAD_CONTENT_ENCODING => ['HTTP_Request2_MessageException'], ]; /** * Response being received * * @var HTTP_Request2_Response */ protected $response; /** * Whether 'sentHeaders' event was sent to observers * * @var boolean */ protected $eventSentHeaders = false; /** * Whether 'receivedHeaders' event was sent to observers * * @var boolean */ protected $eventReceivedHeaders = false; /** * Whether 'sentBoody' event was sent to observers * * @var boolean */ protected $eventSentBody = false; /** * Position within request body * * @var integer * @see callbackReadBody() */ protected $position = 0; /** * Information about last transfer, as returned by curl_getinfo() * * @var array */ protected $lastInfo; /** * Creates a subclass of HTTP_Request2_Exception from curl error data * * @param resource $ch curl handle * * @return HTTP_Request2_Exception */ protected static function wrapCurlError($ch) { $nativeCode = curl_errno($ch); $message = 'Curl error: ' . curl_error($ch); if (!isset(self::$errorMap[$nativeCode])) { return new HTTP_Request2_Exception($message, 0, $nativeCode); } else { $class = self::$errorMap[$nativeCode][0]; $code = empty(self::$errorMap[$nativeCode][1]) ? 0 : self::$errorMap[$nativeCode][1]; return new $class($message, $code, $nativeCode); } } /** * Sends request to the remote server and returns its response * * @param HTTP_Request2 $request HTTP request message * * @return HTTP_Request2_Response * @throws HTTP_Request2_Exception */ public function sendRequest(HTTP_Request2 $request) { if (!extension_loaded('curl')) { throw new HTTP_Request2_LogicException( 'cURL extension not available', HTTP_Request2_Exception::MISCONFIGURATION ); } $this->request = $request; $this->response = null; $this->position = 0; $this->eventSentHeaders = false; $this->eventReceivedHeaders = false; $this->eventSentBody = false; try { if (false === curl_exec($ch = $this->createCurlHandle())) { throw self::wrapCurlError($ch); } } finally { // phpcs:ignore PHPCompatibility.Keywords.NewKeywords.t_finallyFound if (isset($ch)) { $this->lastInfo = curl_getinfo($ch); if (CURLE_OK !== curl_errno($ch)) { $this->request->setLastEvent('warning', curl_error($ch)); } curl_close($ch); } $response = $this->response; unset($this->request, $this->requestBody, $this->response); } if ($jar = $request->getCookieJar()) { $jar->addCookiesFromResponse($response); } if (0 < $this->lastInfo['size_download']) { $request->setLastEvent('receivedBody', $response); } return $response; } /** * Returns information about last transfer * * @return array associative array as returned by curl_getinfo() */ public function getInfo() { return $this->lastInfo; } /** * Creates a new cURL handle and populates it with data from the request * * @return resource a cURL handle, as created by curl_init() * @throws HTTP_Request2_LogicException * @throws HTTP_Request2_NotImplementedException */ protected function createCurlHandle() { $ch = curl_init(); curl_setopt_array( $ch, [ // setup write callbacks CURLOPT_HEADERFUNCTION => [$this, 'callbackWriteHeader'], CURLOPT_WRITEFUNCTION => [$this, 'callbackWriteBody'], // buffer size CURLOPT_BUFFERSIZE => $this->request->getConfig('buffer_size'), // connection timeout CURLOPT_CONNECTTIMEOUT => $this->request->getConfig('connect_timeout'), // save full outgoing headers, in case someone is interested CURLINFO_HEADER_OUT => true, // request url CURLOPT_URL => $this->request->getUrl()->getUrl() ] ); // set up redirects if (!$this->request->getConfig('follow_redirects')) { curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false); } else { if (!@curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true)) { throw new HTTP_Request2_LogicException( 'Redirect support in curl is unavailable due to open_basedir or safe_mode setting', HTTP_Request2_Exception::MISCONFIGURATION ); } curl_setopt($ch, CURLOPT_MAXREDIRS, $this->request->getConfig('max_redirects')); // limit redirects to http(s), works in 5.2.10+ if (defined('CURLOPT_REDIR_PROTOCOLS')) { curl_setopt($ch, CURLOPT_REDIR_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS); } // works in 5.3.2+, http://bugs.php.net/bug.php?id=49571 if ($this->request->getConfig('strict_redirects') && defined('CURLOPT_POSTREDIR')) { curl_setopt($ch, CURLOPT_POSTREDIR, 3); } } // set local IP via CURLOPT_INTERFACE (request #19515) if ($ip = $this->request->getConfig('local_ip')) { curl_setopt($ch, CURLOPT_INTERFACE, $ip); } // request timeout if ($timeout = $this->request->getConfig('timeout')) { curl_setopt($ch, CURLOPT_TIMEOUT, $timeout); } // set HTTP version switch ($this->request->getConfig('protocol_version')) { case '1.0': curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0); break; case '1.1': curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1); } // set request method switch ($this->request->getMethod()) { case HTTP_Request2::METHOD_GET: curl_setopt($ch, CURLOPT_HTTPGET, true); break; case HTTP_Request2::METHOD_POST: curl_setopt($ch, CURLOPT_POST, true); break; case HTTP_Request2::METHOD_HEAD: curl_setopt($ch, CURLOPT_NOBODY, true); break; case HTTP_Request2::METHOD_PUT: curl_setopt($ch, CURLOPT_UPLOAD, true); break; default: curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $this->request->getMethod()); } // set proxy, if needed if ($host = $this->request->getConfig('proxy_host')) { if (!($port = $this->request->getConfig('proxy_port'))) { throw new HTTP_Request2_LogicException( 'Proxy port not provided', HTTP_Request2_Exception::MISSING_VALUE ); } curl_setopt($ch, CURLOPT_PROXY, $host . ':' . $port); if ($user = $this->request->getConfig('proxy_user')) { curl_setopt( $ch, CURLOPT_PROXYUSERPWD, $user . ':' . $this->request->getConfig('proxy_password') ); switch ($this->request->getConfig('proxy_auth_scheme')) { case HTTP_Request2::AUTH_BASIC: curl_setopt($ch, CURLOPT_PROXYAUTH, CURLAUTH_BASIC); break; case HTTP_Request2::AUTH_DIGEST: curl_setopt($ch, CURLOPT_PROXYAUTH, CURLAUTH_DIGEST); } } if ($type = $this->request->getConfig('proxy_type')) { switch ($type) { case 'http': curl_setopt($ch, CURLOPT_PROXYTYPE, CURLPROXY_HTTP); break; case 'socks5': curl_setopt($ch, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5); break; default: throw new HTTP_Request2_NotImplementedException( "Proxy type '{$type}' is not supported" ); } } } // set authentication data if ($auth = $this->request->getAuth()) { curl_setopt($ch, CURLOPT_USERPWD, $auth['user'] . ':' . $auth['password']); switch ($auth['scheme']) { case HTTP_Request2::AUTH_BASIC: curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC); break; case HTTP_Request2::AUTH_DIGEST: curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST); } } // set SSL options foreach ($this->request->getConfig() as $name => $value) { if ('ssl_verify_host' == $name && null !== $value) { curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, $value? 2: 0); } elseif (isset(self::$sslContextMap[$name]) && null !== $value) { curl_setopt($ch, self::$sslContextMap[$name], $value); } } $headers = $this->request->getHeaders(); // make cURL automagically send proper header if (!isset($headers['accept-encoding'])) { $headers['accept-encoding'] = ''; } if (($jar = $this->request->getCookieJar()) && ($cookies = $jar->getMatching($this->request->getUrl(), true)) ) { $headers['cookie'] = (empty($headers['cookie'])? '': $headers['cookie'] . '; ') . $cookies; } // set headers having special cURL keys foreach (self::$headerMap as $name => $option) { if (isset($headers[$name])) { curl_setopt($ch, $option, $headers[$name]); unset($headers[$name]); } } $this->calculateRequestLength($headers); if (isset($headers['content-length']) || isset($headers['transfer-encoding'])) { $this->workaroundPhpBug47204($ch, $headers); } // set headers not having special keys $headersFmt = []; foreach ($headers as $name => $value) { $canonicalName = implode('-', array_map('ucfirst', explode('-', $name))); $headersFmt[] = $canonicalName . ': ' . $value; } curl_setopt($ch, CURLOPT_HTTPHEADER, $headersFmt); return $ch; } /** * Workaround for PHP bug #47204 that prevents rewinding request body * * The workaround consists of reading the entire request body into memory * and setting it as CURLOPT_POSTFIELDS, so it isn't recommended for large * file uploads, use Socket adapter instead. * * @param resource $ch cURL handle * @param array $headers Request headers * * @return void */ protected function workaroundPhpBug47204($ch, &$headers) { // no redirects, no digest auth -> probably no rewind needed // also apply workaround only for POSTs, othrerwise we get // https://pear.php.net/bugs/bug.php?id=20440 for PUTs if (!$this->request->getConfig('follow_redirects') && (!($auth = $this->request->getAuth()) || HTTP_Request2::AUTH_DIGEST !== $auth['scheme']) || HTTP_Request2::METHOD_POST !== $this->request->getMethod() ) { curl_setopt($ch, CURLOPT_READFUNCTION, [$this, 'callbackReadBody']); } else { // rewind may be needed, read the whole body into memory if ($this->requestBody instanceof HTTP_Request2_MultipartBody) { $this->requestBody = $this->requestBody->__toString(); } elseif (is_resource($this->requestBody)) { $fp = $this->requestBody; $this->requestBody = ''; while (!feof($fp)) { $this->requestBody .= fread($fp, 16384); } } // curl hangs up if content-length is present unset($headers['content-length']); curl_setopt($ch, CURLOPT_POSTFIELDS, $this->requestBody); } } /** * Callback function called by cURL for reading the request body * * @param resource $ch cURL handle * @param resource $fd file descriptor (not used) * @param integer $length maximum length of data to return * * @return string part of the request body, up to $length bytes */ protected function callbackReadBody($ch, $fd, $length) { if (!$this->eventSentHeaders) { $this->request->setLastEvent( 'sentHeaders', curl_getinfo($ch, CURLINFO_HEADER_OUT) ); $this->eventSentHeaders = true; } if (in_array($this->request->getMethod(), self::$bodyDisallowed) || 0 == $this->contentLength || $this->position >= $this->contentLength ) { return ''; } if (is_string($this->requestBody)) { $string = substr($this->requestBody, $this->position, $length); } elseif (is_resource($this->requestBody)) { $string = fread($this->requestBody, $length); } else { $string = $this->requestBody->read($length); } $this->request->setLastEvent('sentBodyPart', strlen($string)); $this->position += strlen($string); return $string; } /** * Callback function called by cURL for saving the response headers * * @param resource $ch cURL handle * @param string $string response header (with trailing CRLF) * * @return integer number of bytes saved * @see HTTP_Request2_Response::parseHeaderLine() */ protected function callbackWriteHeader($ch, $string) { if (!$this->eventSentHeaders // we may receive a second set of headers if doing e.g. digest auth // but don't bother with 100-Continue responses (bug #15785) || $this->eventReceivedHeaders && $this->response->getStatus() >= 200 ) { $this->request->setLastEvent( 'sentHeaders', curl_getinfo($ch, CURLINFO_HEADER_OUT) ); } if (!$this->eventSentBody) { $upload = curl_getinfo($ch, CURLINFO_SIZE_UPLOAD); // if body wasn't read by the callback, send event with total body size if ($upload > $this->position) { $this->request->setLastEvent( 'sentBodyPart', $upload - $this->position ); } if ($upload > 0) { $this->request->setLastEvent('sentBody', $upload); } } $this->eventSentHeaders = true; $this->eventSentBody = true; if ($this->eventReceivedHeaders || empty($this->response)) { $this->eventReceivedHeaders = false; $this->response = new HTTP_Request2_Response( $string, false, curl_getinfo($ch, CURLINFO_EFFECTIVE_URL) ); } else { $this->response->parseHeaderLine($string); if ('' == trim($string)) { // don't bother with 100-Continue responses (bug #15785) if (200 <= $this->response->getStatus()) { $this->request->setLastEvent('receivedHeaders', $this->response); } if ($this->request->getConfig('follow_redirects') && $this->response->isRedirect()) { $redirectUrl = new Net_URL2($this->response->getHeader('location')); // for versions lower than 5.2.10, check the redirection URL protocol if (!defined('CURLOPT_REDIR_PROTOCOLS') && $redirectUrl->isAbsolute() && !in_array($redirectUrl->getScheme(), ['http', 'https']) ) { return -1; } if ($jar = $this->request->getCookieJar()) { $jar->addCookiesFromResponse($this->response); if (!$redirectUrl->isAbsolute()) { $redirectUrl = $this->request->getUrl()->resolve($redirectUrl); } if ($cookies = $jar->getMatching($redirectUrl, true)) { curl_setopt($ch, CURLOPT_COOKIE, $cookies); } } } $this->eventReceivedHeaders = true; $this->eventSentBody = false; } } return strlen($string); } /** * Callback function called by cURL for saving the response body * * @param resource $ch cURL handle (not used) * @param string $string part of the response body * * @return integer number of bytes saved * @throws HTTP_Request2_MessageException * @see HTTP_Request2_Response::appendBody() */ protected function callbackWriteBody($ch, $string) { // cURL calls WRITEFUNCTION callback without calling HEADERFUNCTION if // response doesn't start with proper HTTP status line (see bug #15716) if (empty($this->response)) { throw new HTTP_Request2_MessageException( "Malformed response: {$string}", HTTP_Request2_Exception::MALFORMED_RESPONSE ); } if ($this->request->getConfig('store_body')) { $this->response->appendBody($string); } $this->request->setLastEvent('receivedBodyPart', $string); return strlen($string); } } ?> includes/PEAR/HTTP/Request2/Observer/UncompressingDownload.php000064400000021116152214270100020211 0ustar00 * @author Alexey Borzov * @copyright 2008-2022 Alexey Borzov * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License * @link http://pear.php.net/package/HTTP_Request2 */ require_once 'HTTP/Request2/Response.php'; /** * An observer that saves response body to stream, possibly uncompressing it * * This Observer is written in compliment to pear's HTTP_Request2 in order to * avoid reading the whole response body in memory. Instead it writes the body * to a stream. If the body is transferred with content-encoding set to * "deflate" or "gzip" it is decoded on the fly. * * The constructor accepts an already opened (for write) stream (file_descriptor). * If the response is deflate/gzip encoded a "zlib.inflate" filter is applied * to the stream. When the body has been read from the request and written to * the stream ("receivedBody" event) the filter is removed from the stream. * * The "zlib.inflate" filter works fine with pure "deflate" encoding. It does * not understand the "deflate+zlib" and "gzip" headers though, so they have to * be removed prior to being passed to the stream. This is done in the "update" * method. * * It is also possible to limit the size of written extracted bytes by passing * "max_bytes" to the constructor. This is important because e.g. 1GB of * zeroes take about a MB when compressed. * * Exceptions are being thrown if data could not be written to the stream or * the written bytes have already exceeded the requested maximum. If the "gzip" * header is malformed or could not be parsed an exception will be thrown too. * * Example usage follows: * * * require_once 'HTTP/Request2.php'; * require_once 'HTTP/Request2/Observer/UncompressingDownload.php'; * * #$inPath = 'http://carsten.codimi.de/gzip.yaws/daniels.html'; * #$inPath = 'http://carsten.codimi.de/gzip.yaws/daniels.html?deflate=on'; * $inPath = 'http://carsten.codimi.de/gzip.yaws/daniels.html?deflate=on&zlib=on'; * #$outPath = "/dev/null"; * $outPath = "delme"; * * $stream = fopen($outPath, 'wb'); * if (!$stream) { * throw new Exception('fopen failed'); * } * * $request = new HTTP_Request2( * $inPath, * HTTP_Request2::METHOD_GET, * array( * 'store_body' => false, * 'connect_timeout' => 5, * 'timeout' => 10, * 'ssl_verify_peer' => true, * 'ssl_verify_host' => true, * 'ssl_cafile' => null, * 'ssl_capath' => '/etc/ssl/certs', * 'max_redirects' => 10, * 'follow_redirects' => true, * 'strict_redirects' => false * ) * ); * * $observer = new HTTP_Request2_Observer_UncompressingDownload($stream, 9999999); * $request->attach($observer); * * $response = $request->send(); * * fclose($stream); * echo "OK\n"; * * * @category HTTP * @package HTTP_Request2 * @author Delian Krustev * @author Alexey Borzov * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License * @version Release: 2.5.1 * @link http://pear.php.net/package/HTTP_Request2 */ class HTTP_Request2_Observer_UncompressingDownload implements SplObserver { /** * The stream to write response body to * * @var resource */ private $_stream; /** * 'zlib.inflate' filter possibly added to stream * * @var resource */ private $_streamFilter; /** * The value of response's Content-Encoding header * * @var string */ private $_encoding; /** * Whether the observer is still waiting for gzip/deflate header * * @var bool */ private $_processingHeader = true; /** * Starting position in the stream observer writes to * * @var int */ private $_startPosition = 0; /** * Maximum bytes to write * * @var int|null */ private $_maxDownloadSize; /** * Whether response being received is a redirect * * @var bool */ private $_redirect = false; /** * Accumulated body chunks that may contain (gzip) header * * @var string */ private $_possibleHeader = ''; /** * Class constructor * * Note that there might be problems with max_bytes and files bigger * than 2 GB on 32bit platforms * * @param resource $stream a stream (or file descriptor) opened for writing. * @param int $maxDownloadSize maximum bytes to write */ public function __construct($stream, $maxDownloadSize = null) { $this->_stream = $stream; if ($maxDownloadSize) { $this->_maxDownloadSize = $maxDownloadSize; $this->_startPosition = ftell($this->_stream); } } #[ReturnTypeWillChange] /** * Called when the request notifies us of an event. * * @param SplSubject $request The HTTP_Request2 instance * * @return void * @throws HTTP_Request2_MessageException */ public function update(SplSubject $request) { /* @var $request HTTP_Request2 */ $event = $request->getLastEvent(); $encoded = false; /* @var $event['data'] HTTP_Request2_Response */ switch ($event['name']) { case 'receivedHeaders': $this->_processingHeader = true; $this->_redirect = $event['data']->isRedirect(); $this->_encoding = strtolower($event['data']->getHeader('content-encoding') ?: ''); $this->_possibleHeader = ''; break; case 'receivedEncodedBodyPart': if (!$this->_streamFilter && ($this->_encoding === 'deflate' || $this->_encoding === 'gzip') ) { $this->_streamFilter = stream_filter_append( $this->_stream, 'zlib.inflate', STREAM_FILTER_WRITE ); } $encoded = true; // fall-through is intentional case 'receivedBodyPart': if ($this->_redirect) { break; } if (!$encoded || !$this->_processingHeader) { $bytes = fwrite($this->_stream, $event['data']); } else { $offset = 0; $this->_possibleHeader .= $event['data']; if ('deflate' === $this->_encoding) { if (2 > strlen($this->_possibleHeader)) { break; } $header = unpack('n', substr($this->_possibleHeader, 0, 2)); if (0 == $header[1] % 31) { $offset = 2; } } elseif ('gzip' === $this->_encoding) { if (10 > strlen($this->_possibleHeader)) { break; } try { $offset = HTTP_Request2_Response::parseGzipHeader($this->_possibleHeader, false); } catch (HTTP_Request2_MessageException $e) { // need more data? if (false !== strpos($e->getMessage(), 'data too short')) { break; } throw $e; } } $this->_processingHeader = false; $bytes = fwrite($this->_stream, substr($this->_possibleHeader, $offset)); } if (false === $bytes) { throw new HTTP_Request2_MessageException('fwrite failed.'); } if ($this->_maxDownloadSize && ftell($this->_stream) - $this->_startPosition > $this->_maxDownloadSize ) { throw new HTTP_Request2_MessageException( sprintf( 'Body length limit (%d bytes) reached', $this->_maxDownloadSize ) ); } break; case 'receivedBody': if ($this->_streamFilter) { stream_filter_remove($this->_streamFilter); $this->_streamFilter = null; } break; } } } includes/PEAR/HTTP/Request2/Observer/Log.php000064400000012364152214270100014413 0ustar00 * @author Alexey Borzov * @copyright 2008-2022 Alexey Borzov * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License * @link http://pear.php.net/package/HTTP_Request2 */ /** * Exception class for HTTP_Request2 package */ require_once 'HTTP/Request2/Exception.php'; /** * A debug observer useful for debugging / testing. * * This observer logs to a log target data corresponding to the various request * and response events, it logs by default to php://output but can be configured * to log to a file or via the PEAR Log package. * * A simple example: * * require_once 'HTTP/Request2.php'; * require_once 'HTTP/Request2/Observer/Log.php'; * * $request = new HTTP_Request2('http://www.example.com'); * $observer = new HTTP_Request2_Observer_Log(); * $request->attach($observer); * $request->send(); * * * A more complex example with PEAR Log: * * require_once 'HTTP/Request2.php'; * require_once 'HTTP/Request2/Observer/Log.php'; * require_once 'Log.php'; * * $request = new HTTP_Request2('http://www.example.com'); * // we want to log with PEAR log * $observer = new HTTP_Request2_Observer_Log(Log::factory('console')); * * // we only want to log received headers * $observer->events = array('receivedHeaders'); * * $request->attach($observer); * $request->send(); * * * @category HTTP * @package HTTP_Request2 * @author David Jean Louis * @author Alexey Borzov * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License * @version Release: 2.5.1 * @link http://pear.php.net/package/HTTP_Request2 */ class HTTP_Request2_Observer_Log implements SplObserver { // properties {{{ /** * The log target, it can be a a resource or a PEAR Log instance. * * @var resource|Log $target */ protected $target = null; /** * The events to log. * * @var array $events */ public $events = [ 'connect', 'sentHeaders', 'sentBody', 'receivedHeaders', 'receivedBody', 'disconnect', ]; // }}} // __construct() {{{ /** * Constructor. * * @param mixed $target Can be a file path (default: php://output), a resource, * or an instance of the PEAR Log class. * @param array $events Array of events to listen to (default: all events) * * @return void */ public function __construct($target = 'php://output', array $events = []) { if (!empty($events)) { $this->events = $events; } if (is_resource($target) || $target instanceof Log) { $this->target = $target; } elseif (false === ($this->target = @fopen($target, 'ab'))) { throw new HTTP_Request2_Exception("Unable to open '{$target}'"); } } // }}} // update() {{{ #[ReturnTypeWillChange] /** * Called when the request notifies us of an event. * * @param HTTP_Request2 $subject The HTTP_Request2 instance * * @return void */ public function update(SplSubject $subject) { $event = $subject->getLastEvent(); if (!in_array($event['name'], $this->events)) { return; } switch ($event['name']) { case 'connect': $this->log('* Connected to ' . $event['data']); break; case 'sentHeaders': $headers = explode("\r\n", $event['data']); array_pop($headers); foreach ($headers as $header) { $this->log('> ' . $header); } break; case 'sentBody': $this->log('> ' . $event['data'] . ' byte(s) sent'); break; case 'receivedHeaders': $this->log( sprintf( '< HTTP/%s %s %s', $event['data']->getVersion(), $event['data']->getStatus(), $event['data']->getReasonPhrase() ) ); $headers = $event['data']->getHeader(); foreach ($headers as $key => $val) { $this->log('< ' . $key . ': ' . $val); } $this->log('< '); break; case 'receivedBody': $this->log($event['data']->getBody()); break; case 'disconnect': $this->log('* Disconnected'); break; } } // }}} // log() {{{ /** * Logs the given message to the configured target. * * @param string $message Message to display * * @return void */ protected function log($message) { if ($this->target instanceof Log) { $this->target->debug($message); } elseif (is_resource($this->target)) { fwrite($this->target, $message . "\r\n"); } } // }}} } ?>includes/PEAR/HTTP/Request2/Response.php000064400000055001152214270100013674 0ustar00 * @copyright 2008-2022 Alexey Borzov * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License * @link http://pear.php.net/package/HTTP_Request2 */ /** * Exception class for HTTP_Request2 package */ require_once 'HTTP/Request2/Exception.php'; /** * Class representing a HTTP response * * The class is designed to be used in "streaming" scenario, building the * response as it is being received: * * $statusLine = read_status_line(); * $response = new HTTP_Request2_Response($statusLine); * do { * $headerLine = read_header_line(); * $response->parseHeaderLine($headerLine); * } while ($headerLine != ''); * * while ($chunk = read_body()) { * $response->appendBody($chunk); * } * * var_dump($response->getHeader(), $response->getCookies(), $response->getBody()); * * * @category HTTP * @package HTTP_Request2 * @author Alexey Borzov * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License * @version Release: 2.5.1 * @link http://pear.php.net/package/HTTP_Request2 * @link http://tools.ietf.org/html/rfc2616#section-6 */ class HTTP_Request2_Response { /** * HTTP protocol version (e.g. 1.0, 1.1) * * @var string */ protected $version; /** * Status code * * @var integer * @link http://tools.ietf.org/html/rfc2616#section-6.1.1 */ protected $code; /** * Reason phrase * * @var string * @link http://tools.ietf.org/html/rfc2616#section-6.1.1 */ protected $reasonPhrase; /** * Effective URL (may be different from original request URL in case of redirects) * * @var string */ protected $effectiveUrl; /** * Associative array of response headers * * @var array */ protected $headers = []; /** * Cookies set in the response * * @var array */ protected $cookies = []; /** * Name of last header processed by parseHederLine() * * Used to handle the headers that span multiple lines * * @var string */ protected $lastHeader = null; /** * Response body * * @var string */ protected $body = ''; /** * Whether the body is still encoded by Content-Encoding * * cURL provides the decoded body to the callback; if we are reading from * socket the body is still gzipped / deflated * * @var bool */ protected $bodyEncoded; /** * Associative array of HTTP status code / reason phrase. * * @var array * @link http://tools.ietf.org/html/rfc2616#section-10 */ protected static $phrases = [ // 1xx: Informational - Request received, continuing process 100 => 'Continue', 101 => 'Switching Protocols', // 2xx: Success - The action was successfully received, understood and // accepted 200 => 'OK', 201 => 'Created', 202 => 'Accepted', 203 => 'Non-Authoritative Information', 204 => 'No Content', 205 => 'Reset Content', 206 => 'Partial Content', // 3xx: Redirection - Further action must be taken in order to complete // the request 300 => 'Multiple Choices', 301 => 'Moved Permanently', 302 => 'Found', // 1.1 303 => 'See Other', 304 => 'Not Modified', 305 => 'Use Proxy', 307 => 'Temporary Redirect', // 4xx: Client Error - The request contains bad syntax or cannot be // fulfilled 400 => 'Bad Request', 401 => 'Unauthorized', 402 => 'Payment Required', 403 => 'Forbidden', 404 => 'Not Found', 405 => 'Method Not Allowed', 406 => 'Not Acceptable', 407 => 'Proxy Authentication Required', 408 => 'Request Timeout', 409 => 'Conflict', 410 => 'Gone', 411 => 'Length Required', 412 => 'Precondition Failed', 413 => 'Request Entity Too Large', 414 => 'Request-URI Too Long', 415 => 'Unsupported Media Type', 416 => 'Requested Range Not Satisfiable', 417 => 'Expectation Failed', // 5xx: Server Error - The server failed to fulfill an apparently // valid request 500 => 'Internal Server Error', 501 => 'Not Implemented', 502 => 'Bad Gateway', 503 => 'Service Unavailable', 504 => 'Gateway Timeout', 505 => 'HTTP Version Not Supported', 509 => 'Bandwidth Limit Exceeded', ]; /** * Returns the default reason phrase for the given code or all reason phrases * * @param int $code Response code * * @return string|array|null Default reason phrase for $code if $code is given * (null if no phrase is available), array of all * reason phrases if $code is null * @link http://pear.php.net/bugs/18716 */ public static function getDefaultReasonPhrase($code = null) { if (null === $code) { return self::$phrases; } else { return isset(self::$phrases[$code]) ? self::$phrases[$code] : null; } } /** * Constructor, parses the response status line * * @param string $statusLine Response status line (e.g. "HTTP/1.1 200 OK") * @param bool $bodyEncoded Whether body is still encoded by Content-Encoding * @param string $effectiveUrl Effective URL of the response * * @throws HTTP_Request2_MessageException if status line is invalid according to spec */ public function __construct($statusLine, $bodyEncoded = true, $effectiveUrl = null) { if (!preg_match('!^HTTP/(\d\.\d) (\d{3})(?: (.+))?!', $statusLine, $m)) { throw new HTTP_Request2_MessageException( "Malformed response: {$statusLine}", HTTP_Request2_Exception::MALFORMED_RESPONSE ); } $this->version = $m[1]; $this->code = intval($m[2]); $this->reasonPhrase = !empty($m[3]) ? trim($m[3]) : self::getDefaultReasonPhrase($this->code); $this->bodyEncoded = (bool)$bodyEncoded; $this->effectiveUrl = (string)$effectiveUrl; } /** * Parses the line from HTTP response filling $headers array * * The method should be called after reading the line from socket or receiving * it into cURL callback. Passing an empty string here indicates the end of * response headers and triggers additional processing, so be sure to pass an * empty string in the end. * * @param string $headerLine Line from HTTP response * * @return void */ public function parseHeaderLine($headerLine) { $headerLine = trim($headerLine, "\r\n"); if ('' == $headerLine) { // empty string signals the end of headers, process the received ones if (!empty($this->headers['set-cookie'])) { $cookies = is_array($this->headers['set-cookie'])? $this->headers['set-cookie']: [$this->headers['set-cookie']]; foreach ($cookies as $cookieString) { $this->parseCookie($cookieString); } unset($this->headers['set-cookie']); } foreach (array_keys($this->headers) as $k) { if (is_array($this->headers[$k])) { $this->headers[$k] = implode(', ', $this->headers[$k]); } } } elseif (preg_match('!^([^\x00-\x1f\x7f-\xff()<>@,;:\\\\"/\[\]?={}\s]+):(.+)$!', $headerLine, $m)) { // string of the form header-name: header value $name = strtolower($m[1]); $value = trim($m[2]); if (empty($this->headers[$name])) { $this->headers[$name] = $value; } else { if (!is_array($this->headers[$name])) { $this->headers[$name] = [$this->headers[$name]]; } $this->headers[$name][] = $value; } $this->lastHeader = $name; } elseif (preg_match('!^\s+(.+)$!', $headerLine, $m) && $this->lastHeader) { // continuation of a previous header if (!is_array($this->headers[$this->lastHeader])) { $this->headers[$this->lastHeader] .= ' ' . trim($m[1]); } else { $key = count($this->headers[$this->lastHeader]) - 1; $this->headers[$this->lastHeader][$key] .= ' ' . trim($m[1]); } } } /** * Parses a Set-Cookie header to fill $cookies array * * @param string $cookieString value of Set-Cookie header * * @return void * * @link http://web.archive.org/web/20080331104521/http://cgi.netscape.com/newsref/std/cookie_spec.html */ protected function parseCookie($cookieString) { $cookie = [ 'expires' => null, 'domain' => null, 'path' => null, 'secure' => false ]; if (!strpos($cookieString, ';')) { // Only a name=value pair $pos = strpos($cookieString, '='); $cookie['name'] = trim(substr($cookieString, 0, $pos)); $cookie['value'] = trim(substr($cookieString, $pos + 1)); } else { // Some optional parameters are supplied $elements = explode(';', $cookieString); $pos = strpos($elements[0], '='); $cookie['name'] = trim(substr($elements[0], 0, $pos)); $cookie['value'] = trim(substr($elements[0], $pos + 1)); for ($i = 1; $i < count($elements); $i++) { if (false === strpos($elements[$i], '=')) { $elName = trim($elements[$i]); $elValue = null; } else { list ($elName, $elValue) = array_map('trim', explode('=', $elements[$i])); } $elName = strtolower($elName); if ('secure' == $elName) { $cookie['secure'] = true; } elseif ('expires' == $elName) { $cookie['expires'] = str_replace('"', '', $elValue); } elseif ('path' == $elName || 'domain' == $elName) { $cookie[$elName] = urldecode($elValue); } else { $cookie[$elName] = $elValue; } } } $this->cookies[] = $cookie; } /** * Appends a string to the response body * * @param string $bodyChunk part of response body * * @return void */ public function appendBody($bodyChunk) { $this->body .= $bodyChunk; } /** * Returns the effective URL of the response * * This may be different from the request URL if redirects were followed. * * @return string * @link http://pear.php.net/bugs/bug.php?id=18412 */ public function getEffectiveUrl() { return $this->effectiveUrl; } /** * Returns the status code * * @return integer */ public function getStatus() { return $this->code; } /** * Returns the reason phrase * * @return string */ public function getReasonPhrase() { return $this->reasonPhrase; } /** * Whether response is a redirect that can be automatically handled by HTTP_Request2 * * @return bool */ public function isRedirect() { return in_array($this->code, [300, 301, 302, 303, 307]) && isset($this->headers['location']); } /** * Returns either the named header or all response headers * * @param string $headerName Name of header to return * * @return string|array Value of $headerName header (null if header is * not present), array of all response headers if * $headerName is null */ public function getHeader($headerName = null) { if (null === $headerName) { return $this->headers; } else { $headerName = strtolower($headerName); return isset($this->headers[$headerName])? $this->headers[$headerName]: null; } } /** * Returns cookies set in response * * @return array */ public function getCookies() { return $this->cookies; } /** * Returns the body of the response * * @return string * @throws HTTP_Request2_Exception if body cannot be decoded */ public function getBody() { if (0 == strlen($this->body) || !$this->bodyEncoded || !in_array(strtolower($this->getHeader('content-encoding') ?: ''), ['gzip', 'deflate']) ) { return $this->body; } else { if (extension_loaded('mbstring') && (2 & ini_get('mbstring.func_overload'))) { $oldEncoding = mb_internal_encoding(); mb_internal_encoding('8bit'); } try { switch (strtolower($this->getHeader('content-encoding'))) { case 'gzip': return self::decodeGzip($this->body); break; case 'deflate': return self::decodeDeflate($this->body); } } finally { // phpcs:ignore PHPCompatibility.Keywords.NewKeywords.t_finallyFound if (!empty($oldEncoding)) { mb_internal_encoding($oldEncoding); } } } } /** * Get the HTTP version of the response * * @return string */ public function getVersion() { return $this->version; } /** * Checks whether data starts with GZIP format identification bytes from RFC 1952 * * @param string $data gzip-encoded (presumably) data * * @return bool */ public static function hasGzipIdentification($data) { return 0 === strcmp(substr($data, 0, 2), "\x1f\x8b"); } /** * Tries to parse GZIP format header in the given string * * If the header conforms to RFC 1952, its length is returned. If any * sanity check fails, HTTP_Request2_MessageException is thrown. * * Note: This function might be usable outside of HTTP_Request2 so it might * be good idea to be moved to some common package. (Delian Krustev) * * @param string $data Either the complete response body or * the leading part of it * @param boolean $dataComplete Whether $data contains complete response body * * @return int gzip header length in bytes * @throws HTTP_Request2_MessageException * @link http://tools.ietf.org/html/rfc1952 */ public static function parseGzipHeader($data, $dataComplete = false) { // if data is complete, trailing 8 bytes should be present for size and crc32 $length = strlen($data) - ($dataComplete ? 8 : 0); if ($length < 10 || !self::hasGzipIdentification($data)) { throw new HTTP_Request2_MessageException( 'The data does not seem to contain a valid gzip header', HTTP_Request2_Exception::DECODE_ERROR ); } $method = ord(substr($data, 2, 1)); if (8 != $method) { throw new HTTP_Request2_MessageException( 'Error parsing gzip header: unknown compression method', HTTP_Request2_Exception::DECODE_ERROR ); } $flags = ord(substr($data, 3, 1)); if ($flags & 224) { throw new HTTP_Request2_MessageException( 'Error parsing gzip header: reserved bits are set', HTTP_Request2_Exception::DECODE_ERROR ); } // header is 10 bytes minimum. may be longer, though. $headerLength = 10; // extra fields, need to skip 'em if ($flags & 4) { if ($length - $headerLength - 2 < 0) { throw new HTTP_Request2_MessageException( 'Error parsing gzip header: data too short', HTTP_Request2_Exception::DECODE_ERROR ); } $extraLength = unpack('v', substr($data, 10, 2)); if ($length - $headerLength - 2 - $extraLength[1] < 0) { throw new HTTP_Request2_MessageException( 'Error parsing gzip header: data too short', HTTP_Request2_Exception::DECODE_ERROR ); } $headerLength += $extraLength[1] + 2; } // file name, need to skip that if ($flags & 8) { if ($length - $headerLength - 1 < 0) { throw new HTTP_Request2_MessageException( 'Error parsing gzip header: data too short', HTTP_Request2_Exception::DECODE_ERROR ); } $filenameLength = strpos(substr($data, $headerLength), chr(0)); if (false === $filenameLength || $length - $headerLength - $filenameLength - 1 < 0 ) { throw new HTTP_Request2_MessageException( 'Error parsing gzip header: data too short', HTTP_Request2_Exception::DECODE_ERROR ); } $headerLength += $filenameLength + 1; } // comment, need to skip that also if ($flags & 16) { if ($length - $headerLength - 1 < 0) { throw new HTTP_Request2_MessageException( 'Error parsing gzip header: data too short', HTTP_Request2_Exception::DECODE_ERROR ); } $commentLength = strpos(substr($data, $headerLength), chr(0)); if (false === $commentLength || $length - $headerLength - $commentLength - 1 < 0 ) { throw new HTTP_Request2_MessageException( 'Error parsing gzip header: data too short', HTTP_Request2_Exception::DECODE_ERROR ); } $headerLength += $commentLength + 1; } // have a CRC for header. let's check if ($flags & 2) { if ($length - $headerLength - 2 < 0) { throw new HTTP_Request2_MessageException( 'Error parsing gzip header: data too short', HTTP_Request2_Exception::DECODE_ERROR ); } $crcReal = 0xffff & crc32(substr($data, 0, $headerLength)); $crcStored = unpack('v', substr($data, $headerLength, 2)); if ($crcReal != $crcStored[1]) { throw new HTTP_Request2_MessageException( 'Header CRC check failed', HTTP_Request2_Exception::DECODE_ERROR ); } $headerLength += 2; } return $headerLength; } /** * Decodes the message-body encoded by gzip * * The real decoding work is done by gzinflate() built-in function, this * method only parses the header and checks data for compliance with * RFC 1952 * * @param string $data gzip-encoded data * * @return string decoded data * @throws HTTP_Request2_LogicException * @throws HTTP_Request2_MessageException * @link http://tools.ietf.org/html/rfc1952 */ public static function decodeGzip($data) { // If it doesn't look like gzip-encoded data, don't bother if (!self::hasGzipIdentification($data)) { return $data; } if (!function_exists('gzinflate')) { throw new HTTP_Request2_LogicException( 'Unable to decode body: gzip extension not available', HTTP_Request2_Exception::MISCONFIGURATION ); } // unpacked data CRC and size at the end of encoded data $tmp = unpack('V2', substr($data, -8)); $dataCrc = $tmp[1]; $dataSize = $tmp[2]; $headerLength = self::parseGzipHeader($data, true); // don't pass $dataSize to gzinflate, see bugs #13135, #14370 $unpacked = gzinflate(substr($data, $headerLength, -8)); if (false === $unpacked) { throw new HTTP_Request2_MessageException( 'gzinflate() call failed', HTTP_Request2_Exception::DECODE_ERROR ); // GZIP stores the size of the compressed data in bytes modulo // 2^32. To accommodate large file transfers, apply this to the // observed data size. This allows file downloads above 4 GiB. } elseif ((0xffffffff & $dataSize) !== (0xffffffff & strlen($unpacked))) { throw new HTTP_Request2_MessageException( 'Data size check failed', HTTP_Request2_Exception::DECODE_ERROR ); } elseif ((0xffffffff & $dataCrc) !== (0xffffffff & crc32($unpacked))) { throw new HTTP_Request2_MessageException( 'Data CRC check failed', HTTP_Request2_Exception::DECODE_ERROR ); } return $unpacked; } /** * Decodes the message-body encoded by deflate * * @param string $data deflate-encoded data * * @return string decoded data * @throws HTTP_Request2_LogicException */ public static function decodeDeflate($data) { if (!function_exists('gzuncompress')) { throw new HTTP_Request2_LogicException( 'Unable to decode body: gzip extension not available', HTTP_Request2_Exception::MISCONFIGURATION ); } // RFC 2616 defines 'deflate' encoding as zlib format from RFC 1950, // while many applications send raw deflate stream from RFC 1951. // We should check for presence of zlib header and use gzuncompress() or // gzinflate() as needed. See bug #15305 $header = unpack('n', substr($data, 0, 2)); return (0 == $header[1] % 31)? gzuncompress($data): gzinflate($data); } } ?>includes/PEAR/HTTP/Request2/SocketWrapper.php000064400000033336152214270100014676 0ustar00 * @copyright 2008-2022 Alexey Borzov * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License * @link http://pear.php.net/package/HTTP_Request2 */ /** Exception classes for HTTP_Request2 package */ require_once 'HTTP/Request2/Exception.php'; /** * Socket wrapper class used by Socket Adapter * * Needed to properly handle connection errors, global timeout support and * similar things. Loosely based on Net_Socket used by older HTTP_Request. * * @category HTTP * @package HTTP_Request2 * @author Alexey Borzov * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License * @version Release: 2.5.1 * @link http://pear.php.net/package/HTTP_Request2 * @link http://pear.php.net/bugs/bug.php?id=19332 * @link http://tools.ietf.org/html/rfc1928 */ class HTTP_Request2_SocketWrapper { /** * PHP warning messages raised during stream_socket_client() call * * @var array */ protected $connectionWarnings = []; /** * Connected socket * * @var resource */ protected $socket; /** * Sum of start time and global timeout, exception will be thrown if request continues past this time * * @var float */ protected $deadline; /** * Global timeout value, mostly for exception messages * * @var integer */ protected $timeout; /** * Class constructor, tries to establish connection * * @param string $address Address for stream_socket_client() call, * e.g. 'tcp://localhost:80' * @param int $timeout Connection timeout (seconds) * @param array $contextOptions Context options * * @throws HTTP_Request2_LogicException * @throws HTTP_Request2_ConnectionException */ public function __construct($address, $timeout, array $contextOptions = []) { if (!empty($contextOptions) && !isset($contextOptions['socket']) && !isset($contextOptions['ssl']) ) { // Backwards compatibility with 2.1.0 and 2.1.1 releases $contextOptions = ['ssl' => $contextOptions]; } if (isset($contextOptions['ssl'])) { $cryptoMethod = STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT; // phpcs:ignore PHPCompatibility.Constants.NewConstants.stream_crypto_method_tlsv1_2_clientFound if (defined('STREAM_CRYPTO_METHOD_TLSv1_3_CLIENT')) { $cryptoMethod |= STREAM_CRYPTO_METHOD_TLSv1_3_CLIENT; } $contextOptions['ssl'] += [ // Using "Intermediate compatibility" cipher bundle from // https://wiki.mozilla.org/Security/Server_Side_TLS 'ciphers' => 'TLS_AES_128_GCM_SHA256:' . 'TLS_AES_256_GCM_SHA384:' . 'TLS_CHACHA20_POLY1305_SHA256:' . 'ECDHE-ECDSA-AES128-GCM-SHA256:' . 'ECDHE-RSA-AES128-GCM-SHA256:' . 'ECDHE-ECDSA-AES256-GCM-SHA384:' . 'ECDHE-RSA-AES256-GCM-SHA384:' . 'ECDHE-ECDSA-CHACHA20-POLY1305:' . 'ECDHE-RSA-CHACHA20-POLY1305:' . 'DHE-RSA-AES128-GCM-SHA256:' . 'DHE-RSA-AES256-GCM-SHA384', 'disable_compression' => true, 'crypto_method' => $cryptoMethod ]; } $context = stream_context_create(); foreach ($contextOptions as $wrapper => $options) { foreach ($options as $name => $value) { if (!stream_context_set_option($context, $wrapper, $name, $value)) { throw new HTTP_Request2_LogicException( "Error setting '{$wrapper}' wrapper context option '{$name}'" ); } } } set_error_handler([$this, 'connectionWarningsHandler']); $this->socket = stream_socket_client( $address, $errno, $errstr, $timeout, STREAM_CLIENT_CONNECT, $context ); restore_error_handler(); // if we fail to bind to a specified local address (see request #19515), // connection still succeeds, albeit with a warning. Throw an Exception // with the warning text in this case as that connection is unlikely // to be what user wants and as Curl throws an error in similar case. if ($this->connectionWarnings) { if ($this->socket) { fclose($this->socket); } $error = $errstr ? $errstr : implode("\n", $this->connectionWarnings); throw new HTTP_Request2_ConnectionException( "Unable to connect to {$address}. Error: {$error}", 0, $errno ); } // Run socket in non-blocking mode, to prevent possible problems with // HTTPS requests not timing out properly (see bug #21229) stream_set_blocking($this->socket, false); } /** * Destructor, disconnects socket */ public function __destruct() { fclose($this->socket); } /** * Wrapper around fread(), handles global request timeout * * @param int $length Reads up to this number of bytes * * @return string|false Data read from socket by fread() * @throws HTTP_Request2_MessageException In case of timeout */ public function read($length) { // Looks like stream_select() may return true, but then fread() will return an empty string... // For some reason or other happens mostly with servers behind Cloudflare. // Let's do the fread() call in a loop until either an error/eof or non-empty string: do { $data = false; $timeouts = $this->_getTimeoutsForStreamSelect(); $r = [$this->socket]; $w = []; $e = []; if (stream_select($r, $w, $e, $timeouts[0], $timeouts[1])) { $data = fread($this->socket, $length); } $this->checkTimeout(); } while ('' === $data && !$this->eof()); return $data; } /** * Reads until either the end of the socket or a newline, whichever comes first * * Strips the trailing newline from the returned data, handles global * request timeout. Method idea borrowed from Net_Socket PEAR package. * * @param int $bufferSize buffer size to use for reading * @param int $localTimeout timeout value to use just for this call * (used when waiting for "100 Continue" response) * * @return string Available data up to the newline (not including newline) * @throws HTTP_Request2_MessageException In case of timeout */ public function readLine($bufferSize, $localTimeout = null) { $line = ''; while (!feof($this->socket)) { if (null !== $localTimeout) { $timeouts = [$localTimeout, 0]; $started = microtime(true); } else { $timeouts = $this->_getTimeoutsForStreamSelect(); } $r = [$this->socket]; $w = []; $e = []; if (stream_select($r, $w, $e, $timeouts[0], $timeouts[1])) { $line .= @fgets($this->socket, $bufferSize); } if (null === $localTimeout) { $this->checkTimeout(); } elseif (microtime(true) - $started > $localTimeout) { throw new HTTP_Request2_MessageException( "readLine() call timed out", HTTP_Request2_Exception::TIMEOUT ); } if (substr($line, -1) == "\n") { return rtrim($line, "\r\n"); } } return $line; } /** * Wrapper around fwrite(), handles global request timeout * * @param string $data String to be written * * @return int * @throws HTTP_Request2_MessageException */ public function write($data) { $totalWritten = 0; while (strlen($data) && !$this->eof()) { $written = 0; $error = null; $timeouts = $this->_getTimeoutsForStreamSelect(); $r = null; $w = [$this->socket]; $e = null; if (stream_select($r, $w, $e, $timeouts[0], $timeouts[1])) { set_error_handler( static function ($errNo, $errStr) use (&$error) { if (0 !== (E_NOTICE | E_WARNING) & $errNo) { $error = $errStr; } } ); $written = fwrite($this->socket, $data); restore_error_handler(); } $this->checkTimeout(); // php_sockop_write() defined in /main/streams/xp_socket.c may return zero written bytes for non-blocking // sockets in case of transient errors. These writes will not have notices raised and should be retried if (false === $written || 0 === $written && null !== $error) { throw new HTTP_Request2_MessageException( 'Error writing request' . (null === $error ? '' : ': ' . $error) ); } $data = substr($data, $written); $totalWritten += $written; } return $totalWritten; } /** * Tests for end-of-file on a socket * * @return bool */ public function eof() { return feof($this->socket); } /** * Sets request deadline * * If null is passed for $deadline then deadline will be calculated based * on default_socket_timeout PHP setting. This is done to keep BC with previous * versions that used blocking sockets. * * @param float|null $deadline Exception will be thrown if request continues * past this time * @param int $timeout Original request timeout value, to use in * Exception message * * @return void */ public function setDeadline($deadline, $timeout) { if (null === $deadline && 0 < ($defaultTimeout = (int)ini_get('default_socket_timeout'))) { $deadline = microtime(true) + $defaultTimeout; } $this->deadline = $deadline; $this->timeout = $timeout; } /** * Turns on encryption on a socket * * @return void * @throws HTTP_Request2_ConnectionException */ public function enableCrypto() { $cryptoMethod = STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT; // phpcs:ignore PHPCompatibility.Constants.NewConstants.stream_crypto_method_tlsv1_2_clientFound if (defined('STREAM_CRYPTO_METHOD_TLSv1_3_CLIENT')) { $cryptoMethod |= STREAM_CRYPTO_METHOD_TLSv1_3_CLIENT; } try { stream_set_blocking($this->socket, true); if (!stream_socket_enable_crypto($this->socket, true, $cryptoMethod)) { throw new HTTP_Request2_ConnectionException( 'Failed to enable secure connection when connecting through proxy' ); } } finally { // phpcs:ignore PHPCompatibility.Keywords.NewKeywords.t_finallyFound stream_set_blocking($this->socket, false); } } /** * Throws an Exception if stream timed out * * @return void * @throws HTTP_Request2_MessageException */ protected function checkTimeout() { $info = stream_get_meta_data($this->socket); if ($info['timed_out'] || $this->deadline && microtime(true) > $this->deadline) { $reason = $this->timeout ? "after {$this->timeout} second(s)" : 'due to default_socket_timeout php.ini setting'; throw new HTTP_Request2_MessageException( "Request timed out {$reason}", HTTP_Request2_Exception::TIMEOUT ); } } /** * Returns timeouts based on deadline for use with stream_select() * * @return array First element is $tv_sec parameter for stream_select(), * second element is $tv_usec */ private function _getTimeoutsForStreamSelect() { if (!$this->deadline) { return [null, null]; } $parts = array_map( 'intval', explode('.', sprintf('%.6F', $this->deadline - microtime(true))) ); if (0 > $parts[0] || 0 === $parts[0] && $parts[1] < 50000) { return [0, 50000]; } return $parts; } /** * Error handler to use during stream_socket_client() call * * One stream_socket_client() call may produce *multiple* PHP warnings * (especially OpenSSL-related), we keep them in an array to later use for * the message of HTTP_Request2_ConnectionException * * @param int $errno error level * @param string $errstr error message * * @return bool */ protected function connectionWarningsHandler($errno, $errstr) { if ($errno & E_WARNING) { array_unshift($this->connectionWarnings, $errstr); } return true; } } ?> includes/PEAR/HTTP/Request2/MessageException.php000064400000002041152214270100015335 0ustar00 * @copyright 2008-2022 Alexey Borzov * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License * @link http://pear.php.net/package/HTTP_Request2 */ /** * Exception thrown when sending or receiving HTTP message fails * * The exception may contain both package error code and native error code. * * @category HTTP * @package HTTP_Request2 * @author Alexey Borzov * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License * @version Release: 2.5.1 * @link http://pear.php.net/package/HTTP_Request2 */ class HTTP_Request2_MessageException extends HTTP_Request2_Exception { } ?>includes/PEAR/HTTP/Request2/ConnectionException.php000064400000002160152214270100016052 0ustar00 * @copyright 2008-2022 Alexey Borzov * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License * @link http://pear.php.net/package/HTTP_Request2 */ /** * Exception thrown when connection to a web or proxy server fails * * The exception will not contain a package error code, but will contain * native error code, as returned by stream_socket_client() or curl_errno(). * * @category HTTP * @package HTTP_Request2 * @author Alexey Borzov * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License * @version Release: 2.5.1 * @link http://pear.php.net/package/HTTP_Request2 */ class HTTP_Request2_ConnectionException extends HTTP_Request2_Exception { } ?>includes/PEAR/HTTP/Request2/MultipartBody.php000064400000022015152214270100014674 0ustar00 * @copyright 2008-2022 Alexey Borzov * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License * @link http://pear.php.net/package/HTTP_Request2 */ /** Exception class for HTTP_Request2 package */ require_once 'HTTP/Request2/Exception.php'; /** * Class for building multipart/form-data request body * * The class helps to reduce memory consumption by streaming large file uploads * from disk, it also allows monitoring of upload progress (see request #7630) * * @category HTTP * @package HTTP_Request2 * @author Alexey Borzov * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License * @version Release: 2.5.1 * @link http://pear.php.net/package/HTTP_Request2 * @link http://tools.ietf.org/html/rfc1867 */ class HTTP_Request2_MultipartBody { /** * MIME boundary * * @var string */ private $_boundary; /** * Form parameters added via {@link HTTP_Request2::addPostParameter()} * * @var array */ private $_params = []; /** * File uploads added via {@link HTTP_Request2::addUpload()} * * @var array */ private $_uploads = []; /** * Header for parts with parameters * * @var string */ private $_headerParam = "--%s\r\nContent-Disposition: form-data; name=\"%s\"\r\n\r\n"; /** * Header for parts with uploads * * @var string */ private $_headerUpload = "--%s\r\nContent-Disposition: form-data; name=\"%s\"; filename=\"%s\"\r\nContent-Type: %s\r\n\r\n"; /** * Current position in parameter and upload arrays * * First number is index of "current" part, second number is position within * "current" part * * @var array */ private $_pos = [0, 0]; /** * Constructor. Sets the arrays with POST data. * * @param array $params values of form fields set via * {@link HTTP_Request2::addPostParameter()} * @param array $uploads file uploads set via * {@link HTTP_Request2::addUpload()} * @param bool $useBrackets whether to append brackets to array variable names */ public function __construct(array $params, array $uploads, $useBrackets = true) { $this->_params = self::_flattenArray('', $params, $useBrackets); foreach ($uploads as $fieldName => $f) { if (!is_array($f['fp'])) { $this->_uploads[] = $f + ['name' => $fieldName]; } else { for ($i = 0; $i < count($f['fp']); $i++) { $upload = [ 'name' => ($useBrackets? $fieldName . '[' . $i . ']': $fieldName) ]; foreach (['fp', 'filename', 'size', 'type'] as $key) { $upload[$key] = $f[$key][$i]; } $this->_uploads[] = $upload; } } } } /** * Returns the length of the body to use in Content-Length header * * @return integer */ public function getLength() { $boundaryLength = strlen($this->getBoundary()); $headerParamLength = strlen($this->_headerParam) - 4 + $boundaryLength; $headerUploadLength = strlen($this->_headerUpload) - 8 + $boundaryLength; $length = $boundaryLength + 6; foreach ($this->_params as $p) { $length += $headerParamLength + strlen($p[0]) + strlen($p[1]) + 2; } foreach ($this->_uploads as $u) { $length += $headerUploadLength + strlen($u['name']) + strlen($u['type']) + strlen($u['filename']) + $u['size'] + 2; } return $length; } /** * Returns the boundary to use in Content-Type header * * @return string */ public function getBoundary() { if (empty($this->_boundary)) { $this->_boundary = '--' . md5('PEAR-HTTP_Request2-' . microtime()); } return $this->_boundary; } /** * Returns next chunk of request body * * @param integer $length Number of bytes to read * * @return string Up to $length bytes of data, empty string if at end * @throws HTTP_Request2_LogicException */ public function read($length) { $ret = ''; $boundary = $this->getBoundary(); $paramCount = count($this->_params); $uploadCount = count($this->_uploads); while ($length > 0 && $this->_pos[0] <= $paramCount + $uploadCount) { $oldLength = $length; if ($this->_pos[0] < $paramCount) { $param = sprintf( $this->_headerParam, $boundary, $this->_params[$this->_pos[0]][0] ) . $this->_params[$this->_pos[0]][1] . "\r\n"; $ret .= substr($param, $this->_pos[1], $length); $length -= min(strlen($param) - $this->_pos[1], $length); } elseif ($this->_pos[0] < $paramCount + $uploadCount) { $pos = $this->_pos[0] - $paramCount; $header = sprintf( $this->_headerUpload, $boundary, $this->_uploads[$pos]['name'], $this->_uploads[$pos]['filename'], $this->_uploads[$pos]['type'] ); if ($this->_pos[1] < strlen($header)) { $ret .= substr($header, $this->_pos[1], $length); $length -= min(strlen($header) - $this->_pos[1], $length); } $filePos = max(0, $this->_pos[1] - strlen($header)); if ($filePos < $this->_uploads[$pos]['size']) { while ($length > 0 && !feof($this->_uploads[$pos]['fp'])) { if (false === ($chunk = fread($this->_uploads[$pos]['fp'], $length))) { throw new HTTP_Request2_LogicException( 'Failed reading file upload', HTTP_Request2_Exception::READ_ERROR ); } $ret .= $chunk; $length -= strlen($chunk); } } if ($length > 0) { $start = $this->_pos[1] + ($oldLength - $length) - strlen($header) - $this->_uploads[$pos]['size']; $ret .= substr("\r\n", $start, $length); $length -= min(2 - $start, $length); } } else { $closing = '--' . $boundary . "--\r\n"; $ret .= substr($closing, $this->_pos[1], $length); $length -= min(strlen($closing) - $this->_pos[1], $length); } if ($length > 0) { $this->_pos = [$this->_pos[0] + 1, 0]; } else { $this->_pos[1] += $oldLength; } } return $ret; } /** * Sets the current position to the start of the body * * This allows reusing the same body in another request * * @return void */ public function rewind() { $this->_pos = [0, 0]; foreach ($this->_uploads as $u) { rewind($u['fp']); } } /** * Returns the body as string * * Note that it reads all file uploads into memory so it is a good idea not * to use this method with large file uploads and rely on read() instead. * * @return string */ public function __toString() { $this->rewind(); return $this->read($this->getLength()); } /** * Helper function to change the (probably multidimensional) associative array * into the simple one. * * @param string $name name for item * @param mixed $values item's values * @param bool $useBrackets whether to append [] to array variables' names * * @return array array with the following items: array('item name', 'item value'); */ private static function _flattenArray($name, $values, $useBrackets) { if (!is_array($values)) { return [[$name, $values]]; } else { $ret = []; foreach ($values as $k => $v) { if (empty($name)) { $newName = $k; } elseif ($useBrackets) { $newName = $name . '[' . $k . ']'; } else { $newName = $name; } $ret = array_merge($ret, self::_flattenArray($newName, $v, $useBrackets)); } return $ret; } } } ?> includes/PEAR/HTTP/Request2/CookieJar.php000064400000047374152214270100013762 0ustar00 * @copyright 2008-2022 Alexey Borzov * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License * @link http://pear.php.net/package/HTTP_Request2 */ /** Class representing a HTTP request message */ require_once 'HTTP/Request2.php'; /** * Stores cookies and passes them between HTTP requests * * @category HTTP * @package HTTP_Request2 * @author Alexey Borzov * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License * @version Release: @package_version@ * @link http://pear.php.net/package/HTTP_Request2 */ class HTTP_Request2_CookieJar implements Serializable { /** * Array of stored cookies * * The array is indexed by domain, path and cookie name * .example.com * / * some_cookie => cookie data * /subdir * other_cookie => cookie data * .example.org * ... * * @var array */ protected $cookies = []; /** * Whether session cookies should be serialized when serializing the jar * * @var bool */ protected $serializeSession = false; /** * Whether Public Suffix List should be used for domain matching * * @var bool */ protected $useList = true; /** * Whether an attempt to store an invalid cookie should be ignored, rather than cause an Exception * * @var bool */ protected $ignoreInvalid = false; /** * Array with Public Suffix List data * * @var array * @link http://publicsuffix.org/ */ protected static $psl = []; /** * Class constructor, sets various options * * @param bool $serializeSessionCookies Controls serializing session cookies, * see {@link serializeSessionCookies()} * @param bool $usePublicSuffixList Controls using Public Suffix List, * see {@link usePublicSuffixList()} * @param bool $ignoreInvalidCookies Whether invalid cookies should be ignored, * see {@link ignoreInvalidCookies()} */ public function __construct( $serializeSessionCookies = false, $usePublicSuffixList = true, $ignoreInvalidCookies = false ) { $this->serializeSessionCookies($serializeSessionCookies); $this->usePublicSuffixList($usePublicSuffixList); $this->ignoreInvalidCookies($ignoreInvalidCookies); } /** * Returns current time formatted in ISO-8601 at UTC timezone * * @return string */ protected function now() { $dt = new DateTime(); $dt->setTimezone(new DateTimeZone('UTC')); return $dt->format(DateTime::ISO8601); } /** * Checks cookie array for correctness, possibly updating its 'domain', 'path' and 'expires' fields * * The checks are as follows: * - cookie array should contain 'name' and 'value' fields; * - name and value should not contain disallowed symbols; * - 'expires' should be either empty parseable by DateTime; * - 'domain' and 'path' should be either not empty or an URL where * cookie was set should be provided. * - if $setter is provided, then document at that URL should be allowed * to set a cookie for that 'domain'. If $setter is not provided, * then no domain checks will be made. * * 'expires' field will be converted to ISO8601 format from COOKIE format, * 'domain' and 'path' will be set from setter URL if empty. * * @param array $cookie cookie data, as returned by * {@link HTTP_Request2_Response::getCookies()} * @param Net_URL2 $setter URL of the document that sent Set-Cookie header * * @return array Updated cookie array * @throws HTTP_Request2_LogicException * @throws HTTP_Request2_MessageException */ protected function checkAndUpdateFields(array $cookie, Net_URL2 $setter = null) { if ($missing = array_diff(['name', 'value'], array_keys($cookie))) { throw new HTTP_Request2_LogicException( "Cookie array should contain 'name' and 'value' fields", HTTP_Request2_Exception::MISSING_VALUE ); } if (preg_match(HTTP_Request2::REGEXP_INVALID_COOKIE, $cookie['name'])) { throw new HTTP_Request2_LogicException( "Invalid cookie name: '{$cookie['name']}'", HTTP_Request2_Exception::INVALID_ARGUMENT ); } if (preg_match(HTTP_Request2::REGEXP_INVALID_COOKIE, $cookie['value'])) { throw new HTTP_Request2_LogicException( "Invalid cookie value: '{$cookie['value']}'", HTTP_Request2_Exception::INVALID_ARGUMENT ); } $cookie += ['domain' => '', 'path' => '', 'expires' => null, 'secure' => false]; // Need ISO-8601 date @ UTC timezone if (!empty($cookie['expires']) && !preg_match('/^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\+0000$/', $cookie['expires']) ) { try { $dt = new DateTime($cookie['expires']); $dt->setTimezone(new DateTimeZone('UTC')); $cookie['expires'] = $dt->format(DateTime::ISO8601); } catch (Exception $e) { throw new HTTP_Request2_LogicException($e->getMessage()); } } if (empty($cookie['domain']) || empty($cookie['path'])) { if (!$setter) { throw new HTTP_Request2_LogicException( 'Cookie misses domain and/or path component, cookie setter URL needed', HTTP_Request2_Exception::MISSING_VALUE ); } if (empty($cookie['domain'])) { if ($host = $setter->getHost()) { $cookie['domain'] = $host; } else { throw new HTTP_Request2_LogicException( 'Setter URL does not contain host part, can\'t set cookie domain', HTTP_Request2_Exception::MISSING_VALUE ); } } if (empty($cookie['path'])) { $path = $setter->getPath(); $cookie['path'] = empty($path)? '/': substr($path, 0, strrpos($path, '/') + 1); } } if ($setter && !$this->domainMatch($setter->getHost(), $cookie['domain'])) { throw new HTTP_Request2_MessageException( "Domain " . $setter->getHost() . " cannot set cookies for " . $cookie['domain'] ); } return $cookie; } /** * Stores a cookie in the jar * * @param array $cookie cookie data, as returned by * {@link HTTP_Request2_Response::getCookies()} * @param Net_URL2 $setter URL of the document that sent Set-Cookie header * * @return bool whether the cookie was successfully stored * @throws HTTP_Request2_Exception */ public function store(array $cookie, Net_URL2 $setter = null) { try { $cookie = $this->checkAndUpdateFields($cookie, $setter); } catch (HTTP_Request2_Exception $e) { if ($this->ignoreInvalid) { return false; } else { throw $e; } } if (strlen($cookie['value']) && (is_null($cookie['expires']) || $cookie['expires'] > $this->now()) ) { if (!isset($this->cookies[$cookie['domain']])) { $this->cookies[$cookie['domain']] = []; } if (!isset($this->cookies[$cookie['domain']][$cookie['path']])) { $this->cookies[$cookie['domain']][$cookie['path']] = []; } $this->cookies[$cookie['domain']][$cookie['path']][$cookie['name']] = $cookie; } elseif (isset($this->cookies[$cookie['domain']][$cookie['path']][$cookie['name']])) { unset($this->cookies[$cookie['domain']][$cookie['path']][$cookie['name']]); } return true; } /** * Adds cookies set in HTTP response to the jar * * @param HTTP_Request2_Response $response HTTP response message * @param Net_URL2 $setter original request URL, needed for * setting default domain/path. If not given, * effective URL from response will be used. * * @return bool whether all cookies were successfully stored * @throws HTTP_Request2_LogicException */ public function addCookiesFromResponse(HTTP_Request2_Response $response, Net_URL2 $setter = null) { if (null === $setter) { if (!($effectiveUrl = $response->getEffectiveUrl())) { throw new HTTP_Request2_LogicException( 'Response URL required for adding cookies from response', HTTP_Request2_Exception::MISSING_VALUE ); } $setter = new Net_URL2($effectiveUrl); } $success = true; foreach ($response->getCookies() as $cookie) { $success = $this->store($cookie, $setter) && $success; } return $success; } /** * Returns all cookies matching a given request URL * * The following checks are made: * - cookie domain should match request host * - cookie path should be a prefix for request path * - 'secure' cookies will only be sent for HTTPS requests * * @param Net_URL2 $url Request url * @param bool $asString Whether to return cookies as string for "Cookie: " header * * @return array|string Matching cookies */ public function getMatching(Net_URL2 $url, $asString = false) { $host = $url->getHost(); $path = $url->getPath(); $secure = 0 == strcasecmp($url->getScheme(), 'https'); $matched = $ret = []; foreach (array_keys($this->cookies) as $domain) { if ($this->domainMatch($host, $domain)) { foreach (array_keys($this->cookies[$domain]) as $cPath) { if (0 === strpos($path, $cPath)) { foreach ($this->cookies[$domain][$cPath] as $name => $cookie) { if (!$cookie['secure'] || $secure) { $matched[$name][strlen($cookie['path'])] = $cookie; } } } } } } foreach ($matched as $cookies) { krsort($cookies); $ret = array_merge($ret, $cookies); } if (!$asString) { return $ret; } else { $str = ''; foreach ($ret as $c) { $str .= (empty($str)? '': '; ') . $c['name'] . '=' . $c['value']; } return $str; } } /** * Returns all cookies stored in a jar * * @return array */ public function getAll() { $cookies = []; foreach (array_keys($this->cookies) as $domain) { foreach (array_keys($this->cookies[$domain]) as $path) { foreach ($this->cookies[$domain][$path] as $name => $cookie) { $cookies[] = $cookie; } } } return $cookies; } /** * Sets whether session cookies should be serialized when serializing the jar * * @param boolean $serialize serialize? * * @return void */ public function serializeSessionCookies($serialize) { $this->serializeSession = (bool)$serialize; } /** * Sets whether invalid cookies should be silently ignored or cause an Exception * * @param boolean $ignore ignore? * * @return void * * @link http://pear.php.net/bugs/bug.php?id=19937 * @link http://pear.php.net/bugs/bug.php?id=20401 */ public function ignoreInvalidCookies($ignore) { $this->ignoreInvalid = (bool)$ignore; } /** * Sets whether Public Suffix List should be used for restricting cookie-setting * * Without PSL {@link domainMatch()} will only prevent setting cookies for * top-level domains like '.com' or '.org'. However, it will not prevent * setting a cookie for '.co.uk' even though only third-level registrations * are possible in .uk domain. * * With the List it is possible to find the highest level at which a domain * may be registered for a particular top-level domain and consequently * prevent cookies set for '.co.uk' or '.msk.ru'. The same list is used by * Firefox, Chrome and Opera browsers to restrict cookie setting. * * Note that PSL is licensed differently to HTTP_Request2 package (refer to * the license information in public-suffix-list.php), so you can disable * its use if this is an issue for you. * * @param boolean $useList use the list? * * @return void * * @link http://publicsuffix.org/learn/ */ public function usePublicSuffixList($useList) { $this->useList = (bool)$useList; } /** * Returns string representation of object * * @return string * * @see Serializable::serialize() */ public function serialize() { return serialize($this->__serialize()); } /** * Returns an associative array of key/value pairs that represent the serialized form of the object * * @return array */ public function __serialize() // phpcs:ignore PHPCompatibility.FunctionNameRestrictions.NewMagicMethods.__serializeFound { $cookies = $this->getAll(); if (!$this->serializeSession) { for ($i = count($cookies) - 1; $i >= 0; $i--) { if (empty($cookies[$i]['expires'])) { unset($cookies[$i]); } } } return [ 'cookies' => $cookies, 'serializeSession' => $this->serializeSession, 'useList' => $this->useList, 'ignoreInvalid' => $this->ignoreInvalid ]; } /** * Constructs the object from serialized string * * @param string $serialized string representation * * @return void */ public function unserialize($serialized) { $this->__unserialize(unserialize($serialized)); } /** * Constructs the object from array serialized form * * @param array $data serialized form (as generated by {@see __serialize()} * * @return void */ public function __unserialize(array $data) // phpcs:ignore PHPCompatibility.FunctionNameRestrictions.NewMagicMethods.__unserializeFound { $now = $this->now(); $this->serializeSessionCookies($data['serializeSession']); $this->usePublicSuffixList($data['useList']); if (array_key_exists('ignoreInvalid', $data)) { $this->ignoreInvalidCookies($data['ignoreInvalid']); } foreach ($data['cookies'] as $cookie) { if (!empty($cookie['expires']) && $cookie['expires'] <= $now) { continue; } if (!isset($this->cookies[$cookie['domain']])) { $this->cookies[$cookie['domain']] = []; } if (!isset($this->cookies[$cookie['domain']][$cookie['path']])) { $this->cookies[$cookie['domain']][$cookie['path']] = []; } $this->cookies[$cookie['domain']][$cookie['path']][$cookie['name']] = $cookie; } } /** * Checks whether a cookie domain matches a request host. * * The method is used by {@link store()} to check for whether a document * at given URL can set a cookie with a given domain attribute and by * {@link getMatching()} to find cookies matching the request URL. * * @param string $requestHost request host * @param string $cookieDomain cookie domain * * @return bool match success */ public function domainMatch($requestHost, $cookieDomain) { if ($requestHost == $cookieDomain) { return true; } // IP address, we require exact match if (preg_match('/^(?:\d{1,3}\.){3}\d{1,3}$/', $requestHost)) { return false; } if ('.' != $cookieDomain[0]) { $cookieDomain = '.' . $cookieDomain; } // prevents setting cookies for '.com' and similar domains if (!$this->useList && substr_count($cookieDomain, '.') < 2 || $this->useList && !self::getRegisteredDomain($cookieDomain) ) { return false; } return substr('.' . $requestHost, -strlen($cookieDomain)) == $cookieDomain; } /** * Removes subdomains to get the registered domain (the first after top-level) * * The method will check Public Suffix List to find out where top-level * domain ends and registered domain starts. It will remove domain parts * to the left of registered one. * * @param string $domain domain name * * @return string|bool registered domain, will return false if $domain is * either invalid or a TLD itself */ public static function getRegisteredDomain($domain) { $domainParts = explode('.', ltrim($domain, '.')); // load the list if needed if (empty(self::$psl)) { $path = '@data_dir@' . DIRECTORY_SEPARATOR . 'HTTP_Request2'; if (0 === strpos($path, '@' . 'data_dir@')) { $path = realpath( __DIR__ . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . '..' . DIRECTORY_SEPARATOR . 'data' ); } self::$psl = include_once $path . DIRECTORY_SEPARATOR . 'public-suffix-list.php'; } if (!($result = self::checkDomainsList($domainParts, self::$psl))) { // known TLD, invalid domain name return false; } // unknown TLD if (!strpos($result, '.')) { // fallback to checking that domain "has at least two dots" if (2 > ($count = count($domainParts))) { return false; } return $domainParts[$count - 2] . '.' . $domainParts[$count - 1]; } return $result; } /** * Recursive helper method for {@link getRegisteredDomain()} * * @param array $domainParts remaining domain parts * @param mixed $listNode node in {@link HTTP_Request2_CookieJar::$psl} to check * * @return string|null concatenated domain parts, null in case of error */ protected static function checkDomainsList(array $domainParts, $listNode) { $sub = array_pop($domainParts); if (!is_array($listNode) || is_null($sub) || array_key_exists('!' . $sub, $listNode) ) { return $sub; } elseif (array_key_exists($sub, $listNode)) { $result = self::checkDomainsList($domainParts, $listNode[$sub]); } elseif (array_key_exists('*', $listNode)) { $result = self::checkDomainsList($domainParts, $listNode['*']); } else { return $sub; } return (strlen($result ?: '') > 0) ? ($result . '.' . $sub) : null; } } ?>includes/PEAR/HTTP/Request2/NotImplementedException.php000064400000001710152214270100016677 0ustar00 * @copyright 2008-2022 Alexey Borzov * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License * @link http://pear.php.net/package/HTTP_Request2 */ /** * Exception thrown in case of missing features * * @category HTTP * @package HTTP_Request2 * @author Alexey Borzov * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License * @version Release: 2.5.1 * @link http://pear.php.net/package/HTTP_Request2 */ class HTTP_Request2_NotImplementedException extends HTTP_Request2_Exception { } ?>includes/PEAR/HTTP/Request2/SOCKS5.php000064400000011223152214270100013043 0ustar00 * @copyright 2008-2022 Alexey Borzov * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License * @link http://pear.php.net/package/HTTP_Request2 */ /** Socket wrapper class used by Socket Adapter */ require_once 'HTTP/Request2/SocketWrapper.php'; /** * SOCKS5 proxy connection class (used by Socket Adapter) * * @category HTTP * @package HTTP_Request2 * @author Alexey Borzov * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License * @version Release: 2.5.1 * @link http://pear.php.net/package/HTTP_Request2 * @link http://pear.php.net/bugs/bug.php?id=19332 * @link http://tools.ietf.org/html/rfc1928 */ class HTTP_Request2_SOCKS5 extends HTTP_Request2_SocketWrapper { /** * Constructor, tries to connect and authenticate to a SOCKS5 proxy * * @param string $address Proxy address, e.g. 'tcp://localhost:1080' * @param int $timeout Connection timeout (seconds) * @param array $contextOptions Stream context options * @param string $username Proxy user name * @param string $password Proxy password * * @throws HTTP_Request2_LogicException * @throws HTTP_Request2_ConnectionException * @throws HTTP_Request2_MessageException */ public function __construct( $address, $timeout = 10, array $contextOptions = [], $username = null, $password = null ) { parent::__construct($address, $timeout, $contextOptions); if (strlen($username)) { $request = pack('C4', 5, 2, 0, 2); } else { $request = pack('C3', 5, 1, 0); } $this->write($request); $response = unpack('Cversion/Cmethod', $this->read(3)); if (5 != $response['version']) { throw new HTTP_Request2_MessageException( 'Invalid version received from SOCKS5 proxy: ' . $response['version'], HTTP_Request2_Exception::MALFORMED_RESPONSE ); } switch ($response['method']) { case 2: $this->performAuthentication($username, $password); case 0: break; default: throw new HTTP_Request2_ConnectionException( "Connection rejected by proxy due to unsupported auth method" ); } } /** * Performs username/password authentication for SOCKS5 * * @param string $username Proxy user name * @param string $password Proxy password * * @return void * @throws HTTP_Request2_ConnectionException * @throws HTTP_Request2_MessageException * @link http://tools.ietf.org/html/rfc1929 */ protected function performAuthentication($username, $password) { $request = pack('C2', 1, strlen($username)) . $username . pack('C', strlen($password)) . $password; $this->write($request); $response = unpack('Cvn/Cstatus', $this->read(3)); if (1 != $response['vn'] || 0 != $response['status']) { throw new HTTP_Request2_ConnectionException( 'Connection rejected by proxy due to invalid username and/or password' ); } } /** * Connects to a remote host via proxy * * @param string $remoteHost Remote host * @param int $remotePort Remote port * * @return void * @throws HTTP_Request2_ConnectionException * @throws HTTP_Request2_MessageException */ public function connect($remoteHost, $remotePort) { $request = pack('C5', 0x05, 0x01, 0x00, 0x03, strlen($remoteHost)) . $remoteHost . pack('n', $remotePort); $this->write($request); $response = unpack('Cversion/Creply/Creserved', $this->read(1024)); if (5 != $response['version'] || 0 != $response['reserved']) { throw new HTTP_Request2_MessageException( 'Invalid response received from SOCKS5 proxy', HTTP_Request2_Exception::MALFORMED_RESPONSE ); } elseif (0 != $response['reply']) { throw new HTTP_Request2_ConnectionException( "Unable to connect to {$remoteHost}:{$remotePort} through SOCKS5 proxy", 0, $response['reply'] ); } } } ?>includes/PEAR/HTTP/Request2/LogicException.php000064400000002375152214270100015020 0ustar00 * @copyright 2008-2022 Alexey Borzov * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License * @link http://pear.php.net/package/HTTP_Request2 */ /** * Exception that represents error in the program logic * * This exception usually implies a programmer's error, like passing invalid * data to methods or trying to use PHP extensions that weren't installed or * enabled. Usually exceptions of this kind will be thrown before request even * starts. * * The exception will usually contain a package error code. * * @category HTTP * @package HTTP_Request2 * @author Alexey Borzov * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License * @version Release: 2.5.1 * @link http://pear.php.net/package/HTTP_Request2 */ class HTTP_Request2_LogicException extends HTTP_Request2_Exception { } ?>includes/PEAR/HTTP/Request2/Adapter.php000064400000011042152214270100013453 0ustar00 * @copyright 2008-2022 Alexey Borzov * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License * @link http://pear.php.net/package/HTTP_Request2 */ /** * Class representing a HTTP response */ require_once 'HTTP/Request2/Response.php'; /** * Base class for HTTP_Request2 adapters * * HTTP_Request2 class itself only defines methods for aggregating the request * data, all actual work of sending the request to the remote server and * receiving its response is performed by adapters. * * @category HTTP * @package HTTP_Request2 * @author Alexey Borzov * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License * @version Release: 2.5.1 * @link http://pear.php.net/package/HTTP_Request2 */ abstract class HTTP_Request2_Adapter { /** * A list of methods that MUST NOT have a request body, per RFC 2616 * * @var array */ protected static $bodyDisallowed = ['TRACE']; /** * Methods having defined semantics for request body * * Content-Length header (indicating that the body follows, section 4.3 of * RFC 2616) will be sent for these methods even if no body was added * * @var array * @link http://pear.php.net/bugs/bug.php?id=12900 * @link http://pear.php.net/bugs/bug.php?id=14740 */ protected static $bodyRequired = ['POST', 'PUT']; /** * Request being sent * * @var HTTP_Request2 */ protected $request; /** * Request body * * @var string|resource|HTTP_Request2_MultipartBody * @see HTTP_Request2::getBody() */ protected $requestBody; /** * Length of the request body * * @var integer */ protected $contentLength; /** * Sends request to the remote server and returns its response * * @param HTTP_Request2 $request HTTP request message * * @return HTTP_Request2_Response * @throws HTTP_Request2_Exception */ abstract public function sendRequest(HTTP_Request2 $request); /** * Calculates length of the request body, adds proper headers * * @param array $headers associative array of request headers, this method * will add proper 'Content-Length' and 'Content-Type' * headers to this array (or remove them if not needed) * * @return void */ protected function calculateRequestLength(&$headers) { $this->requestBody = $this->request->getBody(); if (is_string($this->requestBody)) { $this->contentLength = strlen($this->requestBody); } elseif (is_resource($this->requestBody)) { $stat = fstat($this->requestBody); $this->contentLength = $stat['size']; rewind($this->requestBody); } else { $this->contentLength = $this->requestBody->getLength(); $headers['content-type'] = 'multipart/form-data; boundary=' . $this->requestBody->getBoundary(); $this->requestBody->rewind(); } if (in_array($this->request->getMethod(), self::$bodyDisallowed) || 0 == $this->contentLength ) { // No body: send a Content-Length header nonetheless (request #12900), // but do that only for methods that require a body (bug #14740) if (in_array($this->request->getMethod(), self::$bodyRequired)) { $headers['content-length'] = 0; } else { unset($headers['content-length']); // if the method doesn't require a body and doesn't have a // body, don't send a Content-Type header. (request #16799) unset($headers['content-type']); } } else { if (empty($headers['content-type'])) { $headers['content-type'] = 'application/x-www-form-urlencoded'; } // Content-Length should not be sent for chunked Transfer-Encoding (bug #20125) if (!isset($headers['transfer-encoding'])) { $headers['content-length'] = $this->contentLength; } } } } ?> includes/PEAR/HTTP/Request2/Exception.php000064400000006351152214270100014040 0ustar00 * @copyright 2008-2022 Alexey Borzov * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License * @link http://pear.php.net/package/HTTP_Request2 */ /** * Base class for exceptions in PEAR */ require_once 'PEAR/Exception.php'; /** * Base exception class for HTTP_Request2 package * * @category HTTP * @package HTTP_Request2 * @author Alexey Borzov * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License * @version Release: 2.5.1 * @link http://pear.php.net/package/HTTP_Request2 * @link http://pear.php.net/pepr/pepr-proposal-show.php?id=132 */ class HTTP_Request2_Exception extends PEAR_Exception { /** * An invalid argument was passed to a method */ const INVALID_ARGUMENT = 1; /** * Some required value was not available */ const MISSING_VALUE = 2; /** * Request cannot be processed due to errors in PHP configuration */ const MISCONFIGURATION = 3; /** * Error reading the local file */ const READ_ERROR = 4; /** * Server returned a response that does not conform to HTTP protocol */ const MALFORMED_RESPONSE = 10; /** * Failure decoding Content-Encoding or Transfer-Encoding of response */ const DECODE_ERROR = 20; /** * Operation timed out */ const TIMEOUT = 30; /** * Number of redirects exceeded 'max_redirects' configuration parameter */ const TOO_MANY_REDIRECTS = 40; /** * Redirect to a protocol other than http(s):// */ const NON_HTTP_REDIRECT = 50; /** * Native error code * * @var int */ private $_nativeCode; /** * Constructor, can set package error code and native error code * * @param string $message exception message * @param int $code package error code, one of class constants * @param int $nativeCode error code from underlying PHP extension */ public function __construct($message = null, $code = null, $nativeCode = null) { parent::__construct($message, $code); $this->_nativeCode = $nativeCode; } /** * Returns error code produced by underlying PHP extension * * For Socket Adapter this may contain error number returned by * stream_socket_client(), for Curl Adapter this will contain error number * returned by curl_errno() * * @return integer */ public function getNativeCode() { return $this->_nativeCode; } } // backwards compatibility, include the child exceptions if installed with PEAR installer require_once 'HTTP/Request2/ConnectionException.php'; require_once 'HTTP/Request2/LogicException.php'; require_once 'HTTP/Request2/MessageException.php'; require_once 'HTTP/Request2/NotImplementedException.php'; ?>includes/PEAR/HTTP/WebDAV/Tools/_parse_propfind_response.php000064400000006321152214270100017625 0ustar00urls = array(); $this->_depth = 0; $xml_parser = xml_parser_create_ns("UTF-8", " "); xml_set_element_handler($xml_parser, array($this, "_startElement"), array($this, "_endElement")); xml_set_character_data_handler($xml_parser, array($this, "_data")); xml_parser_set_option($xml_parser, XML_OPTION_CASE_FOLDING, false); $this->success = xml_parse($xml_parser, $response, true); xml_parser_free($xml_parser); unset($this->_depth); } private function _startElement($parser, $name, $attrs) { if (strstr($name, " ")) { list($ns, $tag) = explode(" ", $name); if ($ns == "") $this->success = false; } else { $ns = ""; $tag = $name; } switch ($this->_depth) { case '2': switch ($tag) { case 'propstat': // TODO check is_executable, lockinfo ... $this->_tmpprop = array("mode" => 0100666 /* all may read and write (for now) */); break; } } $this->_depth++; } private function _endElement($parser, $name) { if (strstr($name, " ")) { list($ns, $tag) = explode(" ", $name); if ($ns == "") $this->success = false; } else { $ns = ""; $tag = $name; } $this->_depth--; switch ($this->_depth) { case '1': switch ($tag) { case 'response': $this->urls[$this->_tmphref] = $this->_tmpvals; unset($this->_tmphref); unset($this->_tmpvals); break; } break; case '2': switch ($tag) { case 'href': $this->_tmphref = $this->_tmpdata; break; } case 'propstat': if (isset($this->_tmpstat) && strstr($this->_tmpstat, " 200 ")) { $this->_tmpvals = $this->_tmpprop; } unset($this->_tmpstat); unset($this->_tmpprop); break; case '3': switch ($tag) { case 'status': $this->_tmpstat = $this->_tmpdata; break; } case '4': if (!isset($this->_tmpdata)) { return; } switch ($tag) { case 'getlastmodified': $this->_tmpprop['atime'] = strtotime($this->_tmpdata); $this->_tmpprop['mtime'] = strtotime($this->_tmpdata); break; case 'creationdate': $t = preg_split("/[^[:digit:]]/", $this->_tmpdata); $this->_tmpprop['ctime'] = mktime((int) $t[3], (int) $t[4], (int) $t[5], (int) $t[1], (int) $t[2], (int) $t[0]); unset($t); break; case 'getcontentlength': $this->_tmpprop['size'] = $this->_tmpdata; break; } case '5': switch ($tag) { case 'collection': $this->_tmpprop['mode'] &= ~0100000; // clear S_IFREG $this->_tmpprop['mode'] |= 040000; // set S_IFDIR break; } } unset($this->_tmpdata); } private function _data($parser, $data) { $this->_tmpdata = $data; } public function stat($href = false) { if ($href) { // TODO } else { reset($this->urls); return current($this->urls); } } } /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * indent-tabs-mode:nil * End: */ includes/PEAR/HTTP/WebDAV/Tools/_parse_lock_response.php000064400000003507152214270100016737 0ustar00success = xml_parse($xml_parser, $response, true); xml_parser_free($xml_parser); } private function _startElement($parser, $name, $attrs) { if (strstr($name, " ")) { list($ns, $tag) = explode(" ", $name); } else { $ns = ""; $tag = $name; } if ($ns == "DAV:") { switch ($tag) { case "locktoken": $this->collect_locktoken = true; break; } } } private function _data($parser, $data) { if ($this->collect_locktoken) { $this->locktoken .= $data; } } private function _endElement($parser, $name) { if (strstr($name, " ")) { list($ns, $tag) = explode(" ", $name); } else { $ns = ""; $tag = $name; } switch ($tag) { case "locktoken": $this->collect_locktoken = false; $this->locktoken = trim($this->locktoken); break; } } } /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * indent-tabs-mode:nil * End: */ includes/PEAR/HTTP/Request2.php000064400000106513152214270100012103 0ustar00 * @copyright 2008-2022 Alexey Borzov * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License * @link http://pear.php.net/package/HTTP_Request2 */ /** * A class representing an URL as per RFC 3986. */ require_once 'Net/URL2.php'; /** * Exception class for HTTP_Request2 package */ require_once 'HTTP/Request2/Exception.php'; /** * Class representing a HTTP request message * * @category HTTP * @package HTTP_Request2 * @author Alexey Borzov * @license http://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License * @version Release: 2.5.1 * @link http://pear.php.net/package/HTTP_Request2 * @link http://tools.ietf.org/html/rfc2616#section-5 */ class HTTP_Request2 implements SplSubject { /** * #@+ * Constants for HTTP request methods * * @link http://tools.ietf.org/html/rfc2616#section-5.1.1 */ const METHOD_OPTIONS = 'OPTIONS'; const METHOD_GET = 'GET'; const METHOD_HEAD = 'HEAD'; const METHOD_POST = 'POST'; const METHOD_PUT = 'PUT'; const METHOD_DELETE = 'DELETE'; const METHOD_TRACE = 'TRACE'; const METHOD_CONNECT = 'CONNECT'; /** * #@- */ /** * #@+ * Constants for HTTP authentication schemes * * @link http://tools.ietf.org/html/rfc2617 */ const AUTH_BASIC = 'basic'; const AUTH_DIGEST = 'digest'; /** * #@- */ /** * Regular expression used to check for invalid symbols in RFC 2616 tokens * * @link http://pear.php.net/bugs/bug.php?id=15630 */ const REGEXP_INVALID_TOKEN = '![\x00-\x1f\x7f-\xff()<>@,;:\\\\"/\[\]?={}\s]!'; /** * Regular expression used to check for invalid symbols in cookie strings * * @link http://pear.php.net/bugs/bug.php?id=15630 * @link http://web.archive.org/web/20080331104521/http://cgi.netscape.com/newsref/std/cookie_spec.html */ const REGEXP_INVALID_COOKIE = '/[\s,;]/'; /** * Fileinfo magic database resource * * @var resource * @see detectMimeType() */ private static $_fileinfoDb; /** * Observers attached to the request (instances of SplObserver) * * @var array */ protected $observers = []; /** * Request URL * * @var Net_URL2 */ protected $url; /** * Request method * * @var string */ protected $method = self::METHOD_GET; /** * Authentication data * * @var array * @see getAuth() */ protected $auth; /** * Request headers * * @var array */ protected $headers = []; /** * Configuration parameters * * @var array * @see setConfig() */ protected $config = [ 'adapter' => 'HTTP_Request2_Adapter_Socket', 'connect_timeout' => 10, 'timeout' => 0, 'use_brackets' => true, 'protocol_version' => '1.1', 'buffer_size' => 16384, 'store_body' => true, 'local_ip' => null, 'proxy_host' => '', 'proxy_port' => '', 'proxy_user' => '', 'proxy_password' => '', 'proxy_auth_scheme' => self::AUTH_BASIC, 'proxy_type' => 'http', 'ssl_verify_peer' => true, 'ssl_verify_host' => true, 'ssl_cafile' => null, 'ssl_capath' => null, 'ssl_local_cert' => null, 'ssl_passphrase' => null, 'digest_compat_ie' => false, 'follow_redirects' => false, 'max_redirects' => 5, 'strict_redirects' => false ]; /** * Last event in request / response handling, intended for observers * * @var array * @see getLastEvent() */ protected $lastEvent = [ 'name' => 'start', 'data' => null ]; /** * Request body * * @var string|resource * @see setBody() */ protected $body = ''; /** * Array of POST parameters * * @var array */ protected $postParams = []; /** * Array of file uploads (for multipart/form-data POST requests) * * @var array */ protected $uploads = []; /** * Adapter used to perform actual HTTP request * * @var HTTP_Request2_Adapter */ protected $adapter; /** * Cookie jar to persist cookies between requests * * @var HTTP_Request2_CookieJar */ protected $cookieJar = null; /** * Constructor. Can set request URL, method and configuration array. * * Also sets a default value for User-Agent header. * * @param string|Net_Url2 $url Request URL * @param string $method Request method * @param array $config Configuration for this Request instance */ public function __construct( $url = null, $method = self::METHOD_GET, array $config = [] ) { $this->setConfig($config); if (!empty($url)) { $this->setUrl($url); } if (!empty($method)) { $this->setMethod($method); } $this->setHeader( 'user-agent', 'HTTP_Request2/2.5.1 ' . '(https://github.com/pear/HTTP_Request2) PHP/' . phpversion() ); } /** * Sets the URL for this request * * If the URL has userinfo part (username & password) these will be removed * and converted to auth data. If the URL does not have a path component, * that will be set to '/'. * * @param string|Net_URL2 $url Request URL * * @return $this * @throws HTTP_Request2_LogicException */ public function setUrl($url) { if (is_string($url)) { $url = new Net_URL2( $url, [Net_URL2::OPTION_USE_BRACKETS => $this->config['use_brackets']] ); } if (!$url instanceof Net_URL2) { throw new HTTP_Request2_LogicException( 'Parameter is not a valid HTTP URL', HTTP_Request2_Exception::INVALID_ARGUMENT ); } // URL contains username / password? if ($url->getUserinfo()) { $username = $url->getUser(); $password = $url->getPassword(); $this->setAuth(rawurldecode($username), $password? rawurldecode($password): ''); $url->setUserinfo(''); } if ('' == $url->getPath()) { $url->setPath('/'); } $this->url = $url; return $this; } /** * Returns the request URL * * @return Net_URL2 */ public function getUrl() { return $this->url; } /** * Sets the request method * * @param string $method one of the methods defined in RFC 2616 * * @return $this * @throws HTTP_Request2_LogicException if the method name is invalid */ public function setMethod($method) { // Method name should be a token: http://tools.ietf.org/html/rfc2616#section-5.1.1 if (preg_match(self::REGEXP_INVALID_TOKEN, $method)) { throw new HTTP_Request2_LogicException( "Invalid request method '{$method}'", HTTP_Request2_Exception::INVALID_ARGUMENT ); } $this->method = $method; return $this; } /** * Returns the request method * * @return string */ public function getMethod() { return $this->method; } /** * Sets the configuration parameter(s) * * The following parameters are available: *
    *
  • 'adapter' - adapter to use (string)
  • *
  • 'connect_timeout' - Connection timeout in seconds (integer)
  • *
  • 'timeout' - Total number of seconds a request can take. * Use 0 for no limit, should be greater than * 'connect_timeout' if set (integer)
  • *
  • 'use_brackets' - Whether to append [] to array variable names (bool)
  • *
  • 'protocol_version' - HTTP Version to use, '1.0' or '1.1' (string)
  • *
  • 'buffer_size' - Buffer size to use for reading and writing (int)
  • *
  • 'store_body' - Whether to store response body in response object. * Set to false if receiving a huge response and * using an Observer to save it (boolean)
  • *
  • 'local_ip' - Specifies the IP address that will be used for accessing * the network (string)
  • *
  • 'proxy_type' - Proxy type, 'http' or 'socks5' (string)
  • *
  • 'proxy_host' - Proxy server host (string)
  • *
  • 'proxy_port' - Proxy server port (integer)
  • *
  • 'proxy_user' - Proxy auth username (string)
  • *
  • 'proxy_password' - Proxy auth password (string)
  • *
  • 'proxy_auth_scheme' - Proxy auth scheme, one of HTTP_Request2::AUTH_* constants (string)
  • *
  • 'proxy' - Shorthand for proxy_* parameters, proxy given as URL, * e.g. 'socks5://localhost:1080/' (string)
  • *
  • 'ssl_verify_peer' - Whether to verify peer's SSL certificate (bool)
  • *
  • 'ssl_verify_host' - Whether to check that Common Name in SSL * certificate matches host name (bool)
  • *
  • 'ssl_cafile' - Cerificate Authority file to verify the peer * with (use with 'ssl_verify_peer') (string)
  • *
  • 'ssl_capath' - Directory holding multiple Certificate * Authority files (string)
  • *
  • 'ssl_local_cert' - Name of a file containing local cerificate (string)
  • *
  • 'ssl_passphrase' - Passphrase with which local certificate * was encoded (string)
  • *
  • 'digest_compat_ie' - Whether to imitate behaviour of MSIE 5 and 6 * in using URL without query string in digest * authentication (boolean)
  • *
  • 'follow_redirects' - Whether to automatically follow HTTP Redirects (boolean)
  • *
  • 'max_redirects' - Maximum number of redirects to follow (integer)
  • *
  • 'strict_redirects' - Whether to keep request method on redirects via status 301 and * 302 (true, needed for compatibility with RFC 2616) * or switch to GET (false, needed for compatibility with most * browsers) (boolean)
  • *
* * @param string|array $nameOrConfig configuration parameter name or array * ('parameter name' => 'parameter value') * @param mixed $value parameter value if $nameOrConfig is not an array * * @return $this * @throws HTTP_Request2_LogicException If the parameter is unknown */ public function setConfig($nameOrConfig, $value = null) { if (is_array($nameOrConfig)) { foreach ($nameOrConfig as $name => $value) { $this->setConfig($name, $value); } } elseif ('proxy' == $nameOrConfig) { $url = new Net_URL2($value); $this->setConfig( [ 'proxy_type' => $url->getScheme(), 'proxy_host' => $url->getHost(), 'proxy_port' => $url->getPort(), 'proxy_user' => rawurldecode($url->getUser()), 'proxy_password' => rawurldecode($url->getPassword()) ] ); } else { if (!array_key_exists($nameOrConfig, $this->config)) { throw new HTTP_Request2_LogicException( "Unknown configuration parameter '{$nameOrConfig}'", HTTP_Request2_Exception::INVALID_ARGUMENT ); } $this->config[$nameOrConfig] = $value; } return $this; } /** * Returns the value(s) of the configuration parameter(s) * * @param string $name parameter name * * @return mixed value of $name parameter, array of all configuration * parameters if $name is not given * @throws HTTP_Request2_LogicException If the parameter is unknown */ public function getConfig($name = null) { if (null === $name) { return $this->config; } elseif (!array_key_exists($name, $this->config)) { throw new HTTP_Request2_LogicException( "Unknown configuration parameter '{$name}'", HTTP_Request2_Exception::INVALID_ARGUMENT ); } return $this->config[$name]; } /** * Sets the authentication data * * @param string $user user name * @param string $password password * @param string $scheme authentication scheme * * @return $this */ public function setAuth($user, $password = '', $scheme = self::AUTH_BASIC) { if (empty($user)) { $this->auth = null; } else { $this->auth = [ 'user' => (string)$user, 'password' => (string)$password, 'scheme' => $scheme ]; } return $this; } /** * Returns the authentication data * * The array has the keys 'user', 'password' and 'scheme', where 'scheme' * is one of the HTTP_Request2::AUTH_* constants. * * @return array */ public function getAuth() { return $this->auth; } /** * Sets request header(s) * * The first parameter may be either a full header string 'header: value' or * header name. In the former case $value parameter is ignored, in the latter * the header's value will either be set to $value or the header will be * removed if $value is null. The first parameter can also be an array of * headers, in that case method will be called recursively. * * Note that headers are treated case insensitively as per RFC 2616. * * * $req->setHeader('Foo: Bar'); // sets the value of 'Foo' header to 'Bar' * $req->setHeader('FoO', 'Baz'); // sets the value of 'Foo' header to 'Baz' * $req->setHeader(array('foo' => 'Quux')); // sets the value of 'Foo' header to 'Quux' * $req->setHeader('FOO'); // removes 'Foo' header from request * * * @param string|array $name header name, header string ('Header: value') * or an array of headers * @param string|array|null $value header value if $name is not an array, * header will be removed if value is null * @param bool $replace whether to replace previous header with the * same name or append to its value * * @return $this * @throws HTTP_Request2_LogicException */ public function setHeader($name, $value = null, $replace = true) { if (is_array($name)) { foreach ($name as $k => $v) { if (is_string($k)) { $this->setHeader($k, $v, $replace); } else { $this->setHeader($v, null, $replace); } } } else { if (null === $value && strpos($name, ':')) { list($name, $value) = array_map('trim', explode(':', $name, 2)); } // Header name should be a token: http://tools.ietf.org/html/rfc2616#section-4.2 if (preg_match(self::REGEXP_INVALID_TOKEN, $name)) { throw new HTTP_Request2_LogicException( "Invalid header name '{$name}'", HTTP_Request2_Exception::INVALID_ARGUMENT ); } // Header names are case insensitive anyway $name = strtolower($name); if (null === $value) { unset($this->headers[$name]); } else { if (is_array($value)) { $value = implode(', ', array_map('trim', $value)); } elseif (is_string($value)) { $value = trim($value); } if (!isset($this->headers[$name]) || $replace) { $this->headers[$name] = $value; } else { $this->headers[$name] .= ', ' . $value; } } } return $this; } /** * Returns the request headers * * The array is of the form ('header name' => 'header value'), header names * are lowercased * * @return array */ public function getHeaders() { return $this->headers; } /** * Adds a cookie to the request * * If the request does not have a CookieJar object set, this method simply * appends a cookie to "Cookie:" header. * * If a CookieJar object is available, the cookie is stored in that object. * Data from request URL will be used for setting its 'domain' and 'path' * parameters, 'expires' and 'secure' will be set to null and false, * respectively. If you need further control, use CookieJar's methods. * * @param string $name cookie name * @param string $value cookie value * * @return $this * @throws HTTP_Request2_LogicException * @see setCookieJar() */ public function addCookie($name, $value) { if (!empty($this->cookieJar)) { $this->cookieJar->store( ['name' => $name, 'value' => $value], $this->url ); } else { $cookie = $name . '=' . $value; if (preg_match(self::REGEXP_INVALID_COOKIE, $cookie)) { throw new HTTP_Request2_LogicException( "Invalid cookie: '{$cookie}'", HTTP_Request2_Exception::INVALID_ARGUMENT ); } $cookies = empty($this->headers['cookie'])? '': $this->headers['cookie'] . '; '; $this->setHeader('cookie', $cookies . $cookie); } return $this; } /** * Sets the request body * * If you provide file pointer rather than file name, it should support * fstat() and rewind() operations. * * @param string|resource|HTTP_Request2_MultipartBody $body Either a * string with the body or filename containing body or * pointer to an open file or object with multipart body data * @param bool $isFilename Whether * first parameter is a filename * * @return $this * @throws HTTP_Request2_LogicException */ public function setBody($body, $isFilename = false) { if (!$isFilename && !is_resource($body)) { if (!$body instanceof HTTP_Request2_MultipartBody) { $this->body = (string)$body; } else { $this->body = $body; } } else { $fileData = $this->fopenWrapper($body, empty($this->headers['content-type'])); $this->body = $fileData['fp']; if (empty($this->headers['content-type'])) { $this->setHeader('content-type', $fileData['type']); } } $this->postParams = $this->uploads = []; return $this; } /** * Returns the request body * * @return string|resource|HTTP_Request2_MultipartBody */ public function getBody() { if (self::METHOD_POST == $this->method && (!empty($this->postParams) || !empty($this->uploads)) ) { if (0 === strpos($this->headers['content-type'], 'application/x-www-form-urlencoded')) { $body = http_build_query($this->postParams, '', '&'); if (!$this->getConfig('use_brackets')) { $body = preg_replace('/%5B\d+%5D=/', '=', $body); } // support RFC 3986 by not encoding '~' symbol (request #15368) return str_replace('%7E', '~', $body); } elseif (0 === strpos($this->headers['content-type'], 'multipart/form-data')) { require_once 'HTTP/Request2/MultipartBody.php'; return new HTTP_Request2_MultipartBody( $this->postParams, $this->uploads, $this->getConfig('use_brackets') ); } } return $this->body; } /** * Adds a file to form-based file upload * * Used to emulate file upload via a HTML form. The method also sets * Content-Type of HTTP request to 'multipart/form-data'. * * If you just want to send the contents of a file as the body of HTTP * request you should use setBody() method. * * If you provide file pointers rather than file names, they should support * fstat() and rewind() operations. * * @param string $fieldName name of file-upload field * @param string|resource|array $filename full name of local file, * pointer to open file or an array of files * @param string $sendFilename filename to send in the request * @param string $contentType content-type of file being uploaded * * @return $this * @throws HTTP_Request2_LogicException */ public function addUpload( $fieldName, $filename, $sendFilename = null, $contentType = null ) { if (!is_array($filename)) { $fileData = $this->fopenWrapper($filename, empty($contentType)); $this->uploads[$fieldName] = [ 'fp' => $fileData['fp'], 'filename' => !empty($sendFilename)? $sendFilename :(is_string($filename)? basename($filename): 'anonymous.blob') , 'size' => $fileData['size'], 'type' => empty($contentType)? $fileData['type']: $contentType ]; } else { $fps = $names = $sizes = $types = []; foreach ($filename as $f) { if (!is_array($f)) { $f = [$f]; } $fileData = $this->fopenWrapper($f[0], empty($f[2])); $fps[] = $fileData['fp']; $names[] = !empty($f[1])? $f[1] :(is_string($f[0])? basename($f[0]): 'anonymous.blob'); $sizes[] = $fileData['size']; $types[] = empty($f[2])? $fileData['type']: $f[2]; } $this->uploads[$fieldName] = [ 'fp' => $fps, 'filename' => $names, 'size' => $sizes, 'type' => $types ]; } if (empty($this->headers['content-type']) || 'application/x-www-form-urlencoded' == $this->headers['content-type'] ) { $this->setHeader('content-type', 'multipart/form-data'); } return $this; } /** * Adds POST parameter(s) to the request. * * @param string|array $name parameter name or array ('name' => 'value') * @param mixed $value parameter value (can be an array) * * @return $this */ public function addPostParameter($name, $value = null) { if (!is_array($name)) { $this->postParams[$name] = $value; } else { foreach ($name as $k => $v) { $this->addPostParameter($k, $v); } } if (empty($this->headers['content-type'])) { $this->setHeader('content-type', 'application/x-www-form-urlencoded'); } return $this; } #[ReturnTypeWillChange] /** * Attaches a new observer * * @param SplObserver $observer any object implementing SplObserver * * @return void */ public function attach(SplObserver $observer) { foreach ($this->observers as $attached) { if ($attached === $observer) { return; } } $this->observers[] = $observer; } #[ReturnTypeWillChange] /** * Detaches an existing observer * * @param SplObserver $observer any object implementing SplObserver * * @return void */ public function detach(SplObserver $observer) { foreach ($this->observers as $key => $attached) { if ($attached === $observer) { unset($this->observers[$key]); return; } } } #[ReturnTypeWillChange] /** * Notifies all observers * * @return void */ public function notify() { foreach ($this->observers as $observer) { $observer->update($this); } } /** * Sets the last event * * Adapters should use this method to set the current state of the request * and notify the observers. * * @param string $name event name * @param mixed $data event data * * @return void */ public function setLastEvent($name, $data = null) { $this->lastEvent = [ 'name' => $name, 'data' => $data ]; $this->notify(); } /** * Returns the last event * * Observers should use this method to access the last change in request. * The following event names are possible: *
    *
  • 'connect' - after connection to remote server, * data is the destination (string)
  • *
  • 'disconnect' - after disconnection from server
  • *
  • 'sentHeaders' - after sending the request headers, * data is the headers sent (string)
  • *
  • 'sentBodyPart' - after sending a part of the request body, * data is the length of that part (int)
  • *
  • 'sentBody' - after sending the whole request body, * data is request body length (int)
  • *
  • 'receivedHeaders' - after receiving the response headers, * data is HTTP_Request2_Response object
  • *
  • 'receivedBodyPart' - after receiving a part of the response * body, data is that part (string)
  • *
  • 'receivedEncodedBodyPart' - as 'receivedBodyPart', but data is still * encoded by Content-Encoding
  • *
  • 'receivedBody' - after receiving the complete response * body, data is HTTP_Request2_Response object
  • *
  • 'warning' - a problem arose during the request * that is not severe enough to throw * an Exception, data is the warning * message (string). Currently dispatched if * response body was received incompletely.
  • *
* Different adapters may not send all the event types. Mock adapter does * not send any events to the observers. * * @return array The array has two keys: 'name' and 'data' */ public function getLastEvent() { return $this->lastEvent; } /** * Sets the adapter used to actually perform the request * * You can pass either an instance of a class implementing HTTP_Request2_Adapter * or a class name. The method will only try to include a file if the class * name starts with HTTP_Request2_Adapter_, it will also try to prepend this * prefix to the class name if it doesn't contain any underscores, so that * * $request->setAdapter('curl'); * * will work. * * @param string|HTTP_Request2_Adapter $adapter Adapter to use * * @return $this * @throws HTTP_Request2_LogicException */ public function setAdapter($adapter) { if (is_string($adapter)) { if (!class_exists($adapter, false)) { if (false === strpos($adapter, '_')) { $adapter = 'HTTP_Request2_Adapter_' . ucfirst($adapter); } if (!class_exists($adapter, true) && preg_match('/^HTTP_Request2_Adapter_([a-zA-Z0-9]+)$/', $adapter) ) { include_once str_replace('_', DIRECTORY_SEPARATOR, $adapter) . '.php'; } if (!class_exists($adapter, false)) { throw new HTTP_Request2_LogicException( "Class {$adapter} not found", HTTP_Request2_Exception::MISSING_VALUE ); } } $adapter = new $adapter; } if (!$adapter instanceof HTTP_Request2_Adapter) { throw new HTTP_Request2_LogicException( 'Parameter is not a HTTP request adapter', HTTP_Request2_Exception::INVALID_ARGUMENT ); } $this->adapter = $adapter; return $this; } /** * Sets the cookie jar * * A cookie jar is used to maintain cookies across HTTP requests and * responses. Cookies from jar will be automatically added to the request * headers based on request URL. * * @param HTTP_Request2_CookieJar|bool $jar Existing CookieJar object, true to * create a new one, false to remove * * @return $this * @throws HTTP_Request2_LogicException */ public function setCookieJar($jar = true) { require_once 'HTTP/Request2/CookieJar.php'; if ($jar instanceof HTTP_Request2_CookieJar) { $this->cookieJar = $jar; } elseif (true === $jar) { $this->cookieJar = new HTTP_Request2_CookieJar(); } elseif (!$jar) { $this->cookieJar = null; } else { throw new HTTP_Request2_LogicException( 'Invalid parameter passed to setCookieJar()', HTTP_Request2_Exception::INVALID_ARGUMENT ); } return $this; } /** * Returns current CookieJar object or null if none * * @return HTTP_Request2_CookieJar|null */ public function getCookieJar() { return $this->cookieJar; } /** * Sends the request and returns the response * * @throws HTTP_Request2_Exception * @return HTTP_Request2_Response */ public function send() { // Sanity check for URL if (!$this->url instanceof Net_URL2 || !$this->url->isAbsolute() || !in_array(strtolower($this->url->getScheme()), ['https', 'http']) ) { throw new HTTP_Request2_LogicException( 'HTTP_Request2 needs an absolute HTTP(S) request URL, ' . ($this->url instanceof Net_URL2 ? "'" . $this->url->__toString() . "'" : 'none') . ' given', HTTP_Request2_Exception::INVALID_ARGUMENT ); } if (empty($this->adapter)) { $this->setAdapter($this->getConfig('adapter')); } // force using single byte encoding if mbstring extension overloads // strlen() and substr(); see bug #1781, bug #10605 if (extension_loaded('mbstring') && (2 & ini_get('mbstring.func_overload'))) { $oldEncoding = mb_internal_encoding(); mb_internal_encoding('8bit'); } try { return $this->adapter->sendRequest($this); } finally { // phpcs:ignore PHPCompatibility.Keywords.NewKeywords.t_finallyFound if (!empty($oldEncoding)) { mb_internal_encoding($oldEncoding); } } } /** * Wrapper around fopen()/fstat() used by setBody() and addUpload() * * @param string|resource $file file name or pointer to open file * @param bool $detectType whether to try autodetecting MIME * type of file, will only work if $file is a * filename, not pointer * * @return array array('fp' => file pointer, 'size' => file size, 'type' => MIME type) * @throws HTTP_Request2_LogicException */ protected function fopenWrapper($file, $detectType = false) { if (!is_string($file) && !is_resource($file)) { throw new HTTP_Request2_LogicException( "Filename or file pointer resource expected", HTTP_Request2_Exception::INVALID_ARGUMENT ); } $fileData = [ 'fp' => is_string($file)? null: $file, 'type' => 'application/octet-stream', 'size' => 0 ]; if (is_string($file)) { if (!($fileData['fp'] = @fopen($file, 'rb'))) { $error = error_get_last(); throw new HTTP_Request2_LogicException( $error['message'], HTTP_Request2_Exception::READ_ERROR ); } if ($detectType) { $fileData['type'] = self::detectMimeType($file); } } if (!($stat = fstat($fileData['fp']))) { throw new HTTP_Request2_LogicException( "fstat() call failed", HTTP_Request2_Exception::READ_ERROR ); } $fileData['size'] = $stat['size']; return $fileData; } /** * Tries to detect MIME type of a file * * The method will try to use fileinfo extension if it is available, * deprecated mime_content_type() function in the other case. If neither * works, default 'application/octet-stream' MIME type is returned * * @param string $filename file name * * @return string file MIME type */ protected static function detectMimeType($filename) { // finfo extension from PECL available if (function_exists('finfo_open')) { if (!isset(self::$_fileinfoDb)) { self::$_fileinfoDb = @finfo_open(FILEINFO_MIME); } if (self::$_fileinfoDb) { $info = finfo_file(self::$_fileinfoDb, $filename); } } // (deprecated) mime_content_type function available if (empty($info) && function_exists('mime_content_type')) { $info = mime_content_type($filename); } return empty($info)? 'application/octet-stream': $info; } } ?> includes/PEAR/Net/URL2.php000064400000104543152214270100011065 0ustar00 * @copyright 2007-2009 Peytz & Co. A/S * @license https://spdx.org/licenses/BSD-3-Clause BSD-3-Clause * @version CVS: $Id$ * @link https://tools.ietf.org/html/rfc3986 */ /** * Represents a URL as per RFC 3986. * * @category Networking * @package Net_URL2 * @author Christian Schmidt * @copyright 2007-2009 Peytz & Co. A/S * @license https://spdx.org/licenses/BSD-3-Clause BSD-3-Clause * @version Release: 2.2.0 * @link https://pear.php.net/package/Net_URL2 */ class Net_URL2 { /** * Do strict parsing in resolve() (see RFC 3986, section 5.2.2). Default * is true. */ const OPTION_STRICT = 'strict'; /** * Represent arrays in query using PHP's [] notation. Default is true. */ const OPTION_USE_BRACKETS = 'use_brackets'; /** * Drop zero-based integer sequences in query using PHP's [] notation. Default * is true. */ const OPTION_DROP_SEQUENCE = 'drop_sequence'; /** * URL-encode query variable keys. Default is true. */ const OPTION_ENCODE_KEYS = 'encode_keys'; /** * Query variable separators when parsing the query string. Every character * is considered a separator. Default is "&". */ const OPTION_SEPARATOR_INPUT = 'input_separator'; /** * Query variable separator used when generating the query string. Default * is "&". */ const OPTION_SEPARATOR_OUTPUT = 'output_separator'; /** * Default options corresponds to how PHP handles $_GET. */ private $_options = array( self::OPTION_STRICT => true, self::OPTION_USE_BRACKETS => true, self::OPTION_DROP_SEQUENCE => true, self::OPTION_ENCODE_KEYS => true, self::OPTION_SEPARATOR_INPUT => '&', self::OPTION_SEPARATOR_OUTPUT => '&', ); /** * @var string|bool */ private $_scheme = false; /** * @var string|bool */ private $_userinfo = false; /** * @var string|bool */ private $_host = false; /** * @var string|bool */ private $_port = false; /** * @var string */ private $_path = ''; /** * @var string|bool */ private $_query = false; /** * @var string|bool */ private $_fragment = false; /** * Constructor. * * @param string $url an absolute or relative URL * @param array $options an array of OPTION_xxx constants * * @uses self::parseUrl() */ public function __construct($url, array $options = array()) { foreach ($options as $optionName => $value) { if (array_key_exists($optionName, $this->_options)) { $this->_options[$optionName] = $value; } } $this->parseUrl($url); } /** * Magic Setter. * * This method will magically set the value of a private variable ($var) * with the value passed as the args * * @param string $var The private variable to set. * @param mixed $arg An argument of any type. * * @return void */ public function __set($var, $arg) { $method = 'set' . $var; if (method_exists($this, $method)) { $this->$method($arg); } } /** * Magic Getter. * * This is the magic get method to retrieve the private variable * that was set by either __set() or it's setter... * * @param string $var The property name to retrieve. * * @return mixed $this->$var Either a boolean false if the * property is not set or the value * of the private property. */ public function __get($var) { $method = 'get' . $var; if (method_exists($this, $method)) { return $this->$method(); } return false; } /** * Returns the scheme, e.g. "http" or "urn", or false if there is no * scheme specified, i.e. if this is a relative URL. * * @return string|bool */ public function getScheme() { return $this->_scheme; } /** * Sets the scheme, e.g. "http" or "urn". Specify false if there is no * scheme specified, i.e. if this is a relative URL. * * @param string|bool $scheme e.g. "http" or "urn", or false if there is no * scheme specified, i.e. if this is a relative * URL * * @return $this * @see getScheme */ public function setScheme($scheme) { $this->_scheme = $scheme; return $this; } /** * Returns the user part of the userinfo part (the part preceding the first * ":"), or false if there is no userinfo part. * * @return string|bool */ public function getUser() { return $this->_userinfo !== false ? preg_replace('(:.*$)', '', $this->_userinfo) : false; } /** * Returns the password part of the userinfo part (the part after the first * ":"), or false if there is no userinfo part (i.e. the URL does not * contain "@" in front of the hostname) or the userinfo part does not * contain ":". * * @return string|bool */ public function getPassword() { return $this->_userinfo !== false ? substr(strstr($this->_userinfo, ':'), 1) : false; } /** * Returns the userinfo part, or false if there is none, i.e. if the * authority part does not contain "@". * * @return string|bool */ public function getUserinfo() { return $this->_userinfo; } /** * Sets the userinfo part. If two arguments are passed, they are combined * in the userinfo part as username ":" password. * * @param string|bool $userinfo userinfo or username * @param string|bool $password optional password, or false * * @return $this */ public function setUserinfo($userinfo, $password = false) { if ($password !== false) { $userinfo .= ':' . $password; } if ($userinfo !== false) { $userinfo = $this->_encodeData($userinfo); } $this->_userinfo = $userinfo; return $this; } /** * Returns the host part, or false if there is no authority part, e.g. * relative URLs. * * @return string|bool a hostname, an IP address, or false */ public function getHost() { return $this->_host; } /** * Sets the host part. Specify false if there is no authority part, e.g. * relative URLs. * * @param string|bool $host a hostname, an IP address, or false * * @return $this */ public function setHost($host) { $this->_host = $host; return $this; } /** * Returns the port number, or false if there is no port number specified, * i.e. if the default port is to be used. * * @return string|bool */ public function getPort() { return $this->_port; } /** * Sets the port number. Specify false if there is no port number specified, * i.e. if the default port is to be used. * * @param string|bool $port a port number, or false * * @return $this */ public function setPort($port) { $this->_port = $port; return $this; } /** * Returns the authority part, i.e. [ userinfo "@" ] host [ ":" port ], or * false if there is no authority. * * @return string|bool */ public function getAuthority() { if (false === $this->_host) { return false; } $authority = ''; if (strlen($this->_userinfo)) { $authority .= $this->_userinfo . '@'; } $authority .= $this->_host; if ($this->_port !== false) { $authority .= ':' . $this->_port; } return $authority; } /** * Sets the authority part, i.e. [ userinfo "@" ] host [ ":" port ]. Specify * false if there is no authority. * * @param string|bool $authority a hostname or an IP address, possibly * with userinfo prefixed and port number * appended, e.g. "foo:bar@example.org:81". * * @return $this */ public function setAuthority($authority) { $this->_userinfo = false; $this->_host = false; $this->_port = false; if ('' === $authority) { $this->_host = $authority; return $this; } if (!preg_match('(^(([^\@]*)\@)?(.+?)(:(\d*))?$)', $authority, $matches)) { return $this; } if ($matches[1]) { $this->_userinfo = $this->_encodeData($matches[2]); } $this->_host = $matches[3]; if (isset($matches[5]) && strlen($matches[5])) { $this->_port = $matches[5]; } return $this; } /** * Returns the path part (possibly an empty string). * * @return string */ public function getPath() { return $this->_path; } /** * Sets the path part (possibly an empty string). * * @param string $path a path * * @return $this */ public function setPath($path) { $this->_path = $path; return $this; } /** * Returns the query string (excluding the leading "?"), or false if "?" * is not present in the URL. * * @return string|bool * @see getQueryVariables */ public function getQuery() { return $this->_query; } /** * Sets the query string (excluding the leading "?"). Specify false if "?" * is not present in the URL. * * @param string|bool $query a query string, e.g. "foo=1&bar=2" * * @return $this * @see setQueryVariables */ public function setQuery($query) { $this->_query = $query; return $this; } /** * Returns the fragment name, or false if "#" is not present in the URL. * * @return string|bool */ public function getFragment() { return $this->_fragment; } /** * Sets the fragment name. Specify false if "#" is not present in the URL. * * @param string|bool $fragment a fragment excluding the leading "#", or * false * * @return $this */ public function setFragment($fragment) { $this->_fragment = $fragment; return $this; } /** * Returns the query string like an array as the variables would appear in * $_GET in a PHP script. If the URL does not contain a "?", an empty array * is returned. * * @return array */ public function getQueryVariables() { $separator = $this->getOption(self::OPTION_SEPARATOR_INPUT); $encodeKeys = $this->getOption(self::OPTION_ENCODE_KEYS); $useBrackets = $this->getOption(self::OPTION_USE_BRACKETS); $return = array(); for ($part = strtok($this->_query, $separator); strlen($part); $part = strtok($separator) ) { list($key, $value) = explode('=', $part, 2) + array(1 => ''); if ($encodeKeys) { $key = rawurldecode($key); } $value = rawurldecode($value); if ($useBrackets) { $return = $this->_queryArrayByKey($key, $value, $return); } else { if (isset($return[$key])) { $return[$key] = (array) $return[$key]; $return[$key][] = $value; } else { $return[$key] = $value; } } } return $return; } /** * Parse a single query key=value pair into an existing php array * * @param string $key query-key * @param string $value query-value * @param array $array of existing query variables (if any) * * @return mixed */ private function _queryArrayByKey($key, $value, array $array = array()) { if (!strlen($key)) { return $array; } $offset = $this->_queryKeyBracketOffset($key); if ($offset === false) { $name = $key; } else { $name = substr($key, 0, $offset); } if (!strlen($name)) { return $array; } if (!$offset) { // named value $array[$name] = $value; } else { // array $brackets = substr($key, $offset); if (!isset($array[$name])) { $array[$name] = null; } $array[$name] = $this->_queryArrayByBrackets( $brackets, $value, $array[$name] ); } return $array; } /** * Parse a key-buffer to place value in array * * @param string $buffer to consume all keys from * @param string $value to be set/add * @param array $array to traverse and set/add value in * * @throws Exception * @return array */ private function _queryArrayByBrackets($buffer, $value, array $array = null) { $entry = &$array; for ($iteration = 0; strlen($buffer); $iteration++) { $open = $this->_queryKeyBracketOffset($buffer); if ($open !== 0) { // Opening bracket [ must exist at offset 0, if not, there is // no bracket to parse and the value dropped. // if this happens in the first iteration, this is flawed, see // as well the second exception below. if ($iteration) { break; } // @codeCoverageIgnoreStart throw new Exception( 'Net_URL2 Internal Error: '. __METHOD__ .'(): ' . 'Opening bracket [ must exist at offset 0' ); // @codeCoverageIgnoreEnd } $close = strpos($buffer, ']', 1); if (!$close) { // this error condition should never be reached as this is a // private method and bracket pairs are checked beforehand. // See as well the first exception for the opening bracket. // @codeCoverageIgnoreStart throw new Exception( 'Net_URL2 Internal Error: '. __METHOD__ .'(): ' . 'Closing bracket ] must exist, not found' ); // @codeCoverageIgnoreEnd } $index = substr($buffer, 1, $close - 1); if (strlen($index)) { $entry = &$entry[$index]; } else { if (!is_array($entry)) { $entry = array(); } $entry[] = &$new; $entry = &$new; unset($new); } $buffer = substr($buffer, $close + 1); } $entry = $value; return $array; } /** * Query-key has brackets ("...[]") * * @param string $key query-key * * @return bool|int offset of opening bracket, false if no brackets */ private function _queryKeyBracketOffset($key) { if (false !== $open = strpos($key, '[') and false === strpos($key, ']', $open + 1) ) { $open = false; } return $open; } /** * Sets the query string to the specified variable in the query string. * * @param array $array (name => value) array * * @return $this */ public function setQueryVariables(array $array) { if (!$array) { $this->_query = false; } else { $this->_query = $this->buildQuery( $array, $this->getOption(self::OPTION_SEPARATOR_OUTPUT) ); } return $this; } /** * Sets the specified variable in the query string. * * @param string $name variable name * @param mixed $value variable value * * @return $this */ public function setQueryVariable($name, $value) { $array = $this->getQueryVariables(); $array[$name] = $value; $this->setQueryVariables($array); return $this; } /** * Removes the specified variable from the query string. * * @param string $name a query string variable, e.g. "foo" in "?foo=1" * * @return void */ public function unsetQueryVariable($name) { $array = $this->getQueryVariables(); unset($array[$name]); $this->setQueryVariables($array); } /** * Returns a string representation of this URL. * * @return string */ public function getURL() { // See RFC 3986, section 5.3 $url = ''; if ($this->_scheme !== false) { $url .= $this->_scheme . ':'; } $authority = $this->getAuthority(); if ($authority === false && strtolower($this->_scheme) === 'file') { $authority = ''; } $url .= $this->_buildAuthorityAndPath($authority, $this->_path); if ($this->_query !== false) { $url .= '?' . $this->_query; } if ($this->_fragment !== false) { $url .= '#' . $this->_fragment; } return $url; } /** * Put authority and path together, wrapping authority * into proper separators/terminators. * * @param string|bool $authority authority * @param string $path path * * @return string */ private function _buildAuthorityAndPath($authority, $path) { if ($authority === false) { return $path; } $terminator = ($path !== '' && $path[0] !== '/') ? '/' : ''; return '//' . $authority . $terminator . $path; } /** * Returns a string representation of this URL. * * @return string * @link https://php.net/language.oop5.magic#object.tostring */ public function __toString() { return $this->getURL(); } /** * Returns a normalized string representation of this URL. This is useful * for comparison of URLs. * * @return string */ public function getNormalizedURL() { $url = clone $this; $url->normalize(); return $url->getUrl(); } /** * Normalizes the URL * * See RFC 3986, Section 6. Normalization and Comparison * * @link https://tools.ietf.org/html/rfc3986#section-6 * * @return void */ public function normalize() { // See RFC 3986, section 6 // Scheme is case-insensitive if ($this->_scheme) { $this->_scheme = strtolower($this->_scheme); } // Hostname is case-insensitive if ($this->_host) { $this->_host = strtolower($this->_host); } // Remove default port number for known schemes (RFC 3986, section 6.2.3) if ('' === $this->_port || $this->_port && $this->_scheme && $this->_port == getservbyname($this->_scheme, 'tcp') ) { $this->_port = false; } // Normalize case of %XX percentage-encodings (RFC 3986, section 6.2.2.1) // Normalize percentage-encoded unreserved characters (section 6.2.2.2) $fields = array(&$this->_userinfo, &$this->_host, &$this->_path, &$this->_query, &$this->_fragment); foreach ($fields as &$field) { if ($field !== false) { $field = $this->_normalize("$field"); } } unset($field); // Path segment normalization (RFC 3986, section 6.2.2.3) $this->_path = self::removeDotSegments($this->_path); // Scheme based normalization (RFC 3986, section 6.2.3) if (false !== $this->_host && '' === $this->_path) { $this->_path = '/'; } // path should start with '/' if there is authority (section 3.3.) if (strlen($this->getAuthority()) && strlen($this->_path) && $this->_path[0] !== '/' ) { $this->_path = '/' . $this->_path; } } /** * Normalize case of %XX percentage-encodings (RFC 3986, section 6.2.2.1) * Normalize percentage-encoded unreserved characters (section 6.2.2.2) * * @param string|array $mixed string or array of strings to normalize * * @return string|array * @see normalize * @see _normalizeCallback() */ private function _normalize($mixed) { return preg_replace_callback( '((?:%[0-9a-fA-Z]{2})+)', array($this, '_normalizeCallback'), $mixed ); } /** * Callback for _normalize() of %XX percentage-encodings * * @param array $matches as by preg_replace_callback * * @return string * @see normalize * @see _normalize * @SuppressWarnings(PHPMD.UnusedPrivateMethod) */ private function _normalizeCallback($matches) { return self::urlencode(urldecode($matches[0])); } /** * Returns whether this instance represents an absolute URL. * * @return bool */ public function isAbsolute() { return (bool) $this->_scheme; } /** * Returns an Net_URL2 instance representing an absolute URL relative to * this URL. * * @param Net_URL2|string $reference relative URL * * @throws Exception * @return $this */ public function resolve($reference) { if (!$reference instanceof Net_URL2) { $reference = new self($reference); } if (!$reference->_isFragmentOnly() && !$this->isAbsolute()) { throw new Exception( 'Base-URL must be absolute if reference is not fragment-only' ); } // A non-strict parser may ignore a scheme in the reference if it is // identical to the base URI's scheme. if (!$this->getOption(self::OPTION_STRICT) && $reference->_scheme == $this->_scheme ) { $reference->_scheme = false; } $target = new self(''); if ($reference->_scheme !== false) { $target->_scheme = $reference->_scheme; $target->setAuthority($reference->getAuthority()); $target->_path = self::removeDotSegments($reference->_path); $target->_query = $reference->_query; } else { $authority = $reference->getAuthority(); if ($authority !== false) { $target->setAuthority($authority); $target->_path = self::removeDotSegments($reference->_path); $target->_query = $reference->_query; } else { if ($reference->_path == '') { $target->_path = $this->_path; if ($reference->_query !== false) { $target->_query = $reference->_query; } else { $target->_query = $this->_query; } } else { if (substr($reference->_path, 0, 1) == '/') { $target->_path = self::removeDotSegments($reference->_path); } else { // Merge paths (RFC 3986, section 5.2.3) if ($this->_host !== false && $this->_path == '') { $target->_path = '/' . $reference->_path; } else { $i = strrpos($this->_path, '/'); if ($i !== false) { $target->_path = substr($this->_path, 0, $i + 1); } $target->_path .= $reference->_path; } $target->_path = self::removeDotSegments($target->_path); } $target->_query = $reference->_query; } $target->setAuthority($this->getAuthority()); } $target->_scheme = $this->_scheme; } $target->_fragment = $reference->_fragment; return $target; } /** * URL is fragment-only * * @SuppressWarnings(PHPMD.UnusedPrivateMethod) * @return bool */ private function _isFragmentOnly() { return ( $this->_fragment !== false && $this->_query === false && $this->_path === '' && $this->_port === false && $this->_host === false && $this->_userinfo === false && $this->_scheme === false ); } /** * Removes dots as described in RFC 3986, section 5.2.4, e.g. * "/foo/../bar/baz" => "/bar/baz" * * @param string $path a path * * @return string a path */ public static function removeDotSegments($path) { $path = (string) $path; $output = ''; // Make sure not to be trapped in an infinite loop due to a bug in this // method $loopLimit = 256; $j = 0; while ('' !== $path && $j++ < $loopLimit) { if (substr($path, 0, 2) === './') { // Step 2.A $path = substr($path, 2); } elseif (substr($path, 0, 3) === '../') { // Step 2.A $path = substr($path, 3); } elseif (substr($path, 0, 3) === '/./' || $path === '/.') { // Step 2.B $path = '/' . substr($path, 3); } elseif (substr($path, 0, 4) === '/../' || $path === '/..') { // Step 2.C $path = '/' . substr($path, 4); $i = strrpos($output, '/'); $output = $i === false ? '' : substr($output, 0, $i); } elseif ($path === '.' || $path === '..') { // Step 2.D $path = ''; } else { // Step 2.E $i = strpos($path, '/', $path[0] === '/'); if ($i === false) { $output .= $path; $path = ''; break; } $output .= substr($path, 0, $i); $path = substr($path, $i); } } if ($path !== '') { $message = sprintf( 'Unable to remove dot segments; hit loop limit %d (left: %s)', $j, var_export($path, true) ); trigger_error($message, E_USER_WARNING); } return $output; } /** * Percent-encodes all non-alphanumeric characters except these: _ . - ~ * Similar to PHP's rawurlencode(), except that it also encodes ~ in PHP * 5.2.x and earlier. * * @param string $string string to encode * * @return string */ public static function urlencode($string) { $encoded = rawurlencode($string); // This is only necessary in PHP < 5.3. $encoded = str_replace('%7E', '~', $encoded); return $encoded; } /** * Returns a Net_URL2 instance representing the canonical URL of the * currently executing PHP script. * * @throws Exception * @return string */ public static function getCanonical() { if (!isset($_SERVER['REQUEST_METHOD'])) { // ALERT - no current URL throw new Exception('Script was not called through a webserver'); } // Begin with a relative URL $url = new self($_SERVER['PHP_SELF']); $url->_scheme = isset($_SERVER['HTTPS']) ? 'https' : 'http'; $url->_host = $_SERVER['SERVER_NAME']; $port = $_SERVER['SERVER_PORT']; if ($url->_scheme == 'http' && $port != 80 || $url->_scheme == 'https' && $port != 443 ) { $url->_port = $port; } return $url; } /** * Returns the URL used to retrieve the current request. * * @return string */ public static function getRequestedURL() { return self::getRequested()->getUrl(); } /** * Returns a Net_URL2 instance representing the URL used to retrieve the * current request. * * @throws Exception * @return $this */ public static function getRequested() { if (!isset($_SERVER['REQUEST_METHOD'])) { // ALERT - no current URL throw new Exception('Script was not called through a webserver'); } // Begin with a relative URL $url = new self($_SERVER['REQUEST_URI']); $url->_scheme = isset($_SERVER['HTTPS']) ? 'https' : 'http'; // Set host and possibly port $url->setAuthority($_SERVER['HTTP_HOST']); return $url; } /** * Returns the value of the specified option. * * @param string $optionName The name of the option to retrieve * * @return mixed */ public function getOption($optionName) { return isset($this->_options[$optionName]) ? $this->_options[$optionName] : false; } /** * A simple version of http_build_query in userland. The encoded string is * percentage encoded according to RFC 3986. * * @param array $data An array, which has to be converted into * QUERY_STRING. Anything is possible. * @param string $separator Separator {@link self::OPTION_SEPARATOR_OUTPUT} * @param string $key For stacked values (arrays in an array). * * @return string */ protected function buildQuery(array $data, $separator, $key = null) { $query = array(); $drop_names = ( $this->_options[self::OPTION_DROP_SEQUENCE] === true && array_keys($data) === array_keys(array_values($data)) ); foreach ($data as $name => $value) { if ($this->getOption(self::OPTION_ENCODE_KEYS) === true) { $name = rawurlencode($name); } if ($key !== null) { if ($this->getOption(self::OPTION_USE_BRACKETS) === true) { $drop_names && $name = ''; $name = $key . '[' . $name . ']'; } else { $name = $key; } } if (is_array($value)) { $query[] = $this->buildQuery($value, $separator, $name); } else { $query[] = $name . '=' . rawurlencode($value); } } return implode($separator, $query); } /** * This method uses a regex to parse the url into the designated parts. * * @param string $url URL * * @return void * @uses self::$_scheme, self::setAuthority(), self::$_path, self::$_query, * self::$_fragment * @see __construct */ protected function parseUrl($url) { // The regular expression is copied verbatim from RFC 3986, appendix B. // The expression does not validate the URL but matches any string. preg_match( '(^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?)', $url, $matches ); // "path" is always present (possibly as an empty string); the rest // are optional. $this->_scheme = !empty($matches[1]) ? $matches[2] : false; $this->setAuthority(!empty($matches[3]) ? $matches[4] : false); $this->_path = $this->_encodeData($matches[5]); $this->_query = !empty($matches[6]) ? $this->_encodeData($matches[7]) : false ; $this->_fragment = !empty($matches[8]) ? $matches[9] : false; } /** * Encode characters that might have been forgotten to encode when passing * in an URL. Applied onto Userinfo, Path and Query. * * @param string $url URL * * @return string * @see parseUrl * @see setAuthority * @link https://pear.php.net/bugs/bug.php?id=20425 */ private function _encodeData($url) { return preg_replace_callback( '([\x-\x20\x22\x3C\x3E\x7F-\xFF]+)', array($this, '_encodeCallback'), $url ); } /** * callback for encoding character data * * @param array $matches Matches * * @return string * @see _encodeData * @SuppressWarnings(PHPMD.UnusedPrivateMethod) */ private function _encodeCallback(array $matches) { return rawurlencode($matches[0]); } } includes/PEAR/Net/Socket.php000064400000046777152214270100011607 0ustar00 * Chuck Hagenbuch * * @category Net * @package Net_Socket * @author Stig Bakken * @author Chuck Hagenbuch * @copyright 1997-2003 The PHP Group * @license http://www.php.net/license/2_02.txt PHP 2.02 * @version CVS: $Id: Socket.php 304428 2010-10-15 13:51:46Z clockwerx $ * @link http://pear.php.net/packages/Net_Socket */ if (!class_exists('PEAR')) require_once 'PEAR.php'; define('NET_SOCKET_READ', 1); define('NET_SOCKET_WRITE', 2); define('NET_SOCKET_ERROR', 4); /** * Generalized Socket class. * * @category Net * @package Net_Socket * @author Stig Bakken * @author Chuck Hagenbuch * @copyright 1997-2003 The PHP Group * @license http://www.php.net/license/2_02.txt PHP 2.02 * @link http://pear.php.net/packages/Net_Socket */ class Net_Socket extends PEAR { /** * Socket file pointer. * @var resource $fp */ var $fp = null; /** * Whether the socket is blocking. Defaults to true. * @var boolean $blocking */ var $blocking = true; /** * Whether the socket is persistent. Defaults to false. * @var boolean $persistent */ var $persistent = false; /** * The IP address to connect to. * @var string $addr */ var $addr = ''; /** * The port number to connect to. * @var integer $port */ var $port = 0; /** * Number of seconds to wait on socket connections before assuming * there's no more data. Defaults to no timeout. * @var integer $timeout */ var $timeout = false; /** * Number of bytes to read at a time in readLine() and * readAll(). Defaults to 2048. * @var integer $lineLength */ var $lineLength = 2048; /** * The string to use as a newline terminator. Usually "\r\n" or "\n". * @var string $newline */ var $newline = "\r\n"; /** * Connect to the specified port. If called when the socket is * already connected, it disconnects and connects again. * * @param string $addr IP address or host name. * @param integer $port TCP port number. * @param boolean $persistent (optional) Whether the connection is * persistent (kept open between requests * by the web server). * @param integer $timeout (optional) How long to wait for data. * @param array $options See options for stream_context_create. * * @access public * * @return boolean | PEAR_Error True on success or a PEAR_Error on failure. */ function connect($addr, $port = 0, $persistent = null, $timeout = null, $options = null) { if (defined('UPDRAFTPLUS_SSL_DISABLE_VERIFY_SSL')) { $ssl_disable_verify = UPDRAFTPLUS_SSL_DISABLE_VERIFY_SSL; } else { $ssl_disable_verify = UpdraftPlus_Options::get_updraft_option('updraft_ssl_disableverify', false); } if (is_resource($this->fp)) { @fclose($this->fp); $this->fp = null; } if (!$addr) { return $this->raiseError('$addr cannot be empty'); } elseif (strspn($addr, '.0123456789') == strlen($addr) || strstr($addr, '/') !== false) { $this->addr = $addr; } else { $this->addr = @gethostbyname($addr); } $this->port = $port % 65536; if ($persistent !== null) { $this->persistent = $persistent; } if ($timeout !== null) { $this->timeout = $timeout; } $openfunc = $this->persistent ? 'pfsockopen' : 'fsockopen'; $errno = 0; $errstr = ''; $old_track_errors = @ini_set('track_errors', 1); //Check if Options are set and sslverify is true if so set options so that stream context can be used to disable ssl if (!$options && $ssl_disable_verify){ $options = 1; } if ($options && function_exists('stream_context_create')) { if ($this->timeout) { $timeout = $this->timeout; } else { $timeout = 100; } if ($ssl_disable_verify){ if (is_array($options)) { if (empty($options['ssl'])) { $options['ssl'] = array( 'verify_peer' => false, 'verify_peer_name' => false, ); } else { $options['ssl']['verify_peer'] = false; $options['ssl']['verify_peer_name'] = false; } } else { $options = array( 'ssl' => array( 'verify_peer' => false, 'verify_peer_name' => false, ) ); } } $context = stream_context_create($options); // Since PHP 5 fsockopen doesn't allow context specification if (function_exists('stream_socket_client')) { $flags = STREAM_CLIENT_CONNECT; if ($this->persistent) { $flags = STREAM_CLIENT_PERSISTENT; } $addr = $this->addr . ':' . $this->port; $fp = stream_socket_client($addr, $errno, $errstr, $timeout, $flags, $context); } else { $fp = @$openfunc($this->addr, $this->port, $errno, $errstr, $timeout, $context); } } else { if ($this->timeout) { $fp = @$openfunc($this->addr, $this->port, $errno, $errstr, $this->timeout); } else { $fp = @$openfunc($this->addr, $this->port, $errno, $errstr); } } if (!$fp) { // @codingStandardsIgnoreLine if ($errno == 0 && !strlen($errstr) && isset($php_errormsg)) { // @codingStandardsIgnoreLine $errstr = $php_errormsg; } @ini_set('track_errors', $old_track_errors); return $this->raiseError($errstr, $errno); } @ini_set('track_errors', $old_track_errors); $this->fp = $fp; return $this->setBlocking($this->blocking); } /** * Disconnects from the peer, closes the socket. * * @access public * @return mixed true on success or a PEAR_Error instance otherwise */ function disconnect() { if (!is_resource($this->fp)) { return $this->raiseError('not connected'); } @fclose($this->fp); $this->fp = null; return true; } /** * Set the newline character/sequence to use. * * @param string $newline Newline character(s) * @return boolean True */ function setNewline($newline) { $this->newline = $newline; return true; } /** * Find out if the socket is in blocking mode. * * @access public * @return boolean The current blocking mode. */ function isBlocking() { return $this->blocking; } /** * Sets whether the socket connection should be blocking or * not. A read call to a non-blocking socket will return immediately * if there is no data available, whereas it will block until there * is data for blocking sockets. * * @param boolean $mode True for blocking sockets, false for nonblocking. * * @access public * @return mixed true on success or a PEAR_Error instance otherwise */ function setBlocking($mode) { if (!is_resource($this->fp)) { return $this->raiseError('not connected'); } $this->blocking = $mode; stream_set_blocking($this->fp, (int)$this->blocking); return true; } /** * Sets the timeout value on socket descriptor, * expressed in the sum of seconds and microseconds * * @param integer $seconds Seconds. * @param integer $microseconds Microseconds. * * @access public * @return mixed true on success or a PEAR_Error instance otherwise */ function setTimeout($seconds, $microseconds) { if (!is_resource($this->fp)) { return $this->raiseError('not connected'); } return socket_set_timeout($this->fp, $seconds, $microseconds); } /** * Sets the file buffering size on the stream. * See php's stream_set_write_buffer for more information. * * @param integer $size Write buffer size. * * @access public * @return mixed on success or an PEAR_Error object otherwise */ function setWriteBuffer($size) { if (!is_resource($this->fp)) { return $this->raiseError('not connected'); } $returned = stream_set_write_buffer($this->fp, $size); if ($returned == 0) { return true; } return $this->raiseError('Cannot set write buffer.'); } /** * Returns information about an existing socket resource. * Currently returns four entries in the result array: * *

* timed_out (bool) - The socket timed out waiting for data
* blocked (bool) - The socket was blocked
* eof (bool) - Indicates EOF event
* unread_bytes (int) - Number of bytes left in the socket buffer
*

* * @access public * @return mixed Array containing information about existing socket * resource or a PEAR_Error instance otherwise */ function getStatus() { if (!is_resource($this->fp)) { return $this->raiseError('not connected'); } return socket_get_status($this->fp); } /** * Get a specified line of data * * @param int $size ?? * * @access public * @return $size bytes of data from the socket, or a PEAR_Error if * not connected. */ function gets($size = null) { if (!is_resource($this->fp)) { return $this->raiseError('not connected'); } if (is_null($size)) { return @fgets($this->fp); } else { return @fgets($this->fp, $size); } } /** * Read a specified amount of data. This is guaranteed to return, * and has the added benefit of getting everything in one fread() * chunk; if you know the size of the data you're getting * beforehand, this is definitely the way to go. * * @param integer $size The number of bytes to read from the socket. * * @access public * @return $size bytes of data from the socket, or a PEAR_Error if * not connected. */ function read($size) { if (!is_resource($this->fp)) { return $this->raiseError('not connected'); } return @fread($this->fp, $size); } /** * Write a specified amount of data. * * @param string $data Data to write. * @param integer $blocksize Amount of data to write at once. * NULL means all at once. * * @access public * @return mixed If the socket is not connected, returns an instance of * PEAR_Error * If the write succeeds, returns the number of bytes written * If the write fails, returns false. */ function write($data, $blocksize = null) { if (!is_resource($this->fp)) { return $this->raiseError('not connected'); } if (is_null($blocksize) && !OS_WINDOWS) { return @fwrite($this->fp, $data); } else { if (is_null($blocksize)) { $blocksize = 1024; } $pos = 0; $size = strlen($data); while ($pos < $size) { $written = @fwrite($this->fp, substr($data, $pos, $blocksize)); if (!$written) { return $written; } $pos += $written; } return $pos; } } /** * Write a line of data to the socket, followed by a trailing newline. * * @param string $data Data to write * * @access public * @return mixed fputs result, or an error */ function writeLine($data) { if (!is_resource($this->fp)) { return $this->raiseError('not connected'); } return fwrite($this->fp, $data . $this->newline); } /** * Tests for end-of-file on a socket descriptor. * * Also returns true if the socket is disconnected. * * @access public * @return bool */ function eof() { return (!is_resource($this->fp) || feof($this->fp)); } /** * Reads a byte of data * * @access public * @return 1 byte of data from the socket, or a PEAR_Error if * not connected. */ function readByte() { if (!is_resource($this->fp)) { return $this->raiseError('not connected'); } return ord(@fread($this->fp, 1)); } /** * Reads a word of data * * @access public * @return 1 word of data from the socket, or a PEAR_Error if * not connected. */ function readWord() { if (!is_resource($this->fp)) { return $this->raiseError('not connected'); } $buf = @fread($this->fp, 2); return (ord($buf[0]) + (ord($buf[1]) << 8)); } /** * Reads an int of data * * @access public * @return integer 1 int of data from the socket, or a PEAR_Error if * not connected. */ function readInt() { if (!is_resource($this->fp)) { return $this->raiseError('not connected'); } $buf = @fread($this->fp, 4); return (ord($buf[0]) + (ord($buf[1]) << 8) + (ord($buf[2]) << 16) + (ord($buf[3]) << 24)); } /** * Reads a zero-terminated string of data * * @access public * @return string, or a PEAR_Error if * not connected. */ function readString() { if (!is_resource($this->fp)) { return $this->raiseError('not connected'); } $string = ''; while (($char = @fread($this->fp, 1)) != "\x00") { $string .= $char; } return $string; } /** * Reads an IP Address and returns it in a dot formatted string * * @access public * @return Dot formatted string, or a PEAR_Error if * not connected. */ function readIPAddress() { if (!is_resource($this->fp)) { return $this->raiseError('not connected'); } $buf = @fread($this->fp, 4); return sprintf('%d.%d.%d.%d', ord($buf[0]), ord($buf[1]), ord($buf[2]), ord($buf[3])); } /** * Read until either the end of the socket or a newline, whichever * comes first. Strips the trailing newline from the returned data. * * @access public * @return All available data up to a newline, without that * newline, or until the end of the socket, or a PEAR_Error if * not connected. */ function readLine() { if (!is_resource($this->fp)) { return $this->raiseError('not connected'); } $line = ''; $timeout = time() + $this->timeout; while (!feof($this->fp) && (!$this->timeout || time() < $timeout)) { $line .= @fgets($this->fp, $this->lineLength); if (substr($line, -1) == "\n") { return rtrim($line, $this->newline); } } return $line; } /** * Read until the socket closes, or until there is no more data in * the inner PHP buffer. If the inner buffer is empty, in blocking * mode we wait for at least 1 byte of data. Therefore, in * blocking mode, if there is no data at all to be read, this * function will never exit (unless the socket is closed on the * remote end). * * @access public * * @return string All data until the socket closes, or a PEAR_Error if * not connected. */ function readAll() { if (!is_resource($this->fp)) { return $this->raiseError('not connected'); } $data = ''; while (!feof($this->fp)) { $data .= @fread($this->fp, $this->lineLength); } return $data; } /** * Runs the equivalent of the select() system call on the socket * with a timeout specified by tv_sec and tv_usec. * * @param integer $state Which of read/write/error to check for. * @param integer $tv_sec Number of seconds for timeout. * @param integer $tv_usec Number of microseconds for timeout. * * @access public * @return False if select fails, integer describing which of read/write/error * are ready, or PEAR_Error if not connected. */ function select($state, $tv_sec, $tv_usec = 0) { if (!is_resource($this->fp)) { return $this->raiseError('not connected'); } $read = null; $write = null; $except = null; if ($state & NET_SOCKET_READ) { $read[] = $this->fp; } if ($state & NET_SOCKET_WRITE) { $write[] = $this->fp; } if ($state & NET_SOCKET_ERROR) { $except[] = $this->fp; } if (false === ($sr = stream_select($read, $write, $except, $tv_sec, $tv_usec))) { return false; } $result = 0; if (count($read)) { $result |= NET_SOCKET_READ; } if (count($write)) { $result |= NET_SOCKET_WRITE; } if (count($except)) { $result |= NET_SOCKET_ERROR; } return $result; } /** * Turns encryption on/off on a connected socket. * * @param bool $enabled Set this parameter to true to enable encryption * and false to disable encryption. * @param integer $type Type of encryption. See stream_socket_enable_crypto() * for values. * * @see http://se.php.net/manual/en/function.stream-socket-enable-crypto.php * @access public * @return false on error, true on success and 0 if there isn't enough data * and the user should try again (non-blocking sockets only). * A PEAR_Error object is returned if the socket is not * connected */ function enableCrypto($enabled, $type) { if (version_compare(phpversion(), "5.1.0", ">=")) { if (!is_resource($this->fp)) { return $this->raiseError('not connected'); } return @stream_socket_enable_crypto($this->fp, $enabled, $type); } else { $msg = 'Net_Socket::enableCrypto() requires php version >= 5.1.0'; return $this->raiseError($msg); } } } includes/PEAR/Net/URL.php000064400000035426152214270100011006 0ustar00 | // +-----------------------------------------------------------------------+ // // $Id: URL.php,v 1.49 2007/06/28 14:43:07 davidc Exp $ // // Net_URL Class class Net_URL { var $options = array('encode_query_keys' => false); /** * Full url * @var string */ var $url; /** * Protocol * @var string */ var $protocol; /** * Username * @var string */ var $username; /** * Password * @var string */ var $password; /** * Host * @var string */ var $host; /** * Port * @var integer */ var $port; /** * Path * @var string */ var $path; /** * Query string * @var array */ var $querystring; /** * Anchor * @var string */ var $anchor; /** * Whether to use [] * @var bool */ var $useBrackets; /** * PHP5 Constructor * * Parses the given url and stores the various parts * Defaults are used in certain cases * * @param string $url Optional URL * @param bool $useBrackets Whether to use square brackets when * multiple querystrings with the same name * exist */ public function __construct($url = null, $useBrackets = true) { $this->url = $url; $this->useBrackets = $useBrackets; $this->initialize(); } function initialize() { $HTTP_SERVER_VARS = !empty($_SERVER) ? $_SERVER : $GLOBALS['HTTP_SERVER_VARS']; $this->user = ''; $this->pass = ''; $this->host = ''; $this->port = 80; $this->path = ''; $this->querystring = array(); $this->anchor = ''; // Only use defaults if not an absolute URL given if (!preg_match('/^[a-z0-9]+:\/\//i', $this->url)) { $this->protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on' ? 'https' : 'http'); /** * Figure out host/port */ if (!empty($HTTP_SERVER_VARS['HTTP_HOST']) && preg_match('/^(.*)(:([0-9]+))?$/U', $HTTP_SERVER_VARS['HTTP_HOST'], $matches)) { $host = $matches[1]; if (!empty($matches[3])) { $port = $matches[3]; } else { $port = $this->getStandardPort($this->protocol); } } $this->user = ''; $this->pass = ''; $this->host = !empty($host) ? $host : (isset($HTTP_SERVER_VARS['SERVER_NAME']) ? $HTTP_SERVER_VARS['SERVER_NAME'] : 'localhost'); $this->port = !empty($port) ? $port : (isset($HTTP_SERVER_VARS['SERVER_PORT']) ? $HTTP_SERVER_VARS['SERVER_PORT'] : $this->getStandardPort($this->protocol)); $this->path = !empty($HTTP_SERVER_VARS['PHP_SELF']) ? $HTTP_SERVER_VARS['PHP_SELF'] : '/'; $this->querystring = isset($HTTP_SERVER_VARS['QUERY_STRING']) ? $this->_parseRawQuerystring($HTTP_SERVER_VARS['QUERY_STRING']) : null; $this->anchor = ''; } // Parse the url and store the various parts if (!empty($this->url)) { $urlinfo = parse_url($this->url); // Default querystring $this->querystring = array(); foreach ($urlinfo as $key => $value) { switch ($key) { case 'scheme': $this->protocol = $value; $this->port = $this->getStandardPort($value); break; case 'user': case 'pass': case 'host': case 'port': $this->$key = $value; break; case 'path': if ($value[0] == '/') { $this->path = $value; } else { $path = dirname($this->path) == DIRECTORY_SEPARATOR ? '' : dirname($this->path); $this->path = sprintf('%s/%s', $path, $value); } break; case 'query': $this->querystring = $this->_parseRawQueryString($value); break; case 'fragment': $this->anchor = $value; break; } } } } /** * Returns full url * * @return string Full url * @access public */ function getURL() { $querystring = $this->getQueryString(); $this->url = $this->protocol . '://' . $this->user . (!empty($this->pass) ? ':' : '') . $this->pass . (!empty($this->user) ? '@' : '') . $this->host . ($this->port == $this->getStandardPort($this->protocol) ? '' : ':' . $this->port) . $this->path . (!empty($querystring) ? '?' . $querystring : '') . (!empty($this->anchor) ? '#' . $this->anchor : ''); return $this->url; } /** * Adds or updates a querystring item (URL parameter). * Automatically encodes parameters with rawurlencode() if $preencoded * is false. * You can pass an array to $value, it gets mapped via [] in the URL if * $this->useBrackets is activated. * * @param string $name Name of item * @param string $value Value of item * @param bool $preencoded Whether value is urlencoded or not, default = not * @access public */ function addQueryString($name, $value, $preencoded = false) { if ($this->getOption('encode_query_keys')) { $name = rawurlencode($name); } if ($preencoded) { $this->querystring[$name] = $value; } else { $this->querystring[$name] = is_array($value) ? array_map('rawurlencode', $value): rawurlencode($value); } } /** * Removes a querystring item * * @param string $name Name of item * @access public */ function removeQueryString($name) { if ($this->getOption('encode_query_keys')) { $name = rawurlencode($name); } if (isset($this->querystring[$name])) { unset($this->querystring[$name]); } } /** * Sets the querystring to literally what you supply * * @param string $querystring The querystring data. Should be of the format foo=bar&x=y etc * @access public */ function addRawQueryString($querystring) { $this->querystring = $this->_parseRawQueryString($querystring); } /** * Returns flat querystring * * @return string Querystring * @access public */ function getQueryString() { if (!empty($this->querystring)) { foreach ($this->querystring as $name => $value) { // Encode var name $name = rawurlencode($name); if (is_array($value)) { foreach ($value as $k => $v) { $querystring[] = $this->useBrackets ? sprintf('%s[%s]=%s', $name, $k, $v) : ($name . '=' . $v); } } elseif (!is_null($value)) { $querystring[] = $name . '=' . $value; } else { $querystring[] = $name; } } $querystring = implode(ini_get('arg_separator.output'), $querystring); } else { $querystring = ''; } return $querystring; } /** * Parses raw querystring and returns an array of it * * @param string $querystring The querystring to parse * @return array An array of the querystring data * @access private */ function _parseRawQuerystring($querystring) { $parts = preg_split('/[' . preg_quote(ini_get('arg_separator.input'), '/') . ']/', $querystring, -1, PREG_SPLIT_NO_EMPTY); $return = array(); foreach ($parts as $part) { if (strpos($part, '=') !== false) { $value = substr($part, strpos($part, '=') + 1); $key = substr($part, 0, strpos($part, '=')); } else { $value = null; $key = $part; } if (!$this->getOption('encode_query_keys')) { $key = rawurldecode($key); } if (preg_match('#^(.*)\[([0-9a-z_-]*)\]#i', $key, $matches)) { $key = $matches[1]; $idx = $matches[2]; // Ensure is an array if (empty($return[$key]) || !is_array($return[$key])) { $return[$key] = array(); } // Add data if ($idx === '') { $return[$key][] = $value; } else { $return[$key][$idx] = $value; } } elseif (!$this->useBrackets AND !empty($return[$key])) { $return[$key] = (array)$return[$key]; $return[$key][] = $value; } else { $return[$key] = $value; } } return $return; } /** * Resolves //, ../ and ./ from a path and returns * the result. Eg: * * /foo/bar/../boo.php => /foo/boo.php * /foo/bar/../../boo.php => /boo.php * /foo/bar/.././/boo.php => /foo/boo.php * * This method can also be called statically. * * @param string $path URL path to resolve * @return string The result */ function resolvePath($path) { $path = explode('/', str_replace('//', '/', $path)); for ($i=0; $i 1 OR ($i == 1 AND $path[0] != '') ) ) { unset($path[$i]); unset($path[$i-1]); $path = array_values($path); $i -= 2; } elseif ($path[$i] == '..' AND $i == 1 AND $path[0] == '') { unset($path[$i]); $path = array_values($path); $i--; } else { continue; } } return implode('/', $path); } /** * Returns the standard port number for a protocol * * @param string $scheme The protocol to lookup * @return integer Port number or NULL if no scheme matches * * @author Philippe Jausions */ function getStandardPort($scheme) { switch (strtolower($scheme)) { case 'http': return 80; case 'https': return 443; case 'ftp': return 21; case 'imap': return 143; case 'imaps': return 993; case 'pop3': return 110; case 'pop3s': return 995; default: return null; } } /** * Forces the URL to a particular protocol * * @param string $protocol Protocol to force the URL to * @param integer $port Optional port (standard port is used by default) */ function setProtocol($protocol, $port = null) { $this->protocol = $protocol; $this->port = is_null($port) ? $this->getStandardPort($protocol) : $port; } /** * Set an option * * This function set an option * to be used thorough the script. * * @access public * @param string $optionName The optionname to set * @param string $value The value of this option. */ function setOption($optionName, $value) { if (!array_key_exists($optionName, $this->options)) { return false; } $this->options[$optionName] = $value; $this->initialize(); } /** * Get an option * * This function gets an option * from the $this->options array * and return it's value. * * @access public * @param string $opionName The name of the option to retrieve * @see $this->options */ function getOption($optionName) { if (!isset($this->options[$optionName])) { return false; } return $this->options[$optionName]; } } ?> includes/PEAR/PEAR/Exception.php000064400000033315152214270100012276 0ustar00 * @author Hans Lellelid * @author Bertrand Mansion * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @link http://pear.php.net/package/PEAR * @since File available since Release 1.3.3 */ /** * Base PEAR_Exception Class * * 1) Features: * * - Nestable exceptions (throw new PEAR_Exception($msg, $prev_exception)) * - Definable triggers, shot when exceptions occur * - Pretty and informative error messages * - Added more context info available (like class, method or cause) * - cause can be a PEAR_Exception or an array of mixed * PEAR_Exceptions/PEAR_ErrorStack warnings * - callbacks for specific exception classes and their children * * 2) Ideas: * * - Maybe a way to define a 'template' for the output * * 3) Inherited properties from PHP Exception Class: * * protected $message * protected $code * protected $line * protected $file * private $trace * * 4) Inherited methods from PHP Exception Class: * * __clone * __construct * getMessage * getCode * getFile * getLine * getTraceSafe * getTraceSafeAsString * __toString * * 5) Usage example * * * require_once 'PEAR/Exception.php'; * * class Test { * function foo() { * throw new PEAR_Exception('Error Message', ERROR_CODE); * } * } * * function myLogger($pear_exception) { * echo $pear_exception->getMessage(); * } * // each time a exception is thrown the 'myLogger' will be called * // (its use is completely optional) * PEAR_Exception::addObserver('myLogger'); * $test = new Test; * try { * $test->foo(); * } catch (PEAR_Exception $e) { * print $e; * } * * * @category pear * @package PEAR * @author Tomas V.V.Cox * @author Hans Lellelid * @author Bertrand Mansion * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @version Release: 1.10.1 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.3.3 * */ class PEAR_Exception extends Exception { const OBSERVER_PRINT = -2; const OBSERVER_TRIGGER = -4; const OBSERVER_DIE = -8; protected $cause; private static $_observers = array(); private static $_uniqueid = 0; private $_trace; /** * Supported signatures: * - PEAR_Exception(string $message); * - PEAR_Exception(string $message, int $code); * - PEAR_Exception(string $message, Exception $cause); * - PEAR_Exception(string $message, Exception $cause, int $code); * - PEAR_Exception(string $message, PEAR_Error $cause); * - PEAR_Exception(string $message, PEAR_Error $cause, int $code); * - PEAR_Exception(string $message, array $causes); * - PEAR_Exception(string $message, array $causes, int $code); * @param string exception message * @param int|Exception|PEAR_Error|array|null exception cause * @param int|null exception code or null * @throws PEAR_Exception if PEAR_Error class not exists or Exception not type of PEAR_Error */ public function __construct($message, $p2 = null, $p3 = null) { if (is_int($p2)) { $code = $p2; $this->cause = null; } elseif (is_object($p2) || is_array($p2)) { // using is_object allows both Exception and PEAR_Error if (is_object($p2) && !($p2 instanceof Exception)) { if (!class_exists('PEAR_Error') || !($p2 instanceof PEAR_Error)) { throw new PEAR_Exception('exception cause must be Exception, ' . 'array, or PEAR_Error'); } } $code = $p3; if (is_array($p2) && isset($p2['message'])) { // fix potential problem of passing in a single warning $p2 = array($p2); } $this->cause = $p2; } else { $code = null; $this->cause = null; } parent::__construct($message, $code); $this->signal(); } /** * @param mixed $callback - A valid php callback, see php func is_callable() * - A PEAR_Exception::OBSERVER_* constant * - An array(const PEAR_Exception::OBSERVER_*, * mixed $options) * @param string $label The name of the observer. Use this if you want * to remove it later with removeObserver() */ public static function addObserver($callback, $label = 'default') { self::$_observers[$label] = $callback; } public static function removeObserver($label = 'default') { unset(self::$_observers[$label]); } /** * @return int unique identifier for an observer */ public static function getUniqueId() { return self::$_uniqueid++; } private function signal() { foreach (self::$_observers as $func) { if (is_callable($func)) { call_user_func($func, $this); continue; } settype($func, 'array'); switch ($func[0]) { case self::OBSERVER_PRINT : $f = (isset($func[1])) ? $func[1] : '%s'; printf($f, $this->getMessage()); break; case self::OBSERVER_TRIGGER : $f = (isset($func[1])) ? $func[1] : E_USER_NOTICE; trigger_error($this->getMessage(), $f); break; case self::OBSERVER_DIE : $f = (isset($func[1])) ? $func[1] : '%s'; die(printf($f, $this->getMessage())); break; default: trigger_error('invalid observer type', E_USER_WARNING); } } } /** * Return specific error information that can be used for more detailed * error messages or translation. * * This method may be overridden in child exception classes in order * to add functionality not present in PEAR_Exception and is a placeholder * to define API * * The returned array must be an associative array of parameter => value like so: *
     * array('name' => $name, 'context' => array(...))
     * 
* @return array */ public function getErrorData() { return array(); } /** * Returns the exception that caused this exception to be thrown * @access public * @return Exception|array The context of the exception */ public function getCause() { return $this->cause; } /** * Function must be public to call on caused exceptions * @param array */ public function getCauseMessage(&$causes) { $trace = $this->getTraceSafe(); $cause = array('class' => get_class($this), 'message' => $this->message, 'file' => 'unknown', 'line' => 'unknown'); if (isset($trace[0])) { if (isset($trace[0]['file'])) { $cause['file'] = $trace[0]['file']; $cause['line'] = $trace[0]['line']; } } $causes[] = $cause; if ($this->cause instanceof PEAR_Exception) { $this->cause->getCauseMessage($causes); } elseif ($this->cause instanceof Exception) { $causes[] = array('class' => get_class($this->cause), 'message' => $this->cause->getMessage(), 'file' => $this->cause->getFile(), 'line' => $this->cause->getLine()); } elseif (class_exists('PEAR_Error') && $this->cause instanceof PEAR_Error) { $causes[] = array('class' => get_class($this->cause), 'message' => $this->cause->getMessage(), 'file' => 'unknown', 'line' => 'unknown'); } elseif (is_array($this->cause)) { foreach ($this->cause as $cause) { if ($cause instanceof PEAR_Exception) { $cause->getCauseMessage($causes); } elseif ($cause instanceof Exception) { $causes[] = array('class' => get_class($cause), 'message' => $cause->getMessage(), 'file' => $cause->getFile(), 'line' => $cause->getLine()); } elseif (class_exists('PEAR_Error') && $cause instanceof PEAR_Error) { $causes[] = array('class' => get_class($cause), 'message' => $cause->getMessage(), 'file' => 'unknown', 'line' => 'unknown'); } elseif (is_array($cause) && isset($cause['message'])) { // PEAR_ErrorStack warning $causes[] = array( 'class' => $cause['package'], 'message' => $cause['message'], 'file' => isset($cause['context']['file']) ? $cause['context']['file'] : 'unknown', 'line' => isset($cause['context']['line']) ? $cause['context']['line'] : 'unknown', ); } } } } public function getTraceSafe() { if (!isset($this->_trace)) { $this->_trace = $this->getTrace(); if (empty($this->_trace)) { $backtrace = debug_backtrace(); $this->_trace = array($backtrace[count($backtrace)-1]); } } return $this->_trace; } public function getErrorClass() { $trace = $this->getTraceSafe(); return $trace[0]['class']; } public function getErrorMethod() { $trace = $this->getTraceSafe(); return $trace[0]['function']; } public function __toString() { if (isset($_SERVER['REQUEST_URI'])) { return $this->toHtml(); } return $this->toText(); } public function toHtml() { $trace = $this->getTraceSafe(); $causes = array(); $this->getCauseMessage($causes); $html = '' . "\n"; foreach ($causes as $i => $cause) { $html .= '\n"; } $html .= '' . "\n" . '' . '' . '' . "\n"; foreach ($trace as $k => $v) { $html .= '' . '' . '' . "\n"; } $html .= '' . '' . '' . "\n" . '
' . str_repeat('-', $i) . ' ' . $cause['class'] . ': ' . htmlspecialchars($cause['message']) . ' in ' . $cause['file'] . ' ' . 'on line ' . $cause['line'] . '' . "
Exception trace
#FunctionLocation
' . $k . ''; if (!empty($v['class'])) { $html .= $v['class'] . $v['type']; } $html .= $v['function']; $args = array(); if (!empty($v['args'])) { foreach ($v['args'] as $arg) { if (is_null($arg)) $args[] = 'null'; elseif (is_array($arg)) $args[] = 'Array'; elseif (is_object($arg)) $args[] = 'Object('.get_class($arg).')'; elseif (is_bool($arg)) $args[] = $arg ? 'true' : 'false'; elseif (is_int($arg) || is_double($arg)) $args[] = $arg; else { $arg = (string)$arg; $str = htmlspecialchars(substr($arg, 0, 16)); if (strlen($arg) > 16) $str .= '…'; $args[] = "'" . $str . "'"; } } } $html .= '(' . implode(', ',$args) . ')' . '' . (isset($v['file']) ? $v['file'] : 'unknown') . ':' . (isset($v['line']) ? $v['line'] : 'unknown') . '
' . ($k+1) . '{main} 
'; return $html; } public function toText() { $causes = array(); $this->getCauseMessage($causes); $causeMsg = ''; foreach ($causes as $i => $cause) { $causeMsg .= str_repeat(' ', $i) . $cause['class'] . ': ' . $cause['message'] . ' in ' . $cause['file'] . ' on line ' . $cause['line'] . "\n"; } return $causeMsg . $this->getTraceAsString(); } }includes/PEAR/PEAR.php000064400000101606152214270100010337 0ustar00 * @author Stig Bakken * @author Tomas V.V.Cox * @author Greg Beaver * @copyright 1997-2010 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License * @version CVS: $Id: PEAR.php 313023 2011-07-06 19:17:11Z dufuz $ * @link http://pear.php.net/package/PEAR * @since File available since Release 0.1 */ /**#@+ * ERROR constants */ define('PEAR_ERROR_RETURN', 1); define('PEAR_ERROR_PRINT', 2); define('PEAR_ERROR_TRIGGER', 4); define('PEAR_ERROR_DIE', 8); define('PEAR_ERROR_CALLBACK', 16); /** * WARNING: obsolete * @deprecated */ define('PEAR_ERROR_EXCEPTION', 32); /**#@-*/ define('PEAR_ZE2', (function_exists('version_compare') && version_compare(zend_version(), "2-dev", "ge"))); if (substr(PHP_OS, 0, 3) == 'WIN') { define('OS_WINDOWS', true); define('OS_UNIX', false); define('PEAR_OS', 'Windows'); } else { define('OS_WINDOWS', false); define('OS_UNIX', true); define('PEAR_OS', 'Unix'); // blatant assumption } $GLOBALS['_PEAR_default_error_mode'] = PEAR_ERROR_RETURN; $GLOBALS['_PEAR_default_error_options'] = E_USER_NOTICE; $GLOBALS['_PEAR_destructor_object_list'] = array(); $GLOBALS['_PEAR_shutdown_funcs'] = array(); $GLOBALS['_PEAR_error_handler_stack'] = array(); /** * Base class for other PEAR classes. Provides rudimentary * emulation of destructors. * * If you want a destructor in your class, inherit PEAR and make a * destructor method called _yourclassname (same name as the * constructor, but with a "_" prefix). Also, in your constructor you * have to call the PEAR constructor: parent::_construct();. * The destructor method will be called without parameters. Note that * at in some SAPI implementations (such as Apache), any output during * the request shutdown (in which destructors are called) seems to be * discarded. If you need to get any debug information from your * destructor, use error_log(), syslog() or something similar. * * IMPORTANT! To use the emulated destructors you need to create the * objects by reference: $obj =& new PEAR_child; * * @category pear * @package PEAR * @author Stig Bakken * @author Tomas V.V. Cox * @author Greg Beaver * @copyright 1997-2006 The PHP Group * @license http://opensource.org/licenses/bsd-license.php New BSD License * @version Release: 1.9.4 * @link http://pear.php.net/package/PEAR * @see PEAR_Error * @since Class available since PHP 4.0.2 * @link http://pear.php.net/manual/en/core.pear.php#core.pear.pear */ class PEAR { /** * Whether to enable internal debug messages. * * @var bool * @access private */ var $_debug = false; /** * Default error mode for this object. * * @var int * @access private */ var $_default_error_mode = null; /** * Default error options used for this object when error mode * is PEAR_ERROR_TRIGGER. * * @var int * @access private */ var $_default_error_options = null; /** * Default error handler (callback) for this object, if error mode is * PEAR_ERROR_CALLBACK. * * @var string * @access private */ var $_default_error_handler = ''; /** * Which class to use for error objects. * * @var string * @access private */ var $_error_class = 'PEAR_Error'; /** * An array of expected errors. * * @var array * @access private */ var $_expected_errors = array(); /** * Constructor. Registers this object in * $_PEAR_destructor_object_list for destructor emulation if a * destructor object exists. * * @param string $error_class (optional) which class to use for * error objects, defaults to PEAR_Error. * @access public * @return self */ public function __construct($error_class = null) { $classname = strtolower(get_class($this)); if ($this->_debug) { print "PEAR constructor called, class=$classname\n"; } if ($error_class !== null) { $this->_error_class = $error_class; } while ($classname && strcasecmp($classname, "pear")) { $destructor = "_$classname"; if (method_exists($this, $destructor)) { global $_PEAR_destructor_object_list; $_PEAR_destructor_object_list[] = &$this; if (!isset($GLOBALS['_PEAR_SHUTDOWN_REGISTERED'])) { register_shutdown_function("_PEAR_call_destructors"); $GLOBALS['_PEAR_SHUTDOWN_REGISTERED'] = true; } break; } else { $classname = get_parent_class($classname); } } } /** * Destructor (the emulated type of...). Does nothing right now, * but is included for forward compatibility, so subclass * destructors should always call it. * * See the note in the class desciption about output from * destructors. * * @access public * @return void */ public function __destruct() { if ($this->_debug) { printf("PEAR destructor called, class=%s\n", strtolower(get_class($this))); } } /** * If you have a class that's mostly/entirely static, and you need static * properties, you can use this method to simulate them. Eg. in your method(s) * do this: $myVar = &PEAR::getStaticProperty('myclass', 'myVar'); * You MUST use a reference, or they will not persist! * * @access public * @param string $class The calling classname, to prevent clashes * @param string $var The variable to retrieve. * @return mixed A reference to the variable. If not set it will be * auto initialised to NULL. */ static function &getStaticProperty($class, $var) { static $properties; if (!isset($properties[$class])) { $properties[$class] = array(); } if (!array_key_exists($var, $properties[$class])) { $properties[$class][$var] = null; } return $properties[$class][$var]; } /** * Use this function to register a shutdown method for static * classes. * * @access public * @param mixed $func The function name (or array of class/method) to call * @param mixed $args The arguments to pass to the function * @return void */ function registerShutdownFunc($func, $args = array()) { // if we are called statically, there is a potential // that no shutdown func is registered. Bug #6445 if (!isset($GLOBALS['_PEAR_SHUTDOWN_REGISTERED'])) { register_shutdown_function("_PEAR_call_destructors"); $GLOBALS['_PEAR_SHUTDOWN_REGISTERED'] = true; } $GLOBALS['_PEAR_shutdown_funcs'][] = array($func, $args); } /** * Tell whether a value is a PEAR error. * * @param mixed $data the value to test * @param int $code if $data is an error object, return true * only if $code is a string and * $obj->getMessage() == $code or * $code is an integer and $obj->getCode() == $code * @access public * @return bool true if parameter is an error */ static function isError($data, $code = null) { if (!is_a($data, 'PEAR_Error')) { return false; } if (is_null($code)) { return true; } elseif (is_string($code)) { return $data->getMessage() == $code; } return $data->getCode() == $code; } /** * Sets how errors generated by this object should be handled. * Can be invoked both in objects and statically. If called * statically, setErrorHandling sets the default behaviour for all * PEAR objects. If called in an object, setErrorHandling sets * the default behaviour for that object. * * @param int $mode * One of PEAR_ERROR_RETURN, PEAR_ERROR_PRINT, * PEAR_ERROR_TRIGGER, PEAR_ERROR_DIE, * PEAR_ERROR_CALLBACK or PEAR_ERROR_EXCEPTION. * * @param mixed $options * When $mode is PEAR_ERROR_TRIGGER, this is the error level (one * of E_USER_NOTICE, E_USER_WARNING or E_USER_ERROR). * * When $mode is PEAR_ERROR_CALLBACK, this parameter is expected * to be the callback function or method. A callback * function is a string with the name of the function, a * callback method is an array of two elements: the element * at index 0 is the object, and the element at index 1 is * the name of the method to call in the object. * * When $mode is PEAR_ERROR_PRINT or PEAR_ERROR_DIE, this is * a printf format string used when printing the error * message. * * @access public * @return void * @see PEAR_ERROR_RETURN * @see PEAR_ERROR_PRINT * @see PEAR_ERROR_TRIGGER * @see PEAR_ERROR_DIE * @see PEAR_ERROR_CALLBACK * @see PEAR_ERROR_EXCEPTION * * @since PHP 4.0.5 */ function setErrorHandling($mode = null, $options = null) { if (isset($this) && is_a($this, 'PEAR')) { $setmode = &$this->_default_error_mode; $setoptions = &$this->_default_error_options; } else { $setmode = &$GLOBALS['_PEAR_default_error_mode']; $setoptions = &$GLOBALS['_PEAR_default_error_options']; } switch ($mode) { case PEAR_ERROR_EXCEPTION: case PEAR_ERROR_RETURN: case PEAR_ERROR_PRINT: case PEAR_ERROR_TRIGGER: case PEAR_ERROR_DIE: case null: $setmode = $mode; $setoptions = $options; break; case PEAR_ERROR_CALLBACK: $setmode = $mode; // class/object method callback if (is_callable($options)) { $setoptions = $options; } else { trigger_error("invalid error callback", E_USER_WARNING); } break; default: trigger_error("invalid error mode", E_USER_WARNING); break; } } /** * This method is used to tell which errors you expect to get. * Expected errors are always returned with error mode * PEAR_ERROR_RETURN. Expected error codes are stored in a stack, * and this method pushes a new element onto it. The list of * expected errors are in effect until they are popped off the * stack with the popExpect() method. * * Note that this method can not be called statically * * @param mixed $code a single error code or an array of error codes to expect * * @return int the new depth of the "expected errors" stack * @access public */ function expectError($code = '*') { if (is_array($code)) { array_push($this->_expected_errors, $code); } else { array_push($this->_expected_errors, array($code)); } return count($this->_expected_errors); } /** * This method pops one element off the expected error codes * stack. * * @return array the list of error codes that were popped */ function popExpect() { return array_pop($this->_expected_errors); } /** * This method checks unsets an error code if available * * @param mixed error code * @return bool true if the error code was unset, false otherwise * @access private * @since PHP 4.3.0 */ function _checkDelExpect($error_code) { $deleted = false; foreach ($this->_expected_errors as $key => $error_array) { if (in_array($error_code, $error_array)) { unset($this->_expected_errors[$key][array_search($error_code, $error_array)]); $deleted = true; } // clean up empty arrays if (0 == count($this->_expected_errors[$key])) { unset($this->_expected_errors[$key]); } } return $deleted; } /** * This method deletes all occurences of the specified element from * the expected error codes stack. * * @param mixed $error_code error code that should be deleted * @return mixed list of error codes that were deleted or error * @access public * @since PHP 4.3.0 */ function delExpect($error_code) { $deleted = false; if ((is_array($error_code) && (0 != count($error_code)))) { // $error_code is a non-empty array here; we walk through it trying // to unset all values foreach ($error_code as $key => $error) { $deleted = $this->_checkDelExpect($error) ? true : false; } return $deleted ? true : PEAR::raiseError("The expected error you submitted does not exist"); // IMPROVE ME } elseif (!empty($error_code)) { // $error_code comes alone, trying to unset it if ($this->_checkDelExpect($error_code)) { return true; } return PEAR::raiseError("The expected error you submitted does not exist"); // IMPROVE ME } // $error_code is empty return PEAR::raiseError("The expected error you submitted is empty"); // IMPROVE ME } /** * This method is a wrapper that returns an instance of the * configured error class with this object's default error * handling applied. If the $mode and $options parameters are not * specified, the object's defaults are used. * * @param mixed $message a text error message or a PEAR error object * * @param int $code a numeric error code (it is up to your class * to define these if you want to use codes) * * @param int $mode One of PEAR_ERROR_RETURN, PEAR_ERROR_PRINT, * PEAR_ERROR_TRIGGER, PEAR_ERROR_DIE, * PEAR_ERROR_CALLBACK, PEAR_ERROR_EXCEPTION. * * @param mixed $options If $mode is PEAR_ERROR_TRIGGER, this parameter * specifies the PHP-internal error level (one of * E_USER_NOTICE, E_USER_WARNING or E_USER_ERROR). * If $mode is PEAR_ERROR_CALLBACK, this * parameter specifies the callback function or * method. In other error modes this parameter * is ignored. * * @param string $userinfo If you need to pass along for example debug * information, this parameter is meant for that. * * @param string $error_class The returned error object will be * instantiated from this class, if specified. * * @param bool $skipmsg If true, raiseError will only pass error codes, * the error message parameter will be dropped. * * @access public * @return object a PEAR error object * @see PEAR::setErrorHandling * @since PHP 4.0.5 */ function &raiseError($message = null, $code = null, $mode = null, $options = null, $userinfo = null, $error_class = null, $skipmsg = false) { // The error is yet a PEAR error object if (is_object($message)) { $code = $message->getCode(); $userinfo = $message->getUserInfo(); $error_class = $message->getType(); $message->error_message_prefix = ''; $message = $message->getMessage(); } if ( isset($this) && isset($this->_expected_errors) && count($this->_expected_errors) > 0 && count($exp = end($this->_expected_errors)) ) { if ($exp[0] == "*" || (is_int(reset($exp)) && in_array($code, $exp)) || (is_string(reset($exp)) && in_array($message, $exp)) ) { $mode = PEAR_ERROR_RETURN; } } // No mode given, try global ones if ($mode === null) { // Class error handler if (isset($this) && isset($this->_default_error_mode)) { $mode = $this->_default_error_mode; $options = $this->_default_error_options; // Global error handler } elseif (isset($GLOBALS['_PEAR_default_error_mode'])) { $mode = $GLOBALS['_PEAR_default_error_mode']; $options = $GLOBALS['_PEAR_default_error_options']; } } if ($error_class !== null) { $ec = $error_class; } elseif (isset($this) && isset($this->_error_class)) { $ec = $this->_error_class; } else { $ec = 'PEAR_Error'; } if (intval(PHP_VERSION) < 5) { // little non-eval hack to fix bug #12147 include 'PEAR/FixPHP5PEARWarnings.php'; return $a; } if ($skipmsg) { $a = new $ec($code, $mode, $options, $userinfo); } else { $a = new $ec($message, $code, $mode, $options, $userinfo); } return $a; } /** * Simpler form of raiseError with fewer options. In most cases * message, code and userinfo are enough. * * @param mixed $message a text error message or a PEAR error object * * @param int $code a numeric error code (it is up to your class * to define these if you want to use codes) * * @param string $userinfo If you need to pass along for example debug * information, this parameter is meant for that. * * @access public * @return object a PEAR error object * @see PEAR::raiseError */ function &throwError($message = null, $code = null, $userinfo = null) { if (isset($this) && is_a($this, 'PEAR')) { $a = &$this->raiseError($message, $code, null, null, $userinfo); return $a; } $a = &PEAR::raiseError($message, $code, null, null, $userinfo); return $a; } function staticPushErrorHandling($mode, $options = null) { $stack = &$GLOBALS['_PEAR_error_handler_stack']; $def_mode = &$GLOBALS['_PEAR_default_error_mode']; $def_options = &$GLOBALS['_PEAR_default_error_options']; $stack[] = array($def_mode, $def_options); switch ($mode) { case PEAR_ERROR_EXCEPTION: case PEAR_ERROR_RETURN: case PEAR_ERROR_PRINT: case PEAR_ERROR_TRIGGER: case PEAR_ERROR_DIE: case null: $def_mode = $mode; $def_options = $options; break; case PEAR_ERROR_CALLBACK: $def_mode = $mode; // class/object method callback if (is_callable($options)) { $def_options = $options; } else { trigger_error("invalid error callback", E_USER_WARNING); } break; default: trigger_error("invalid error mode", E_USER_WARNING); break; } $stack[] = array($mode, $options); return true; } function staticPopErrorHandling() { $stack = &$GLOBALS['_PEAR_error_handler_stack']; $setmode = &$GLOBALS['_PEAR_default_error_mode']; $setoptions = &$GLOBALS['_PEAR_default_error_options']; array_pop($stack); list($mode, $options) = $stack[sizeof($stack) - 1]; array_pop($stack); switch ($mode) { case PEAR_ERROR_EXCEPTION: case PEAR_ERROR_RETURN: case PEAR_ERROR_PRINT: case PEAR_ERROR_TRIGGER: case PEAR_ERROR_DIE: case null: $setmode = $mode; $setoptions = $options; break; case PEAR_ERROR_CALLBACK: $setmode = $mode; // class/object method callback if (is_callable($options)) { $setoptions = $options; } else { trigger_error("invalid error callback", E_USER_WARNING); } break; default: trigger_error("invalid error mode", E_USER_WARNING); break; } return true; } /** * Push a new error handler on top of the error handler options stack. With this * you can easily override the actual error handler for some code and restore * it later with popErrorHandling. * * @param mixed $mode (same as setErrorHandling) * @param mixed $options (same as setErrorHandling) * * @return bool Always true * * @see PEAR::setErrorHandling */ function pushErrorHandling($mode, $options = null) { $stack = &$GLOBALS['_PEAR_error_handler_stack']; if (isset($this) && is_a($this, 'PEAR')) { $def_mode = &$this->_default_error_mode; $def_options = &$this->_default_error_options; } else { $def_mode = &$GLOBALS['_PEAR_default_error_mode']; $def_options = &$GLOBALS['_PEAR_default_error_options']; } $stack[] = array($def_mode, $def_options); if (isset($this) && is_a($this, 'PEAR')) { $this->setErrorHandling($mode, $options); } else { PEAR::setErrorHandling($mode, $options); } $stack[] = array($mode, $options); return true; } /** * Pop the last error handler used * * @return bool Always true * * @see PEAR::pushErrorHandling */ function popErrorHandling() { $stack = &$GLOBALS['_PEAR_error_handler_stack']; array_pop($stack); list($mode, $options) = $stack[sizeof($stack) - 1]; array_pop($stack); if (isset($this) && is_a($this, 'PEAR')) { $this->setErrorHandling($mode, $options); } else { PEAR::setErrorHandling($mode, $options); } return true; } /** * OS independant PHP extension load. Remember to take care * on the correct extension name for case sensitive OSes. * * @param string $ext The extension name * @return bool Success or not on the dl() call */ function loadExtension($ext) { if (extension_loaded($ext)) { return true; } // if either returns true dl() will produce a FATAL error, stop that if ( function_exists('dl') === false || ini_get('enable_dl') != 1 || ini_get('safe_mode') == 1 ) { return false; } if (OS_WINDOWS) { $suffix = '.dll'; } elseif (PHP_OS == 'HP-UX') { $suffix = '.sl'; } elseif (PHP_OS == 'AIX') { $suffix = '.a'; } elseif (PHP_OS == 'OSX') { $suffix = '.bundle'; } else { $suffix = '.so'; } return @dl('php_'.$ext.$suffix) || @dl($ext.$suffix); } } if (PEAR_ZE2) { include_once 'PEAR5.php'; } function _PEAR_call_destructors() { global $_PEAR_destructor_object_list; if (is_array($_PEAR_destructor_object_list) && sizeof($_PEAR_destructor_object_list)) { reset($_PEAR_destructor_object_list); if (PEAR_ZE2) { $destructLifoExists = PEAR5::getStaticProperty('PEAR', 'destructlifo'); } else { $destructLifoExists = PEAR::getStaticProperty('PEAR', 'destructlifo'); } if ($destructLifoExists) { $_PEAR_destructor_object_list = array_reverse($_PEAR_destructor_object_list); } foreach ($_PEAR_destructor_object_list as $k => $objref) { $classname = get_class($objref); while ($classname) { $destructor = "_$classname"; if (method_exists($objref, $destructor)) { $objref->$destructor(); break; } else { $classname = get_parent_class($classname); } } } // Empty the object list to ensure that destructors are // not called more than once. $_PEAR_destructor_object_list = array(); } // Now call the shutdown functions if ( isset($GLOBALS['_PEAR_shutdown_funcs']) && is_array($GLOBALS['_PEAR_shutdown_funcs']) && !empty($GLOBALS['_PEAR_shutdown_funcs']) ) { foreach ($GLOBALS['_PEAR_shutdown_funcs'] as $value) { call_user_func_array($value[0], $value[1]); } } } /** * Standard PEAR error class for PHP 4 * * This class is supserseded by {@link PEAR_Exception} in PHP 5 * * @category pear * @package PEAR * @author Stig Bakken * @author Tomas V.V. Cox * @author Gregory Beaver * @copyright 1997-2006 The PHP Group * @license http://opensource.org/licenses/bsd-license.php New BSD License * @version Release: 1.9.4 * @link http://pear.php.net/manual/en/core.pear.pear-error.php * @see PEAR::raiseError(), PEAR::throwError() * @since Class available since PHP 4.0.2 */ class PEAR_Error { var $error_message_prefix = ''; var $mode = PEAR_ERROR_RETURN; var $level = E_USER_NOTICE; var $code = -1; var $message = ''; var $userinfo = ''; var $backtrace = null; /** * PEAR_Error constructor * * @param string $message message * * @param int $code (optional) error code * * @param int $mode (optional) error mode, one of: PEAR_ERROR_RETURN, * PEAR_ERROR_PRINT, PEAR_ERROR_DIE, PEAR_ERROR_TRIGGER, * PEAR_ERROR_CALLBACK or PEAR_ERROR_EXCEPTION * * @param mixed $options (optional) error level, _OR_ in the case of * PEAR_ERROR_CALLBACK, the callback function or object/method * tuple. * * @param string $userinfo (optional) additional user/debug info * * @access public * */ function __construct($message = 'unknown error', $code = null, $mode = null, $options = null, $userinfo = null) { if ($mode === null) { $mode = PEAR_ERROR_RETURN; } $this->message = $message; $this->code = $code; $this->mode = $mode; $this->userinfo = $userinfo; if (PEAR_ZE2) { $skiptrace = PEAR5::getStaticProperty('PEAR_Error', 'skiptrace'); } else { $skiptrace = PEAR::getStaticProperty('PEAR_Error', 'skiptrace'); } if (!$skiptrace) { $this->backtrace = debug_backtrace(); if (isset($this->backtrace[0]) && isset($this->backtrace[0]['object'])) { unset($this->backtrace[0]['object']); } } if ($mode & PEAR_ERROR_CALLBACK) { $this->level = E_USER_NOTICE; $this->callback = $options; } else { if ($options === null) { $options = E_USER_NOTICE; } $this->level = $options; $this->callback = null; } if ($this->mode & PEAR_ERROR_PRINT) { if (is_null($options) || is_int($options)) { $format = "%s"; } else { $format = $options; } printf($format, $this->getMessage()); } if ($this->mode & PEAR_ERROR_TRIGGER) { trigger_error($this->getMessage(), $this->level); } if ($this->mode & PEAR_ERROR_DIE) { $msg = $this->getMessage(); if (is_null($options) || is_int($options)) { $format = "%s"; if (substr($msg, -1) != "\n") { $msg .= "\n"; } } else { $format = $options; } die(sprintf($format, $msg)); } if ($this->mode & PEAR_ERROR_CALLBACK && is_callable($this->callback)) { call_user_func($this->callback, $this); } if ($this->mode & PEAR_ERROR_EXCEPTION) { trigger_error("PEAR_ERROR_EXCEPTION is obsolete, use class PEAR_Exception for exceptions", E_USER_WARNING); eval('$e = new Exception($this->message, $this->code);throw($e);'); } } /** * Get the error mode from an error object. * * @return int error mode * @access public */ function getMode() { return $this->mode; } /** * Get the callback function/method from an error object. * * @return mixed callback function or object/method array * @access public */ function getCallback() { return $this->callback; } /** * Get the error message from an error object. * * @return string full error message * @access public */ function getMessage() { return ($this->error_message_prefix . $this->message); } /** * Get error code from an error object * * @return int error code * @access public */ function getCode() { return $this->code; } /** * Get the name of this error/exception. * * @return string error/exception name (type) * @access public */ function getType() { return get_class($this); } /** * Get additional user-supplied information. * * @return string user-supplied information * @access public */ function getUserInfo() { return $this->userinfo; } /** * Get additional debug information supplied by the application. * * @return string debug information * @access public */ function getDebugInfo() { return $this->getUserInfo(); } /** * Get the call backtrace from where the error was generated. * Supported with PHP 4.3.0 or newer. * * @param int $frame (optional) what frame to fetch * @return array Backtrace, or NULL if not available. * @access public */ function getBacktrace($frame = null) { if (defined('PEAR_IGNORE_BACKTRACE')) { return null; } if ($frame === null) { return $this->backtrace; } return $this->backtrace[$frame]; } function addUserInfo($info) { if (empty($this->userinfo)) { $this->userinfo = $info; } else { $this->userinfo .= " ** $info"; } } function __toString() { return $this->getMessage(); } /** * Make a string representation of this object. * * @return string a string with an object summary * @access public */ function toString() { $modes = array(); $levels = array(E_USER_NOTICE => 'notice', E_USER_WARNING => 'warning', E_USER_ERROR => 'error'); if ($this->mode & PEAR_ERROR_CALLBACK) { if (is_array($this->callback)) { $callback = (is_object($this->callback[0]) ? strtolower(get_class($this->callback[0])) : $this->callback[0]) . '::' . $this->callback[1]; } else { $callback = $this->callback; } return sprintf('[%s: message="%s" code=%d mode=callback '. 'callback=%s prefix="%s" info="%s"]', strtolower(get_class($this)), $this->message, $this->code, $callback, $this->error_message_prefix, $this->userinfo); } if ($this->mode & PEAR_ERROR_PRINT) { $modes[] = 'print'; } if ($this->mode & PEAR_ERROR_TRIGGER) { $modes[] = 'trigger'; } if ($this->mode & PEAR_ERROR_DIE) { $modes[] = 'die'; } if ($this->mode & PEAR_ERROR_RETURN) { $modes[] = 'return'; } return sprintf('[%s: message="%s" code=%d mode=%s level=%s '. 'prefix="%s" info="%s"]', strtolower(get_class($this)), $this->message, $this->code, implode("|", $modes), $levels[$this->level], $this->error_message_prefix, $this->userinfo); } } /* * Local Variables: * mode: php * tab-width: 4 * c-basic-offset: 4 * End: */ includes/PEAR/PEAR5.php000064400000002077152214270100010426 0ustar00 * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @link https://github.com/windowsazure/azure-sdk-for-php */ namespace WindowsAzure\Blob\Internal; use WindowsAzure\Common\Internal\FilterableService; /** * This interface has all REST APIs provided by Windows Azure for Blob service. * * @category Microsoft * @package WindowsAzure\Blob\Internal * @author Azure PHP SDK * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @version Release: 0.4.1_2015-03 * @link https://github.com/windowsazure/azure-sdk-for-php * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd135733.aspx */ interface IBlob extends FilterableService { /** * Gets the properties of the Blob service. * * @param Models\BlobServiceOptions $options optional blob service options. * * @return WindowsAzure\Common\Models\GetServicePropertiesResult * * @see http://msdn.microsoft.com/en-us/library/windowsazure/hh452239.aspx */ public function getServiceProperties($options = null); /** * Sets the properties of the Blob service. * * @param ServiceProperties $serviceProperties new service properties * @param Models\BlobServiceOptions $options optional parameters * * @return none. * * @see http://msdn.microsoft.com/en-us/library/windowsazure/hh452235.aspx */ public function setServiceProperties($serviceProperties, $options = null); /** * Lists all of the containers in the given storage account. * * @param Models\ListContainersOptions $options optional parameters * * @return WindowsAzure\Blob\Models\ListContainersResult * * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179352.aspx */ public function listContainers($options = null); /** * Creates a new container in the given storage account. * * @param string $container name * @param Models\CreateContainerOptions $options optional parameters * * @return none. * * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179468.aspx */ public function createContainer($container, $options = null); /** * Creates a new container in the given storage account. * * @param string $container name * @param Models\DeleteContainerOptions $options optional parameters * * @return none. * * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179408.aspx */ public function deleteContainer($container, $options = null); /** * Returns all properties and metadata on the container. * * @param string $container name * @param Models\BlobServiceOptions $options optional parameters * * @return Models\GetContainerPropertiesResult * * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179370.aspx */ public function getContainerProperties($container, $options = null); /** * Returns only user-defined metadata for the specified container. * * @param string $container name * @param Models\BlobServiceOptions $options optional parameters * * @return Models\GetContainerPropertiesResult * * @see http://msdn.microsoft.com/en-us/library/windowsazure/ee691976.aspx */ public function getContainerMetadata($container, $options = null); /** * Gets the access control list (ACL) and any container-level access policies * for the container. * * @param string $container name * @param Models\BlobServiceOptions $options optional parameters * * @return Models\GetContainerAclResult * * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179469.aspx */ public function getContainerAcl($container, $options = null); /** * Sets the ACL and any container-level access policies for the container. * * @param string $container name * @param Models\ContainerAcl $acl access control list for container * @param Models\BlobServiceOptions $options optional parameters * * @return none. * * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179391.aspx */ public function setContainerAcl($container, $acl, $options = null); /** * Sets metadata headers on the container. * * @param string $container name * @param array $metadata metadata key/value pair. * @param Models\SetContainerMetadataOptions $options optional parameters * * @return none. * * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179362.aspx */ public function setContainerMetadata($container, $metadata, $options = null); /** * Lists all of the blobs in the given container. * * @param string $container name * @param Models\ListBlobsOptions $options optional parameters * * @return Models\ListBlobsResult * * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd135734.aspx */ public function listBlobs($container, $options = null); /** * Creates a new page blob. Note that calling createPageBlob to create a page * blob only initializes the blob. * To add content to a page blob, call createBlobPages method. * * @param string $container name of the container * @param string $blob name of the blob * @param int $length specifies the maximum size for the * page blob, up to 1 TB. The page blob size must be aligned to a 512-byte * boundary. * @param Models\CreateBlobOptions $options optional parameters * * @return CopyBlobResult * * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179451.aspx */ public function createPageBlob($container, $blob, $length, $options = null); /** * Creates a new block blob or updates the content of an existing block blob. * Updating an existing block blob overwrites any existing metadata on the blob. * Partial updates are not supported with createBlockBlob; the content of the * existing blob is overwritten with the content of the new blob. To perform a * partial update of the content of a block blob, use the createBlockList method. * * @param string $container name of the container * @param string $blob name of the blob * @param string $content content of the blob * @param Models\CreateBlobOptions $options optional parameters * * @return CopyBlobResult * * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179451.aspx */ public function createBlockBlob($container, $blob, $content, $options = null); /** * Clears a range of pages from the blob. * * @param string $container name of the container * @param string $blob name of the blob * @param Models\PageRange $range Can be up to the value of the * blob's full size. * @param Models\CreateBlobPagesOptions $options optional parameters * * @return Models\CreateBlobPagesResult. * * @see http://msdn.microsoft.com/en-us/library/windowsazure/ee691975.aspx */ public function clearBlobPages($container, $blob, $range, $options = null); /** * Creates a range of pages to a page blob. * * @param string $container name of the container * @param string $blob name of the blob * @param Models\PageRange $range Can be up to 4 MB in size * @param string $content the blob contents * @param Models\CreateBlobPagesOptions $options optional parameters * * @return Models\CreateBlobPagesResult. * * @see http://msdn.microsoft.com/en-us/library/windowsazure/ee691975.aspx */ public function createBlobPages($container, $blob, $range, $content, $options = null ); /** * Creates a new block to be committed as part of a block blob. * * @param string $container name of the container * @param string $blob name of the blob * @param string $blockId must be less than or equal to * 64 bytes in size. For a given blob, the length of the value specified for the * blockid parameter must be the same size for each block. * @param string $content the blob block contents * @param Models\CreateBlobBlockOptions $options optional parameters * * @return none. * * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd135726.aspx */ public function createBlobBlock($container, $blob, $blockId, $content, $options = null ); /** * This method writes a blob by specifying the list of block IDs that make up the * blob. In order to be written as part of a blob, a block must have been * successfully written to the server in a prior createBlobBlock method. * * You can call Put Block List to update a blob by uploading only those blocks * that have changed, then committing the new and existing blocks together. * You can do this by specifying whether to commit a block from the committed * block list or from the uncommitted block list, or to commit the most recently * uploaded version of the block, whichever list it may belong to. * * @param string $container name of the container * @param string $blob name of the blob * @param Models\BlockList $blockList the block list entries * @param Models\CommitBlobBlocksOptions $options optional parameters * * @return none. * * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179467.aspx */ public function commitBlobBlocks($container, $blob, $blockList, $options = null); /** * Retrieves the list of blocks that have been uploaded as part of a block blob. * * There are two block lists maintained for a blob: * 1) Committed Block List: The list of blocks that have been successfully * committed to a given blob with commitBlobBlocks. * 2) Uncommitted Block List: The list of blocks that have been uploaded for a * blob using Put Block (REST API), but that have not yet been committed. * These blocks are stored in Windows Azure in association with a blob, but do * not yet form part of the blob. * * @param string $container name of the container * @param string $blob name of the blob * @param Models\ListBlobBlocksOptions $options optional parameters * * @return Models\ListBlobBlocksResult * * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179400.aspx */ public function listBlobBlocks($container, $blob, $options = null); /** * Returns all properties and metadata on the blob. * * @param string $container name of the container * @param string $blob name of the blob * @param Models\GetBlobPropertiesOptions $options optional parameters * * @return Models\GetBlobPropertiesResult * * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179394.aspx */ public function getBlobProperties($container, $blob, $options = null); /** * Returns all properties and metadata on the blob. * * @param string $container name of the container * @param string $blob name of the blob * @param Models\GetBlobMetadataOptions $options optional parameters * * @return Models\GetBlobMetadataResult * * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179350.aspx */ public function getBlobMetadata($container, $blob, $options = null); /** * Returns a list of active page ranges for a page blob. Active page ranges are * those that have been populated with data. * * @param string $container name of the container * @param string $blob name of the blob * @param Models\ListPageBlobRangesOptions $options optional parameters * * @return Models\ListPageBlobRangesResult * * @see http://msdn.microsoft.com/en-us/library/windowsazure/ee691973.aspx */ public function listPageBlobRanges($container, $blob, $options = null); /** * Sets system properties defined for a blob. * * @param string $container name of the container * @param string $blob name of the blob * @param Models\SetBlobPropertiesOptions $options optional parameters * * @return Models\SetBlobPropertiesResult * * @see http://msdn.microsoft.com/en-us/library/windowsazure/ee691966.aspx */ public function setBlobProperties($container, $blob, $options = null); /** * Sets metadata headers on the blob. * * @param string $container name of the container * @param string $blob name of the blob * @param array $metadata key/value pair representation * @param Models\SetBlobMetadataOptions $options optional parameters * * @return Models\SetBlobMetadataResult * * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179414.aspx */ public function setBlobMetadata($container, $blob, $metadata, $options = null); /** * Reads or downloads a blob from the system, including its metadata and * properties. * * @param string $container name of the container * @param string $blob name of the blob * @param Models\GetBlobOptions $options optional parameters * * @return Models\GetBlobResult * * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179440.aspx */ public function getBlob($container, $blob, $options = null); /** * Deletes a blob or blob snapshot. * * Note that if the snapshot entry is specified in the $options then only this * blob snapshot is deleted. To delete all blob snapshots, do not set Snapshot * and just set getDeleteSnaphotsOnly to true. * * @param string $container name of the container * @param string $blob name of the blob * @param Models\DeleteBlobOptions $options optional parameters * * @return none * * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179413.aspx */ public function deleteBlob($container, $blob, $options = null); /** * Creates a snapshot of a blob. * * @param string $container name of the container * @param string $blob name of the blob * @param Models\CreateBlobSnapshotOptions $options optional parameters * * @return Models\CreateBlobSnapshotResult * * @see http://msdn.microsoft.com/en-us/library/windowsazure/ee691971.aspx */ public function createBlobSnapshot($container, $blob, $options = null); /** * Copies a source blob to a destination blob within the same storage account. * * @param string $destinationContainer name of container * @param string $destinationBlob name of blob * @param string $sourceContainer name of container * @param string $sourceBlob name of blob * @param Models\CopyBlobOptions $options optional parameters * * @return CopyBlobResult * * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd894037.aspx */ public function copyBlob($destinationContainer, $destinationBlob, $sourceContainer, $sourceBlob, $options = null ); /** * Establishes an exclusive one-minute write lock on a blob. To write to a locked * blob, a client must provide a lease ID. * * @param string $container name of the container * @param string $blob name of the blob * @param Models\AcquireLeaseOptions $options optional parameters * * @return Models\AcquireLeaseResult * * @see http://msdn.microsoft.com/en-us/library/windowsazure/ee691972.aspx */ public function acquireLease($container, $blob, $options = null); /** * Renews an existing lease * * @param string $container name of the container * @param string $blob name of the blob * @param string $leaseId lease id when acquiring * @param Models\BlobServiceOptions $options optional parameters * * @return Models\AcquireLeaseResult * * @see http://msdn.microsoft.com/en-us/library/windowsazure/ee691972.aspx */ public function renewLease($container, $blob, $leaseId, $options = null); /** * Frees the lease if it is no longer needed so that another client may * immediately acquire a lease against the blob. * * @param string $container name of the container * @param string $blob name of the blob * @param string $leaseId lease id when acquiring * @param Models\BlobServiceOptions $options optional parameters * * @return none * * @see http://msdn.microsoft.com/en-us/library/windowsazure/ee691972.aspx */ public function releaseLease($container, $blob, $leaseId, $options = null); /** * Ends the lease but ensure that another client cannot acquire a new lease until * the current lease period has expired. * * @param string $container name of the container * @param string $blob name of the blob * @param Models\BlobServiceOptions $options optional parameters * * @return none * * @see http://msdn.microsoft.com/en-us/library/windowsazure/ee691972.aspx */ public function breakLease($container, $blob, $options = null); } includes/WindowsAzure/Blob/Models/GetContainerACLResult.php000064400000006626152214270100017732 0ustar00 * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @link https://github.com/windowsazure/azure-sdk-for-php */ namespace WindowsAzure\Blob\Models; use WindowsAzure\Blob\Models\ContainerAcl; /** * Holds container ACL * * @category Microsoft * @package WindowsAzure\Blob\Models * @author Azure PHP SDK * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @version Release: 0.4.1_2015-03 * @link https://github.com/windowsazure/azure-sdk-for-php */ class GetContainerAclResult { /** * @var ContainerAcl */ private $_containerACL; /** * @var \DateTime */ private $_lastModified; /** * @var string */ private $_etag; /** * Parses the given array into signed identifiers * * @param string $publicAccess container public access * @param string $etag container etag * @param \DateTime $lastModified last modification date * @param array $parsed parsed response into array * representation * * @return none. */ public static function create($publicAccess, $etag, $lastModified, $parsed) { $result = new GetContainerAclResult(); $result->setETag($etag); $result->setLastModified($lastModified); $acl = ContainerAcl::create($publicAccess, $parsed); $result->setContainerAcl($acl); return $result; } /** * Gets container ACL * * @return ContainerAcl */ public function getContainerAcl() { return $this->_containerACL; } /** * Sets container ACL * * @param ContainerAcl $containerACL value. * * @return none. */ public function setContainerAcl($containerACL) { $this->_containerACL = $containerACL; } /** * Gets container lastModified. * * @return \DateTime. */ public function getLastModified() { return $this->_lastModified; } /** * Sets container lastModified. * * @param \DateTime $lastModified value. * * @return none. */ public function setLastModified($lastModified) { $this->_lastModified = $lastModified; } /** * Gets container etag. * * @return string. */ public function getETag() { return $this->_etag; } /** * Sets container etag. * * @param string $etag value. * * @return none. */ public function setETag($etag) { $this->_etag = $etag; } } includes/WindowsAzure/Blob/Models/SetBlobPropertiesResult.php000064400000007210152214270100020425 0ustar00 * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @link https://github.com/windowsazure/azure-sdk-for-php */ namespace WindowsAzure\Blob\Models; use WindowsAzure\Common\Internal\Resources; use WindowsAzure\Common\Internal\Validate; use WindowsAzure\Common\Internal\Utilities; /** * Holds result of calling setBlobProperties wrapper * * @category Microsoft * @package WindowsAzure\Blob\Models * @author Azure PHP SDK * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @version Release: 0.4.1_2015-03 * @link https://github.com/windowsazure/azure-sdk-for-php */ class SetBlobPropertiesResult { /** * @var \DateTime */ private $_lastModified; /** * @var string */ private $_etag; /** * @var integer */ private $_sequenceNumber; /** * Creates SetBlobPropertiesResult from response headers. * * @param array $headers response headers * * @return SetBlobPropertiesResult */ public static function create($headers) { $result = new SetBlobPropertiesResult(); $date = $headers[Resources::LAST_MODIFIED]; $result->setLastModified(Utilities::rfc1123ToDateTime($date)); $result->setETag($headers[Resources::ETAG]); if (array_key_exists(Resources::X_MS_BLOB_SEQUENCE_NUMBER, $headers)) { $sNumber = $headers[Resources::X_MS_BLOB_SEQUENCE_NUMBER]; $result->setSequenceNumber(intval($sNumber)); } return $result; } /** * Gets blob lastModified. * * @return \DateTime. */ public function getLastModified() { return $this->_lastModified; } /** * Sets blob lastModified. * * @param \DateTime $lastModified value. * * @return none. */ public function setLastModified($lastModified) { Validate::isDate($lastModified); $this->_lastModified = $lastModified; } /** * Gets blob etag. * * @return string. */ public function getETag() { return $this->_etag; } /** * Sets blob etag. * * @param string $etag value. * * @return none. */ public function setETag($etag) { Validate::isString($etag, 'etag'); $this->_etag = $etag; } /** * Gets blob sequenceNumber. * * @return int. */ public function getSequenceNumber() { return $this->_sequenceNumber; } /** * Sets blob sequenceNumber. * * @param int $sequenceNumber value. * * @return none. */ public function setSequenceNumber($sequenceNumber) { Validate::isInteger($sequenceNumber, 'sequenceNumber'); $this->_sequenceNumber = $sequenceNumber; } } includes/WindowsAzure/Blob/Models/PageWriteOption.php000064400000002623152214270100016702 0ustar00 * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @link https://github.com/windowsazure/azure-sdk-for-php */ namespace WindowsAzure\Blob\Models; /** * Holds available blob page write options * * @category Microsoft * @package WindowsAzure\Blob\Models * @author Azure PHP SDK * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @version Release: 0.4.1_2015-03 * @link https://github.com/windowsazure/azure-sdk-for-php */ class PageWriteOption { const CLEAR_OPTION = 'clear'; const UPDATE_OPTION = 'update'; } includes/WindowsAzure/Blob/Models/ListPageBlobRangesOptions.php000064400000007437152214270100020655 0ustar00 * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @link https://github.com/windowsazure/azure-sdk-for-php */ namespace WindowsAzure\Blob\Models; use WindowsAzure\Common\Internal\Validate; /** * Optional parameters for listPageBlobRanges wrapper * * @category Microsoft * @package WindowsAzure\Blob\Models * @author Azure PHP SDK * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @version Release: 0.4.1_2015-03 * @link https://github.com/windowsazure/azure-sdk-for-php */ class ListPageBlobRangesOptions extends BlobServiceOptions { /** * @var string */ private $_leaseId; /** * @var string */ private $_snapshot; /** * @var integer */ private $_rangeStart; /** * @var integer */ private $_rangeEnd; /** * @var AccessCondition */ private $_accessCondition; /** * Gets lease Id for the blob * * @return string */ public function getLeaseId() { return $this->_leaseId; } /** * Sets lease Id for the blob * * @param string $leaseId the blob lease id. * * @return none */ public function setLeaseId($leaseId) { $this->_leaseId = $leaseId; } /** * Gets blob snapshot. * * @return string. */ public function getSnapshot() { return $this->_snapshot; } /** * Sets blob snapshot. * * @param string $snapshot value. * * @return none. */ public function setSnapshot($snapshot) { $this->_snapshot = $snapshot; } /** * Gets rangeStart * * @return integer */ public function getRangeStart() { return $this->_rangeStart; } /** * Sets rangeStart * * @param integer $rangeStart the blob lease id. * * @return none */ public function setRangeStart($rangeStart) { Validate::isInteger($rangeStart, 'rangeStart'); $this->_rangeStart = $rangeStart; } /** * Gets rangeEnd * * @return integer */ public function getRangeEnd() { return $this->_rangeEnd; } /** * Sets rangeEnd * * @param integer $rangeEnd range end value in bytes * * @return none */ public function setRangeEnd($rangeEnd) { Validate::isInteger($rangeEnd, 'rangeEnd'); $this->_rangeEnd = $rangeEnd; } /** * Gets access condition * * @return AccessCondition */ public function getAccessCondition() { return $this->_accessCondition; } /** * Sets access condition * * @param AccessCondition $accessCondition value to use. * * @return none. */ public function setAccessCondition($accessCondition) { $this->_accessCondition = $accessCondition; } } includes/WindowsAzure/Blob/Models/ListBlobsOptions.php000064400000011753152214270100017077 0ustar00 * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @link https://github.com/windowsazure/azure-sdk-for-php */ namespace WindowsAzure\Blob\Models; use WindowsAzure\Common\Internal\Validate; /** * Optional parameters for listBlobs API. * * @category Microsoft * @package WindowsAzure\Blob\Models * @author Azure PHP SDK * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @version Release: 0.4.1_2015-03 * @link https://github.com/windowsazure/azure-sdk-for-php */ class ListBlobsOptions extends BlobServiceOptions { /** * @var string */ private $_prefix; /** * @var string */ private $_marker; /** * @var string */ private $_delimiter; /** * @var integer */ private $_maxResults; /** * @var boolean */ private $_includeMetadata; /** * @var boolean */ private $_includeSnapshots; /** * @var boolean */ private $_includeUncommittedBlobs; /** * Gets prefix. * * @return string. */ public function getPrefix() { return $this->_prefix; } /** * Sets prefix. * * @param string $prefix value. * * @return none. */ public function setPrefix($prefix) { Validate::isString($prefix, 'prefix'); $this->_prefix = $prefix; } /** * Gets delimiter. * * @return string. */ public function getDelimiter() { return $this->_delimiter; } /** * Sets prefix. * * @param string $delimiter value. * * @return none. */ public function setDelimiter($delimiter) { Validate::isString($delimiter, 'delimiter'); $this->_delimiter = $delimiter; } /** * Gets marker. * * @return string. */ public function getMarker() { return $this->_marker; } /** * Sets marker. * * @param string $marker value. * * @return none. */ public function setMarker($marker) { Validate::isString($marker, 'marker'); $this->_marker = $marker; } /** * Gets max results. * * @return integer. */ public function getMaxResults() { return $this->_maxResults; } /** * Sets max results. * * @param integer $maxResults value. * * @return none. */ public function setMaxResults($maxResults) { Validate::isInteger($maxResults, 'maxResults'); $this->_maxResults = $maxResults; } /** * Indicates if metadata is included or not. * * @return boolean. */ public function getIncludeMetadata() { return $this->_includeMetadata; } /** * Sets the include metadata flag. * * @param bool $includeMetadata value. * * @return none. */ public function setIncludeMetadata($includeMetadata) { Validate::isBoolean($includeMetadata); $this->_includeMetadata = $includeMetadata; } /** * Indicates if snapshots is included or not. * * @return boolean. */ public function getIncludeSnapshots() { return $this->_includeSnapshots; } /** * Sets the include snapshots flag. * * @param bool $includeSnapshots value. * * @return none. */ public function setIncludeSnapshots($includeSnapshots) { Validate::isBoolean($includeSnapshots); $this->_includeSnapshots = $includeSnapshots; } /** * Indicates if uncommittedBlobs is included or not. * * @return boolean. */ public function getIncludeUncommittedBlobs() { return $this->_includeUncommittedBlobs; } /** * Sets the include uncommittedBlobs flag. * * @param bool $includeUncommittedBlobs value. * * @return none. */ public function setIncludeUncommittedBlobs($includeUncommittedBlobs) { Validate::isBoolean($includeUncommittedBlobs); $this->_includeUncommittedBlobs = $includeUncommittedBlobs; } } includes/WindowsAzure/Blob/Models/AccessCondition.php000064400000017105152214270100016673 0ustar00 * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @link https://github.com/windowsazure/azure-sdk-for-php */ namespace WindowsAzure\Blob\Models; use WindowsAzure\Common\Internal\Resources; use WindowsAzure\Common\Internal\Validate; use WindowsAzure\Common\Internal\WindowsAzureUtilities; /** * Represents a set of access conditions to be used for operations against the * storage services. * * @category Microsoft * @package WindowsAzure\Blob\Models * @author Azure PHP SDK * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @version Release: 0.4.1_2015-03 * @link https://github.com/windowsazure/azure-sdk-for-php */ class AccessCondition { /** * Represents the header type. * * @var string */ private $_header = Resources::EMPTY_STRING; /** * Represents the header value. * * @var string */ private $_value; /** * Constructor * * @param string $headerType header name * @param string $value header value */ protected function __construct($headerType, $value) { $this->setHeader($headerType); $this->setValue($value); } /** * Specifies that no access condition is set. * * @return \WindowsAzure\Blob\Models\AccessCondition */ public static function none() { return new AccessCondition(Resources::EMPTY_STRING, null); } /** * Returns an access condition such that an operation will be performed only if * the resource's ETag value matches the specified ETag value. *

* Setting this access condition modifies the request to include the HTTP * If-Match conditional header. If this access condition is set, the * operation is performed only if the ETag of the resource matches the specified * ETag. *

* For more information, see * * Specifying Conditional Headers for Blob Service Operations. * * @param string $etag a string that represents the ETag value to check. * * @return \WindowsAzure\Blob\Models\AccessCondition */ public static function ifMatch($etag) { return new AccessCondition(Resources::IF_MATCH, $etag); } /** * Returns an access condition such that an operation will be performed only if * the resource has been modified since the specified time. *

* Setting this access condition modifies the request to include the HTTP * If-Modified-Since conditional header. If this access condition is set, * the operation is performed only if the resource has been modified since the * specified time. *

* For more information, see * * Specifying Conditional Headers for Blob Service Operations. * * @param \DateTime $lastModified date that represents the last-modified * time to check for the resource. * * @return \WindowsAzure\Blob\Models\AccessCondition */ public static function ifModifiedSince($lastModified) { Validate::isDate($lastModified); return new AccessCondition( Resources::IF_MODIFIED_SINCE, $lastModified ); } /** * Returns an access condition such that an operation will be performed only if * the resource's ETag value does not match the specified ETag value. *

* Setting this access condition modifies the request to include the HTTP * If-None-Match conditional header. If this access condition is set, the * operation is performed only if the ETag of the resource does not match the * specified ETag. *

* For more information, * see * Specifying Conditional Headers for Blob Service Operations. * * @param string $etag string that represents the ETag value to check. * * @return \WindowsAzure\Blob\Models\AccessCondition */ public static function ifNoneMatch($etag) { return new AccessCondition(Resources::IF_NONE_MATCH, $etag); } /** * Returns an access condition such that an operation will be performed only if * the resource has not been modified since the specified time. *

* Setting this access condition modifies the request to include the HTTP * If-Unmodified-Since conditional header. If this access condition is * set, the operation is performed only if the resource has not been modified * since the specified time. *

* For more information, see * * Specifying Conditional Headers for Blob Service Operations. * * @param \DateTime $lastModified date that represents the last-modified * time to check for the resource. * * @return \WindowsAzure\Blob\Models\AccessCondition */ public static function ifNotModifiedSince($lastModified) { Validate::isDate($lastModified); return new AccessCondition( Resources::IF_UNMODIFIED_SINCE, $lastModified ); } /** * Sets header type * * @param string $headerType can be one of Resources * * @return none. */ public function setHeader($headerType) { $valid = AccessCondition::isValid($headerType); Validate::isTrue($valid, Resources::INVALID_HT_MSG); $this->_header = $headerType; } /** * Gets header type * * @return string. */ public function getHeader() { return $this->_header; } /** * Sets the header value * * @param string $value the value to use * * @return none */ public function setValue($value) { $this->_value = $value; } /** * Gets the header value * * @return string */ public function getValue() { return $this->_value; } /** * Check if the $headerType belongs to valid header types * * @param string $headerType candidate header type * * @return boolean */ public static function isValid($headerType) { if ( $headerType == Resources::EMPTY_STRING || $headerType == Resources::IF_UNMODIFIED_SINCE || $headerType == Resources::IF_MATCH || $headerType == Resources::IF_MODIFIED_SINCE || $headerType == Resources::IF_NONE_MATCH ) { return true; } else { return false; } } } includes/WindowsAzure/Blob/Models/AccessPolicy.php000064400000006163152214270100016206 0ustar00 * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @link https://github.com/windowsazure/azure-sdk-for-php */ namespace WindowsAzure\Blob\Models; use WindowsAzure\Common\Internal\Utilities; use WindowsAzure\Common\Internal\Validate; /** * Holds container access policy elements * * @category Microsoft * @package WindowsAzure\Blob\Models * @author Azure PHP SDK * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @version Release: 0.4.1_2015-03 * @link https://github.com/windowsazure/azure-sdk-for-php */ class AccessPolicy { /** * @var string */ private $_start; /** * @var \DateTime */ private $_expiry; /** * @var \DateTime */ private $_permission; /** * Gets start. * * @return \DateTime. */ public function getStart() { return $this->_start; } /** * Sets start. * * @param \DateTime $start value. * * @return none. */ public function setStart($start) { Validate::isDate($start); $this->_start = $start; } /** * Gets expiry. * * @return \DateTime. */ public function getExpiry() { return $this->_expiry; } /** * Sets expiry. * * @param \DateTime $expiry value. * * @return none. */ public function setExpiry($expiry) { Validate::isDate($expiry); $this->_expiry = $expiry; } /** * Gets permission. * * @return string. */ public function getPermission() { return $this->_permission; } /** * Sets permission. * * @param string $permission value. * * @return none. */ public function setPermission($permission) { $this->_permission = $permission; } /** * Converts this current object to XML representation. * * @return array. */ public function toArray() { $array = array(); $array['Start'] = Utilities::convertToEdmDateTime($this->_start); $array['Expiry'] = Utilities::convertToEdmDateTime($this->_expiry); $array['Permission'] = $this->_permission; return $array; } } includes/WindowsAzure/Blob/Models/Blob.php000064400000006551152214270100014504 0ustar00 * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @link https://github.com/windowsazure/azure-sdk-for-php */ namespace WindowsAzure\Blob\Models; /** * Represents windows azure blob object * * @category Microsoft * @package WindowsAzure\Blob\Models * @author Azure PHP SDK * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @version Release: 0.4.1_2015-03 * @link https://github.com/windowsazure/azure-sdk-for-php */ class Blob { /** * @var string */ private $_name; /** * @var string */ private $_url; /** * @var string */ private $_snapshot; /** * @var array */ private $_metadata; /** * @var BlobProperties */ private $_properties; /** * Gets blob name. * * @return string. */ public function getName() { return $this->_name; } /** * Sets blob name. * * @param string $name value. * * @return none. */ public function setName($name) { $this->_name = $name; } /** * Gets blob snapshot. * * @return string. */ public function getSnapshot() { return $this->_snapshot; } /** * Sets blob snapshot. * * @param string $snapshot value. * * @return none. */ public function setSnapshot($snapshot) { $this->_snapshot = $snapshot; } /** * Gets blob url. * * @return string. */ public function getUrl() { return $this->_url; } /** * Sets blob url. * * @param string $url value. * * @return none. */ public function setUrl($url) { $this->_url = $url; } /** * Gets blob metadata. * * @return array. */ public function getMetadata() { return $this->_metadata; } /** * Sets blob metadata. * * @param string $metadata value. * * @return none. */ public function setMetadata($metadata) { $this->_metadata = $metadata; } /** * Gets blob properties. * * @return BlobProperties. */ public function getProperties() { return $this->_properties; } /** * Sets blob properties. * * @param BlobProperties $properties value. * * @return none. */ public function setProperties($properties) { $this->_properties = $properties; } } includes/WindowsAzure/Blob/Models/GetBlobOptions.php000064400000010450152214270100016511 0ustar00 * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @link https://github.com/windowsazure/azure-sdk-for-php */ namespace WindowsAzure\Blob\Models; use WindowsAzure\Common\Internal\Validate; /** * Optional parameters for getBlob wrapper * * @category Microsoft * @package WindowsAzure\Blob\Models * @author Azure PHP SDK * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @version Release: 0.4.1_2015-03 * @link https://github.com/windowsazure/azure-sdk-for-php */ class GetBlobOptions extends BlobServiceOptions { /** * @var string */ private $_leaseId; /** * @var string */ private $_snapshot; /** * @var AccessCondition */ private $_accessCondition; /** * @var boolean */ private $_computeRangeMD5; /** * @var integer */ private $_rangeStart; /** * @var integer */ private $_rangeEnd; /** * Gets lease Id for the blob * * @return string */ public function getLeaseId() { return $this->_leaseId; } /** * Sets lease Id for the blob * * @param string $leaseId the blob lease id. * * @return none */ public function setLeaseId($leaseId) { $this->_leaseId = $leaseId; } /** * Gets access condition * * @return AccessCondition */ public function getAccessCondition() { return $this->_accessCondition; } /** * Sets access condition * * @param AccessCondition $accessCondition value to use. * * @return none. */ public function setAccessCondition($accessCondition) { $this->_accessCondition = $accessCondition; } /** * Gets blob snapshot. * * @return string. */ public function getSnapshot() { return $this->_snapshot; } /** * Sets blob snapshot. * * @param string $snapshot value. * * @return none. */ public function setSnapshot($snapshot) { $this->_snapshot = $snapshot; } /** * Gets rangeStart * * @return integer */ public function getRangeStart() { return $this->_rangeStart; } /** * Sets rangeStart * * @param integer $rangeStart the blob lease id. * * @return none */ public function setRangeStart($rangeStart) { Validate::isInteger($rangeStart, 'rangeStart'); $this->_rangeStart = $rangeStart; } /** * Gets rangeEnd * * @return integer */ public function getRangeEnd() { return $this->_rangeEnd; } /** * Sets rangeEnd * * @param integer $rangeEnd range end value in bytes * * @return none */ public function setRangeEnd($rangeEnd) { Validate::isInteger($rangeEnd, 'rangeEnd'); $this->_rangeEnd = $rangeEnd; } /** * Gets computeRangeMD5 * * @return boolean */ public function getComputeRangeMD5() { return $this->_computeRangeMD5; } /** * Sets computeRangeMD5 * * @param boolean $computeRangeMD5 value * * @return none */ public function setComputeRangeMD5($computeRangeMD5) { Validate::isBoolean($computeRangeMD5); $this->_computeRangeMD5 = $computeRangeMD5; } } includes/WindowsAzure/Blob/Models/ListContainersResult.php000064400000014105152214270100017760 0ustar00 * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @link https://github.com/windowsazure/azure-sdk-for-php */ namespace WindowsAzure\Blob\Models; use WindowsAzure\Common\Internal\Resources; use WindowsAzure\Common\Internal\Utilities; use WindowsAzure\Blob\Models\Container; /** * Container to hold list container response object. * * @category Microsoft * @package WindowsAzure\Blob\Models * @author Azure PHP SDK * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @version Release: 0.4.1_2015-03 * @link https://github.com/windowsazure/azure-sdk-for-php */ class ListContainersResult { /** * @var array */ private $_containers; /** * @var string */ private $_prefix; /** * @var string */ private $_marker; /** * @var string */ private $_nextMarker; /** * @var integer */ private $_maxResults; /** * @var string */ private $_accountName; /** * Creates ListBlobResult object from parsed XML response. * * @param array $parsedResponse XML response parsed into array. * * @return ListBlobResult */ public static function create($parsedResponse) { $result = new ListContainersResult(); $result->_accountName = Utilities::tryGetKeysChainValue( $parsedResponse, Resources::XTAG_ATTRIBUTES, Resources::XTAG_ACCOUNT_NAME ); $result->_prefix = Utilities::tryGetValue( $parsedResponse, Resources::QP_PREFIX ); $result->_marker = Utilities::tryGetValue( $parsedResponse, Resources::QP_MARKER ); $result->_nextMarker = Utilities::tryGetValue( $parsedResponse, Resources::QP_NEXT_MARKER ); $result->_maxResults = Utilities::tryGetValue( $parsedResponse, Resources::QP_MAX_RESULTS ); $result->_containers = array(); $rawContainer = array(); if ( !empty($parsedResponse['Containers']) ) { $containersArray = $parsedResponse['Containers']['Container']; $rawContainer = Utilities::getArray($containersArray); } foreach ($rawContainer as $value) { $container = new Container(); $container->setName($value['Name']); $container->setUrl($value['Url']); $container->setMetadata( Utilities::tryGetValue($value, Resources::QP_METADATA, array()) ); $properties = new ContainerProperties(); $date = $value['Properties']['Last-Modified']; $date = Utilities::rfc1123ToDateTime($date); $properties->setLastModified($date); $properties->setETag($value['Properties']['Etag']); $container->setProperties($properties); $result->_containers[] = $container; } return $result; } /** * Sets containers. * * @param array $containers list of containers. * * @return none */ public function setContainers($containers) { $this->_containers = array(); foreach ($containers as $container) { $this->_containers[] = clone $container; } } /** * Gets containers. * * @return array */ public function getContainers() { return $this->_containers; } /** * Gets prefix. * * @return string */ public function getPrefix() { return $this->_prefix; } /** * Sets prefix. * * @param string $prefix value. * * @return none */ public function setPrefix($prefix) { $this->_prefix = $prefix; } /** * Gets marker. * * @return string */ public function getMarker() { return $this->_marker; } /** * Sets marker. * * @param string $marker value. * * @return none */ public function setMarker($marker) { $this->_marker = $marker; } /** * Gets max results. * * @return string */ public function getMaxResults() { return $this->_maxResults; } /** * Sets max results. * * @param string $maxResults value. * * @return none */ public function setMaxResults($maxResults) { $this->_maxResults = $maxResults; } /** * Gets next marker. * * @return string */ public function getNextMarker() { return $this->_nextMarker; } /** * Sets next marker. * * @param string $nextMarker value. * * @return none */ public function setNextMarker($nextMarker) { $this->_nextMarker = $nextMarker; } /** * Gets account name. * * @return string */ public function getAccountName() { return $this->_accountName; } /** * Sets account name. * * @param string $accountName value. * * @return none */ public function setAccountName($accountName) { $this->_accountName = $accountName; } }includes/WindowsAzure/Blob/Models/GetBlobPropertiesOptions.php000064400000005376152214270100020601 0ustar00 * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @link https://github.com/windowsazure/azure-sdk-for-php */ namespace WindowsAzure\Blob\Models; /** * Optional parameters for getBlobProperties wrapper * * @category Microsoft * @package WindowsAzure\Blob\Models * @author Azure PHP SDK * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @version Release: 0.4.1_2015-03 * @link https://github.com/windowsazure/azure-sdk-for-php */ class GetBlobPropertiesOptions extends BlobServiceOptions { /** * @var string */ private $_leaseId; /** * @var string */ private $_snapshot; /** * @var AccessCondition */ private $_accessCondition; /** * Gets lease Id for the blob * * @return string */ public function getLeaseId() { return $this->_leaseId; } /** * Sets lease Id for the blob * * @param string $leaseId the blob lease id. * * @return none */ public function setLeaseId($leaseId) { $this->_leaseId = $leaseId; } /** * Gets access condition * * @return AccessCondition */ public function getAccessCondition() { return $this->_accessCondition; } /** * Sets access condition * * @param AccessCondition $accessCondition value to use. * * @return none. */ public function setAccessCondition($accessCondition) { $this->_accessCondition = $accessCondition; } /** * Gets blob snapshot. * * @return string. */ public function getSnapshot() { return $this->_snapshot; } /** * Sets blob snapshot. * * @param string $snapshot value. * * @return none. */ public function setSnapshot($snapshot) { $this->_snapshot = $snapshot; } } includes/WindowsAzure/Blob/Models/SignedIdentifier.php000064400000004717152214270100017044 0ustar00 * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @link https://github.com/windowsazure/azure-sdk-for-php */ namespace WindowsAzure\Blob\Models; use WindowsAzure\Blob\Models\AccessPolicy; /** * Holds container signed identifiers. * * @category Microsoft * @package WindowsAzure\Blob\Models * @author Azure PHP SDK * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @version Release: 0.4.1_2015-03 * @link https://github.com/windowsazure/azure-sdk-for-php */ class SignedIdentifier { private $_id; private $_accessPolicy; /** * Gets id. * * @return string. */ public function getId() { return $this->_id; } /** * Sets id. * * @param string $id value. * * @return none. */ public function setId($id) { $this->_id = $id; } /** * Gets accessPolicy. * * @return string. */ public function getAccessPolicy() { return $this->_accessPolicy; } /** * Sets accessPolicy. * * @param string $accessPolicy value. * * @return none. */ public function setAccessPolicy($accessPolicy) { $this->_accessPolicy = $accessPolicy; } /** * Converts this current object to XML representation. * * @return array. */ public function toArray() { $array = array(); $array['SignedIdentifier']['Id'] = $this->_id; $array['SignedIdentifier']['AccessPolicy'] = $this->_accessPolicy->toArray(); return $array; } } includes/WindowsAzure/Blob/Models/AcquireLeaseOptions.php000064400000003576152214270100017551 0ustar00 * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @link https://github.com/windowsazure/azure-sdk-for-php */ namespace WindowsAzure\Blob\Models; /** * Optional parameters for acquireLease wrapper * * @category Microsoft * @package WindowsAzure\Blob\Models * @author Azure PHP SDK * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @version Release: 0.4.1_2015-03 * @link https://github.com/windowsazure/azure-sdk-for-php */ class AcquireLeaseOptions extends BlobServiceOptions { /** * @var AccessCondition */ private $_accessCondition; /** * Gets access condition * * @return AccessCondition */ public function getAccessCondition() { return $this->_accessCondition; } /** * Sets access condition * * @param AccessCondition $accessCondition value to use. * * @return none. */ public function setAccessCondition($accessCondition) { $this->_accessCondition = $accessCondition; } } includes/WindowsAzure/Blob/Models/BlockList.php000064400000011003152214270100015500 0ustar00 * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @link https://github.com/windowsazure/azure-sdk-for-php */ namespace WindowsAzure\Blob\Models; use WindowsAzure\Common\Internal\Validate; use WindowsAzure\Common\Internal\Resources; use WindowsAzure\Common\Internal\Serialization\XmlSerializer; use WindowsAzure\Blob\Models\Block; /** * Holds block list used for commitBlobBlocks * * @category Microsoft * @package WindowsAzure\Blob\Models * @author Azure PHP SDK * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @version Release: 0.4.1_2015-03 * @link https://github.com/windowsazure/azure-sdk-for-php */ class BlockList { /** * @var array */ private $_entries; public static $xmlRootName = 'BlockList'; /** * Creates block list from array of blocks. * * @param array $array The blocks array. * * @return BlockList */ public static function create($array) { $blockList = new BlockList(); foreach ($array as $value) { $blockList->addEntry($value->getBlockId(), $value->getType()); } return $blockList; } /** * Adds new entry to the block list entries. * * @param string $blockId The block id. * @param string $type The entry type, you can use BlobBlockType. * * @return none */ public function addEntry($blockId, $type) { Validate::isString($blockId, 'blockId'); Validate::isTrue( BlobBlockType::isValid($type), sprintf(Resources::INVALID_BTE_MSG, get_class(new BlobBlockType())) ); $block = new Block(); $block->setBlockId($blockId); $block->setType($type); $this->_entries[] = $block; } /** * Addds committed block entry. * * @param string $blockId The block id. * * @return none */ public function addCommittedEntry($blockId) { $this->addEntry($blockId, BlobBlockType::COMMITTED_TYPE); } /** * Addds uncommitted block entry. * * @param string $blockId The block id. * * @return none */ public function addUncommittedEntry($blockId) { $this->addEntry($blockId, BlobBlockType::UNCOMMITTED_TYPE); } /** * Addds latest block entry. * * @param string $blockId The block id. * * @return none */ public function addLatestEntry($blockId) { $this->addEntry($blockId, BlobBlockType::LATEST_TYPE); } /** * Gets blob block entry. * * @param string $blockId The id of the block. * * @return Block */ public function getEntry($blockId) { foreach ($this->_entries as $value) { if ($blockId == $value->getBlockId()) { return $value; } } return null; } /** * Gets all blob block entries. * * @return string */ public function getEntries() { return $this->_entries; } /** * Converts the BlockList object to XML representation * * @param XmlSerializer $xmlSerializer The XML serializer. * * @return string */ public function toXml($xmlSerializer) { $properties = array(XmlSerializer::ROOT_NAME => self::$xmlRootName); $array = array(); foreach ($this->_entries as $value) { $array[] = array( $value->getType() => base64_encode($value->getBlockId()) ); } return $xmlSerializer->serialize($array, $properties); } } includes/WindowsAzure/Blob/Models/DeleteBlobOptions.php000064400000006546152214270100017207 0ustar00 * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @link https://github.com/windowsazure/azure-sdk-for-php */ namespace WindowsAzure\Blob\Models; use WindowsAzure\Common\Internal\Validate; /** * Optional parameters for deleteBlob wrapper * * @category Microsoft * @package WindowsAzure\Blob\Models * @author Azure PHP SDK * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @version Release: 0.4.1_2015-03 * @link https://github.com/windowsazure/azure-sdk-for-php */ class DeleteBlobOptions extends BlobServiceOptions { /** * @var string */ private $_leaseId; /** * @var string */ private $_snapshot; /** * @var AccessCondition */ private $_accessCondition; /** * @var boolean */ private $_deleteSnaphotsOnly; /** * Gets lease Id for the blob * * @return string */ public function getLeaseId() { return $this->_leaseId; } /** * Sets lease Id for the blob * * @param string $leaseId the blob lease id. * * @return none */ public function setLeaseId($leaseId) { $this->_leaseId = $leaseId; } /** * Gets access condition * * @return AccessCondition */ public function getAccessCondition() { return $this->_accessCondition; } /** * Sets access condition * * @param AccessCondition $accessCondition value to use. * * @return none. */ public function setAccessCondition($accessCondition) { $this->_accessCondition = $accessCondition; } /** * Gets blob snapshot. * * @return string. */ public function getSnapshot() { return $this->_snapshot; } /** * Sets blob snapshot. * * @param string $snapshot value. * * @return none. */ public function setSnapshot($snapshot) { $this->_snapshot = $snapshot; } /** * Gets blob deleteSnaphotsOnly. * * @return boolean. */ public function getDeleteSnaphotsOnly() { return $this->_deleteSnaphotsOnly; } /** * Sets blob deleteSnaphotsOnly. * * @param string $deleteSnaphotsOnly value. * * @return boolean. */ public function setDeleteSnaphotsOnly($deleteSnaphotsOnly) { Validate::isBoolean($deleteSnaphotsOnly); $this->_deleteSnaphotsOnly = $deleteSnaphotsOnly; } } includes/WindowsAzure/Blob/Models/BlobType.php000064400000002574152214270100015347 0ustar00 * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @link https://github.com/windowsazure/azure-sdk-for-php */ namespace WindowsAzure\Blob\Models; /** * Encapsulates blob types * * @category Microsoft * @package WindowsAzure\Blob\Models * @author Azure PHP SDK * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @version Release: 0.4.1_2015-03 * @link https://github.com/windowsazure/azure-sdk-for-php */ class BlobType { const BLOCK_BLOB = 'BlockBlob'; const PAGE_BLOB = 'PageBlob'; } includes/WindowsAzure/Blob/Models/ListBlobBlocksResult.php000064400000014560152214270100017674 0ustar00 * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @link https://github.com/windowsazure/azure-sdk-for-php */ namespace WindowsAzure\Blob\Models; use WindowsAzure\Common\Internal\Validate; use WindowsAzure\Common\Internal\Resources; use WindowsAzure\Common\Internal\Utilities; /** * Holds result of listBlobBlocks * * @category Microsoft * @package WindowsAzure\Blob\Models * @author Azure PHP SDK * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @version Release: 0.4.1_2015-03 * @link https://github.com/windowsazure/azure-sdk-for-php */ class ListBlobBlocksResult { /** * @var \DateTime */ private $_lastModified; /** * @var string */ private $_etag; /** * @var string */ private $_contentType; /** * @var integer */ private $_contentLength; /** * @var array */ private $_committedBlocks; /** * @var array */ private $_uncommittedBlocks; /** * Gets block entries from parsed response * * @param array $parsed HTTP response * @param string $type Block type * * @return array */ private static function _getEntries($parsed, $type) { $entries = array(); if (is_array($parsed)) { $rawEntries = array(); if ( array_key_exists($type, $parsed) && is_array($parsed[$type]) && !empty($parsed[$type]) ) { $rawEntries = Utilities::getArray($parsed[$type]['Block']); } foreach ($rawEntries as $value) { $entries[base64_decode($value['Name'])] = $value['Size']; } } return $entries; } /** * Creates ListBlobBlocksResult from given response headers and parsed body * * @param array $headers HTTP response headers * @param array $parsed HTTP response body in array representation * * @return ListBlobBlocksResult */ public static function create($headers, $parsed) { $result = new ListBlobBlocksResult(); $clean = array_change_key_case($headers); $result->setETag(Utilities::tryGetValue($clean, Resources::ETAG)); $date = Utilities::tryGetValue($clean, Resources::LAST_MODIFIED); if (!is_null($date)) { $date = Utilities::rfc1123ToDateTime($date); $result->setLastModified($date); } $result->setContentLength( intval( Utilities::tryGetValue($clean, Resources::X_MS_BLOB_CONTENT_LENGTH) ) ); $result->setContentType( Utilities::tryGetValue($clean, Resources::CONTENT_TYPE) ); $result->_uncommittedBlocks = self::_getEntries( $parsed, 'UncommittedBlocks' ); $result->_committedBlocks = self::_getEntries($parsed, 'CommittedBlocks'); return $result; } /** * Gets blob lastModified. * * @return \DateTime. */ public function getLastModified() { return $this->_lastModified; } /** * Sets blob lastModified. * * @param \DateTime $lastModified value. * * @return none. */ public function setLastModified($lastModified) { Validate::isDate($lastModified); $this->_lastModified = $lastModified; } /** * Gets blob etag. * * @return string. */ public function getETag() { return $this->_etag; } /** * Sets blob etag. * * @param string $etag value. * * @return none. */ public function setETag($etag) { $this->_etag = $etag; } /** * Gets blob contentType. * * @return string. */ public function getContentType() { return $this->_contentType; } /** * Sets blob contentType. * * @param string $contentType value. * * @return none. */ public function setContentType($contentType) { $this->_contentType = $contentType; } /** * Gets blob contentLength. * * @return integer. */ public function getContentLength() { return $this->_contentLength; } /** * Sets blob contentLength. * * @param integer $contentLength value. * * @return none. */ public function setContentLength($contentLength) { Validate::isInteger($contentLength, 'contentLength'); $this->_contentLength = $contentLength; } /** * Gets uncommitted blocks * * @return array */ public function getUncommittedBlocks() { return $this->_uncommittedBlocks; } /** * Sets uncommitted blocks * * @param array $uncommittedBlocks The uncommitted blocks entries * * @return none. */ public function setUncommittedBlocks($uncommittedBlocks) { $this->_uncommittedBlocks = $uncommittedBlocks; } /** * Gets committed blocks * * @return array */ public function getCommittedBlocks() { return $this->_committedBlocks; } /** * Sets committed blocks * * @param array $committedBlocks The committed blocks entries * * @return none. */ public function setCommittedBlocks($committedBlocks) { $this->_committedBlocks = $committedBlocks; } } includes/WindowsAzure/Blob/Models/CreateBlobSnapshotOptions.php000064400000005360152214270100020721 0ustar00 * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @link https://github.com/windowsazure/azure-sdk-for-php */ namespace WindowsAzure\Blob\Models; /** * The optional parameters for createBlobSnapshot wrapper. * * @category Microsoft * @package WindowsAzure\Blob\Models * @author Azure PHP SDK * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @version Release: 0.4.1_2015-03 * @link https://github.com/windowsazure/azure-sdk-for-php */ class CreateBlobSnapshotOptions extends BlobServiceOptions { /** * @var array */ private $_metadata; /** * @var AccessCondition */ private $_accessCondition; /** * @var string */ private $_leaseId; /** * Gets metadata. * * @return array */ public function getMetadata() { return $this->_metadata; } /** * Sets metadata. * * @param array $metadata The metadata array. * * @return none */ public function setMetadata($metadata) { $this->_metadata = $metadata; } /** * Gets access condition. * * @return AccessCondition */ public function getAccessCondition() { return $this->_accessCondition; } /** * Sets access condition. * * @param AccessCondition $accessCondition The access condition object. * * @return none */ public function setAccessCondition($accessCondition) { $this->_accessCondition = $accessCondition; } /** * Gets lease Id. * * @return string */ public function getLeaseId() { return $this->_leaseId; } /** * Sets lease Id. * * @param string $leaseId The lease Id. * * @return none */ public function setLeaseId($leaseId) { $this->_leaseId = $leaseId; } } includes/WindowsAzure/Blob/Models/CreateBlobBlockOptions.php000064400000004372152214270100020156 0ustar00 * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @link https://github.com/windowsazure/azure-sdk-for-php */ namespace WindowsAzure\Blob\Models; /** * Optional parameters for createBlobBlock wrapper * * @category Microsoft * @package WindowsAzure\Blob\Models * @author Azure PHP SDK * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @version Release: 0.4.1_2015-03 * @link https://github.com/windowsazure/azure-sdk-for-php */ class CreateBlobBlockOptions extends BlobServiceOptions { /** * @var string */ private $_contentMD5; /** * @var string */ private $_leaseId; /** * Gets lease Id for the blob * * @return string */ public function getLeaseId() { return $this->_leaseId; } /** * Sets lease Id for the blob * * @param string $leaseId the blob lease id. * * @return none */ public function setLeaseId($leaseId) { $this->_leaseId = $leaseId; } /** * Gets blob contentMD5. * * @return string. */ public function getContentMD5() { return $this->_contentMD5; } /** * Sets blob contentMD5. * * @param string $contentMD5 value. * * @return none. */ public function setContentMD5($contentMD5) { $this->_contentMD5 = $contentMD5; } } includes/WindowsAzure/Blob/Models/LeaseMode.php000064400000002713152214270100015460 0ustar00 * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @link https://github.com/windowsazure/azure-sdk-for-php */ namespace WindowsAzure\Blob\Models; /** * Modes for leasing a blob * * @category Microsoft * @package WindowsAzure\Blob\Models * @author Azure PHP SDK * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @version Release: 0.4.1_2015-03 * @link https://github.com/windowsazure/azure-sdk-for-php */ class LeaseMode { const ACQUIRE_ACTION = 'acquire'; const RENEW_ACTION = 'renew'; const RELEASE_ACTION = 'release'; const BREAK_ACTION = 'break'; } includes/WindowsAzure/Blob/Models/ContainerProperties.php000064400000004302152214270100017615 0ustar00 * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @link https://github.com/windowsazure/azure-sdk-for-php */ namespace WindowsAzure\Blob\Models; /** * Holds container properties fields * * @category Microsoft * @package WindowsAzure\Blob\Models * @author Azure PHP SDK * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @version Release: 0.4.1_2015-03 * @link https://github.com/windowsazure/azure-sdk-for-php */ class ContainerProperties { /** * @var \DateTime */ private $_lastModified; /** * @var string */ private $_etag; /** * Gets container lastModified. * * @return \DateTime. */ public function getLastModified() { return $this->_lastModified; } /** * Sets container lastModified. * * @param \DateTime $lastModified value. * * @return none. */ public function setLastModified($lastModified) { $this->_lastModified = $lastModified; } /** * Gets container etag. * * @return string. */ public function getETag() { return $this->_etag; } /** * Sets container etag. * * @param string $etag value. * * @return none. */ public function setETag($etag) { $this->_etag = $etag; } } includes/WindowsAzure/Blob/Models/CopyBlobOptions.php000064400000010420152214270100016701 0ustar00 * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @link https://github.com/windowsazure/azure-sdk-for-php */ namespace WindowsAzure\Blob\Models; use WindowsAzure\Common\Internal\Validate; /** * optional parameters for CopyBlobOptions wrapper * * @category Microsoft * @package WindowsAzure\Blob\Models * @author Azure PHP SDK * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @version Release: 0.4.1_2015-03 * @link https://github.com/windowsazure/azure-sdk-for-php */ class CopyBlobOptions extends BlobServiceOptions { /** * @var AccessCondition */ private $_accessCondition; /** * @var AccessCondition */ private $_sourceAccessCondition; /** * @var array */ private $_metadata; /** * @var string */ private $_sourceSnapshot; /** * @var string */ private $_leaseId; /** * @var sourceLeaseId */ private $_sourceLeaseId; /** * Gets access condition * * @return AccessCondition */ public function getAccessCondition() { return $this->_accessCondition; } /** * Sets access condition * * @param AccessCondition $accessCondition value to use. * * @return none. */ public function setAccessCondition($accessCondition) { $this->_accessCondition = $accessCondition; } /** * Gets source access condition * * @return SourceAccessCondition */ public function getSourceAccessCondition() { return $this->_sourceAccessCondition; } /** * Sets source access condition * * @param SourceAccessCondition $sourceAccessCondition value to use. * * @return none. */ public function setSourceAccessCondition($sourceAccessCondition) { $this->_sourceAccessCondition = $sourceAccessCondition; } /** * Gets metadata. * * @return array. */ public function getMetadata() { return $this->_metadata; } /** * Sets metadata. * * @param array $metadata value. * * @return none. */ public function setMetadata($metadata) { $this->_metadata = $metadata; } /** * Gets source snapshot. * * @return string */ public function getSourceSnapshot() { return $this->_sourceSnapshot; } /** * Sets source snapshot. * * @param string $sourceSnapshot value. * * @return none */ public function setSourceSnapshot($sourceSnapshot) { $this->_sourceSnapshot = $sourceSnapshot; } /** * Gets lease ID. * * @return string */ public function getLeaseId() { return $this->_leaseId; } /** * Sets lease ID. * * @param string $leaseId value. * * @return none */ public function setLeaseId($leaseId) { $this->_leaseId = $leaseId; } /** * Gets source lease ID. * * @return string */ public function getSourceLeaseId() { return $this->_sourceLeaseId; } /** * Sets source lease ID. * * @param string $sourceLeaseId value. * * @return none */ public function setSourceLeaseId($sourceLeaseId) { $this->_sourceLeaseId = $sourceLeaseId; } } includes/WindowsAzure/Blob/Models/BlobPrefix.php000064400000003277152214270100015664 0ustar00 * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @link https://github.com/windowsazure/azure-sdk-for-php */ namespace WindowsAzure\Blob\Models; /** * Represents BlobPrefix object * * @category Microsoft * @package WindowsAzure\Blob\Models * @author Azure PHP SDK * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @version Release: 0.4.1_2015-03 * @link https://github.com/windowsazure/azure-sdk-for-php */ class BlobPrefix { /** * @var string */ private $_name; /** * Gets blob name. * * @return string. */ public function getName() { return $this->_name; } /** * Sets blob name. * * @param string $name value. * * @return none. */ public function setName($name) { $this->_name = $name; } } includes/WindowsAzure/Blob/Models/SetBlobMetadataOptions.php000064400000004513152214270100020171 0ustar00 * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @link https://github.com/windowsazure/azure-sdk-for-php */ namespace WindowsAzure\Blob\Models; /** * The optional parameters for setBlobMetadata API. * * @category Microsoft * @package WindowsAzure\Blob\Models * @author Azure PHP SDK * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @version Release: 0.4.1_2015-03 * @link https://github.com/windowsazure/azure-sdk-for-php */ class SetBlobMetadataOptions extends BlobServiceOptions { /** * @var string */ private $_leaseId; /** * @var AccessCondition */ private $_accessCondition; /** * Gets lease Id for the blob * * @return string */ public function getLeaseId() { return $this->_leaseId; } /** * Sets lease Id for the blob * * @param string $leaseId the blob lease id. * * @return none */ public function setLeaseId($leaseId) { $this->_leaseId = $leaseId; } /** * Gets access condition * * @return AccessCondition */ public function getAccessCondition() { return $this->_accessCondition; } /** * Sets access condition * * @param AccessCondition $accessCondition value to use. * * @return none. */ public function setAccessCondition($accessCondition) { $this->_accessCondition = $accessCondition; } } includes/WindowsAzure/Blob/Models/CreateContainerOptions.php000064400000007165152214270100020252 0ustar00 * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @link https://github.com/windowsazure/azure-sdk-for-php */ namespace WindowsAzure\Blob\Models; use WindowsAzure\Blob\Models\BlobServiceOptions; use WindowsAzure\Common\Internal\Validate; /** * Optional parameters for createContainer API * * @category Microsoft * @package WindowsAzure\Blob\Models * @author Azure PHP SDK * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @version Release: 0.4.1_2015-03 * @link https://github.com/windowsazure/azure-sdk-for-php */ class CreateContainerOptions extends BlobServiceOptions { /** * @var string */ private $_publicAccess; /** * @var array */ private $_metadata; /** * Gets container public access. * * @return string. */ public function getPublicAccess() { return $this->_publicAccess; } /** * Specifies whether data in the container may be accessed publicly and the level * of access. Possible values include: * 1) container: Specifies full public read access for container and blob data. * Clients can enumerate blobs within the container via anonymous request, but * cannot enumerate containers within the storage account. * 2) blob: Specifies public read access for blobs. Blob data within this * container can be read via anonymous request, but container data is not * available. Clients cannot enumerate blobs within the container via * anonymous request. * If this value is not specified in the request, container data is private to * the account owner. * * @param string $publicAccess access modifier for the container * * @return none. */ public function setPublicAccess($publicAccess) { Validate::isString($publicAccess, 'publicAccess'); $this->_publicAccess = $publicAccess; } /** * Gets user defined metadata. * * @return array. */ public function getMetadata() { return $this->_metadata; } /** * Sets user defined metadata. This metadata should be added without the header * prefix (x-ms-meta-*). * * @param array $metadata user defined metadata object in array form. * * @return none. */ public function setMetadata($metadata) { $this->_metadata = $metadata; } /** * Adds new metadata element. This element should be added without the header * prefix (x-ms-meta-*). * * @param string $key metadata key element. * @param string $value metadata value element. * * @return none. */ public function addMetadata($key, $value) { $this->_metadata[$key] = $value; } } includes/WindowsAzure/Blob/Models/ListPageBlobRangesResult.php000064400000011444152214270100020471 0ustar00 * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @link https://github.com/windowsazure/azure-sdk-for-php */ namespace WindowsAzure\Blob\Models; use WindowsAzure\Common\Internal\Validate; use WindowsAzure\Common\Internal\Utilities; use WindowsAzure\Common\Internal\Resources; use WindowsAzure\Blob\Models\PageRange; /** * Holds result of calling listPageBlobRanges wrapper * * @category Microsoft * @package WindowsAzure\Blob\Models * @author Azure PHP SDK * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @version Release: 0.4.1_2015-03 * @link https://github.com/windowsazure/azure-sdk-for-php */ class ListPageBlobRangesResult { /** * @var \DateTime */ private $_lastModified; /** * @var string */ private $_etag; /** * @var integer */ private $_contentLength; /** * @var array */ private $_pageRanges; /** * Creates BlobProperties object from $parsed response in array representation * * @param array $headers HTTP response headers * @param array $parsed parsed response in array format. * * @return ListPageBlobRangesResult */ public static function create($headers, $parsed) { $result = new ListPageBlobRangesResult(); $headers = array_change_key_case($headers); $date = $headers[Resources::LAST_MODIFIED]; $date = Utilities::rfc1123ToDateTime($date); $blobLength = intval($headers[Resources::X_MS_BLOB_CONTENT_LENGTH]); $rawPageRanges = array(); if (!empty($parsed['PageRange'])) { $parsed = array_change_key_case($parsed); $rawPageRanges = Utilities::getArray($parsed['pagerange']); } $result->_pageRanges = array(); foreach ($rawPageRanges as $value) { $result->_pageRanges[] = new PageRange( intval($value['Start']), intval($value['End']) ); } $result->setContentLength($blobLength); $result->setETag($headers[Resources::ETAG]); $result->setLastModified($date); return $result; } /** * Gets blob lastModified. * * @return \DateTime. */ public function getLastModified() { return $this->_lastModified; } /** * Sets blob lastModified. * * @param \DateTime $lastModified value. * * @return none. */ public function setLastModified($lastModified) { Validate::isDate($lastModified); $this->_lastModified = $lastModified; } /** * Gets blob etag. * * @return string. */ public function getETag() { return $this->_etag; } /** * Sets blob etag. * * @param string $etag value. * * @return none. */ public function setETag($etag) { Validate::isString($etag, 'etag'); $this->_etag = $etag; } /** * Gets blob contentLength. * * @return integer. */ public function getContentLength() { return $this->_contentLength; } /** * Sets blob contentLength. * * @param integer $contentLength value. * * @return none. */ public function setContentLength($contentLength) { Validate::isInteger($contentLength, 'contentLength'); $this->_contentLength = $contentLength; } /** * Gets page ranges * * @return array */ public function getPageRanges() { return $this->_pageRanges; } /** * Sets page ranges * * @param array $pageRanges page ranges to set * * @return none */ public function setPageRanges($pageRanges) { $this->_pageRanges = array(); foreach ($pageRanges as $pageRange) { $this->_pageRanges[] = clone $pageRange; } } } includes/WindowsAzure/Blob/Models/GetContainerPropertiesResult.php000064400000006054152214270100021462 0ustar00 * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @link https://github.com/windowsazure/azure-sdk-for-php */ namespace WindowsAzure\Blob\Models; /** * Holds result of getContainerProperties and getContainerMetadata * * @category Microsoft * @package WindowsAzure\Blob\Models * @author Azure PHP SDK * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @version Release: 0.4.1_2015-03 * @link https://github.com/windowsazure/azure-sdk-for-php */ class GetContainerPropertiesResult { /** * @var \DateTime */ private $_lastModified; /** * @var string */ private $_etag; /** * @var array */ private $_metadata; /** * Any operation that modifies the container or its properties or metadata * updates the last modified time. Operations on blobs do not affect the last * modified time of the container. * * @return \DateTime. */ public function getLastModified() { return $this->_lastModified; } /** * Sets container lastModified. * * @param \DateTime $lastModified value. * * @return none. */ public function setLastModified($lastModified) { $this->_lastModified = $lastModified; } /** * The entity tag for the container. If the request version is 2011-08-18 or * newer, the ETag value will be in quotes. * * @return string. */ public function getETag() { return $this->_etag; } /** * Sets container etag. * * @param string $etag value. * * @return none. */ public function setETag($etag) { $this->_etag = $etag; } /** * Gets user defined metadata. * * @return array. */ public function getMetadata() { return $this->_metadata; } /** * Sets user defined metadata. This metadata should be added without the header * prefix (x-ms-meta-*). * * @param array $metadata user defined metadata object in array form. * * @return none. */ public function setMetadata($metadata) { $this->_metadata = $metadata; } } includes/WindowsAzure/Blob/Models/BlobServiceOptions.php000064400000003255152214270100017377 0ustar00 * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @link https://github.com/windowsazure/azure-sdk-for-php */ namespace WindowsAzure\Blob\Models; /** * Blob service options. * * @category Microsoft * @package WindowsAzure\Blob\Models * @author Azure PHP SDK * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @version Release: 0.4.1_2015-03 * @link https://github.com/windowsazure/azure-sdk-for-php */ class BlobServiceOptions { private $_timeout; /** * Gets timeout. * * @return string. */ public function getTimeout() { return $this->_timeout; } /** * Sets timeout. * * @param string $timeout value. * * @return none. */ public function setTimeout($timeout) { $this->_timeout = $timeout; } } includes/WindowsAzure/Blob/Models/CreateBlobOptions.php000064400000020165152214270100017201 0ustar00 * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @link https://github.com/windowsazure/azure-sdk-for-php */ namespace WindowsAzure\Blob\Models; use WindowsAzure\Common\Internal\Validate; /** * optional parameters for createXXXBlob wrapper * * @category Microsoft * @package WindowsAzure\Blob\Models * @author Azure PHP SDK * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @version Release: 0.4.1_2015-03 * @link https://github.com/windowsazure/azure-sdk-for-php */ class CreateBlobOptions extends BlobServiceOptions { /** * @var string */ private $_contentType; /** * @var string */ private $_contentEncoding; /** * @var string */ private $_contentLanguage; /** * @var string */ private $_contentMD5; /** * @var string */ private $_cacheControl; /** * @var string */ private $_blobContentType; /** * @var string */ private $_blobContentEncoding; /** * @var string */ private $_blobContentLanguage; /** * @var string */ private $_blobContentMD5; /** * @var string */ private $_blobCacheControl; /** * @var array */ private $_metadata; /** * @var string */ private $_leaseId; /** * @var integer */ private $_sequenceNumber; /** * @var AccessCondition */ private $_accessCondition; /** * Gets blob ContentType. * * @return string. */ public function getBlobContentType() { return $this->_blobContentType; } /** * Sets blob ContentType. * * @param string $blobContentType value. * * @return none. */ public function setBlobContentType($blobContentType) { $this->_blobContentType = $blobContentType; } /** * Gets blob ContentEncoding. * * @return string. */ public function getBlobContentEncoding() { return $this->_blobContentEncoding; } /** * Sets blob ContentEncoding. * * @param string $blobContentEncoding value. * * @return none. */ public function setBlobContentEncoding($blobContentEncoding) { $this->_blobContentEncoding = $blobContentEncoding; } /** * Gets blob ContentLanguage. * * @return string. */ public function getBlobContentLanguage() { return $this->_blobContentLanguage; } /** * Sets blob ContentLanguage. * * @param string $blobContentLanguage value. * * @return none. */ public function setBlobContentLanguage($blobContentLanguage) { $this->_blobContentLanguage = $blobContentLanguage; } /** * Gets blob ContentMD5. * * @return string. */ public function getBlobContentMD5() { return $this->_blobContentMD5; } /** * Sets blob ContentMD5. * * @param string $blobContentMD5 value. * * @return none. */ public function setBlobContentMD5($blobContentMD5) { $this->_blobContentMD5 = $blobContentMD5; } /** * Gets blob cache control. * * @return string. */ public function getBlobCacheControl() { return $this->_blobCacheControl; } /** * Sets blob cacheControl. * * @param string $blobCacheControl value to use. * * @return none. */ public function setBlobCacheControl($blobCacheControl) { $this->_blobCacheControl = $blobCacheControl; } /** * Gets blob contentType. * * @return string. */ public function getContentType() { return $this->_contentType; } /** * Sets blob contentType. * * @param string $contentType value. * * @return none. */ public function setContentType($contentType) { $this->_contentType = $contentType; } /** * Gets contentEncoding. * * @return string. */ public function getContentEncoding() { return $this->_contentEncoding; } /** * Sets contentEncoding. * * @param string $contentEncoding value. * * @return none. */ public function setContentEncoding($contentEncoding) { $this->_contentEncoding = $contentEncoding; } /** * Gets contentLanguage. * * @return string. */ public function getContentLanguage() { return $this->_contentLanguage; } /** * Sets contentLanguage. * * @param string $contentLanguage value. * * @return none. */ public function setContentLanguage($contentLanguage) { $this->_contentLanguage = $contentLanguage; } /** * Gets contentMD5. * * @return string. */ public function getContentMD5() { return $this->_contentMD5; } /** * Sets contentMD5. * * @param string $contentMD5 value. * * @return none. */ public function setContentMD5($contentMD5) { $this->_contentMD5 = $contentMD5; } /** * Gets cacheControl. * * @return string. */ public function getCacheControl() { return $this->_cacheControl; } /** * Sets cacheControl. * * @param string $cacheControl value to use. * * @return none. */ public function setCacheControl($cacheControl) { $this->_cacheControl = $cacheControl; } /** * Gets access condition * * @return AccessCondition */ public function getAccessCondition() { return $this->_accessCondition; } /** * Sets access condition * * @param AccessCondition $accessCondition value to use. * * @return none. */ public function setAccessCondition($accessCondition) { $this->_accessCondition = $accessCondition; } /** * Gets blob metadata. * * @return array. */ public function getMetadata() { return $this->_metadata; } /** * Sets blob metadata. * * @param string $metadata value. * * @return none. */ public function setMetadata($metadata) { $this->_metadata = $metadata; } /** * Gets blob sequenceNumber. * * @return int. */ public function getSequenceNumber() { return $this->_sequenceNumber; } /** * Sets blob sequenceNumber. * * @param int $sequenceNumber value. * * @return none. */ public function setSequenceNumber($sequenceNumber) { Validate::isInteger($sequenceNumber, 'sequenceNumber'); $this->_sequenceNumber = $sequenceNumber; } /** * Gets lease Id for the blob * * @return string */ public function getLeaseId() { return $this->_leaseId; } /** * Sets lease Id for the blob * * @param string $leaseId the blob lease id. * * @return none */ public function setLeaseId($leaseId) { $this->_leaseId = $leaseId; } } includes/WindowsAzure/Blob/Models/GetBlobMetadataResult.php000064400000006706152214270100020006 0ustar00 * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @link https://github.com/windowsazure/azure-sdk-for-php */ namespace WindowsAzure\Blob\Models; use WindowsAzure\Common\Internal\Resources; use WindowsAzure\Common\Internal\Validate; use WindowsAzure\Common\Internal\Utilities; /** * Holds results of calling getBlobMetadata wrapper * * @category Microsoft * @package WindowsAzure\Blob\Models * @author Azure PHP SDK * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @version Release: 0.4.1_2015-03 * @link https://github.com/windowsazure/azure-sdk-for-php */ class GetBlobMetadataResult { /** * @var \DateTime */ private $_lastModified; /** * @var string */ private $_etag; /** * @var array */ private $_metadata; /** * Creates GetBlobMetadataResult from response headers. * * @param array $headers The HTTP response headers. * @param array $metadata The blob metadata array. * * @return GetBlobMetadataResult */ public static function create($headers, $metadata) { $result = new GetBlobMetadataResult(); $date = $headers[Resources::LAST_MODIFIED]; $result->setLastModified(Utilities::rfc1123ToDateTime($date)); $result->setETag($headers[Resources::ETAG]); $result->setMetadata(is_null($metadata) ? array() : $metadata); return $result; } /** * Gets blob lastModified. * * @return \DateTime. */ public function getLastModified() { return $this->_lastModified; } /** * Sets blob lastModified. * * @param \DateTime $lastModified value. * * @return none. */ public function setLastModified($lastModified) { Validate::isDate($lastModified); $this->_lastModified = $lastModified; } /** * Gets blob etag. * * @return string. */ public function getETag() { return $this->_etag; } /** * Sets blob etag. * * @param string $etag value. * * @return none. */ public function setETag($etag) { Validate::isString($etag, 'etag'); $this->_etag = $etag; } /** * Gets blob metadata. * * @return array. */ public function getMetadata() { return $this->_metadata; } /** * Sets blob metadata. * * @param string $metadata value. * * @return none. */ public function setMetadata($metadata) { $this->_metadata = $metadata; } } includes/WindowsAzure/Blob/Models/Container.php000064400000006132152214270100015543 0ustar00 * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @link https://github.com/windowsazure/azure-sdk-for-php */ namespace WindowsAzure\Blob\Models; use WindowsAzure\Common\Internal\Resources; use WindowsAzure\Common\Internal\Utilities; /** * WindowsAzure container object. * * @category Microsoft * @package WindowsAzure\Blob\Models * @author Azure PHP SDK * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @version Release: 0.4.1_2015-03 * @link https://github.com/windowsazure/azure-sdk-for-php */ class Container { /** * @var string */ private $_name; /** * @var string */ private $_url; /** * @var array */ private $_metadata; /** * @var ContainerProperties */ private $_properties; /** * Gets container name. * * @return string. */ public function getName() { return $this->_name; } /** * Sets container name. * * @param string $name value. * * @return none. */ public function setName($name) { $this->_name = $name; } /** * Gets container url. * * @return string. */ public function getUrl() { return $this->_url; } /** * Sets container url. * * @param string $url value. * * @return none. */ public function setUrl($url) { $this->_url = $url; } /** * Gets container metadata. * * @return array. */ public function getMetadata() { return $this->_metadata; } /** * Sets container metadata. * * @param array $metadata value. * * @return none. */ public function setMetadata($metadata) { $this->_metadata = $metadata; } /** * Gets container properties * * @return ContainerProperties */ public function getProperties() { return $this->_properties; } /** * Sets container properties * * @param ContainerProperties $properties container properties * * @return none. */ public function setProperties($properties) { $this->_properties = $properties; } } includes/WindowsAzure/Blob/Models/BreakLeaseResult.php000064400000004407152214270100017021 0ustar00 * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @link https://github.com/windowsazure/azure-sdk-for-php */ namespace WindowsAzure\Blob\Models; use WindowsAzure\Common\Internal\Resources; use WindowsAzure\Common\Internal\Utilities; /** * The result of calling breakLease API. * * @category Microsoft * @package WindowsAzure\Blob\Models * @author Azure PHP SDK * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @version Release: 0.4.1_2015-03 * @link https://github.com/windowsazure/azure-sdk-for-php */ class BreakLeaseResult { /** * @var string */ private $_leaseTime; /** * Creates BreakLeaseResult from response headers * * @param array $headers response headers * * @return BreakLeaseResult */ public static function create($headers) { $result = new BreakLeaseResult(); $result->setLeaseTime( Utilities::tryGetValue($headers, Resources::X_MS_LEASE_TIME) ); return $result; } /** * Gets lease time. * * @return string */ public function getLeaseTime() { return $this->_leaseTime; } /** * Sets lease time. * * @param string $leaseTime the blob lease time. * * @return none */ public function setLeaseTime($leaseTime) { $this->_leaseTime = $leaseTime; } }includes/WindowsAzure/Blob/Models/PageRange.php000064400000005543152214270100015457 0ustar00 * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @link https://github.com/windowsazure/azure-sdk-for-php */ namespace WindowsAzure\Blob\Models; /** * Holds info about page range used in HTTP requests * * @category Microsoft * @package WindowsAzure\Blob\Models * @author Azure PHP SDK * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @version Release: 0.4.1_2015-03 * @link https://github.com/windowsazure/azure-sdk-for-php */ class PageRange { /** * @var integer */ private $_start; /** * @var integer */ private $_end; /** * Constructor * * @param integer $start the page start value * @param integer $end the page end value * * @return PageRange */ public function __construct($start = null, $end = null) { $this->_start = $start; $this->_end = $end; } /** * Sets page start range * * @param integer $start the page range start * * @return none. */ public function setStart($start) { $this->_start = $start; } /** * Gets page start range * * @return integer */ public function getStart() { return $this->_start; } /** * Sets page end range * * @param integer $end the page range end * * @return none. */ public function setEnd($end) { $this->_end = $end; } /** * Gets page end range * * @return integer */ public function getEnd() { return $this->_end; } /** * Gets page range length * * @return integer */ public function getLength() { return $this->_end - $this->_start + 1; } /** * Sets page range length * * @param integer $value new page range * * @return none */ public function setLength($value) { $this->_end = $this->_start + $value - 1; } } includes/WindowsAzure/Blob/Models/ListContainersOptions.php000064400000010376152214270100020143 0ustar00 * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @link https://github.com/windowsazure/azure-sdk-for-php */ namespace WindowsAzure\Blob\Models; use WindowsAzure\Blob\Models\BlobServiceOptions; use \WindowsAzure\Common\Internal\Validate; /** * Options for listBlobs API. * * @category Microsoft * @package WindowsAzure\Blob\Models * @author Azure PHP SDK * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @version Release: 0.4.1_2015-03 * @link https://github.com/windowsazure/azure-sdk-for-php */ class ListContainersOptions extends BlobServiceOptions { /** * Filters the results to return only containers whose name begins with the * specified prefix. * * @var string */ private $_prefix; /** * Identifies the portion of the list to be returned with the next list operation * The operation returns a marker value within the * response body if the list returned was not complete. The marker value may * then be used in a subsequent call to request the next set of list items. * The marker value is opaque to the client. * * @var string */ private $_marker; /** * Specifies the maximum number of containers to return. If the request does not * specify maxresults, or specifies a value greater than 5,000, the server will * return up to 5,000 items. If the parameter is set to a value less than or * equal to zero, the server will return status code 400 (Bad Request). * * @var string */ private $_maxResults; /** * Include this parameter to specify that the container's metadata be returned * as part of the response body. * * @var bool */ private $_includeMetadata; /** * Gets prefix. * * @return string. */ public function getPrefix() { return $this->_prefix; } /** * Sets prefix. * * @param string $prefix value. * * @return none. */ public function setPrefix($prefix) { Validate::isString($prefix, 'prefix'); $this->_prefix = $prefix; } /** * Gets marker. * * @return string. */ public function getMarker() { return $this->_marker; } /** * Sets marker. * * @param string $marker value. * * @return none. */ public function setMarker($marker) { Validate::isString($marker, 'marker'); $this->_marker = $marker; } /** * Gets max results. * * @return string. */ public function getMaxResults() { return $this->_maxResults; } /** * Sets max results. * * @param string $maxResults value. * * @return none. */ public function setMaxResults($maxResults) { Validate::isString($maxResults, 'maxResults'); $this->_maxResults = $maxResults; } /** * Indicates if metadata is included or not. * * @return string. */ public function getIncludeMetadata() { return $this->_includeMetadata; } /** * Sets the include metadata flag. * * @param bool $includeMetadata value. * * @return none. */ public function setIncludeMetadata($includeMetadata) { Validate::isBoolean($includeMetadata); $this->_includeMetadata = $includeMetadata; } } includes/WindowsAzure/Blob/Models/GetBlobResult.php000064400000006574152214270100016350 0ustar00 * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @link https://github.com/windowsazure/azure-sdk-for-php */ namespace WindowsAzure\Blob\Models; use WindowsAzure\Blob\Models\BlobProperties; use WindowsAzure\Common\Internal\Utilities; /** * Holds result of GetBlob API. * * @category Microsoft * @package WindowsAzure\Blob\Models * @author Azure PHP SDK * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @version Release: 0.4.1_2015-03 * @link https://github.com/windowsazure/azure-sdk-for-php */ class GetBlobResult { /** * @var BlobProperties */ private $_properties; /** * @var array */ private $_metadata; /** * @var resource */ private $_contentStream; /** * Creates GetBlobResult from getBlob call. * * @param array $headers The HTTP response headers. * @param string $body The response body. * @param array $metadata The blob metadata. * * @return GetBlobResult */ public static function create($headers, $body, $metadata) { $result = new GetBlobResult(); $result->setContentStream(Utilities::stringToStream($body)); $result->setProperties(BlobProperties::create($headers)); $result->setMetadata(is_null($metadata) ? array() : $metadata); return $result; } /** * Gets blob metadata. * * @return array */ public function getMetadata() { return $this->_metadata; } /** * Sets blob metadata. * * @param string $metadata value. * * @return none */ public function setMetadata($metadata) { $this->_metadata = $metadata; } /** * Gets blob properties. * * @return BlobProperties */ public function getProperties() { return $this->_properties; } /** * Sets blob properties. * * @param BlobProperties $properties value. * * @return none */ public function setProperties($properties) { $this->_properties = $properties; } /** * Gets blob contentStream. * * @return resource */ public function getContentStream() { return $this->_contentStream; } /** * Sets blob contentStream. * * @param resource $contentStream The stream handle. * * @return none */ public function setContentStream($contentStream) { $this->_contentStream = $contentStream; } } includes/WindowsAzure/Blob/Models/CreateBlobPagesResult.php000064400000010365152214270100020005 0ustar00 * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @link https://github.com/windowsazure/azure-sdk-for-php */ namespace WindowsAzure\Blob\Models; use WindowsAzure\Common\Internal\Resources; use WindowsAzure\Common\Internal\Validate; use WindowsAzure\Common\Internal\Utilities; /** * Holds result of calling create or clear blob pages * * @category Microsoft * @package WindowsAzure\Blob\Models * @author Azure PHP SDK * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @version Release: 0.4.1_2015-03 * @link https://github.com/windowsazure/azure-sdk-for-php */ class CreateBlobPagesResult { /** * @var \DateTime */ private $_lastModified; /** * @var string */ private $_etag; /** * @var integer */ private $_sequenceNumber; /** * @var string */ private $_contentMD5; /** * Creates CreateBlobPagesResult object from $parsed response in array * representation * * @param array $headers HTTP response headers * * @return CreateBlobPagesResult */ public static function create($headers) { $result = new CreateBlobPagesResult(); $clean = array_change_key_case($headers); $date = $clean[Resources::LAST_MODIFIED]; $date = Utilities::rfc1123ToDateTime($date); $result->setETag($clean[Resources::ETAG]); $result->setLastModified($date); $result->setContentMD5( Utilities::tryGetValue($clean, Resources::CONTENT_MD5) ); $result->setSequenceNumber( intval( Utilities::tryGetValue($clean, Resources::X_MS_BLOB_SEQUENCE_NUMBER) ) ); return $result; } /** * Gets blob lastModified. * * @return \DateTime. */ public function getLastModified() { return $this->_lastModified; } /** * Sets blob lastModified. * * @param \DateTime $lastModified value. * * @return none. */ public function setLastModified($lastModified) { Validate::isDate($lastModified); $this->_lastModified = $lastModified; } /** * Gets blob etag. * * @return string. */ public function getETag() { return $this->_etag; } /** * Sets blob etag. * * @param string $etag value. * * @return none. */ public function setETag($etag) { Validate::isString($etag, 'etag'); $this->_etag = $etag; } /** * Gets blob contentMD5. * * @return string. */ public function getContentMD5() { return $this->_contentMD5; } /** * Sets blob contentMD5. * * @param string $contentMD5 value. * * @return none. */ public function setContentMD5($contentMD5) { $this->_contentMD5 = $contentMD5; } /** * Gets blob sequenceNumber. * * @return int. */ public function getSequenceNumber() { return $this->_sequenceNumber; } /** * Sets blob sequenceNumber. * * @param int $sequenceNumber value. * * @return none. */ public function setSequenceNumber($sequenceNumber) { Validate::isInteger($sequenceNumber, 'sequenceNumber'); $this->_sequenceNumber = $sequenceNumber; } } includes/WindowsAzure/Blob/Models/AcquireLeaseResult.php000064400000004422152214270100017363 0ustar00 * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @link https://github.com/windowsazure/azure-sdk-for-php */ namespace WindowsAzure\Blob\Models; use WindowsAzure\Common\Internal\Resources; use WindowsAzure\Common\Internal\Utilities; /** * The result of calling acquireLease API. * * @category Microsoft * @package WindowsAzure\Blob\Models * @author Azure PHP SDK * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @version Release: 0.4.1_2015-03 * @link https://github.com/windowsazure/azure-sdk-for-php */ class AcquireLeaseResult { /** * @var string */ private $_leaseId; /** * Creates AcquireLeaseResult from response headers * * @param array $headers response headers * * @return AcquireLeaseResult */ public static function create($headers) { $result = new AcquireLeaseResult(); $result->setLeaseId( Utilities::tryGetValue($headers, Resources::X_MS_LEASE_ID) ); return $result; } /** * Gets lease Id for the blob * * @return string */ public function getLeaseId() { return $this->_leaseId; } /** * Sets lease Id for the blob * * @param string $leaseId the blob lease id. * * @return none */ public function setLeaseId($leaseId) { $this->_leaseId = $leaseId; } } includes/WindowsAzure/Blob/Models/BlobBlockType.php000064400000003521152214270100016313 0ustar00 * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @link https://github.com/windowsazure/azure-sdk-for-php */ namespace WindowsAzure\Blob\Models; /** * Holds available blob block types * * @category Microsoft * @package WindowsAzure\Blob\Models * @author Azure PHP SDK * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @version Release: 0.4.1_2015-03 * @link https://github.com/windowsazure/azure-sdk-for-php */ class BlobBlockType { const COMMITTED_TYPE = 'Committed'; const UNCOMMITTED_TYPE = 'Uncommitted'; const LATEST_TYPE = 'Latest'; /** * Validates the provided type. * * @param string $type The entry type. * * @return boolean */ public static function isValid($type) { switch ($type) { case self::COMMITTED_TYPE: case self::LATEST_TYPE: case self::UNCOMMITTED_TYPE: return true; default: return false; } } } includes/WindowsAzure/Blob/Models/SetContainerMetadataOptions.php000064400000004255152214270100021240 0ustar00 * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @link https://github.com/windowsazure/azure-sdk-for-php */ namespace WindowsAzure\Blob\Models; use WindowsAzure\Blob\Models\AccessCondition; use WindowsAzure\Blob\Models\BlobServiceOptions; /** * Optional parameters for setContainerMetadata wrapper * * @category Microsoft * @package WindowsAzure\Blob\Models * @author Azure PHP SDK * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @version Release: 0.4.1_2015-03 * @link https://github.com/windowsazure/azure-sdk-for-php */ class SetContainerMetadataOptions extends BlobServiceOptions { /** * @var AccessCondition */ private $_accessCondition; /** * Constructs the access condition object with none option. */ public function __construct() { $this->_accessCondition = AccessCondition::none(); } /** * Gets access condition * * @return AccessCondition */ public function getAccessCondition() { return $this->_accessCondition; } /** * Sets access condition * * @param AccessCondition $accessCondition value to use. * * @return none. */ public function setAccessCondition($accessCondition) { $this->_accessCondition = $accessCondition; } } includes/WindowsAzure/Blob/Models/BlobProperties.php000064400000022207152214270100016555 0ustar00 * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @link https://github.com/windowsazure/azure-sdk-for-php */ namespace WindowsAzure\Blob\Models; use WindowsAzure\Common\Internal\Resources; use WindowsAzure\Common\Internal\Validate; use WindowsAzure\Common\Internal\Utilities; /** * Represents blob properties * * @category Microsoft * @package WindowsAzure\Blob\Models * @author Azure PHP SDK * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @version Release: 0.4.1_2015-03 * @link https://github.com/windowsazure/azure-sdk-for-php */ class BlobProperties { /** * @var \DateTime */ private $_lastModified; /** * @var string */ private $_etag; /** * @var string */ private $_contentType; /** * @var integer */ private $_contentLength; /** * @var string */ private $_contentEncoding; /** * @var string */ private $_contentLanguage; /** * @var string */ private $_contentMD5; /** * @var string */ private $_contentRange; /** * @var string */ private $_cacheControl; /** * @var string */ private $_blobType; /** * @var string */ private $_leaseStatus; /** * @var integer */ private $_sequenceNumber; /** * Creates BlobProperties object from $parsed response in array representation * * @param array $parsed parsed response in array format. * * @return BlobProperties */ public static function create($parsed) { $result = new BlobProperties(); $clean = array_change_key_case($parsed); $date = Utilities::tryGetValue($clean, Resources::LAST_MODIFIED); $result->setBlobType(Utilities::tryGetValue($clean, 'blobtype')); $result->setContentLength(intval($clean[Resources::CONTENT_LENGTH])); $result->setETag(Utilities::tryGetValue($clean, Resources::ETAG)); if (!is_null($date)) { $date = Utilities::rfc1123ToDateTime($date); $result->setLastModified($date); } $result->setLeaseStatus(Utilities::tryGetValue($clean, 'leasestatus')); $result->setLeaseStatus( Utilities::tryGetValue( $clean, Resources::X_MS_LEASE_STATUS, $result->getLeaseStatus() ) ); $result->setSequenceNumber( intval( Utilities::tryGetValue($clean, Resources::X_MS_BLOB_SEQUENCE_NUMBER) ) ); $result->setContentRange( Utilities::tryGetValue($clean, Resources::CONTENT_RANGE) ); $result->setCacheControl( Utilities::tryGetValue($clean, Resources::CACHE_CONTROL) ); $result->setBlobType( Utilities::tryGetValue( $clean, Resources::X_MS_BLOB_TYPE, $result->getBlobType() ) ); $result->setContentEncoding( Utilities::tryGetValue($clean, Resources::CONTENT_ENCODING) ); $result->setContentLanguage( Utilities::tryGetValue($clean, Resources::CONTENT_LANGUAGE) ); $result->setContentMD5( Utilities::tryGetValue($clean, Resources::CONTENT_MD5) ); $result->setContentType( Utilities::tryGetValue($clean, Resources::CONTENT_TYPE) ); return $result; } /** * Gets blob lastModified. * * @return \DateTime. */ public function getLastModified() { return $this->_lastModified; } /** * Sets blob lastModified. * * @param \DateTime $lastModified value. * * @return none. */ public function setLastModified($lastModified) { Validate::isDate($lastModified); $this->_lastModified = $lastModified; } /** * Gets blob etag. * * @return string. */ public function getETag() { return $this->_etag; } /** * Sets blob etag. * * @param string $etag value. * * @return none. */ public function setETag($etag) { $this->_etag = $etag; } /** * Gets blob contentType. * * @return string. */ public function getContentType() { return $this->_contentType; } /** * Sets blob contentType. * * @param string $contentType value. * * @return none. */ public function setContentType($contentType) { $this->_contentType = $contentType; } /** * Gets blob contentRange. * * @return string. */ public function getContentRange() { return $this->_contentRange; } /** * Sets blob contentRange. * * @param string $contentRange value. * * @return none. */ public function setContentRange($contentRange) { $this->_contentRange = $contentRange; } /** * Gets blob contentLength. * * @return integer. */ public function getContentLength() { return $this->_contentLength; } /** * Sets blob contentLength. * * @param integer $contentLength value. * * @return none. */ public function setContentLength($contentLength) { Validate::isInteger($contentLength, 'contentLength'); $this->_contentLength = $contentLength; } /** * Gets blob contentEncoding. * * @return string. */ public function getContentEncoding() { return $this->_contentEncoding; } /** * Sets blob contentEncoding. * * @param string $contentEncoding value. * * @return none. */ public function setContentEncoding($contentEncoding) { $this->_contentEncoding = $contentEncoding; } /** * Gets blob contentLanguage. * * @return string. */ public function getContentLanguage() { return $this->_contentLanguage; } /** * Sets blob contentLanguage. * * @param string $contentLanguage value. * * @return none. */ public function setContentLanguage($contentLanguage) { $this->_contentLanguage = $contentLanguage; } /** * Gets blob contentMD5. * * @return string. */ public function getContentMD5() { return $this->_contentMD5; } /** * Sets blob contentMD5. * * @param string $contentMD5 value. * * @return none. */ public function setContentMD5($contentMD5) { $this->_contentMD5 = $contentMD5; } /** * Gets blob cacheControl. * * @return string. */ public function getCacheControl() { return $this->_cacheControl; } /** * Sets blob cacheControl. * * @param string $cacheControl value. * * @return none. */ public function setCacheControl($cacheControl) { $this->_cacheControl = $cacheControl; } /** * Gets blob blobType. * * @return string. */ public function getBlobType() { return $this->_blobType; } /** * Sets blob blobType. * * @param string $blobType value. * * @return none. */ public function setBlobType($blobType) { $this->_blobType = $blobType; } /** * Gets blob leaseStatus. * * @return string. */ public function getLeaseStatus() { return $this->_leaseStatus; } /** * Sets blob leaseStatus. * * @param string $leaseStatus value. * * @return none. */ public function setLeaseStatus($leaseStatus) { $this->_leaseStatus = $leaseStatus; } /** * Gets blob sequenceNumber. * * @return int. */ public function getSequenceNumber() { return $this->_sequenceNumber; } /** * Sets blob sequenceNumber. * * @param int $sequenceNumber value. * * @return none. */ public function setSequenceNumber($sequenceNumber) { Validate::isInteger($sequenceNumber, 'sequenceNumber'); $this->_sequenceNumber = $sequenceNumber; } } includes/WindowsAzure/Blob/Models/ListBlobBlocksOptions.php000064400000011012152214270100020036 0ustar00 * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @link https://github.com/windowsazure/azure-sdk-for-php */ namespace WindowsAzure\Blob\Models; use WindowsAzure\Common\Internal\Validate; /** * Optional parameters for listBlobBlock wrapper * * @category Microsoft * @package WindowsAzure\Blob\Models * @author Azure PHP SDK * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @version Release: 0.4.1_2015-03 * @link https://github.com/windowsazure/azure-sdk-for-php */ class ListBlobBlocksOptions extends BlobServiceOptions { /** * @var string */ private $_leaseId; /** * @var string */ private $_snapshot; /** * @var boolean */ private $_includeUncommittedBlobs; /** * @var boolean */ private $_includeCommittedBlobs; /** * Holds result of list type. You can access it by this order: * $_listType[$this->_includeUncommittedBlobs][$this->_includeCommittedBlobs] * * @var array */ private static $_listType; /** * Constructs the static variable $listType. */ public function __construct() { self::$_listType[true][true] = 'all'; self::$_listType[true][false] = 'uncommitted'; self::$_listType[false][true] = 'committed'; self::$_listType[false][false] = 'all'; $this->_includeUncommittedBlobs = false; $this->_includeCommittedBlobs = false; } /** * Gets lease Id for the blob * * @return string */ public function getLeaseId() { return $this->_leaseId; } /** * Sets lease Id for the blob * * @param string $leaseId the blob lease id. * * @return none */ public function setLeaseId($leaseId) { $this->_leaseId = $leaseId; } /** * Gets blob snapshot. * * @return string. */ public function getSnapshot() { return $this->_snapshot; } /** * Sets blob snapshot. * * @param string $snapshot value. * * @return none. */ public function setSnapshot($snapshot) { $this->_snapshot = $snapshot; } /** * Sets the include uncommittedBlobs flag. * * @param bool $includeUncommittedBlobs value. * * @return none. */ public function setIncludeUncommittedBlobs($includeUncommittedBlobs) { Validate::isBoolean($includeUncommittedBlobs); $this->_includeUncommittedBlobs = $includeUncommittedBlobs; } /** * Indicates if uncommittedBlobs is included or not. * * @return boolean. */ public function getIncludeUncommittedBlobs() { return $this->_includeUncommittedBlobs; } /** * Sets the include committedBlobs flag. * * @param bool $includeCommittedBlobs value. * * @return none. */ public function setIncludeCommittedBlobs($includeCommittedBlobs) { Validate::isBoolean($includeCommittedBlobs); $this->_includeCommittedBlobs = $includeCommittedBlobs; } /** * Indicates if committedBlobs is included or not. * * @return boolean. */ public function getIncludeCommittedBlobs() { return $this->_includeCommittedBlobs; } /** * Gets block list type. * * @return string */ public function getBlockListType() { $includeUncommitted = $this->_includeUncommittedBlobs; $includeCommitted = $this->_includeCommittedBlobs; return self::$_listType[$includeUncommitted][$includeCommitted]; } } includes/WindowsAzure/Blob/Models/Block.php000064400000004211152214270100014647 0ustar00 * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @link https://github.com/windowsazure/azure-sdk-for-php */ namespace WindowsAzure\Blob\Models; /** * Holds information about blob block. * * @category Microsoft * @package WindowsAzure\Blob\Models * @author Azure PHP SDK * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @version Release: 0.4.1_2015-03 * @link https://github.com/windowsazure/azure-sdk-for-php */ class Block { /** * @var string */ private $_blockId; /** * @var string */ private $_type; /** * Sets the blockId. * * @param string $blockId The id of the block. * * @return none */ public function setBlockId($blockId) { $this->_blockId = $blockId; } /** * Gets the blockId. * * @return string */ public function getBlockId() { return $this->_blockId; } /** * Sets the type. * * @param string $type The type of the block. * * @return none */ public function setType($type) { $this->_type = $type; } /** * Gets the type. * * @return string */ public function getType() { return $this->_type; } } includes/WindowsAzure/Blob/Models/SetBlobPropertiesOptions.php000064400000015134152214270100020606 0ustar00 * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @link https://github.com/windowsazure/azure-sdk-for-php */ namespace WindowsAzure\Blob\Models; use WindowsAzure\Common\Internal\Validate; /** * Optional parameters for setBlobProperties wrapper * * @category Microsoft * @package WindowsAzure\Blob\Models * @author Azure PHP SDK * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @version Release: 0.4.1_2015-03 * @link https://github.com/windowsazure/azure-sdk-for-php */ class SetBlobPropertiesOptions extends BlobServiceOptions { /** * @var BlobProperties */ private $_blobProperties; /** * @var string */ private $_leaseId; /** * @var string */ private $_sequenceNumberAction; /** * @var AccessCondition */ private $_accessCondition; /** * Creates a new SetBlobPropertiesOptions with a specified BlobProperties * instance. * * @param BlobProperties $blobProperties The blob properties instance. */ public function __construct($blobProperties = null) { $this->_blobProperties = is_null($blobProperties) ? new BlobProperties() : clone $blobProperties; } /** * Gets access condition * * @return AccessCondition */ public function getAccessCondition() { return $this->_accessCondition; } /** * Sets access condition * * @param AccessCondition $accessCondition value to use. * * @return none. */ public function setAccessCondition($accessCondition) { $this->_accessCondition = $accessCondition; } /** * Gets blob sequenceNumber. * * @return integer. */ public function getSequenceNumber() { return $this->_blobProperties->getSequenceNumber(); } /** * Sets blob sequenceNumber. * * @param integer $sequenceNumber value. * * @return none. */ public function setSequenceNumber($sequenceNumber) { $this->_blobProperties->setSequenceNumber($sequenceNumber); } /** * Gets lease Id for the blob * * @return string */ public function getSequenceNumberAction() { return $this->_sequenceNumberAction; } /** * Sets lease Id for the blob * * @param string $sequenceNumberAction action. * * @return none */ public function setSequenceNumberAction($sequenceNumberAction) { $this->_sequenceNumberAction = $sequenceNumberAction; } /** * Gets lease Id for the blob * * @return string */ public function getLeaseId() { return $this->_leaseId; } /** * Sets lease Id for the blob * * @param string $leaseId the blob lease id. * * @return none */ public function setLeaseId($leaseId) { $this->_leaseId = $leaseId; } /** * Gets blob blobContentLength. * * @return integer. */ public function getBlobContentLength() { return $this->_blobProperties->getContentLength(); } /** * Sets blob blobContentLength. * * @param integer $blobContentLength value. * * @return none. */ public function setBlobContentLength($blobContentLength) { $this->_blobProperties->setContentLength($blobContentLength); } /** * Gets blob ContentType. * * @return string. */ public function getBlobContentType() { return $this->_blobProperties->getContentType(); } /** * Sets blob ContentType. * * @param string $blobContentType value. * * @return none. */ public function setBlobContentType($blobContentType) { $this->_blobProperties->setContentType($blobContentType); } /** * Gets blob ContentEncoding. * * @return string. */ public function getBlobContentEncoding() { return $this->_blobProperties->getContentEncoding(); } /** * Sets blob ContentEncoding. * * @param string $blobContentEncoding value. * * @return none. */ public function setBlobContentEncoding($blobContentEncoding) { $this->_blobProperties->setContentEncoding($blobContentEncoding); } /** * Gets blob ContentLanguage. * * @return string. */ public function getBlobContentLanguage() { return $this->_blobProperties->getContentLanguage(); } /** * Sets blob ContentLanguage. * * @param string $blobContentLanguage value. * * @return none. */ public function setBlobContentLanguage($blobContentLanguage) { $this->_blobProperties->setContentLanguage($blobContentLanguage); } /** * Gets blob ContentMD5. * * @return string. */ public function getBlobContentMD5() { return $this->_blobProperties->getContentMD5(); } /** * Sets blob ContentMD5. * * @param string $blobContentMD5 value. * * @return none. */ public function setBlobContentMD5($blobContentMD5) { $this->_blobProperties->setContentMD5($blobContentMD5); } /** * Gets blob cache control. * * @return string. */ public function getBlobCacheControl() { return $this->_blobProperties->getCacheControl(); } /** * Sets blob cacheControl. * * @param string $blobCacheControl value to use. * * @return none. */ public function setBlobCacheControl($blobCacheControl) { $this->_blobProperties->setCacheControl($blobCacheControl); } }includes/WindowsAzure/Blob/Models/GetBlobPropertiesResult.php000064400000004333152214270100020414 0ustar00 * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @link https://github.com/windowsazure/azure-sdk-for-php */ namespace WindowsAzure\Blob\Models; /** * Holds result of calling getBlobProperties * * @category Microsoft * @package WindowsAzure\Blob\Models * @author Azure PHP SDK * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @version Release: 0.4.1_2015-03 * @link https://github.com/windowsazure/azure-sdk-for-php */ class GetBlobPropertiesResult { /** * @var BlobProperties */ private $_properties; /** * @var array */ private $_metadata; /** * Gets blob metadata. * * @return array. */ public function getMetadata() { return $this->_metadata; } /** * Sets blob metadata. * * @param string $metadata value. * * @return none. */ public function setMetadata($metadata) { $this->_metadata = $metadata; } /** * Gets blob properties. * * @return BlobProperties. */ public function getProperties() { return $this->_properties; } /** * Sets blob properties. * * @param BlobProperties $properties value. * * @return none. */ public function setProperties($properties) { $this->_properties = $properties; } } includes/WindowsAzure/Blob/Models/SetBlobMetadataResult.php000064400000005603152214270100020015 0ustar00 * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @link https://github.com/windowsazure/azure-sdk-for-php */ namespace WindowsAzure\Blob\Models; use WindowsAzure\Common\Internal\Resources; use WindowsAzure\Common\Internal\Validate; use WindowsAzure\Common\Internal\Utilities; /** * Holds results of calling getBlobMetadata wrapper * * @category Microsoft * @package WindowsAzure\Blob\Models * @author Azure PHP SDK * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @version Release: 0.4.1_2015-03 * @link https://github.com/windowsazure/azure-sdk-for-php */ class SetBlobMetadataResult { /** * @var \DateTime */ private $_lastModified; /** * @var string */ private $_etag; /** * Creates SetBlobMetadataResult from response headers. * * @param array $headers response headers * * @return SetBlobMetadataResult */ public static function create($headers) { $result = new SetBlobMetadataResult(); $date = $headers[Resources::LAST_MODIFIED]; $result->setLastModified(Utilities::rfc1123ToDateTime($date)); $result->setETag($headers[Resources::ETAG]); return $result; } /** * Gets blob lastModified. * * @return \DateTime. */ public function getLastModified() { return $this->_lastModified; } /** * Sets blob lastModified. * * @param \DateTime $lastModified value. * * @return none. */ public function setLastModified($lastModified) { Validate::isDate($lastModified); $this->_lastModified = $lastModified; } /** * Gets blob etag. * * @return string. */ public function getETag() { return $this->_etag; } /** * Sets blob etag. * * @param string $etag value. * * @return none. */ public function setETag($etag) { Validate::isString($etag, 'etag'); $this->_etag = $etag; } } includes/WindowsAzure/Blob/Models/CreateBlobSnapshotResult.php000064400000007332152214270100020545 0ustar00 * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @link https://github.com/windowsazure/azure-sdk-for-php */ namespace WindowsAzure\Blob\Models; use WindowsAzure\Common\Internal\Resources; use WindowsAzure\Common\Internal\Validate; use WindowsAzure\Common\Internal\Utilities; /** * The result of creating Blob snapshot. * * @category Microsoft * @package WindowsAzure\Blob\Models * @author Azure PHP SDK * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @version Release: 0.4.1_2015-03 * @link https://github.com/windowsazure/azure-sdk-for-php */ class CreateBlobSnapshotResult { /** * A DateTime value which uniquely identifies the snapshot. * @var string */ private $_snapshot; /** * The ETag for the destination blob. * @var string */ private $_etag; /** * The date/time that the copy operation to the destination blob completed. * @var \DateTime */ private $_lastModified; /** * Creates CreateBlobSnapshotResult object from the response of the * create Blob snapshot request. * * @param array $headers The HTTP response headers in array representation. * * @return CreateBlobSnapshotResult */ public static function create($headers) { $result = new CreateBlobSnapshotResult(); $headerWithLowerCaseKey = array_change_key_case($headers); $result->setETag($headerWithLowerCaseKey[Resources::ETAG]); $result->setLastModified( Utilities::rfc1123ToDateTime( $headerWithLowerCaseKey[Resources::LAST_MODIFIED] ) ); $result->setSnapshot($headerWithLowerCaseKey[Resources::X_MS_SNAPSHOT]); return $result; } /** * Gets snapshot. * * @return string */ public function getSnapshot() { return $this->_snapshot; } /** * Sets snapshot. * * @param string $snapshot value. * * @return none */ public function setSnapshot($snapshot) { $this->_snapshot = $snapshot; } /** * Gets ETag. * * @return string */ public function getETag() { return $this->_etag; } /** * Sets ETag. * * @param string $etag value. * * @return none */ public function setETag($etag) { $this->_etag = $etag; } /** * Gets blob lastModified. * * @return \DateTime */ public function getLastModified() { return $this->_lastModified; } /** * Sets blob lastModified. * * @param \DateTime $lastModified value. * * @return none */ public function setLastModified($lastModified) { $this->_lastModified = $lastModified; } } includes/WindowsAzure/Blob/Models/CreateBlobPagesOptions.php000064400000005421152214270100020157 0ustar00 * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @link https://github.com/windowsazure/azure-sdk-for-php */ namespace WindowsAzure\Blob\Models; /** * Optional parameters for create and clear blob pages * * @category Microsoft * @package WindowsAzure\Blob\Models * @author Azure PHP SDK * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @version Release: 0.4.1_2015-03 * @link https://github.com/windowsazure/azure-sdk-for-php */ class CreateBlobPagesOptions extends BlobServiceOptions { /** * @var string */ private $_contentMD5; /** * @var string */ private $_leaseId; /** * @var AccessCondition */ private $_accessCondition; /** * Gets access condition * * @return AccessCondition */ public function getAccessCondition() { return $this->_accessCondition; } /** * Sets access condition * * @param AccessCondition $accessCondition value to use. * * @return none. */ public function setAccessCondition($accessCondition) { $this->_accessCondition = $accessCondition; } /** * Gets lease Id for the blob * * @return string */ public function getLeaseId() { return $this->_leaseId; } /** * Sets lease Id for the blob * * @param string $leaseId the blob lease id. * * @return none */ public function setLeaseId($leaseId) { $this->_leaseId = $leaseId; } /** * Gets blob contentMD5. * * @return string. */ public function getContentMD5() { return $this->_contentMD5; } /** * Sets blob contentMD5. * * @param string $contentMD5 value. * * @return none. */ public function setContentMD5($contentMD5) { $this->_contentMD5 = $contentMD5; } } includes/WindowsAzure/Blob/Models/DeleteContainerOptions.php000064400000003572152214270100020247 0ustar00 * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @link https://github.com/windowsazure/azure-sdk-for-php */ namespace WindowsAzure\Blob\Models; /** * The optional for deleteContainer API. * * @category Microsoft * @package WindowsAzure\Blob\Models * @author Azure PHP SDK * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @version Release: 0.4.1_2015-03 * @link https://github.com/windowsazure/azure-sdk-for-php */ class DeleteContainerOptions extends BlobServiceOptions { /** * @var AccessCondition */ private $_accessCondition; /** * Gets access condition * * @return AccessCondition */ public function getAccessCondition() { return $this->_accessCondition; } /** * Sets access condition * * @param AccessCondition $accessCondition value to use. * * @return none. */ public function setAccessCondition($accessCondition) { $this->_accessCondition = $accessCondition; } } includes/WindowsAzure/Blob/Models/CommitBlobBlocksOptions.php000064400000012434152214270100020364 0ustar00 * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @link https://github.com/windowsazure/azure-sdk-for-php */ namespace WindowsAzure\Blob\Models; use WindowsAzure\Common\Internal\Validate; /** * Optional parameters for commitBlobBlocks * * @category Microsoft * @package WindowsAzure\Blob\Models * @author Azure PHP SDK * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @version Release: 0.4.1_2015-03 * @link https://github.com/windowsazure/azure-sdk-for-php */ class CommitBlobBlocksOptions extends BlobServiceOptions { /** * @var string */ private $_blobContentType; /** * @var string */ private $_blobContentEncoding; /** * @var string */ private $_blobContentLanguage; /** * @var string */ private $_blobContentMD5; /** * @var string */ private $_blobCacheControl; /** * @var array */ private $_metadata; /** * @var string */ private $_leaseId; /** * @var AccessCondition */ private $_accessCondition; /** * Gets blob ContentType. * * @return string. */ public function getBlobContentType() { return $this->_blobContentType; } /** * Sets blob ContentType. * * @param string $blobContentType value. * * @return none. */ public function setBlobContentType($blobContentType) { $this->_blobContentType = $blobContentType; } /** * Gets blob ContentEncoding. * * @return string. */ public function getBlobContentEncoding() { return $this->_blobContentEncoding; } /** * Sets blob ContentEncoding. * * @param string $blobContentEncoding value. * * @return none. */ public function setBlobContentEncoding($blobContentEncoding) { $this->_blobContentEncoding = $blobContentEncoding; } /** * Gets blob ContentLanguage. * * @return string. */ public function getBlobContentLanguage() { return $this->_blobContentLanguage; } /** * Sets blob ContentLanguage. * * @param string $blobContentLanguage value. * * @return none. */ public function setBlobContentLanguage($blobContentLanguage) { $this->_blobContentLanguage = $blobContentLanguage; } /** * Gets blob ContentMD5. * * @return string. */ public function getBlobContentMD5() { return $this->_blobContentMD5; } /** * Sets blob ContentMD5. * * @param string $blobContentMD5 value. * * @return none. */ public function setBlobContentMD5($blobContentMD5) { $this->_blobContentMD5 = $blobContentMD5; } /** * Gets blob cache control. * * @return string. */ public function getBlobCacheControl() { return $this->_blobCacheControl; } /** * Sets blob cacheControl. * * @param string $blobCacheControl value to use. * * @return none. */ public function setBlobCacheControl($blobCacheControl) { $this->_blobCacheControl = $blobCacheControl; } /** * Gets access condition * * @return AccessCondition */ public function getAccessCondition() { return $this->_accessCondition; } /** * Sets access condition * * @param AccessCondition $accessCondition value to use. * * @return none. */ public function setAccessCondition($accessCondition) { $this->_accessCondition = $accessCondition; } /** * Gets blob metadata. * * @return array. */ public function getMetadata() { return $this->_metadata; } /** * Sets blob metadata. * * @param string $metadata value. * * @return none. */ public function setMetadata($metadata) { $this->_metadata = $metadata; } /** * Gets lease Id for the blob * * @return string */ public function getLeaseId() { return $this->_leaseId; } /** * Sets lease Id for the blob * * @param string $leaseId the blob lease id. * * @return none */ public function setLeaseId($leaseId) { $this->_leaseId = $leaseId; } } includes/WindowsAzure/Blob/Models/PublicAccessType.php000064400000003622152214270100017024 0ustar00 * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @link https://github.com/windowsazure/azure-sdk-for-php */ namespace WindowsAzure\Blob\Models; use WindowsAzure\Common\Internal\Resources; /** * Holds public acces types for a container. * * @category Microsoft * @package WindowsAzure\Blob\Models * @author Azure PHP SDK * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @version Release: 0.4.1_2015-03 * @link https://github.com/windowsazure/azure-sdk-for-php */ class PublicAccessType { const NONE = Resources::EMPTY_STRING; const BLOBS_ONLY = 'blob'; const CONTAINER_AND_BLOBS = 'container'; /** * Validates the public access. * * @param string $type The public access type. * * @return boolean */ public static function isValid($type) { switch ($type) { case self::NONE: case self::BLOBS_ONLY: case self::CONTAINER_AND_BLOBS: return true; default: return false; } } } includes/WindowsAzure/Blob/Models/CopyBlobResult.php000064400000006013152214270100016527 0ustar00 * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @link https://github.com/windowsazure/azure-sdk-for-php */ namespace WindowsAzure\Blob\Models; use WindowsAzure\Common\Internal\Resources; use WindowsAzure\Common\Internal\Utilities; /** * The result of calling copyBlob API. * * @category Microsoft * @package WindowsAzure\Blob\Models * @author Azure PHP SDK * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @version Release: 0.4.1_2015-03 * @link https://github.com/windowsazure/azure-sdk-for-php */ class CopyBlobResult { /** * @var string */ private $_etag; /** * @var \DateTime */ private $_lastModified; /** * Creates CopyBlobResult object from the response of the copy blob request. * * @param array $headers The HTTP response headers in array representation. * * @return CopyBlobResult */ public static function create($headers) { $result = new CopyBlobResult(); $result->setETag(Utilities::tryGetValueInsensitive( Resources::ETAG, $headers)); if (Utilities::arrayKeyExistsInsensitive(Resources::LAST_MODIFIED, $headers)) { $lastModified = Utilities::tryGetValueInsensitive( Resources::LAST_MODIFIED, $headers); $result->setLastModified(Utilities::rfc1123ToDateTime($lastModified)); } return $result; } /** * Gets ETag. * * @return string */ public function getETag() { return $this->_etag; } /** * Sets ETag. * * @param string $etag value. * * @return none */ public function setETag($etag) { $this->_etag = $etag; } /** * Gets blob lastModified. * * @return \DateTime */ public function getLastModified() { return $this->_lastModified; } /** * Sets blob lastModified. * * @param \DateTime $lastModified value. * * @return none */ public function setLastModified($lastModified) { $this->_lastModified = $lastModified; } } includes/WindowsAzure/Blob/Models/ListBlobsResult.php000064400000017051152214270100016717 0ustar00 * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @link https://github.com/windowsazure/azure-sdk-for-php */ namespace WindowsAzure\Blob\Models; use WindowsAzure\Common\Internal\Resources; use WindowsAzure\Blob\Models\Blob; use WindowsAzure\Common\Internal\Utilities; use WindowsAzure\Common\Internal\InvalidArgumentTypeException; /** * Hold result of calliing listBlobs wrapper. * * @category Microsoft * @package WindowsAzure\Blob\Models * @author Azure PHP SDK * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @version Release: 0.4.1_2015-03 * @link https://github.com/windowsazure/azure-sdk-for-php */ class ListBlobsResult { /** * @var array */ private $_blobPrefixes; /** * @var array */ private $_blobs; /** * @var string */ private $_delimiter; /** * @var string */ private $_prefix; /** * @var string */ private $_marker; /** * @var string */ private $_nextMarker; /** * @var integer */ private $_maxResults; /** * @var string */ private $_containerName; /** * Creates ListBlobsResult object from parsed XML response. * * @param array $parsed XML response parsed into array. * * @return ListBlobsResult */ public static function create($parsed) { $result = new ListBlobsResult(); $result->_containerName = Utilities::tryGetKeysChainValue( $parsed, Resources::XTAG_ATTRIBUTES, Resources::XTAG_CONTAINER_NAME ); $result->_prefix = Utilities::tryGetValue( $parsed, Resources::QP_PREFIX ); $result->_marker = Utilities::tryGetValue( $parsed, Resources::QP_MARKER ); $result->_nextMarker = Utilities::tryGetValue( $parsed, Resources::QP_NEXT_MARKER ); $result->_maxResults = intval( Utilities::tryGetValue($parsed, Resources::QP_MAX_RESULTS, 0) ); $result->_delimiter = Utilities::tryGetValue( $parsed, Resources::QP_DELIMITER ); $result->_blobs = array(); $result->_blobPrefixes = array(); $rawBlobs = array(); $rawBlobPrefixes = array(); if ( is_array($parsed['Blobs']) && array_key_exists('Blob', $parsed['Blobs']) ) { $rawBlobs = Utilities::getArray($parsed['Blobs']['Blob']); } foreach ($rawBlobs as $value) { $blob = new Blob(); $blob->setName($value['Name']); if (isset($value['Url'])) $blob->setUrl($value['Url']); $blob->setSnapshot(Utilities::tryGetValue($value, 'Snapshot')); $blob->setProperties( BlobProperties::create( Utilities::tryGetValue($value, 'Properties') ) ); $blob->setMetadata( Utilities::tryGetValue($value, Resources::QP_METADATA, array()) ); $result->_blobs[] = $blob; } if ( is_array($parsed['Blobs']) && array_key_exists('BlobPrefix', $parsed['Blobs']) ) { $rawBlobPrefixes = Utilities::getArray($parsed['Blobs']['BlobPrefix']); } foreach ($rawBlobPrefixes as $value) { $blobPrefix = new BlobPrefix(); $blobPrefix->setName($value['Name']); $result->_blobPrefixes[] = $blobPrefix; } return $result; } /** * Gets blobs. * * @return array */ public function getBlobs() { return $this->_blobs; } /** * Sets blobs. * * @param array $blobs list of blobs * * @return none */ public function setBlobs($blobs) { $this->_blobs = array(); foreach ($blobs as $blob) { $this->_blobs[] = clone $blob; } } /** * Gets blobPrefixes. * * @return array */ public function getBlobPrefixes() { return $this->_blobPrefixes; } /** * Sets blobPrefixes. * * @param array $blobPrefixes list of blobPrefixes * * @return none */ public function setBlobPrefixes($blobPrefixes) { $this->_blobPrefixes = array(); foreach ($blobPrefixes as $blob) { $this->_blobPrefixes[] = clone $blob; } } /** * Gets prefix. * * @return string */ public function getPrefix() { return $this->_prefix; } /** * Sets prefix. * * @param string $prefix value. * * @return none */ public function setPrefix($prefix) { $this->_prefix = $prefix; } /** * Gets prefix. * * @return string */ public function getDelimiter() { return $this->_delimiter; } /** * Sets prefix. * * @param string $delimiter value. * * @return none */ public function setDelimiter($delimiter) { $this->_delimiter = $delimiter; } /** * Gets marker. * * @return string */ public function getMarker() { return $this->_marker; } /** * Sets marker. * * @param string $marker value. * * @return none */ public function setMarker($marker) { $this->_marker = $marker; } /** * Gets max results. * * @return integer */ public function getMaxResults() { return $this->_maxResults; } /** * Sets max results. * * @param integer $maxResults value. * * @return none */ public function setMaxResults($maxResults) { $this->_maxResults = $maxResults; } /** * Gets next marker. * * @return string */ public function getNextMarker() { return $this->_nextMarker; } /** * Sets next marker. * * @param string $nextMarker value. * * @return none */ public function setNextMarker($nextMarker) { $this->_nextMarker = $nextMarker; } /** * Gets container name. * * @return string */ public function getContainerName() { return $this->_containerName; } /** * Sets container name. * * @param string $containerName value. * * @return none */ public function setContainerName($containerName) { $this->_containerName = $containerName; } } includes/WindowsAzure/Blob/Models/ContainerACL.php000064400000015064152214270100016067 0ustar00 * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @link https://github.com/windowsazure/azure-sdk-for-php */ namespace WindowsAzure\Blob\Models; use WindowsAzure\Common\Internal\Utilities; use WindowsAzure\Common\Internal\Validate; use WindowsAzure\Common\Internal\Resources; use WindowsAzure\Blob\Models\AccessPolicy; use WindowsAzure\Blob\Models\SignedIdentifier; use WindowsAzure\Blob\Models\PublicAccessType; use WindowsAzure\Common\Internal\Serialization\XmlSerializer; /** * Holds conatiner ACL members. * * @category Microsoft * @package WindowsAzure\Blob\Models * @author Azure PHP SDK * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @version Release: 0.4.1_2015-03 * @link https://github.com/windowsazure/azure-sdk-for-php */ class ContainerAcl { /** * All available types can be found in PublicAccessType * * @var string */ private $_publicAccess; /** * @var array */ private $_signedIdentifiers = array(); /* * The root name of XML elemenet representation. * * @var string */ public static $xmlRootName = 'SignedIdentifiers'; /** * Parses the given array into signed identifiers. * * @param string $publicAccess The container public access. * @param array $parsed The parsed response into array representation. * * @return none */ public static function create($publicAccess, $parsed) { $result = new ContainerAcl(); $result->_publicAccess = $publicAccess; $result->_signedIdentifiers = array(); if (!empty($parsed) && is_array($parsed['SignedIdentifier'])) { $entries = $parsed['SignedIdentifier']; $temp = Utilities::getArray($entries); foreach ($temp as $value) { $startString = urldecode($value['AccessPolicy']['Start']); $expiryString = urldecode($value['AccessPolicy']['Expiry']); $start = Utilities::convertToDateTime($startString); $expiry = Utilities::convertToDateTime($expiryString); $permission = $value['AccessPolicy']['Permission']; $id = $value['Id']; $result->addSignedIdentifier($id, $start, $expiry, $permission); } } return $result; } /** * Gets container signed modifiers. * * @return array. */ public function getSignedIdentifiers() { return $this->_signedIdentifiers; } /** * Sets container signed modifiers. * * @param array $signedIdentifiers value. * * @return none. */ public function setSignedIdentifiers($signedIdentifiers) { $this->_signedIdentifiers = $signedIdentifiers; } /** * Gets container publicAccess. * * @return string. */ public function getPublicAccess() { return $this->_publicAccess; } /** * Sets container publicAccess. * * @param string $publicAccess value. * * @return none. */ public function setPublicAccess($publicAccess) { Validate::isTrue( PublicAccessType::isValid($publicAccess), Resources::INVALID_BLOB_PAT_MSG ); $this->_publicAccess = $publicAccess; } /** * Adds new signed modifier * * @param string $id a unique id for this modifier * @param \DateTime $start The time at which the Shared Access Signature * becomes valid. If omitted, start time for this call is assumed to be * the time when the Blob service receives the request. * @param \DateTime $expiry The time at which the Shared Access Signature * becomes invalid. This field may be omitted if it has been specified as * part of a container-level access policy. * @param string $permission The permissions associated with the Shared * Access Signature. The user is restricted to operations allowed by the * permissions. Valid permissions values are read (r), write (w), delete (d) and * list (l). * * @return none. * * @see http://msdn.microsoft.com/en-us/library/windowsazure/hh508996.aspx */ public function addSignedIdentifier($id, $start, $expiry, $permission) { Validate::isString($id, 'id'); Validate::isDate($start); Validate::isDate($expiry); Validate::isString($permission, 'permission'); $accessPolicy = new AccessPolicy(); $accessPolicy->setStart($start); $accessPolicy->setExpiry($expiry); $accessPolicy->setPermission($permission); $signedIdentifier = new SignedIdentifier(); $signedIdentifier->setId($id); $signedIdentifier->setAccessPolicy($accessPolicy); $this->_signedIdentifiers[] = $signedIdentifier; } /** * Converts this object to array representation for XML serialization * * @return array. */ public function toArray() { $array = array(); foreach ($this->_signedIdentifiers as $value) { $array[] = $value->toArray(); } return $array; } /** * Converts this current object to XML representation. * * @param XmlSerializer $xmlSerializer The XML serializer. * * @return string. */ public function toXml($xmlSerializer) { $properties = array( XmlSerializer::DEFAULT_TAG => 'SignedIdentifier', XmlSerializer::ROOT_NAME => self::$xmlRootName ); return $xmlSerializer->serialize($this->toArray(), $properties); } } includes/WindowsAzure/Blob/Models/GetBlobMetadataOptions.php000064400000005372152214270100020161 0ustar00 * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @link https://github.com/windowsazure/azure-sdk-for-php */ namespace WindowsAzure\Blob\Models; /** * Optional parameters for getBlobMetadata wrapper * * @category Microsoft * @package WindowsAzure\Blob\Models * @author Azure PHP SDK * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @version Release: 0.4.1_2015-03 * @link https://github.com/windowsazure/azure-sdk-for-php */ class GetBlobMetadataOptions extends BlobServiceOptions { /** * @var string */ private $_leaseId; /** * @var string */ private $_snapshot; /** * @var AccessCondition */ private $_accessCondition; /** * Gets lease Id for the blob * * @return string */ public function getLeaseId() { return $this->_leaseId; } /** * Sets lease Id for the blob * * @param string $leaseId the blob lease id. * * @return none */ public function setLeaseId($leaseId) { $this->_leaseId = $leaseId; } /** * Gets access condition * * @return AccessCondition */ public function getAccessCondition() { return $this->_accessCondition; } /** * Sets access condition * * @param AccessCondition $accessCondition value to use. * * @return none. */ public function setAccessCondition($accessCondition) { $this->_accessCondition = $accessCondition; } /** * Gets blob snapshot. * * @return string. */ public function getSnapshot() { return $this->_snapshot; } /** * Sets blob snapshot. * * @param string $snapshot value. * * @return none. */ public function setSnapshot($snapshot) { $this->_snapshot = $snapshot; } } includes/WindowsAzure/Blob/BlobRestProxy.php000064400000240450152214270100015157 0ustar00 * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @link https://github.com/windowsazure/azure-sdk-for-php */ namespace WindowsAzure\Blob; use WindowsAzure\Common\Internal\Utilities; use WindowsAzure\Common\Internal\Resources; use WindowsAzure\Common\Internal\Validate; use WindowsAzure\Common\Models\ServiceProperties; use WindowsAzure\Common\Internal\ServiceRestProxy; use WindowsAzure\Blob\Internal\IBlob; use WindowsAzure\Blob\Models\BlobServiceOptions; use WindowsAzure\Common\Models\GetServicePropertiesResult; use WindowsAzure\Blob\Models\ListContainersOptions; use WindowsAzure\Blob\Models\ListContainersResult; use WindowsAzure\Blob\Models\CreateContainerOptions; use WindowsAzure\Blob\Models\GetContainerPropertiesResult; use WindowsAzure\Blob\Models\GetContainerACLResult; use WindowsAzure\Blob\Models\SetContainerMetadataOptions; use WindowsAzure\Blob\Models\DeleteContainerOptions; use WindowsAzure\Blob\Models\ListBlobsOptions; use WindowsAzure\Blob\Models\ListBlobsResult; use WindowsAzure\Blob\Models\BlobType; use WindowsAzure\Blob\Models\Block; use WindowsAzure\Blob\Models\CreateBlobOptions; use WindowsAzure\Blob\Models\BlobProperties; use WindowsAzure\Blob\Models\GetBlobPropertiesOptions; use WindowsAzure\Blob\Models\GetBlobPropertiesResult; use WindowsAzure\Blob\Models\SetBlobPropertiesOptions; use WindowsAzure\Blob\Models\SetBlobPropertiesResult; use WindowsAzure\Blob\Models\GetBlobMetadataOptions; use WindowsAzure\Blob\Models\GetBlobMetadataResult; use WindowsAzure\Blob\Models\SetBlobMetadataOptions; use WindowsAzure\Blob\Models\SetBlobMetadataResult; use WindowsAzure\Blob\Models\GetBlobOptions; use WindowsAzure\Blob\Models\GetBlobResult; use WindowsAzure\Blob\Models\DeleteBlobOptions; use WindowsAzure\Blob\Models\LeaseMode; use WindowsAzure\Blob\Models\AcquireLeaseOptions; use WindowsAzure\Blob\Models\AcquireLeaseResult; use WindowsAzure\Blob\Models\CreateBlobPagesOptions; use WindowsAzure\Blob\Models\CreateBlobPagesResult; use WindowsAzure\Blob\Models\PageWriteOption; use WindowsAzure\Blob\Models\ListPageBlobRangesOptions; use WindowsAzure\Blob\Models\ListPageBlobRangesResult; use WindowsAzure\Blob\Models\CreateBlobBlockOptions; use WindowsAzure\Blob\Models\CommitBlobBlocksOptions; use WindowsAzure\Blob\Models\BlockList; use WindowsAzure\Blob\Models\ListBlobBlocksOptions; use WindowsAzure\Blob\Models\ListBlobBlocksResult; use WindowsAzure\Blob\Models\CopyBlobOptions; use WindowsAzure\Blob\Models\CreateBlobSnapshotOptions; use WindowsAzure\Blob\Models\CreateBlobSnapshotResult; use WindowsAzure\Blob\Models\PageRange; use WindowsAzure\Blob\Models\CopyBlobResult; use WindowsAzure\Blob\Models\BreakLeaseResult; /** * This class constructs HTTP requests and receive HTTP responses for blob * service layer. * * @category Microsoft * @package WindowsAzure\Blob * @author Azure PHP SDK * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @version Release: 0.4.1_2015-03 * @link https://github.com/windowsazure/azure-sdk-for-php */ class BlobRestProxy extends ServiceRestProxy implements IBlob { /** * @var int Defaults to 32MB */ private $_SingleBlobUploadThresholdInBytes = 33554432 ; /** * Get the value for SingleBlobUploadThresholdInBytes * * @return int */ public function getSingleBlobUploadThresholdInBytes() { return $this->_SingleBlobUploadThresholdInBytes; } /** * Set the value for SingleBlobUploadThresholdInBytes, Max 64MB * * @param int $val The max size to send as a single blob block * * @return none */ public function setSingleBlobUploadThresholdInBytes($val) { if ($val > 67108864) { // What should the proper action here be? $val = 67108864; } elseif ($val < 1) { // another spot that could use looking at $val = 33554432; } $this->_SingleBlobUploadThresholdInBytes = $val; } /** * Gets the copy blob source name with specified parameters. * * @param string $containerName The name of the container. * @param string $blobName The name of the blob. * @param Models\CopyBlobOptions $options The optional parameters. * * @return string */ private function _getCopyBlobSourceName($containerName, $blobName, $options) { $sourceName = $this->_getBlobUrl($containerName, $blobName); if (!is_null($options->getSourceSnapshot())) { $sourceName .= '?snapshot=' . $options->getSourceSnapshot(); } return $sourceName; } /** * Creates URI path for blob. * * @param string $container The container name. * @param string $blob The blob name. * * @return string */ private function _createPath($container, $blob) { $encodedBlob = urlencode($blob); // Unencode the forward slashes to match what the server expects. $encodedBlob = str_replace('%2F', '/', $encodedBlob); // Unencode the backward slashes to match what the server expects. $encodedBlob = str_replace('%5C', '/', $encodedBlob); // Re-encode the spaces (encoded as space) to the % encoding. $encodedBlob = str_replace('+', '%20', $encodedBlob); // Empty container means accessing default container if (empty($container)) { return $encodedBlob; } else { return $container . '/' . $encodedBlob; } } /** * Creates full URI to the given blob. * * @param string $container The container name. * @param string $blob The blob name. * * @return string */ private function _getBlobUrl($container, $blob) { $encodedBlob = urlencode($blob); // Unencode the forward slashes to match what the server expects. $encodedBlob = str_replace('%2F', '/', $encodedBlob); // Unencode the backward slashes to match what the server expects. $encodedBlob = str_replace('%5C', '/', $encodedBlob); // Re-encode the spaces (encoded as space) to the % encoding. $encodedBlob = str_replace('+', '%20', $encodedBlob); // Empty container means accessing default container if (empty($container)) { $encodedBlob = $encodedBlob; } else { $encodedBlob = $container . '/' . $encodedBlob; } return $this->getUri() . '/' . $encodedBlob; } /** * Creates GetBlobPropertiesResult from headers array. * * @param array $headers The HTTP response headers array. * * @return GetBlobPropertiesResult */ private function _getBlobPropertiesResultFromResponse($headers) { $result = new GetBlobPropertiesResult(); $properties = new BlobProperties(); $d = $headers[Resources::LAST_MODIFIED]; $bType = $headers[Resources::X_MS_BLOB_TYPE]; $cLength = intval($headers[Resources::CONTENT_LENGTH]); $lStatus = Utilities::tryGetValue($headers, Resources::X_MS_LEASE_STATUS); $cType = Utilities::tryGetValue($headers, Resources::CONTENT_TYPE); $cMD5 = Utilities::tryGetValue($headers, Resources::CONTENT_MD5); $cEncoding = Utilities::tryGetValue($headers, Resources::CONTENT_ENCODING); $cLanguage = Utilities::tryGetValue($headers, Resources::CONTENT_LANGUAGE); $cControl = Utilities::tryGetValue($headers, Resources::CACHE_CONTROL); $etag = $headers[Resources::ETAG]; $metadata = $this->getMetadataArray($headers); if (array_key_exists(Resources::X_MS_BLOB_SEQUENCE_NUMBER, $headers)) { $sNumber = intval($headers[Resources::X_MS_BLOB_SEQUENCE_NUMBER]); $properties->setSequenceNumber($sNumber); } $properties->setBlobType($bType); $properties->setCacheControl($cControl); $properties->setContentEncoding($cEncoding); $properties->setContentLanguage($cLanguage); $properties->setContentLength($cLength); $properties->setContentMD5($cMD5); $properties->setContentType($cType); $properties->setETag($etag); $properties->setLastModified(Utilities::rfc1123ToDateTime($d)); $properties->setLeaseStatus($lStatus); $result->setProperties($properties); $result->setMetadata($metadata); return $result; } /** * Helper method for getContainerProperties and getContainerMetadata. * * @param string $container The container name. * @param Models\BlobServiceOptions $options The optional parameters. * @param string $operation The operation string. Should be * 'metadata' to get metadata. * * @return Models\GetContainerPropertiesResult */ private function _getContainerPropertiesImpl($container, $options = null, $operation = null ) { Validate::isString($container, 'container'); $method = Resources::HTTP_GET; $headers = array(); $queryParams = array(); $postParams = array(); $path = $container; $statusCode = Resources::STATUS_OK; if (is_null($options)) { $options = new BlobServiceOptions(); } $this->addOptionalQueryParam( $queryParams, Resources::QP_REST_TYPE, 'container' ); $this->addOptionalQueryParam( $queryParams, Resources::QP_COMP, $operation ); $this->addOptionalQueryParam( $queryParams, Resources::QP_TIMEOUT, $options->getTimeout() ); $response = $this->send( $method, $headers, $queryParams, $postParams, $path, $statusCode ); $result = new GetContainerPropertiesResult(); $metadata = $this->getMetadataArray($response->getHeader()); $date = $response->getHeader(Resources::LAST_MODIFIED); $date = Utilities::rfc1123ToDateTime($date); $result->setETag($response->getHeader(Resources::ETAG)); $result->setMetadata($metadata); $result->setLastModified($date); return $result; } /** * Adds optional create blob headers. * * @param CreateBlobOptions $options The optional parameters. * @param array $headers The HTTP request headers. * * @return array */ private function _addCreateBlobOptionalHeaders($options, $headers) { $contentType = $options->getContentType(); $metadata = $options->getMetadata(); $blobContentType = $options->getBlobContentType(); $blobContentEncoding = $options->getBlobContentEncoding(); $blobContentLanguage = $options->getBlobContentLanguage(); $blobContentMD5 = $options->getBlobContentMD5(); $blobCacheControl = $options->getBlobCacheControl(); $leaseId = $options->getLeaseId(); if (!is_null($contentType)) { $this->addOptionalHeader( $headers, Resources::CONTENT_TYPE, $options->getContentType() ); } else { $this->addOptionalHeader( $headers, Resources::CONTENT_TYPE, Resources::BINARY_FILE_TYPE ); } $headers = $this->addMetadataHeaders($headers, $metadata); $headers = $this->addOptionalAccessConditionHeader( $headers, $options->getAccessCondition() ); $this->addOptionalHeader( $headers, Resources::CONTENT_ENCODING, $options->getContentEncoding() ); $this->addOptionalHeader( $headers, Resources::CONTENT_LANGUAGE, $options->getContentLanguage() ); $this->addOptionalHeader( $headers, Resources::CONTENT_MD5, $options->getContentMD5() ); $this->addOptionalHeader( $headers, Resources::CACHE_CONTROL, $options->getCacheControl() ); $this->addOptionalHeader( $headers, Resources::X_MS_LEASE_ID, $leaseId ); $this->addOptionalHeader( $headers, Resources::X_MS_BLOB_CONTENT_TYPE, $blobContentType ); $this->addOptionalHeader( $headers, Resources::X_MS_BLOB_CONTENT_ENCODING, $blobContentEncoding ); $this->addOptionalHeader( $headers, Resources::X_MS_BLOB_CONTENT_LANGUAGE, $blobContentLanguage ); $this->addOptionalHeader( $headers, Resources::X_MS_BLOB_CONTENT_MD5, $blobContentMD5 ); $this->addOptionalHeader( $headers, Resources::X_MS_BLOB_CACHE_CONTROL, $blobCacheControl ); return $headers; } /** * Adds Range header to the headers array. * * @param array $headers The HTTP request headers. * @param integer $start The start byte. * @param integer $end The end byte. * * @return array */ private function _addOptionalRangeHeader($headers, $start, $end) { if (!is_null($start) || !is_null($end)) { $range = $start . '-' . $end; $rangeValue = 'bytes=' . $range; $this->addOptionalHeader($headers, Resources::RANGE, $rangeValue); } return $headers; } /** * Does the actual work for leasing a blob. * * @param string $leaseAction The lease action string. * @param string $container The container name. * @param string $blob The blob to lease name. * @param string $leaseId The existing lease id. * @param BlobServiceOptions $options The optional parameters. * @param AccessCondition $accessCondition The access conditions. * * @return array */ private function _putLeaseImpl($leaseAction, $container, $blob, $leaseId, $options, $accessCondition = null ) { Validate::isString($blob, 'blob'); Validate::notNullOrEmpty($blob, 'blob'); Validate::isString($container, 'container'); $method = Resources::HTTP_PUT; $headers = array(); $queryParams = array(); $postParams = array(); $path = $this->_createPath($container, $blob); $statusCode = Resources::EMPTY_STRING; switch ($leaseAction) { case LeaseMode::ACQUIRE_ACTION: $this->addOptionalHeader($headers, Resources::X_MS_LEASE_DURATION, -1); $statusCode = Resources::STATUS_CREATED; break; case LeaseMode::RENEW_ACTION: $statusCode = Resources::STATUS_OK; break; case LeaseMode::RELEASE_ACTION: $statusCode = Resources::STATUS_OK; break; case LeaseMode::BREAK_ACTION: $statusCode = Resources::STATUS_ACCEPTED; break; default: throw new \Exception(Resources::NOT_IMPLEMENTED_MSG); } if (!is_null($options)) { $options = new BlobServiceOptions(); } $headers = $this->addOptionalAccessConditionHeader( $headers, $accessCondition ); $this->addOptionalHeader($headers, Resources::X_MS_LEASE_ID, $leaseId); $this->addOptionalHeader( $headers, Resources::X_MS_LEASE_ACTION, $leaseAction ); $this->addOptionalQueryParam($queryParams, Resources::QP_COMP, 'lease'); $this->addOptionalQueryParam( $queryParams, Resources::QP_TIMEOUT, $options->getTimeout() ); $response = $this->send( $method, $headers, $queryParams, $postParams, $path, $statusCode ); return $response->getHeader(); } /** * Does actual work for create and clear blob pages. * * @param string $action Either clear or create. * @param string $container The container name. * @param string $blob The blob name. * @param PageRange $range The page ranges. * @param string|resource $content The content stream. * @param CreateBlobPagesOptions $options The optional parameters. * * @return CreateBlobPagesResult */ private function _updatePageBlobPagesImpl($action, $container, $blob, $range, $content, $options = null ) { Validate::isString($blob, 'blob'); Validate::notNullOrEmpty($blob, 'blob'); Validate::isString($container, 'container'); Validate::isTrue( $range instanceof PageRange, sprintf( Resources::INVALID_PARAM_MSG, 'range', get_class(new PageRange()) ) ); Validate::isTrue( is_string($content) || is_resource($content), sprintf(Resources::INVALID_PARAM_MSG, 'content', 'string|resource') ); $method = Resources::HTTP_PUT; $headers = array(); $queryParams = array(); $postParams = array(); $path = $this->_createPath($container, $blob); $statusCode = Resources::STATUS_CREATED; // If read file failed for any reason it will throw an exception. $body = is_resource($content) ? stream_get_contents($content) : $content; if (is_null($options)) { $options = new CreateBlobPagesOptions(); } $headers = $this->_addOptionalRangeHeader( $headers, $range->getStart(), $range->getEnd() ); $headers = $this->addOptionalAccessConditionHeader( $headers, $options->getAccessCondition() ); $this->addOptionalHeader( $headers, Resources::X_MS_LEASE_ID, $options->getLeaseId() ); $this->addOptionalHeader( $headers, Resources::CONTENT_MD5, $options->getContentMD5() ); $this->addOptionalHeader( $headers, Resources::X_MS_PAGE_WRITE, $action ); $this->addOptionalHeader( $headers, Resources::CONTENT_TYPE, Resources::URL_ENCODED_CONTENT_TYPE ); $this->addOptionalQueryParam($queryParams, Resources::QP_COMP, 'page'); $this->addOptionalQueryParam( $queryParams, Resources::QP_TIMEOUT, $options->getTimeout() ); $response = $this->send( $method, $headers, $queryParams, $postParams, $path, $statusCode, $body ); return CreateBlobPagesResult::create($response->getHeader()); } /** * Gets the properties of the Blob service. * * @param Models\BlobServiceOptions $options The optional parameters. * * @return WindowsAzure\Common\Models\GetServicePropertiesResult * * @see http://msdn.microsoft.com/en-us/library/windowsazure/hh452239.aspx */ public function getServiceProperties($options = null) { $method = Resources::HTTP_GET; $headers = array(); $queryParams = array(); $postParams = array(); $path = Resources::EMPTY_STRING; $statusCode = Resources::STATUS_OK; if (is_null($options)) { $options = new BlobServiceOptions(); } $this->addOptionalQueryParam( $queryParams, Resources::QP_TIMEOUT, $options->getTimeout() ); $this->addOptionalQueryParam( $queryParams, Resources::QP_REST_TYPE, 'service' ); $this->addOptionalQueryParam( $queryParams, Resources::QP_COMP, 'properties' ); $response = $this->send( $method, $headers, $queryParams, $postParams, $path, $statusCode ); $parsed = $this->dataSerializer->unserialize($response->getBody()); return GetServicePropertiesResult::create($parsed); } /** * Sets the properties of the Blob service. * * It's recommended to use getServiceProperties, alter the returned object and * then use setServiceProperties with this altered object. * * @param ServiceProperties $serviceProperties The service properties. * @param Models\BlobServiceOptions $options The optional parameters. * * @return none * * @see http://msdn.microsoft.com/en-us/library/windowsazure/hh452235.aspx */ public function setServiceProperties($serviceProperties, $options = null) { Validate::isTrue( $serviceProperties instanceof ServiceProperties, Resources::INVALID_SVC_PROP_MSG ); $method = Resources::HTTP_PUT; $headers = array(); $queryParams = array(); $postParams = array(); $statusCode = Resources::STATUS_ACCEPTED; $path = Resources::EMPTY_STRING; $body = $serviceProperties->toXml($this->dataSerializer); if (is_null($options)) { $options = new BlobServiceOptions(); } $this->addOptionalQueryParam( $queryParams, Resources::QP_REST_TYPE, 'service' ); $this->addOptionalQueryParam( $queryParams, Resources::QP_COMP, 'properties' ); $this->addOptionalQueryParam( $queryParams, Resources::QP_TIMEOUT, $options->getTimeout() ); $this->addOptionalHeader( $headers, Resources::CONTENT_TYPE, Resources::URL_ENCODED_CONTENT_TYPE ); $this->send( $method, $headers, $queryParams, $postParams, $path, $statusCode, $body ); } /** * Lists all of the containers in the given storage account. * * @param Models\ListContainersOptions $options The optional parameters. * * @return WindowsAzure\Blob\Models\ListContainersResult * * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179352.aspx */ public function listContainers($options = null) { $method = Resources::HTTP_GET; $headers = array(); $queryParams = array(); $postParams = array(); $path = Resources::EMPTY_STRING; $statusCode = Resources::STATUS_OK; if (is_null($options)) { $options = new ListContainersOptions(); } $this->addOptionalQueryParam( $queryParams, Resources::QP_TIMEOUT, $options->getTimeout() ); $this->addOptionalQueryParam( $queryParams, Resources::QP_COMP, 'list' ); $this->addOptionalQueryParam( $queryParams, Resources::QP_PREFIX, $options->getPrefix() ); $this->addOptionalQueryParam( $queryParams, Resources::QP_MARKER, $options->getMarker() ); $this->addOptionalQueryParam( $queryParams, Resources::QP_MAX_RESULTS, $options->getMaxResults() ); $isInclude = $options->getIncludeMetadata(); $isInclude = $isInclude ? 'metadata' : null; $this->addOptionalQueryParam( $queryParams, Resources::QP_INCLUDE, $isInclude ); $response = $this->send( $method, $headers, $queryParams, $postParams, $path, $statusCode ); $parsed = $this->dataSerializer->unserialize($response->getBody()); return ListContainersResult::create($parsed); } /** * Creates a new container in the given storage account. * * @param string $container The container name. * @param Models\CreateContainerOptions $options The optional parameters. * * @return none * * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179468.aspx */ public function createContainer($container, $options = null) { Validate::isString($container, 'container'); Validate::notNullOrEmpty($container, 'container'); $method = Resources::HTTP_PUT; $headers = array(); $postParams = array(); $queryParams = array(Resources::QP_REST_TYPE => 'container'); $path = $container; $statusCode = Resources::STATUS_CREATED; if (is_null($options)) { $options = new CreateContainerOptions(); } $this->addOptionalQueryParam( $queryParams, Resources::QP_TIMEOUT, $options->getTimeout() ); $metadata = $options->getMetadata(); $headers = $this->generateMetadataHeaders($metadata); $this->addOptionalHeader( $headers, Resources::X_MS_BLOB_PUBLIC_ACCESS, $options->getPublicAccess() ); $this->send( $method, $headers, $queryParams, $postParams, $path, $statusCode ); } /** * Creates a new container in the given storage account. * * @param string $container The container name. * @param Models\DeleteContainerOptions $options The optional parameters. * * @return none * * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179408.aspx */ public function deleteContainer($container, $options = null) { Validate::isString($container, 'container'); Validate::notNullOrEmpty($container, 'container'); $method = Resources::HTTP_DELETE; $headers = array(); $postParams = array(); $queryParams = array(); $path = $container; $statusCode = Resources::STATUS_ACCEPTED; if (is_null($options)) { $options = new DeleteContainerOptions(); } $headers = $this->addOptionalAccessConditionHeader( $headers, $options->getAccessCondition() ); $this->addOptionalQueryParam( $queryParams, Resources::QP_TIMEOUT, $options->getTimeout() ); $this->addOptionalQueryParam( $queryParams, Resources::QP_REST_TYPE, 'container' ); $this->send( $method, $headers, $queryParams, $postParams, $path, $statusCode ); } /** * Returns all properties and metadata on the container. * * @param string $container name * @param Models\BlobServiceOptions $options optional parameters * * @return Models\GetContainerPropertiesResult * * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179370.aspx */ public function getContainerProperties($container, $options = null) { return $this->_getContainerPropertiesImpl($container, $options); } /** * Returns only user-defined metadata for the specified container. * * @param string $container name * @param Models\BlobServiceOptions $options optional parameters * * @return Models\GetContainerPropertiesResult * * @see http://msdn.microsoft.com/en-us/library/windowsazure/ee691976.aspx */ public function getContainerMetadata($container, $options = null) { return $this->_getContainerPropertiesImpl($container, $options, 'metadata'); } /** * Gets the access control list (ACL) and any container-level access policies * for the container. * * @param string $container The container name. * @param Models\BlobServiceOptions $options The optional parameters. * * @return Models\GetContainerAclResult * * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179469.aspx */ public function getContainerAcl($container, $options = null) { Validate::isString($container, 'container'); $method = Resources::HTTP_GET; $headers = array(); $postParams = array(); $queryParams = array(); $path = $container; $statusCode = Resources::STATUS_OK; if (is_null($options)) { $options = new BlobServiceOptions(); } $this->addOptionalQueryParam( $queryParams, Resources::QP_TIMEOUT, $options->getTimeout() ); $this->addOptionalQueryParam( $queryParams, Resources::QP_REST_TYPE, 'container' ); $this->addOptionalQueryParam( $queryParams, Resources::QP_COMP, 'acl' ); $response = $this->send( $method, $headers, $queryParams, $postParams, $path, $statusCode ); $access = $response->getHeader(Resources::X_MS_BLOB_PUBLIC_ACCESS); $etag = $response->getHeader(Resources::ETAG); $modified = $response->getHeader(Resources::LAST_MODIFIED); $modifiedDate = Utilities::convertToDateTime($modified); $parsed = $this->dataSerializer->unserialize($response->getBody()); return GetContainerAclResult::create($access, $etag, $modifiedDate, $parsed); } /** * Sets the ACL and any container-level access policies for the container. * * @param string $container name * @param Models\ContainerAcl $acl access control list for container * @param Models\BlobServiceOptions $options optional parameters * * @return none * * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179391.aspx */ public function setContainerAcl($container, $acl, $options = null) { Validate::isString($container, 'container'); Validate::notNullOrEmpty($acl, 'acl'); $method = Resources::HTTP_PUT; $headers = array(); $postParams = array(); $queryParams = array(); $path = $container; $statusCode = Resources::STATUS_OK; $body = $acl->toXml($this->dataSerializer); if (is_null($options)) { $options = new BlobServiceOptions(); } $this->addOptionalQueryParam( $queryParams, Resources::QP_TIMEOUT, $options->getTimeout() ); $this->addOptionalQueryParam( $queryParams, Resources::QP_REST_TYPE, 'container' ); $this->addOptionalQueryParam( $queryParams, Resources::QP_COMP, 'acl' ); $this->addOptionalHeader( $headers, Resources::X_MS_BLOB_PUBLIC_ACCESS, $acl->getPublicAccess() ); $this->addOptionalHeader( $headers, Resources::CONTENT_TYPE, Resources::URL_ENCODED_CONTENT_TYPE ); $this->send( $method, $headers, $queryParams, $postParams, $path, $statusCode, $body ); } /** * Sets metadata headers on the container. * * @param string $container name * @param array $metadata metadata key/value pair. * @param Models\SetContainerMetadataOptions $options optional parameters * * @return none * * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179362.aspx */ public function setContainerMetadata($container, $metadata, $options = null) { Validate::isString($container, 'container'); $this->validateMetadata($metadata); $method = Resources::HTTP_PUT; $headers = $this->generateMetadataHeaders($metadata); $postParams = array(); $queryParams = array(); $path = $container; $statusCode = Resources::STATUS_OK; if (is_null($options)) { $options = new SetContainerMetadataOptions(); } $this->addOptionalQueryParam( $queryParams, Resources::QP_TIMEOUT, $options->getTimeout() ); $this->addOptionalQueryParam( $queryParams, Resources::QP_REST_TYPE, 'container' ); $this->addOptionalQueryParam( $queryParams, Resources::QP_COMP, 'metadata' ); $headers = $this->addOptionalAccessConditionHeader( $headers, $options->getAccessCondition() ); $this->send( $method, $headers, $queryParams, $postParams, $path, $statusCode ); } /** * Lists all of the blobs in the given container. * * @param string $container The container name. * @param Models\ListBlobsOptions $options The optional parameters. * * @return Models\ListBlobsResult * * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd135734.aspx */ public function listBlobs($container, $options = null) { Validate::isString($container, 'container'); $method = Resources::HTTP_GET; $headers = array(); $postParams = array(); $queryParams = array(); $path = $container; $statusCode = Resources::STATUS_OK; if (is_null($options)) { $options = new ListBlobsOptions(); } $this->addOptionalQueryParam( $queryParams, Resources::QP_TIMEOUT, $options->getTimeout() ); $this->addOptionalQueryParam( $queryParams, Resources::QP_REST_TYPE, 'container' ); $this->addOptionalQueryParam( $queryParams, Resources::QP_COMP, 'list' ); $this->addOptionalQueryParam( $queryParams, Resources::QP_PREFIX, str_replace('\\', '/', $options->getPrefix()) ); $this->addOptionalQueryParam( $queryParams, Resources::QP_MARKER, $options->getMarker() ); $this->addOptionalQueryParam( $queryParams, Resources::QP_DELIMITER, $options->getDelimiter() ); $this->addOptionalQueryParam( $queryParams, Resources::QP_MAX_RESULTS, $options->getMaxResults() ); $includeMetadata = $options->getIncludeMetadata(); $includeSnapshots = $options->getIncludeSnapshots(); $includeUncommittedBlobs = $options->getIncludeUncommittedBlobs(); $includeValue = $this->groupQueryValues( array( $includeMetadata ? 'metadata' : null, $includeSnapshots ? 'snapshots' : null, $includeUncommittedBlobs ? 'uncommittedblobs' : null ) ); $this->addOptionalQueryParam( $queryParams, Resources::QP_INCLUDE, $includeValue ); $response = $this->send( $method, $headers, $queryParams, $postParams, $path, $statusCode ); $parsed = $this->dataSerializer->unserialize($response->getBody()); return ListBlobsResult::create($parsed); } /** * Creates a new page blob. Note that calling createPageBlob to create a page * blob only initializes the blob. * To add content to a page blob, call createBlobPages method. * * @param string $container The container name. * @param string $blob The blob name. * @param integer $length Specifies the maximum size for the * page blob, up to 1 TB. The page blob size must be aligned to a 512-byte * boundary. * @param Models\CreateBlobOptions $options The optional parameters. * * @return CopyBlobResult * * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179451.aspx */ public function createPageBlob($container, $blob, $length, $options = null) { Validate::isString($container, 'container'); Validate::isString($blob, 'blob'); Validate::notNullOrEmpty($blob, 'blob'); Validate::isInteger($length, 'length'); Validate::notNull($length, 'length'); $method = Resources::HTTP_PUT; $headers = array(); $postParams = array(); $queryParams = array(); $path = $this->_createPath($container, $blob); $statusCode = Resources::STATUS_CREATED; if (is_null($options)) { $options = new CreateBlobOptions(); } $this->addOptionalHeader( $headers, Resources::X_MS_BLOB_TYPE, BlobType::PAGE_BLOB ); $this->addOptionalHeader( $headers, Resources::X_MS_BLOB_CONTENT_LENGTH, $length ); $this->addOptionalHeader( $headers, Resources::X_MS_BLOB_SEQUENCE_NUMBER, $options->getSequenceNumber() ); $headers = $this->_addCreateBlobOptionalHeaders($options, $headers); $this->addOptionalQueryParam( $queryParams, Resources::QP_TIMEOUT, $options->getTimeout() ); $response = $this->send( $method, $headers, $queryParams, $postParams, $path, $statusCode ); return CopyBlobResult::create($response->getHeader()); } /** * Creates a new block blob or updates the content of an existing block blob. * * Updating an existing block blob overwrites any existing metadata on the blob. * Partial updates are not supported with createBlockBlob the content of the * existing blob is overwritten with the content of the new blob. To perform a * partial update of the content o f a block blob, use the createBlockList * method. * Note that the default content type is application/octet-stream. * * @param string $container The name of the container. * @param string $blob The name of the blob. * @param string|resource $content The content of the blob. * @param Models\CreateBlobOptions $options The optional parameters. * * @return CopyBlobResult * * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179451.aspx */ public function createBlockBlob($container, $blob, $content, $options = null) { Validate::isString($container, 'container'); Validate::isString($blob, 'blob'); Validate::notNullOrEmpty($blob, 'blob'); Validate::isTrue( is_string($content) || is_resource($content), sprintf(Resources::INVALID_PARAM_MSG, 'content', 'string|resource') ); $method = Resources::HTTP_PUT; $headers = array(); $postParams = array(); $queryParams = array(); $bodySize = false; $path = $this->_createPath($container, $blob); $statusCode = Resources::STATUS_CREATED; if (is_null($options)) { $options = new CreateBlobOptions(); } if (is_resource($content)) { $cStat = fstat($content); // if the resource is a remote file, $cStat will be false if ($cStat) { $bodySize = $cStat['size']; } } else { $bodySize = strlen($content); } // if we have a size we can try to one shot this, else failsafe on block upload if (is_int($bodySize) && $bodySize <= $this->_SingleBlobUploadThresholdInBytes) { $headers = $this->_addCreateBlobOptionalHeaders($options, $headers); $this->addOptionalHeader( $headers, Resources::X_MS_BLOB_TYPE, BlobType::BLOCK_BLOB ); $this->addOptionalQueryParam( $queryParams, Resources::QP_TIMEOUT, $options->getTimeout() ); // If read file failed for any reason it will throw an exception. $body = is_resource($content) ? stream_get_contents($content) : $content; $response = $this->send( $method, $headers, $queryParams, $postParams, $path, $statusCode, $body ); } else { // This is for large or failsafe upload $end = 0; $counter = 0; $body = ''; $blockIds = array(); // if threshold is lower than 4mb, honor threshold, else use 4mb $blockSize = ($this->_SingleBlobUploadThresholdInBytes < 4194304) ? $this->_SingleBlobUploadThresholdInBytes : 4194304; while(!$end) { if (is_resource($content)) { $body = fread($content, $blockSize); if (feof($content)) { $end = 1; } } else { if (strlen($content) <= $blockSize) { $body = $content; $end = 1; } else { $body = substr($content, 0, $blockSize); $content = substr_replace($content, '', 0, $blockSize); } } $block = new Block(); $block->setBlockId(base64_encode(str_pad($counter++, '0', 6))); $block->setType('Uncommitted'); array_push($blockIds, $block); $this->createBlobBlock($container, $blob, $block->getBlockId(), $body); } $response = $this->commitBlobBlocks($container, $blob, $blockIds, $options); } return CopyBlobResult::create($response->getHeader()); } /** * Clears a range of pages from the blob. * * @param string $container name of the container * @param string $blob name of the blob * @param Models\PageRange $range Can be up to the value of the * blob's full size. Note that ranges must be aligned to 512 (0-511, 512-1023) * @param Models\CreateBlobPagesOptions $options optional parameters * * @return Models\CreateBlobPagesResult. * * @see http://msdn.microsoft.com/en-us/library/windowsazure/ee691975.aspx */ public function clearBlobPages($container, $blob, $range, $options = null) { return $this->_updatePageBlobPagesImpl( PageWriteOption::CLEAR_OPTION, $container, $blob, $range, Resources::EMPTY_STRING, $options ); } /** * Creates a range of pages to a page blob. * * @param string $container name of the container * @param string $blob name of the blob * @param Models\PageRange $range Can be up to 4 MB in size * Note that ranges must be aligned to 512 (0-511, 512-1023) * @param string $content the blob contents. * @param Models\CreateBlobPagesOptions $options optional parameters * * @return Models\CreateBlobPagesResult. * * @see http://msdn.microsoft.com/en-us/library/windowsazure/ee691975.aspx */ public function createBlobPages($container, $blob, $range, $content, $options = null ) { return $this->_updatePageBlobPagesImpl( PageWriteOption::UPDATE_OPTION, $container, $blob, $range, $content, $options ); } /** * Creates a new block to be committed as part of a block blob. * * @param string $container name of the container * @param string $blob name of the blob * @param string $blockId must be less than or equal to * 64 bytes in size. For a given blob, the length of the value specified for the * blockid parameter must be the same size for each block. * @param string $content the blob block contents * @param Models\CreateBlobBlockOptions $options optional parameters * * @return none * * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd135726.aspx */ public function createBlobBlock($container, $blob, $blockId, $content, $options = null ) { Validate::isString($container, 'container'); Validate::isString($blob, 'blob'); Validate::notNullOrEmpty($blob, 'blob'); Validate::isString($blockId, 'blockId'); Validate::notNullOrEmpty($blockId, 'blockId'); Validate::isTrue( is_string($content) || is_resource($content), sprintf(Resources::INVALID_PARAM_MSG, 'content', 'string|resource') ); $method = Resources::HTTP_PUT; $headers = array(); $postParams = array(); $queryParams = array(); $path = $this->_createPath($container, $blob); $statusCode = Resources::STATUS_CREATED; $body = $content; if (is_null($options)) { $options = new CreateBlobBlockOptions(); } $this->addOptionalHeader( $headers, Resources::X_MS_LEASE_ID, $options->getLeaseId() ); $this->addOptionalHeader( $headers, Resources::CONTENT_MD5, $options->getContentMD5() ); $this->addOptionalHeader( $headers, Resources::CONTENT_TYPE, Resources::URL_ENCODED_CONTENT_TYPE ); $this->addOptionalQueryParam( $queryParams, Resources::QP_TIMEOUT, $options->getTimeout() ); $this->addOptionalQueryParam( $queryParams, Resources::QP_COMP, 'block' ); $this->addOptionalQueryParam( $queryParams, Resources::QP_BLOCKID, base64_encode($blockId) ); $response = $this->send( $method, $headers, $queryParams, $postParams, $path, $statusCode, $body ); return CopyBlobResult::create($response->getHeader()); } /** * This method writes a blob by specifying the list of block IDs that make up the * blob. In order to be written as part of a blob, a block must have been * successfully written to the server in a prior createBlobBlock method. * * You can call Put Block List to update a blob by uploading only those blocks * that have changed, then committing the new and existing blocks together. * You can do this by specifying whether to commit a block from the committed * block list or from the uncommitted block list, or to commit the most recently * uploaded version of the block, whichever list it may belong to. * * @param string $container The container name. * @param string $blob The blob name. * @param Models\BlockList|array $blockList The block entries. * @param Models\CommitBlobBlocksOptions $options The optional parameters. * * @return CopyBlobResult * * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179467.aspx */ public function commitBlobBlocks($container, $blob, $blockList, $options = null) { Validate::isString($container, 'container'); Validate::isString($blob, 'blob'); Validate::notNullOrEmpty($blob, 'blob'); Validate::isTrue( $blockList instanceof BlockList || is_array($blockList), sprintf( Resources::INVALID_PARAM_MSG, 'blockList', get_class(new BlockList()) ) ); $method = Resources::HTTP_PUT; $headers = array(); $postParams = array(); $queryParams = array(); $path = $this->_createPath($container, $blob); $statusCode = Resources::STATUS_CREATED; $isArray = is_array($blockList); $blockList = $isArray ? BlockList::create($blockList) : $blockList; $body = $blockList->toXml($this->dataSerializer); if (is_null($options)) { $options = new CommitBlobBlocksOptions(); } $blobContentType = $options->getBlobContentType(); $blobContentEncoding = $options->getBlobContentEncoding(); $blobContentLanguage = $options->getBlobContentLanguage(); $blobContentMD5 = $options->getBlobContentMD5(); $blobCacheControl = $options->getBlobCacheControl(); $leaseId = $options->getLeaseId(); $contentType = Resources::URL_ENCODED_CONTENT_TYPE; $metadata = $options->getMetadata(); $headers = $this->generateMetadataHeaders($metadata); $headers = $this->addOptionalAccessConditionHeader( $headers, $options->getAccessCondition() ); $this->addOptionalHeader( $headers, Resources::X_MS_LEASE_ID, $leaseId ); $this->addOptionalHeader( $headers, Resources::X_MS_BLOB_CACHE_CONTROL, $blobCacheControl ); $this->addOptionalHeader( $headers, Resources::X_MS_BLOB_CONTENT_TYPE, $blobContentType ); $this->addOptionalHeader( $headers, Resources::X_MS_BLOB_CONTENT_ENCODING, $blobContentEncoding ); $this->addOptionalHeader( $headers, Resources::X_MS_BLOB_CONTENT_LANGUAGE, $blobContentLanguage ); $this->addOptionalHeader( $headers, Resources::X_MS_BLOB_CONTENT_MD5, $blobContentMD5 ); $this->addOptionalHeader( $headers, Resources::CONTENT_TYPE, $contentType ); $this->addOptionalQueryParam( $queryParams, Resources::QP_TIMEOUT, $options->getTimeout() ); $this->addOptionalQueryParam( $queryParams, Resources::QP_COMP, 'blocklist' ); return $this->send( $method, $headers, $queryParams, $postParams, $path, $statusCode, $body ); } /** * Retrieves the list of blocks that have been uploaded as part of a block blob. * * There are two block lists maintained for a blob: * 1) Committed Block List: The list of blocks that have been successfully * committed to a given blob with commitBlobBlocks. * 2) Uncommitted Block List: The list of blocks that have been uploaded for a * blob using Put Block (REST API), but that have not yet been committed. * These blocks are stored in Windows Azure in association with a blob, but do * not yet form part of the blob. * * @param string $container name of the container * @param string $blob name of the blob * @param Models\ListBlobBlocksOptions $options optional parameters * * @return Models\ListBlobBlocksResult * * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179400.aspx */ public function listBlobBlocks($container, $blob, $options = null) { Validate::isString($container, 'container'); Validate::isString($blob, 'blob'); Validate::notNullOrEmpty($blob, 'blob'); $method = Resources::HTTP_GET; $headers = array(); $postParams = array(); $queryParams = array(); $path = $this->_createPath($container, $blob); $statusCode = Resources::STATUS_OK; if (is_null($options)) { $options = new ListBlobBlocksOptions(); } $this->addOptionalHeader( $headers, Resources::X_MS_LEASE_ID, $options->getLeaseId() ); $this->addOptionalQueryParam( $queryParams, Resources::QP_TIMEOUT, $options->getTimeout() ); $this->addOptionalQueryParam( $queryParams, Resources::QP_BLOCK_LIST_TYPE, $options->getBlockListType() ); $this->addOptionalQueryParam( $queryParams, Resources::QP_SNAPSHOT, $options->getSnapshot() ); $this->addOptionalQueryParam( $queryParams, Resources::QP_COMP, 'blocklist' ); $response = $this->send( $method, $headers, $queryParams, $postParams, $path, $statusCode ); $parsed = $this->dataSerializer->unserialize($response->getBody()); return ListBlobBlocksResult::create($response->getHeader(), $parsed); } /** * Returns all properties and metadata on the blob. * * @param string $container name of the container * @param string $blob name of the blob * @param Models\GetBlobPropertiesOptions $options optional parameters * * @return Models\GetBlobPropertiesResult * * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179394.aspx */ public function getBlobProperties($container, $blob, $options = null) { Validate::isString($container, 'container'); Validate::isString($blob, 'blob'); Validate::notNullOrEmpty($blob, 'blob'); $method = Resources::HTTP_HEAD; $headers = array(); $postParams = array(); $queryParams = array(); $path = $this->_createPath($container, $blob); $statusCode = Resources::STATUS_OK; if (is_null($options)) { $options = new GetBlobPropertiesOptions(); } $headers = $this->addOptionalAccessConditionHeader( $headers, $options->getAccessCondition() ); $this->addOptionalHeader( $headers, Resources::X_MS_LEASE_ID, $options->getLeaseId() ); $this->addOptionalQueryParam( $queryParams, Resources::QP_SNAPSHOT, $options->getSnapshot() ); $this->addOptionalQueryParam( $queryParams, Resources::QP_TIMEOUT, $options->getTimeout() ); $response = $this->send( $method, $headers, $queryParams, $postParams, $path, $statusCode ); return $this->_getBlobPropertiesResultFromResponse($response->getHeader()); } /** * Returns all properties and metadata on the blob. * * @param string $container name of the container * @param string $blob name of the blob * @param Models\GetBlobMetadataOptions $options optional parameters * * @return Models\GetBlobMetadataResult * * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179350.aspx */ public function getBlobMetadata($container, $blob, $options = null) { Validate::isString($container, 'container'); Validate::isString($blob, 'blob'); Validate::notNullOrEmpty($blob, 'blob'); $method = Resources::HTTP_HEAD; $headers = array(); $postParams = array(); $queryParams = array(); $path = $this->_createPath($container, $blob); $statusCode = Resources::STATUS_OK; if (is_null($options)) { $options = new GetBlobMetadataOptions(); } $headers = $this->addOptionalAccessConditionHeader( $headers, $options->getAccessCondition() ); $this->addOptionalHeader( $headers, Resources::X_MS_LEASE_ID, $options->getLeaseId() ); $this->addOptionalQueryParam( $queryParams, Resources::QP_SNAPSHOT, $options->getSnapshot() ); $this->addOptionalQueryParam( $queryParams, Resources::QP_TIMEOUT, $options->getTimeout() ); $this->addOptionalQueryParam( $queryParams, Resources::QP_COMP, 'metadata' ); $response = $this->send( $method, $headers, $queryParams, $postParams, $path, $statusCode ); $metadata = $this->getMetadataArray($response->getHeader()); return GetBlobMetadataResult::create($response->getHeader(), $metadata); } /** * Returns a list of active page ranges for a page blob. Active page ranges are * those that have been populated with data. * * @param string $container name of the container * @param string $blob name of the blob * @param Models\ListPageBlobRangesOptions $options optional parameters * * @return Models\ListPageBlobRangesResult * * @see http://msdn.microsoft.com/en-us/library/windowsazure/ee691973.aspx */ public function listPageBlobRanges($container, $blob, $options = null) { Validate::isString($container, 'container'); Validate::isString($blob, 'blob'); Validate::notNullOrEmpty($blob, 'blob'); $method = Resources::HTTP_GET; $headers = array(); $queryParams = array(); $postParams = array(); $path = $this->_createPath($container, $blob); $statusCode = Resources::STATUS_OK; if (is_null($options)) { $options = new ListPageBlobRangesOptions(); } $headers = $this->addOptionalAccessConditionHeader( $headers, $options->getAccessCondition() ); $headers = $this->_addOptionalRangeHeader( $headers, $options->getRangeStart(), $options->getRangeEnd() ); $this->addOptionalHeader( $headers, Resources::X_MS_LEASE_ID, $options->getLeaseId() ); $this->addOptionalQueryParam( $queryParams, Resources::QP_SNAPSHOT, $options->getSnapshot() ); $this->addOptionalQueryParam( $queryParams, Resources::QP_TIMEOUT, $options->getTimeout() ); $this->addOptionalQueryParam( $queryParams, Resources::QP_COMP, 'pagelist' ); $response = $this->send( $method, $headers, $queryParams, $postParams, $path, $statusCode ); $parsed = $this->dataSerializer->unserialize($response->getBody()); return ListPageBlobRangesResult::create($response->getHeader(), $parsed); } /** * Sets system properties defined for a blob. * * @param string $container name of the container * @param string $blob name of the blob * @param Models\SetBlobPropertiesOptions $options optional parameters * * @return Models\SetBlobPropertiesResult * * @see http://msdn.microsoft.com/en-us/library/windowsazure/ee691966.aspx */ public function setBlobProperties($container, $blob, $options = null) { Validate::isString($container, 'container'); Validate::isString($blob, 'blob'); Validate::notNullOrEmpty($blob, 'blob'); $method = Resources::HTTP_PUT; $headers = array(); $postParams = array(); $queryParams = array(); $path = $this->_createPath($container, $blob); $statusCode = Resources::STATUS_OK; if (is_null($options)) { $options = new SetBlobPropertiesOptions(); } $blobContentType = $options->getBlobContentType(); $blobContentEncoding = $options->getBlobContentEncoding(); $blobContentLanguage = $options->getBlobContentLanguage(); $blobContentLength = $options->getBlobContentLength(); $blobContentMD5 = $options->getBlobContentMD5(); $blobCacheControl = $options->getBlobCacheControl(); $leaseId = $options->getLeaseId(); $sNumberAction = $options->getSequenceNumberAction(); $sNumber = $options->getSequenceNumber(); $headers = $this->addOptionalAccessConditionHeader( $headers, $options->getAccessCondition() ); $this->addOptionalHeader( $headers, Resources::X_MS_LEASE_ID, $leaseId ); $this->addOptionalHeader( $headers, Resources::X_MS_BLOB_CACHE_CONTROL, $blobCacheControl ); $this->addOptionalHeader( $headers, Resources::X_MS_BLOB_CONTENT_TYPE, $blobContentType ); $this->addOptionalHeader( $headers, Resources::X_MS_BLOB_CONTENT_ENCODING, $blobContentEncoding ); $this->addOptionalHeader( $headers, Resources::X_MS_BLOB_CONTENT_LANGUAGE, $blobContentLanguage ); $this->addOptionalHeader( $headers, Resources::X_MS_BLOB_CONTENT_LENGTH, $blobContentLength ); $this->addOptionalHeader( $headers, Resources::X_MS_BLOB_CONTENT_MD5, $blobContentMD5 ); $this->addOptionalHeader( $headers, Resources::X_MS_BLOB_SEQUENCE_NUMBER_ACTION, $sNumberAction ); $this->addOptionalHeader( $headers, Resources::X_MS_BLOB_SEQUENCE_NUMBER, $sNumber ); $this->addOptionalQueryParam($queryParams, Resources::QP_COMP, 'properties'); $this->addOptionalQueryParam( $queryParams, Resources::QP_TIMEOUT, $options->getTimeout() ); $response = $this->send( $method, $headers, $queryParams, $postParams, $path, $statusCode ); return SetBlobPropertiesResult::create($response->getHeader()); } /** * Sets metadata headers on the blob. * * @param string $container name of the container * @param string $blob name of the blob * @param array $metadata key/value pair representation * @param Models\SetBlobMetadataOptions $options optional parameters * * @return Models\SetBlobMetadataResult * * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179414.aspx */ public function setBlobMetadata($container, $blob, $metadata, $options = null) { Validate::isString($container, 'container'); Validate::isString($blob, 'blob'); Validate::notNullOrEmpty($blob, 'blob'); $this->validateMetadata($metadata); $method = Resources::HTTP_PUT; $headers = array(); $postParams = array(); $queryParams = array(); $path = $this->_createPath($container, $blob); $statusCode = Resources::STATUS_OK; if (is_null($options)) { $options = new SetBlobMetadataOptions(); } $headers = $this->addOptionalAccessConditionHeader( $headers, $options->getAccessCondition() ); $headers = $this->addMetadataHeaders($headers, $metadata); $this->addOptionalHeader( $headers, Resources::X_MS_LEASE_ID, $options->getLeaseId() ); $this->addOptionalQueryParam( $queryParams, Resources::QP_TIMEOUT, $options->getTimeout() ); $this->addOptionalQueryParam( $queryParams, Resources::QP_COMP, 'metadata' ); $response = $this->send( $method, $headers, $queryParams, $postParams, $path, $statusCode ); return SetBlobMetadataResult::create($response->getHeader()); } /** * Reads or downloads a blob from the system, including its metadata and * properties. * * @param string $container name of the container * @param string $blob name of the blob * @param Models\GetBlobOptions $options optional parameters * * @return Models\GetBlobResult * * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179440.aspx */ public function getBlob($container, $blob, $options = null) { Validate::isString($container, 'container'); Validate::isString($blob, 'blob'); $method = Resources::HTTP_GET; $headers = array(); $postParams = array(); $queryParams = array(); $path = $this->_createPath($container, $blob); $statusCode = array( Resources::STATUS_OK, Resources::STATUS_PARTIAL_CONTENT ); if (is_null($options)) { $options = new GetBlobOptions(); } $getMD5 = $options->getComputeRangeMD5(); $headers = $this->addOptionalAccessConditionHeader( $headers, $options->getAccessCondition() ); $headers = $this->_addOptionalRangeHeader( $headers, $options->getRangeStart(), $options->getRangeEnd() ); $this->addOptionalHeader( $headers, Resources::X_MS_LEASE_ID, $options->getLeaseId() ); $this->addOptionalHeader( $headers, Resources::X_MS_RANGE_GET_CONTENT_MD5, $getMD5 ? 'true' : null ); $this->addOptionalQueryParam( $queryParams, Resources::QP_TIMEOUT, $options->getTimeout() ); $this->addOptionalQueryParam( $queryParams, Resources::QP_SNAPSHOT, $options->getSnapshot() ); $response = $this->send( $method, $headers, $queryParams, $postParams, $path, $statusCode ); $metadata = $this->getMetadataArray($response->getHeader()); return GetBlobResult::create( $response->getHeader(), $response->getBody(), $metadata ); } /** * Deletes a blob or blob snapshot. * * Note that if the snapshot entry is specified in the $options then only this * blob snapshot is deleted. To delete all blob snapshots, do not set Snapshot * and just set getDeleteSnaphotsOnly to true. * * @param string $container name of the container * @param string $blob name of the blob * @param Models\DeleteBlobOptions $options optional parameters * * @return none * * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd179413.aspx */ public function deleteBlob($container, $blob, $options = null) { Validate::isString($container, 'container'); Validate::isString($blob, 'blob'); Validate::notNullOrEmpty($blob, 'blob'); $method = Resources::HTTP_DELETE; $headers = array(); $postParams = array(); $queryParams = array(); $path = $this->_createPath($container, $blob); $statusCode = Resources::STATUS_ACCEPTED; if (is_null($options)) { $options = new DeleteBlobOptions(); } if (is_null($options->getSnapshot())) { $delSnapshots = $options->getDeleteSnaphotsOnly() ? 'only' : 'include'; $this->addOptionalHeader( $headers, Resources::X_MS_DELETE_SNAPSHOTS, $delSnapshots ); } else { $this->addOptionalQueryParam( $queryParams, Resources::QP_SNAPSHOT, $options->getSnapshot() ); } $headers = $this->addOptionalAccessConditionHeader( $headers, $options->getAccessCondition() ); $this->addOptionalHeader( $headers, Resources::X_MS_LEASE_ID, $options->getLeaseId() ); $this->addOptionalQueryParam( $queryParams, Resources::QP_TIMEOUT, $options->getTimeout() ); $this->send( $method, $headers, $queryParams, $postParams, $path, $statusCode ); } /** * Creates a snapshot of a blob. * * @param string $container The name of the container. * @param string $blob The name of the blob. * @param Models\CreateBlobSnapshotOptions $options The optional parameters. * * @return Models\CreateBlobSnapshotResult * * @see http://msdn.microsoft.com/en-us/library/windowsazure/ee691971.aspx */ public function createBlobSnapshot($container, $blob, $options = null) { Validate::isString($container, 'container'); Validate::isString($blob, 'blob'); Validate::notNullOrEmpty($blob, 'blob'); $method = Resources::HTTP_PUT; $headers = array(); $postParams = array(); $queryParams = array(); $path = $this->_createPath($container, $blob); $expectedStatusCode = Resources::STATUS_CREATED; if (is_null($options)) { $options = new CreateBlobSnapshotOptions(); } $queryParams[Resources::QP_COMP] = 'snapshot'; $this->addOptionalQueryParam( $queryParams, Resources::QP_TIMEOUT, $options->getTimeout() ); $headers = $this->addOptionalAccessConditionHeader( $headers, $options->getAccessCondition() ); $headers = $this->addMetadataHeaders($headers, $options->getMetadata()); $this->addOptionalHeader( $headers, Resources::X_MS_LEASE_ID, $options->getLeaseId() ); $response = $this->send( $method, $headers, $queryParams, $postParams, $path, $expectedStatusCode ); return CreateBlobSnapshotResult::create($response->getHeader()); } /** * Copies a source blob to a destination blob within the same storage account. * * @param string $destinationContainer name of the destination * container * @param string $destinationBlob name of the destination * blob * @param string $sourceContainer name of the source * container * @param string $sourceBlob name of the source * blob * @param Models\CopyBlobOptions $options optional parameters * * @return CopyBlobResult * * @see http://msdn.microsoft.com/en-us/library/windowsazure/dd894037.aspx */ public function copyBlob( $destinationContainer, $destinationBlob, $sourceContainer, $sourceBlob, $options = null ) { $method = Resources::HTTP_PUT; $headers = array(); $postParams = array(); $queryParams = array(); $destinationBlobPath = $this->_createPath( $destinationContainer, $destinationBlob ); $statusCode = Resources::STATUS_ACCEPTED; if (is_null($options)) { $options = new CopyBlobOptions(); } $this->addOptionalQueryParam( $queryParams, Resources::QP_TIMEOUT, $options->getTimeout() ); $sourceBlobPath = $this->_getCopyBlobSourceName( $sourceContainer, $sourceBlob, $options ); $headers = $this->addOptionalAccessConditionHeader( $headers, $options->getAccessCondition() ); $headers = $this->addOptionalSourceAccessConditionHeader( $headers, $options->getSourceAccessCondition() ); $this->addOptionalHeader( $headers, Resources::X_MS_COPY_SOURCE, $sourceBlobPath ); $headers = $this->addMetadataHeaders($headers, $options->getMetadata()); $this->addOptionalHeader( $headers, Resources::X_MS_LEASE_ID, $options->getLeaseId() ); $this->addOptionalHeader( $headers, Resources::X_MS_SOURCE_LEASE_ID, $options->getSourceLeaseId() ); $response = $this->send( $method, $headers, $queryParams, $postParams, $destinationBlobPath, $statusCode ); return CopyBlobResult::create($response->getHeader()); } /** * Establishes an exclusive one-minute write lock on a blob. To write to a locked * blob, a client must provide a lease ID. * * @param string $container name of the container * @param string $blob name of the blob * @param Models\AcquireLeaseOptions $options optional parameters * * @return Models\AcquireLeaseResult * * @see http://msdn.microsoft.com/en-us/library/windowsazure/ee691972.aspx */ public function acquireLease($container, $blob, $options = null) { $headers = $this->_putLeaseImpl( LeaseMode::ACQUIRE_ACTION, $container, $blob, null /* leaseId */, is_null($options) ? new AcquireLeaseOptions() : $options, is_null($options) ? null : $options->getAccessCondition() ); return AcquireLeaseResult::create($headers); } /** * Renews an existing lease * * @param string $container name of the container * @param string $blob name of the blob * @param string $leaseId lease id when acquiring * @param Models\BlobServiceOptions $options optional parameters * * @return Models\AcquireLeaseResult * * @see http://msdn.microsoft.com/en-us/library/windowsazure/ee691972.aspx */ public function renewLease($container, $blob, $leaseId, $options = null) { $headers = $this->_putLeaseImpl( LeaseMode::RENEW_ACTION, $container, $blob, $leaseId, is_null($options) ? new BlobServiceOptions() : $options ); return AcquireLeaseResult::create($headers); } /** * Frees the lease if it is no longer needed so that another client may * immediately acquire a lease against the blob. * * @param string $container name of the container * @param string $blob name of the blob * @param string $leaseId lease id when acquiring * @param Models\BlobServiceOptions $options optional parameters * * @return none * * @see http://msdn.microsoft.com/en-us/library/windowsazure/ee691972.aspx */ public function releaseLease($container, $blob, $leaseId, $options = null) { $this->_putLeaseImpl( LeaseMode::RELEASE_ACTION, $container, $blob, $leaseId, is_null($options) ? new BlobServiceOptions() : $options ); } /** * Ends the lease but ensure that another client cannot acquire a new lease until * the current lease period has expired. * * @param string $container name of the container * @param string $blob name of the blob * @param Models\BlobServiceOptions $options optional parameters * * @return BreakLeaseResult * * @see http://msdn.microsoft.com/en-us/library/windowsazure/ee691972.aspx */ public function breakLease($container, $blob, $options = null) { $headers = $this->_putLeaseImpl( LeaseMode::BREAK_ACTION, $container, $blob, null, is_null($options) ? new BlobServiceOptions() : $options ); return BreakLeaseResult::create($headers); } } includes/WindowsAzure/Common/Internal/Atom/Entry.php000064400000033006152214270100016525 0ustar00 * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @link https://github.com/WindowsAzure/azure-sdk-for-php */ namespace WindowsAzure\Common\Internal\Atom; use WindowsAzure\Common\Internal\Utilities; use WindowsAzure\Common\Internal\Resources; use WindowsAzure\Common\Internal\Validate; /** * The Entry class of ATOM standard. * * @category Microsoft * @package WindowsAzure\Common\Internal\Atom * @author Azure PHP SDK * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @version Release: 0.4.1_2015-03 * @link https://github.com/WindowsAzure/azure-sdk-for-php */ class Entry extends AtomBase { // @codingStandardsIgnoreStart /** * The author of the entry. * * @var Person */ protected $author; /** * The category of the entry. * * @var array */ protected $category; /** * The content of the entry. * * @var string */ protected $content; /** * The contributor of the entry. * * @var string */ protected $contributor; /** * An unqiue ID representing the entry. * * @var string */ protected $id; /** * The link of the entry. * * @var string */ protected $link; /** * Is the entry published. * * @var boolean */ protected $published; /** * The copy right of the entry. * * @var string */ protected $rights; /** * The source of the entry. * * @var string */ protected $source; /** * The summary of the entry. * * @var string */ protected $summary; /** * The title of the entry. * * @var string */ protected $title; /** * Is the entry updated. * * @var \DateTime */ protected $updated; /** * The extension element of the entry. * * @var string */ protected $extensionElement; /** * Creates an ATOM Entry instance with default parameters. */ public function __construct() { $this->attributes = array(); } /** * Populate the properties of an ATOM Entry instance with specified XML.. * * @param string $xmlString A string representing an ATOM entry instance. * * @return none */ public function parseXml($xmlString) { Validate::notNull($xmlString, 'xmlString'); $this->fromXml(simplexml_load_string($xmlString)); } /** * Creates an ATOM ENTRY instance with specified simpleXML object * * @param \SimpleXMLElement $entryXml xml element of ATOM ENTRY * * @return none */ public function fromXml($entryXml) { Validate::notNull($entryXml, 'entryXml'); Validate::isA($entryXml, '\SimpleXMLElement', 'entryXml'); $this->attributes = (array)$entryXml->attributes(); $entryArray = (array)$entryXml; if (array_key_exists(Resources::AUTHOR, $entryArray)) { $this->author = $this->processAuthorNode($entryArray); } if (array_key_exists(Resources::CATEGORY, $entryArray)) { $this->category = $this->processCategoryNode($entryArray); } if (array_key_exists('content', $entryArray)) { $content = new Content(); $content->fromXml($entryArray['content']); $this->content = $content; } if (array_key_exists(Resources::CONTRIBUTOR, $entryArray)) { $this->contributor = $this->processContributorNode($entryArray); } if (array_key_exists('id', $entryArray)) { $this->id = (string)$entryArray['id']; } if (array_key_exists(Resources::LINK, $entryArray)) { $this->link = $this->processLinkNode($entryArray); } if (array_key_exists('published', $entryArray)) { $this->published = $entryArray['published']; } if (array_key_exists('rights', $entryArray)) { $this->rights = $entryArray['rights']; } if (array_key_exists('source', $entryArray)) { $source = new Source(); $source->parseXml($entryArray['source']->asXML()); $this->source = $source; } if (array_key_exists('title', $entryArray)) { $this->title = $entryArray['title']; } if (array_key_exists('updated', $entryArray)) { $this->updated = \DateTime::createFromFormat( \DateTime::ATOM, (string)$entryArray['updated'] ); } } /** * Gets the author of the entry. * * @return Person */ public function getAuthor() { return $this->author; } /** * Sets the author of the entry. * * @param Person $author The author of the entry. * * @return none */ public function setAuthor($author) { $this->author = $author; } /** * Gets the category. * * @return array */ public function getCategory() { return $this->category; } /** * Sets the category. * * @param string $category The category of the entry. * * @return none */ public function setCategory($category) { $this->category = $category; } /** * Gets the content. * * @return Content. */ public function getContent() { return $this->content; } /** * Sets the content. * * @param Content $content Sets the content of the entry. * * @return none */ public function setContent($content) { $this->content = $content; } /** * Gets the contributor. * * @return string */ public function getContributor() { return $this->contributor; } /** * Sets the contributor. * * @param string $contributor The contributor of the entry. * * @return none */ public function setContributor($contributor) { $this->contributor = $contributor; } /** * Gets the ID of the entry. * * @return string */ public function getId() { return $this->id; } /** * Sets the ID of the entry. * * @param string $id The id of the entry. * * @return none */ public function setId($id) { $this->id = $id; } /** * Gets the link of the entry. * * @return string */ public function getLink() { return $this->link; } /** * Sets the link of the entry. * * @param string $link The link of the entry. * * @return none */ public function setLink($link) { $this->link = $link; } /** * Gets published of the entry. * * @return boolean */ public function getPublished() { return $this->published; } /** * Sets published of the entry. * * @param boolean $published Is the entry published. * * @return none */ public function setPublished($published) { $this->published = $published; } /** * Gets the rights of the entry. * * @return string */ public function getRights() { return $this->rights; } /** * Sets the rights of the entry. * * @param string $rights The rights of the entry. * * @return none */ public function setRights($rights) { $this->rights = $rights; } /** * Gets the source of the entry. * * @return string */ public function getSource() { return $this->source; } /** * Sets the source of the entry. * * @param string $source The source of the entry. * * @return none */ public function setSource($source) { $this->source = $source; } /** * Gets the summary of the entry. * * @return string */ public function getSummary() { return $this->summary; } /** * Sets the summary of the entry. * * @param string $summary The summary of the entry. * * @return none */ public function setSummary($summary) { $this->summary = $summary; } /** * Gets the title of the entry. * * @return string */ public function getTitle() { return $this->title; } /** * Sets the title of the entry. * * @param string $title The title of the entry. * * @return none */ public function setTitle($title) { $this->title = $title; } /** * Gets updated. * * @return \DateTime */ public function getUpdated() { return $this->updated; } /** * Sets updated * * @param \DateTime $updated updated. * * @return none */ public function setUpdated($updated) { $this->updated = $updated; } /** * Gets extension element. * * @return string */ public function getExtensionElement() { return $this->extensionElement; } /** * Sets extension element. * * @param string $extensionElement The extension element of the entry. * * @return none */ public function setExtensionElement($extensionElement) { $this->extensionElement = $extensionElement; } /** * Writes a inner XML string representing the entry. * * @param \XMLWriter $xmlWriter The XML writer. * * @return none */ public function writeXml($xmlWriter) { Validate::notNull($xmlWriter, 'xmlWriter'); $xmlWriter->startElementNS( 'atom', Resources::ENTRY, Resources::ATOM_NAMESPACE ); $this->writeInnerXml($xmlWriter); $xmlWriter->endElement(); } /** * Writes a inner XML string representing the entry. * * @param \XMLWriter $xmlWriter The XML writer. * * @return none */ public function writeInnerXml($xmlWriter) { if (!is_null($this->attributes)) { if (is_array($this->attributes)) { foreach ( $this->attributes as $attributeName => $attributeValue ) { $xmlWriter->writeAttribute($attributeName, $attributeValue); } } } if (!is_null($this->author)) { $this->writeArrayItem( $xmlWriter, $this->author, Resources::AUTHOR ); } if (!is_null($this->category)) { $this->writeArrayItem( $xmlWriter, $this->category, Resources::CATEGORY ); } if (!is_null($this->content)) { $this->content->writeXml($xmlWriter); } if (!is_null($this->contributor)) { $this->writeArrayItem( $xmlWriter, $this->contributor, Resources::CONTRIBUTOR ); } $this->writeOptionalElementNS( $xmlWriter, 'atom', 'id', Resources::ATOM_NAMESPACE, $this->id ); if (!is_null($this->link)) { $this->writeArrayItem( $xmlWriter, $this->link, Resources::LINK ); } $this->writeOptionalElementNS( $xmlWriter, 'atom', 'published', Resources::ATOM_NAMESPACE, $this->published ); $this->writeOptionalElementNS( $xmlWriter, 'atom', 'rights', Resources::ATOM_NAMESPACE, $this->rights ); $this->writeOptionalElementNS( $xmlWriter, 'atom', 'source', Resources::ATOM_NAMESPACE, $this->source ); $this->writeOptionalElementNS( $xmlWriter, 'atom', 'summary', Resources::ATOM_NAMESPACE, $this->summary ); $this->writeOptionalElementNS( $xmlWriter, 'atom', 'title', Resources::ATOM_NAMESPACE, $this->title ); if (!is_null($this->updated)) { $xmlWriter->writeElementNS( 'atom', 'updated', Resources::ATOM_NAMESPACE, $this->updated->format(\DateTime::ATOM) ); } } } // @codingStandardsIgnoreEndincludes/WindowsAzure/Common/Internal/Atom/Generator.php000064400000011023152214270100017345 0ustar00 * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @link https://github.com/WindowsAzure/azure-sdk-for-php */ namespace WindowsAzure\Common\Internal\Atom; use WindowsAzure\Common\Internal\Utilities; use WindowsAzure\Common\Internal\Resources; /** * The generator class of ATOM library. * * @category Microsoft * @package WindowsAzure\Common\Internal\Atom * @author Azure PHP SDK * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @version Release: 0.4.1_2015-03 * @link https://github.com/WindowsAzure/azure-sdk-for-php */ class Generator extends AtomBase { /** * The of the generator. * * @var string */ protected $text; /** * The Uri of the generator. * * @var string */ protected $uri; /** * The version of the generator. * * @var string */ protected $version; /** * Creates a generator instance with specified XML string. * * @param string $xmlString A string representing a generator * instance. * * @return none */ public static function parseXml($xmlString) { $generatorXml = new \SimpleXMLElement($xmlString); $generatorArray = (array)$generatorXml; $attributes = $generatorXml->attributes(); if (!empty($attributes['uri'])) { $this->uri = (string)$attributes['uri']; } if (!empty($attributes['version'])) { $this->version = (string)$attributes['version']; } $this->text = (string)$generatorXml; } /** * Creates an ATOM generator instance with specified name. * * @param string $text The text content of the generator. * * @return none */ public function __construct($text = null) { if (!empty($text)) { $this->text = $text; } } /** * Gets the text of the generator. * * @return string */ public function getText() { return $this->text; } /** * Sets the text of the generator. * * @param string $text The text of the generator. * * @return none */ public function setText($text) { $this->text = $text; } /** * Gets the URI of the generator. * * @return string */ public function getUri() { return $this->uri; } /** * Sets the URI of the generator. * * @param string $uri The URI of the generator. * * @return none */ public function setUri($uri) { $this->uri = $uri; } /** * Gets the version of the generator. * * @return string */ public function getVersion() { return $this->version; } /** * Sets the version of the generator. * * @param string $version The version of the generator. * * @return none */ public function setVersion($version) { $this->version = $version; } /** * Writes an XML representing the generator. * * @param \XMLWriter $xmlWriter The XML writer. * * @return none */ public function writeXml($xmlWriter) { $xmlWriter->startElementNS( 'atom', Resources::CATEGORY, Resources::ATOM_NAMESPACE ); $this->writeOptionalAttribute( $xmlWriter, 'uri', $this->uri ); $this->writeOptionalAttribute( $xmlWriter, 'version', $this->version ); $xmlWriter->writeRaw($this->text); $xmlWriter->endElement(); } } includes/WindowsAzure/Common/Internal/Atom/Category.php000064400000013640152214270100017203 0ustar00 * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @link https://github.com/WindowsAzure/azure-sdk-for-php */ namespace WindowsAzure\Common\Internal\Atom; use WindowsAzure\Common\Internal\Resources; use WindowsAzure\Common\Internal\Utilities; use WindowsAzure\Common\Internal\Validate; /** * The category class of the ATOM standard. * * @category Microsoft * @package WindowsAzure\Common\Internal\Atom * @author Azure PHP SDK * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @version Release: 0.4.1_2015-03 * @link https://github.com/WindowsAzure/azure-sdk-for-php */ class Category extends AtomBase { /** * The term of the category. * * @var string */ protected $term; /** * The scheme of the category. * * @var string */ protected $scheme; /** * The label of the category. * * @var string */ protected $label; /** * The undefined content of the category. * * @var string */ protected $undefinedContent; /** * Creates a Category instance with specified text. * * @param string $undefinedContent The undefined content of the category. * * @return none */ public function __construct($undefinedContent = Resources::EMPTY_STRING) { $this->undefinedContent = $undefinedContent; } /** * Creates an ATOM Category instance with specified xml string. * * @param string $xmlString an XML based string of ATOM CONTENT. * * @return none */ public function parseXml($xmlString) { Validate::notNull($xmlString, 'xmlString'); Validate::isString($xmlString, 'xmlString'); $categoryXml = simplexml_load_string($xmlString); $attributes = $categoryXml->attributes(); if (!empty($attributes['term'])) { $this->term = (string)$attributes['term']; } if (!empty($attributes['scheme'])) { $this->scheme = (string)$attributes['scheme']; } if (!empty($attributes['label'])) { $this->label = (string)$attributes['label']; } $this->undefinedContent =(string)$categoryXml; } /** * Gets the term of the category. * * @return string */ public function getTerm() { return $this->term; } /** * Sets the term of the category. * * @param string $term The term of the category. * * @return none */ public function setTerm($term) { $this->term = $term; } /** * Gets the scheme of the category. * * @return string */ public function getScheme() { return $this->scheme; } /** * Sets the scheme of the category. * * @param string $scheme The scheme of the category. * * @return none */ public function setScheme($scheme) { $this->scheme = $scheme; } /** * Gets the label of the category. * * @return string The label. */ public function getLabel() { return $this->label; } /** * Sets the label of the category. * * @param string $label The label of the category. * * @return none */ public function setLabel($label) { $this->label = $label; } /** * Gets the undefined content of the category. * * @return string */ public function getUndefinedContent() { return $this->undefinedContent; } /** * Sets the undefined content of the category. * * @param string $undefinedContent The undefined content of the category. * * @return none */ public function setUndefinedContent($undefinedContent) { $this->undefinedContent = $undefinedContent; } /** * Writes an XML representing the category. * * @param \XMLWriter $xmlWriter The XML writer. * * @return none */ public function writeXml($xmlWriter) { Validate::notNull($xmlWriter, 'xmlWriter'); $xmlWriter->startElementNS( 'atom', 'category', Resources::ATOM_NAMESPACE ); $this->writeInnerXml($xmlWriter); $xmlWriter->endElement(); } /** * Writes an XML representing the category. * * @param \XMLWriter $xmlWriter The XML writer. * * @return none */ public function writeInnerXml($xmlWriter) { Validate::notNull($xmlWriter, 'xmlWriter'); $this->writeOptionalAttribute( $xmlWriter, 'term', $this->term ); $this->writeOptionalAttribute( $xmlWriter, 'scheme', $this->scheme ); $this->writeOptionalAttribute( $xmlWriter, 'label', $this->label ); if (!empty($this->undefinedContent)) { $xmlWriter->WriteRaw($this->undefinedContent); } } } includes/WindowsAzure/Common/Internal/Atom/AtomLink.php000064400000017077152214270100017154 0ustar00 * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @link https://github.com/WindowsAzure/azure-sdk-for-php */ namespace WindowsAzure\Common\Internal\Atom; use WindowsAzure\Common\Internal\Resources; use WindowsAzure\Common\Internal\Utilities; use WindowsAzure\Common\Internal\Validate; /** * This link defines a reference from an entry or feed to a Web resource. * * @category Microsoft * @package WindowsAzure\Common\Internal\Atom * @author Azure PHP SDK * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @version Release: 0.4.1_2015-03 * @link https://github.com/WindowsAzure/azure-sdk-for-php */ class AtomLink extends AtomBase { /** * The undefined content. * * @var string */ protected $undefinedContent; /** * The HREF of the link. * * @var string */ protected $href; /** * The rel attribute of the link. * * @var string */ protected $rel; /** * The media type of the link. * * @var string */ protected $type; /** * The language of HREF. * * @var string */ protected $hreflang; /** * The titile of the link. * * @var string */ protected $title; /** * The length of the link. * * @var integer */ protected $length; /** * Creates a AtomLink instance with specified text. */ public function __construct() { } /** * Parse an ATOM Link xml. * * @param string $xmlString an XML based string of ATOM Link. * * @return none */ public function parseXml($xmlString) { Validate::notNull($xmlString, 'xmlString'); Validate::isString($xmlString, 'xmlString'); $atomLinkXml = simplexml_load_string($xmlString); $attributes = $atomLinkXml->attributes(); if (!empty($attributes['href'])) { $this->href = (string)$attributes['href']; } if (!empty($attributes['rel'])) { $this->rel = (string)$attributes['rel']; } if (!empty($attributes['type'])) { $this->type = (string)$attributes['type']; } if (!empty($attributes['hreflang'])) { $this->hreflang = (string)$attributes['hreflang']; } if (!empty($attributes['title'])) { $this->title = (string)$attributes['title']; } if (!empty($attributes['length'])) { $this->length = (integer)$attributes['length']; } $undefinedContent = (string)$atomLinkXml; if (empty($undefinedContent)) { $this->undefinedContent = null; } else { $this->undefinedContent = (string)$atomLinkXml; } } /** * Gets the href of the link. * * @return string */ public function getHref() { return $this->href; } /** * Sets the href of the link. * * @param string $href The href of the link. * * @return none */ public function setHref($href) { $this->href = $href; } /** * Gets the rel of the atomLink. * * @return string */ public function getRel() { return $this->rel; } /** * Sets the rel of the link. * * @param string $rel The rel of the atomLink. * * @return none */ public function setRel($rel) { $this->rel = $rel; } /** * Gets the type of the link. * * @return string */ public function getType() { return $this->type; } /** * Sets the type of the link. * * @param string $type The type of the link. * * @return none */ public function setType($type) { $this->type = $type; } /** * Gets the language of the href. * * @return string */ public function getHrefLang() { return $this->hrefLang; } /** * Sets the language of the href. * * @param string $hrefLang The language of the href. * * @return none */ public function setHrefLang($hrefLang) { $this->hrefLang = $hrefLang; } /** * Gets the title of the link. * * @return string */ public function getTitle() { return $this->title; } /** * Sets the title of the link. * * @param string $title The title of the link. * * @return none */ public function setTitle($title) { $this->title = $title; } /** * Gets the length of the link. * * @return string */ public function getLength() { return $this->length; } /** * Sets the length of the link. * * @param string $length The length of the link. * * @return none */ public function setLength($length) { $this->length = $length; } /** * Gets the undefined content. * * @return string */ public function getUndefinedContent() { return $this->undefinedContent; } /** * Sets the undefined content. * * @param string $undefinedContent The undefined content. * * @return none */ public function setUndefinedContent($undefinedContent) { $this->undefinedContent = $undefinedContent; } /** * Writes an XML representing the ATOM link item. * * @param \XMLWriter $xmlWriter The xml writer. * * @return none */ public function writeXml($xmlWriter) { Validate::notNull($xmlWriter, 'xmlWriter'); $xmlWriter->startElementNS( 'atom', Resources::LINK, Resources::ATOM_NAMESPACE ); $this->writeInnerXml($xmlWriter); $xmlWriter->endElement(); } /** * Writes the inner XML representing the ATOM link item. * * @param \XMLWriter $xmlWriter The xml writer. * * @return none */ public function writeInnerXml($xmlWriter) { Validate::notNull($xmlWriter, 'xmlWriter'); $this->writeOptionalAttribute($xmlWriter, 'href', $this->href); $this->writeOptionalAttribute($xmlWriter, 'rel', $this->rel); $this->writeOptionalAttribute($xmlWriter, 'type', $this->type); $this->writeOptionalAttribute($xmlWriter, 'hreflang', $this->hreflang); $this->writeOptionalAttribute($xmlWriter, 'title', $this->title); $this->writeOptionalAttribute($xmlWriter, 'length', $this->length); if (!empty($this->undefinedContent)) { $xmlWriter->writeRaw($this->undefinedContent); } } } includes/WindowsAzure/Common/Internal/Atom/Feed.php000064400000037277152214270100016305 0ustar00 * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @link https://github.com/WindowsAzure/azure-sdk-for-php */ namespace WindowsAzure\Common\Internal\Atom; use WindowsAzure\Common\Internal\Validate; use WindowsAzure\Common\Internal\Resources; /** * The feed class of ATOM library. * * @category Microsoft * @package WindowsAzure\Common\Internal\Atom * @author Azure PHP SDK * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @version Release: 0.4.1_2015-03 * @link https://github.com/WindowsAzure/azure-sdk-for-php */ class Feed extends AtomBase { // @codingStandardsIgnoreStart /** * The entry of the feed. * * @var array */ protected $entry; /** * the author of the feed. * * @var array */ protected $author; /** * The category of the feed. * * @var array */ protected $category; /** * The contributor of the feed. * * @var array */ protected $contributor; /** * The generator of the feed. * * @var Generator */ protected $generator; /** * The icon of the feed. * * @var string */ protected $icon; /** * The ID of the feed. * * @var string */ protected $id; /** * The link of the feed. * * @var array */ protected $link; /** * The logo of the feed. * * @var string */ protected $logo; /** * The rights of the feed. * * @var string */ protected $rights; /** * The subtitle of the feed. * * @var string */ protected $subtitle; /** * The title of the feed. * * @var string */ protected $title; /** * The update of the feed. * * @var \DateTime */ protected $updated; /** * The extension element of the feed. * * @var string */ protected $extensionElement; /** * Creates an ATOM FEED object with default parameters. */ public function __construct() { $this->attributes = array(); } /** * Creates a feed object with specified XML string. * * @param string $xmlString An XML string representing the feed object. * * @return none */ public function parseXml($xmlString) { $feedXml = simplexml_load_string($xmlString); $attributes = $feedXml->attributes(); $feedArray = (array)$feedXml; if (!empty($attributes)) { $this->attributes = (array)$attributes; } if (array_key_exists('author', $feedArray)) { $this->author = $this->processAuthorNode($feedArray); } if (array_key_exists('entry', $feedArray)) { $this->entry = $this->processEntryNode($feedArray); } if (array_key_exists('category', $feedArray)) { $this->category = $this->processCategoryNode($feedArray); } if (array_key_exists('contributor', $feedArray)) { $this->contributor = $this->processContributorNode($feedArray); } if (array_key_exists('generator', $feedArray)) { $generator = new Generator(); $generatorValue = $feedArray['generator']; if (is_string($generatorValue)) { $generator->setText($generatorValue); } else { $generator->parseXml($generatorValue->asXML()); } $this->generator = $generator; } if (array_key_exists('icon', $feedArray)) { $this->icon = (string)$feedArray['icon']; } if (array_key_exists('id', $feedArray)) { $this->id = (string)$feedArray['id']; } if (array_key_exists('link', $feedArray)) { $this->link = $this->processLinkNode($feedArray); } if (array_key_exists('logo', $feedArray)) { $this->logo = (string)$feedArray['logo']; } if (array_key_exists('rights', $feedArray)) { $this->rights = (string)$feedArray['rights']; } if (array_key_exists('subtitle', $feedArray)) { $this->subtitle = (string)$feedArray['subtitle']; } if (array_key_exists('title', $feedArray)) { $this->title = (string)$feedArray['title']; } if (array_key_exists('updated', $feedArray)) { $this->updated = \DateTime::createFromFormat( \DateTime::ATOM, (string)$feedArray['updated'] ); } } /** * Gets the attributes of the feed. * * @return array */ public function getAttributes() { return $this->attributes; } /** * Sets the attributes of the feed. * * @param array $attributes The attributes of the array. * * @return array */ public function setAttributes($attributes) { Validate::isArray($attributes, 'attributes'); $this->attributes = $attributes; } /** * Adds an attribute to the feed object instance. * * @param string $attributeKey The key of the attribute. * @param mixed $attributeValue The value of the attribute. * * @return none */ public function addAttribute($attributeKey, $attributeValue) { $this->attributes[$attributeKey] = $attributeValue; } /** * Gets the author of the feed. * * @return Person */ public function getAuthor() { return $this->author; } /** * Sets the author of the feed. * * @param Person $author The author of the feed. * * @return none */ public function setAuthor($author) { Validate::isArray($author, 'author'); $person = new Person(); foreach ($author as $authorInstance) { Validate::isInstanceOf($authorInstance, $person, 'author'); } $this->author = $author; } /** * Gets the category of the feed. * * @return Category */ public function getCategory() { return $this->category; } /** * Sets the category of the feed. * * @param Category $category The category of the feed. * * @return none */ public function setCategory($category) { Validate::isArray($category, 'category'); $categoryClassInstance = new Category(); foreach ($category as $categoryInstance) { Validate::isInstanceOf( $categoryInstance, $categoryClassInstance, 'category' ); } $this->category = $category; } /** * Gets contributor. * * @return array */ public function getContributor() { return $this->contributor; } /** * Sets contributor. * * @param string $contributor The contributor of the feed. * * @return none */ public function setContributor($contributor) { Validate::isArray($contributor, 'contributor'); $person = new Person(); foreach ($contributor as $contributorInstance) { Validate::isInstanceOf($contributorInstance, $person, 'contributor'); } $this->contributor = $contributor; } /** * Gets generator. * * @return string */ public function getGenerator() { return $this->generator; } /** * Sets the generator. * * @param string $generator Sets the generator of the feed. * * @return none */ public function setGenerator($generator) { $this->generator = $generator; } /** * Gets the icon of the feed. * * @return string */ public function getIcon() { return $this->icon; } /** * Sets the icon of the feed. * * @param string $icon The icon of the feed. * * @return none */ public function setIcon($icon) { $this->icon = $icon; } /** * Gets the ID of the feed. * * @return string */ public function getId() { return $this->id; } /** * Sets the ID of the feed. * * @param string $id The ID of the feed. * * @return none */ public function setId($id) { $this->id = $id; } /** * Gets the link of the feed. * * @return array */ public function getLink() { return $this->link; } /** * Sets the link of the feed. * * @param array $link The link of the feed. * * @return none */ public function setLink($link) { Validate::isArray($link, 'link'); $this->link = $link; } /** * Gets the logo of the feed. * * @return string */ public function getLogo() { return $this->logo; } /** * Sets the logo of the feed. * * @param string $logo The logo of the feed. * * @return none */ public function setLogo($logo) { $this->logo = $logo; } /** * Gets the rights of the feed. * * @return string */ public function getRights() { return $this->rights; } /** * Sets the rights of the feed. * * @param string $rights The rights of the feed. * * @return none */ public function setRights($rights) { $this->rights = $rights; } /** * Gets the sub title. * * @return string */ public function getSubtitle() { return $this->subtitle; } /** * Sets the sub title of the feed. * * @param string $subtitle Sets the sub title of the feed. * * @return none */ public function setSubtitle($subtitle) { $this->subtitle = $subtitle; } /** * Gets the title of the feed. * * @return string. */ public function getTitle() { return $this->title; } /** * Sets the title of the feed. * * @param string $title The title of the feed. * * @return none */ public function setTitle($title) { $this->title = $title; } /** * Gets the updated. * * @return \DateTime */ public function getUpdated() { return $this->updated; } /** * Sets the updated. * * @param \DateTime $updated updated * * @return none */ public function setUpdated($updated) { Validate::isInstanceOf($updated, new \DateTime(), 'updated'); $this->updated = $updated; } /** * Gets the extension element. * * @return string */ public function getExtensionElement() { return $this->extensionElement; } /** * Sets the extension element. * * @param string $extensionElement The extension element. * * @return none */ public function setExtensionElement($extensionElement) { $this->extensionElement = $extensionElement; } /** * Gets the entry of the feed. * * @return Entry */ public function getEntry() { return $this->entry; } /** * Sets the entry of the feed. * * @param Entry $entry The entry of the feed. * * @return none */ public function setEntry($entry) { $this->entry = $entry; } /** * Writes an XML representing the feed object. * * @param \XMLWriter $xmlWriter The XML writer. * * @return none */ public function writeXml($xmlWriter) { Validate::notNull($xmlWriter, 'xmlWriter'); $xmlWriter->startElementNS('atom', 'feed', Resources::ATOM_NAMESPACE); $this->writeInnerXml($xmlWriter); $xmlWriter->endElement(); } /** * Writes an XML representing the feed object. * * @param \XMLWriter $xmlWriter The XML writer. * * @return none */ public function writeInnerXml($xmlWriter) { Validate::notNull($xmlWriter, 'xmlWriter'); if (!is_null($this->attributes)) { if (is_array($this->attributes)) { foreach ( $this->attributes as $attributeName => $attributeValue ) { $xmlWriter->writeAttribute($attributeName, $attributeValue); } } } if (!is_null($this->author)) { $this->writeArrayItem( $xmlWriter, $this->author, Resources::AUTHOR ); } if (!is_null($this->category)) { $this->writeArrayItem( $xmlWriter, $this->category, Resources::CATEGORY ); } if (!is_null($this->contributor)) { $this->writeArrayItem( $xmlWriter, $this->contributor, Resources::CONTRIBUTOR ); } if (!is_null($this->generator)) { $this->generator->writeXml($xmlWriter); } $this->writeOptionalElementNS( $xmlWriter, 'atom', 'icon', Resources::ATOM_NAMESPACE, $this->icon ); $this->writeOptionalElementNS( $xmlWriter, 'atom', 'logo', Resources::ATOM_NAMESPACE, $this->logo ); $this->writeOptionalElementNS( $xmlWriter, 'atom', 'id', Resources::ATOM_NAMESPACE, $this->id ); if (!is_null($this->link)) { $this->writeArrayItem( $xmlWriter, $this->link, Resources::LINK ); } $this->writeOptionalElementNS( $xmlWriter, 'atom', 'rights', Resources::ATOM_NAMESPACE, $this->rights ); $this->writeOptionalElementNS( $xmlWriter, 'atom', 'subtitle', Resources::ATOM_NAMESPACE, $this->subtitle ); $this->writeOptionalElementNS( $xmlWriter, 'atom', 'title', Resources::ATOM_NAMESPACE, $this->title ); if (!is_null($this->updated)) { $xmlWriter->writeElementNS( 'atom', 'updated', Resources::ATOM_NAMESPACE, $this->updated->format(\DateTime::ATOM) ); } } } // @codingStandardsIgnoreEndincludes/WindowsAzure/Common/Internal/Atom/AtomBase.php000064400000022441152214270100017120 0ustar00 * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @link https://github.com/WindowsAzure/azure-sdk-for-php */ namespace WindowsAzure\Common\Internal\Atom; use WindowsAzure\Common\Internal\Validate; use WindowsAzure\Common\Internal\Resources; use WindowsAzure\Common\Internal\Atom\AtomLink; /** * The base class of ATOM library. * * @category Microsoft * @package WindowsAzure\Common\Internal\Atom * @author Azure PHP SDK * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @version Release: 0.4.1_2015-03 * @link https://github.com/WindowsAzure/azure-sdk-for-php */ class AtomBase { /** * The attributes of the feed. * * @var array */ protected $attributes; /** * Creates an ATOM base object with default parameters. */ public function __construct() { $this->attributes = array(); $atomlink = new AtomLink(); } /** * Gets the attributes of the ATOM class. * * @return array */ public function getAttributes() { return $this->attributes; } /** * Sets the attributes of the ATOM class. * * @param array $attributes The attributes of the array. * * @return array */ public function setAttributes($attributes) { Validate::isArray($attributes, 'attributes'); $this->attributes = $attributes; } /** * Sets an attribute to the ATOM object instance. * * @param string $attributeKey The key of the attribute. * @param mixed $attributeValue The value of the attribute. * * @return none */ public function setAttribute($attributeKey, $attributeValue) { $this->attributes[$attributeKey] = $attributeValue; } /** * Gets an attribute with a specified attribute key. * * @param string $attributeKey The key of the attribute. * * @return none */ public function getAttribute($attributeKey) { return $this->attributes[$attributeKey]; } /** * Processes author node. * * @param array $xmlWriter The XML writer. * @param array $itemArray An array of item to write. * @param array $elementName The name of the element. * * @return array */ protected function writeArrayItem($xmlWriter, $itemArray, $elementName) { Validate::notNull($xmlWriter, 'xmlWriter'); Validate::isArray($itemArray, 'itemArray'); Validate::isString($elementName, 'elementName'); foreach ($itemArray as $itemInstance) { $xmlWriter->startElementNS( 'atom', $elementName, Resources::ATOM_NAMESPACE ); $itemInstance->writeInnerXml($xmlWriter); $xmlWriter->endElement(); } } /** * Processes author node. * * @param array $xmlArray An array of simple xml elements. * * @return array */ protected function processAuthorNode($xmlArray) { $author = array(); $authorItem = $xmlArray[Resources::AUTHOR]; if (is_array($authorItem)) { foreach ($xmlArray[Resources::AUTHOR] as $authorXmlInstance) { $authorInstance = new Person(); $authorInstance->parseXml($authorXmlInstance->asXML()); $author[] = $authorInstance; } } else { $authorInstance = new Person(); $authorInstance->parseXml($authorItem->asXML()); $author[] = $authorInstance; } return $author; } /** * Processes entry node. * * @param array $xmlArray An array of simple xml elements. * * @return array */ protected function processEntryNode($xmlArray) { $entry = array(); $entryItem = $xmlArray[Resources::ENTRY]; if (is_array($entryItem)) { foreach ($xmlArray[Resources::ENTRY] as $entryXmlInstance) { $entryInstance = new Entry(); $entryInstance->fromXml($entryXmlInstance); $entry[] = $entryInstance; } } else { $entryInstance = new Entry(); $entryInstance->fromXml($entryItem); $entry[] = $entryInstance; } return $entry; } /** * Processes category node. * * @param array $xmlArray An array of simple xml elements. * * @return array */ protected function processCategoryNode($xmlArray) { $category = array(); $categoryItem = $xmlArray[Resources::CATEGORY]; if (is_array($categoryItem)) { foreach ($xmlArray[Resources::CATEGORY] as $categoryXmlInstance) { $categoryInstance = new Category(); $categoryInstance->parseXml($categoryXmlInstance->asXML()); $category[] = $categoryInstance; } } else { $categoryInstance = new Category(); $categoryInstance->parseXml($categoryItem->asXML()); $category[] = $categoryInstance; } return $category; } /** * Processes contributor node. * * @param array $xmlArray An array of simple xml elements. * * @return array */ protected function processContributorNode($xmlArray) { $category = array(); $contributorItem = $xmlArray[Resources::CONTRIBUTOR]; if (is_array($contributorItem)) { foreach ($xmlArray[Resources::CONTRIBUTOR] as $contributorXmlInstance) { $contributorInstance = new Person(); $contributorInstance->parseXml($contributorXmlInstance->asXML()); $contributor[] = $contributorInstance; } } elseif (is_string($contributorItem)) { $contributorInstance = new Person(); $contributorInstance->setName((string)$contributorItem); $contributor[] = $contributorInstance; } else { $contributorInstance = new Person(); $contributorInstance->parseXml($contributorItem->asXML()); $contributor[] = $contributorInstance; } return $contributor; } /** * Processes link node. * * @param array $xmlArray An array of simple xml elements. * * @return array */ protected function processLinkNode($xmlArray) { $link = array(); $linkValue = $xmlArray[Resources::LINK]; if (is_array($linkValue)) { foreach ($xmlArray[Resources::LINK] as $linkValueInstance) { $linkInstance = new AtomLink(); $linkInstance->parseXml($linkValueInstance->asXML()); $link[] = $linkInstance; } } else { $linkInstance = new AtomLink(); $linkInstance->parseXml($linkValue->asXML()); $link[] = $linkInstance; } return $link; } /** * Writes an optional attribute for ATOM. * * @param \XMLWriter $xmlWriter The XML writer. * @param string $attributeName The name of the attribute. * @param mixed $attributeValue The value of the attribute. * * @return none */ protected function writeOptionalAttribute( $xmlWriter, $attributeName, $attributeValue ) { Validate::notNull($xmlWriter, 'xmlWriter'); Validate::isString($attributeName, 'attributeName'); if (!empty($attributeValue)) { $xmlWriter->writeAttribute( $attributeName, $attributeValue ); } } /** * Writes the optional elements namespaces. * * @param \XmlWriter $xmlWriter The XML writer. * @param string $prefix The prefix. * @param string $elementName The element name. * @param string $namespace The namespace name. * @param string $elementValue The element value. * * @return none */ protected function writeOptionalElementNS( $xmlWriter, $prefix, $elementName, $namespace, $elementValue ) { Validate::notNull($xmlWriter, 'xmlWriter'); Validate::isString($elementName, 'elementName'); if (!empty($elementValue)) { $xmlWriter->writeElementNS( $prefix, $elementName, $namespace, $elementValue ); } } } includes/WindowsAzure/Common/Internal/Atom/Person.php000064400000012104152214270100016666 0ustar00 * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @link https://github.com/WindowsAzure/azure-sdk-for-php */ namespace WindowsAzure\Common\Internal\Atom; use WindowsAzure\Common\Internal\Utilities; use WindowsAzure\Common\Internal\Resources; use WindowsAzure\Common\Internal\Validate; /** * The person class of ATOM library. * * @category Microsoft * @package WindowsAzure\Common\Internal\Atom * @author Azure PHP SDK * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @version Release: 0.4.1_2015-03 * @link https://github.com/WindowsAzure/azure-sdk-for-php */ class Person extends AtomBase { /** * The name of the person. * * @var string */ protected $name; /** * The Uri of the person. * * @var string */ protected $uri; /** * The email of the person. * * @var string */ protected $email; /** * Creates an ATOM person instance with specified name. * * @param string $name The name of the person. */ public function __construct($name = Resources::EMPTY_STRING) { $this->name = $name; } /** * Populates the properties with a specified XML string. * * @param string $xmlString An XML based string representing * the Person instance. * * @return none */ public function parseXml($xmlString) { $personXml = simplexml_load_string($xmlString); $attributes = $personXml->attributes(); $personArray = (array)$personXml; if (array_key_exists('name', $personArray)) { $this->name = (string)$personArray['name']; } if (array_key_exists('uri', $personArray)) { $this->uri = (string)$personArray['uri']; } if (array_key_exists('email', $personArray)) { $this->email = (string)$personArray['email']; } } /** * Gets the name of the person. * * @return string */ public function getName() { return $this->name; } /** * Sets the name of the person. * * @param string $name The name of the person. * * @return none */ public function setName($name) { $this->name = $name; } /** * Gets the URI of the person. * * @return string */ public function getUri() { return $this->uri; } /** * Sets the URI of the person. * * @param string $uri The URI of the person. * * @return none */ public function setUri($uri) { $this->uri = $uri; } /** * Gets the email of the person. * * @return string */ public function getEmail() { return $this->email; } /** * Sets the email of the person. * * @param string $email The email of the person. * * @return none */ public function setEmail($email) { $this->email = $email; } /** * Writes an XML representing the person. * * @param \XMLWriter $xmlWriter The XML writer. * * @return none */ public function writeXml($xmlWriter) { Validate::notNull($xmlWriter, 'xmlWriter'); $xmlWriter->startElementNS( 'atom', 'person', Resources::ATOM_NAMESPACE ); $this->writeInnerXml($xmlWriter); $xmlWriter->endElement(); } /** * Writes a inner XML representing the person. * * @param \XMLWriter $xmlWriter The XML writer. * * @return none */ public function writeInnerXml($xmlWriter) { Validate::notNull($xmlWriter, 'xmlWriter'); $xmlWriter->writeElementNS( 'atom', 'name', Resources::ATOM_NAMESPACE, $this->name ); $this->writeOptionalElementNS( $xmlWriter, 'atom', 'uri', Resources::ATOM_NAMESPACE, $this->uri ); $this->writeOptionalElementNS( $xmlWriter, 'atom', 'email', Resources::ATOM_NAMESPACE, $this->email ); } } includes/WindowsAzure/Common/Internal/Atom/Source.php000064400000033230152214270100016663 0ustar00 * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @link https://github.com/WindowsAzure/azure-sdk-for-php */ namespace WindowsAzure\Common\Internal\Atom; use WindowsAzure\Common\Internal\Validate; use WindowsAzure\Common\Internal\Resources; /** * The source class of ATOM library. * * @category Microsoft * @package WindowsAzure\Common\Internal\Atom * @author Azure PHP SDK * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @version Release: 0.4.1_2015-03 * @link https://github.com/WindowsAzure/azure-sdk-for-php */ class Source extends AtomBase { // @codingStandardsIgnoreStart /** * The author the source. * * @var array */ protected $author; /** * The category of the source. * * @var array */ protected $category; /** * The contributor of the source. * * @var array */ protected $contributor; /** * The generator of the source. * * @var Generator */ protected $generator; /** * The icon of the source. * * @var string */ protected $icon; /** * The ID of the source. * * @var string */ protected $id; /** * The link of the source. * * @var AtomLink */ protected $link; /** * The logo of the source. * * @var string */ protected $logo; /** * The rights of the source. * * @var string */ protected $rights; /** * The subtitle of the source. * * @var string */ protected $subtitle; /** * The title of the source. * * @var string */ protected $title; /** * The update of the source. * * @var \DateTime */ protected $updated; /** * The extension element of the source. * * @var string */ protected $extensionElement; /** * Creates an ATOM FEED object with default parameters. */ public function __construct() { $this->attributes = array(); $this->category = array(); $this->contributor = array(); $this->author = array(); } /** * Creates a source object with specified XML string. * * @param string $xmlString The XML string representing a source. * * @return none */ public function parseXml($xmlString) { $sourceXml = new \SimpleXMLElement($xmlString); $attributes = $sourceXml->attributes(); $sourceArray = (array)$sourceXml; if (array_key_exists(Resources::AUTHOR, $sourceArray)) { $this->content = $this->processAuthorNode($sourceArray); } if (array_key_exists(Resources::CATEGORY, $sourceArray)) { $this->category = $this->processCategoryNode($sourceArray); } if (array_key_exists(Resources::CONTRIBUTOR, $sourceArray)) { $this->contributor = $this->processContributorNode($sourceArray); } if (array_key_exists('generator', $sourceArray)) { $generator = new Generator(); $generator->setText((string)$sourceArray['generator']->asXML()); $this->generator = $generator; } if (array_key_exists('icon', $sourceArray)) { $this->icon = (string)$sourceArray['icon']; } if (array_key_exists('id', $sourceArray)) { $this->id = (string)$sourceArray['id']; } if (array_key_exists(Resources::LINK, $sourceArray)) { $this->link = $this->processLinkNode($sourceArray); } if (array_key_exists('logo', $sourceArray)) { $this->logo = (string)$sourceArray['logo']; } if (array_key_exists('rights', $sourceArray)) { $this->rights = (string)$sourceArray['rights']; } if (array_key_exists('subtitle', $sourceArray)) { $this->subtitle = (string)$sourceArray['subtitle']; } if (array_key_exists('title', $sourceArray)) { $this->title = (string)$sourceArray['title']; } if (array_key_exists('updated', $sourceArray)) { $this->updated = \DateTime::createFromFormat( \DateTime::ATOM, (string)$sourceArray['updated'] ); } } /** * Gets the author of the source. * * @return array */ public function getAuthor() { return $this->author; } /** * Sets the author of the source. * * @param array $author An array of authors of the sources. * * @return none */ public function setAuthor($author) { $this->author = $author; } /** * Gets the category of the source. * * @return array */ public function getCategory() { return $this->category; } /** * Sets the category of the source. * * @param array $category The category of the source. * * @return none */ public function setCategory($category) { $this->category = $category; } /** * Gets contributor. * * @return array */ public function getContributor() { return $this->contributor; } /** * Sets contributor. * * @param array $contributor The contributors of the source. * * @return none */ public function setContributor($contributor) { $this->contributor = $contributor; } /** * Gets generator. * * @return Generator */ public function getGenerator() { return $this->generator; } /** * Sets the generator. * * @param Generator $generator Sets the generator of the source. * * @return none */ public function setGenerator($generator) { $this->generator = $generator; } /** * Gets the icon of the source. * * @return string */ public function getIcon() { return $this->icon; } /** * Sets the icon of the source. * * @param string $icon The icon of the source. * * @return string */ public function setIcon($icon) { $this->icon = $icon; } /** * Gets the ID of the source. * * @return string */ public function getId() { return $this->id; } /** * Sets the ID of the source. * * @param string $id The ID of the source. * * @return string */ public function setId($id) { $this->id = $id; } /** * Gets the link of the source. * * @return array */ public function getLink() { return $this->link; } /** * Sets the link of the source. * * @param array $link The link of the source. * * @return none */ public function setLink($link) { $this->link = $link; } /** * Gets the logo of the source. * * @return string */ public function getLogo() { return $this->logo; } /** * Sets the logo of the source. * * @param string $logo The logo of the source. * * @return none */ public function setLogo($logo) { $this->logo = $logo; } /** * Gets the rights of the source. * * @return string */ public function getRights() { return $this->rights; } /** * Sets the rights of the source. * * @param string $rights The rights of the source. * * @return none */ public function setRights($rights) { $this->rights = $rights; } /** * Gets the sub title. * * @return string */ public function getSubtitle() { return $this->subtitle; } /** * Sets the sub title of the source. * * @param string $subtitle Sets the sub title of the source. * * @return none */ public function setSubtitle($subtitle) { $this->subtitle = $subtitle; } /** * Gets the title of the source. * * @return string. */ public function getTitle() { return $this->title; } /** * Sets the title of the source. * * @param string $title The title of the source. * * @return none */ public function setTitle($title) { $this->title = $title; } /** * Gets the updated. * * @return \DateTime */ public function getUpdated() { return $this->updated; } /** * Sets the updated. * * @param \DateTime $updated updated * * @return none */ public function setUpdated($updated) { $this->updated = $updated; } /** * Gets the extension element. * * @return string */ public function getExtensionElement() { return $this->extensionElement; } /** * Sets the extension element. * * @param string $extensionElement The extension element. * * @return none */ public function setExtensionElement($extensionElement) { $this->extensionElement = $extensionElement; } /** * Writes an XML representing the source object. * * @param \XMLWriter $xmlWriter The XML writer. * * @return none */ public function writeXml($xmlWriter) { Validate::notNull($xmlWriter, 'xmlWriter'); $xmlWriter->startElementNS( 'atom', 'source', Resources::ATOM_NAMESPACE ); $this->writeInnerXml($xmlWriter); $xmlWriter->endElement(); } /** * Writes a inner XML representing the source object. * * @param \XMLWriter $xmlWriter The XML writer. * * @return none */ public function writeInnerXml($xmlWriter) { Validate::notNull($xmlWriter, 'xmlWriter'); if (!is_null($this->attributes)) { if (is_array($this->attributes)) { foreach ($this->attributes as $attributeName => $attributeValue) { $xmlWriter->writeAttribute($attributeName, $attributeValue); } } } if (!is_null($this->author)) { Validate::isArray($this->author, Resources::AUTHOR); $this->writeArrayItem($xmlWriter, $this->author, Resources::AUTHOR); } if (!is_null($this->category)) { Validate::isArray($this->category, Resources::CATEGORY); $this->writeArrayItem( $xmlWriter, $this->category, Resources::CATEGORY ); } if (!is_null($this->contributor)) { Validate::isArray($this->contributor, Resources::CONTRIBUTOR); $this->writeArrayItem( $xmlWriter, $this->contributor, Resources::CONTRIBUTOR ); } if (!is_null($this->generator)) { $this->generator->writeXml($xmlWriter); } if (!is_null($this->icon)) { $xmlWriter->writeElementNS( 'atom', 'icon', Resources::ATOM_NAMESPACE, $this->icon ); } $this->writeOptionalElementNS( $xmlWriter, 'atom', 'logo', Resources::ATOM_NAMESPACE, $this->logo ); $this->writeOptionalElementNS( $xmlWriter, 'atom', 'id', Resources::ATOM_NAMESPACE, $this->id ); if (!is_null($this->link)) { Validate::isArray($this->link, Resources::LINK); $this->writeArrayItem( $xmlWriter, $this->link, Resources::LINK ); } $this->writeOptionalElementNS( $xmlWriter, 'atom', 'rights', Resources::ATOM_NAMESPACE, $this->rights ); $this->writeOptionalElementNS( $xmlWriter, 'atom', 'subtitle', Resources::ATOM_NAMESPACE, $this->subtitle ); $this->writeOptionalElementNS( $xmlWriter, 'atom', 'title', Resources::ATOM_NAMESPACE, $this->title ); if (!is_null($this->updated)) { $xmlWriter->writeElementNS( 'atom', 'updated', Resources::ATOM_NAMESPACE, $this->updated->format(\DateTime::ATOM) ); } } } // @codingStandardsIgnoreEndincludes/WindowsAzure/Common/Internal/Atom/Content.php000064400000011643152214270100017041 0ustar00 * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @link https://github.com/WindowsAzure/azure-sdk-for-php */ namespace WindowsAzure\Common\Internal\Atom; use WindowsAzure\Common\Internal\Resources; use WindowsAzure\Common\Internal\Utilities; use WindowsAzure\Common\Internal\Validate; use WindowsAzure\Common\Internal\Atom\AtomProperties; /** * The content class of ATOM standard. * * @category Microsoft * @package WindowsAzure\Common\Internal\Atom * @author Azure PHP SDK * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @version Release: 0.4.1_2015-03 * @link https://github.com/WindowsAzure/azure-sdk-for-php */ class Content extends AtomBase { /** * The text of the content. * * @var string */ protected $text; /** * The type of the content. * * @var string */ protected $type; /** * Source XML object * * @var \SimpleXMLElement */ protected $xml; /** * Creates a Content instance with specified text. * * @param string $text The text of the content. * * @return none */ public function __construct($text = null) { $this->text = $text; } /** * Creates an ATOM CONTENT instance with specified xml string. * * @param string $xmlString an XML based string of ATOM CONTENT. * * @return none */ public function parseXml($xmlString) { Validate::notNull($xmlString, 'xmlString'); Validate::isString($xmlString, 'xmlString'); $this->fromXml(simplexml_load_string($xmlString)); } /** * Creates an ATOM CONTENT instance with specified simpleXML object * * @param \SimpleXMLElement $contentXml xml element of ATOM CONTENT * * @return none */ public function fromXml($contentXml) { Validate::notNull($contentXml, 'contentXml'); Validate::isA($contentXml, '\SimpleXMLElement', 'contentXml'); $attributes = $contentXml->attributes(); if (!empty($attributes['type'])) { $this->content = (string)$attributes['type']; } $text = ''; foreach ($contentXml->children() as $child) { $text .= $child->asXML(); } $this->text = $text; $this->xml = $contentXml; } /** * Gets the text of the content. * * @return string */ public function getText() { return $this->text; } /** * Sets the text of the content. * * @param string $text The text of the content. * * @return none */ public function setText($text) { $this->text = $text; } /** * Gets the xml object of the content. * * @return \SimpleXMLElement */ public function getXml() { return $this->xml; } /** * Gets the type of the content. * * @return string */ public function getType() { return $this->type; } /** * Sets the type of the content. * * @param string $type The type of the content. * * @return none */ public function setType($type) { $this->type = $type; } /** * Writes an XML representing the content. * * @param \XMLWriter $xmlWriter The XML writer. * * @return none */ public function writeXml($xmlWriter) { Validate::notNull($xmlWriter, 'xmlWriter'); $xmlWriter->startElementNS( 'atom', 'content', Resources::ATOM_NAMESPACE ); $this->writeOptionalAttribute( $xmlWriter, 'type', $this->type ); $this->writeInnerXml($xmlWriter); $xmlWriter->endElement(); } /** * Writes an inner XML representing the content. * * @param \XMLWriter $xmlWriter The XML writer. * * @return none */ public function writeInnerXml($xmlWriter) { Validate::notNull($xmlWriter, 'xmlWriter'); $xmlWriter->writeRaw($this->text); } } includes/WindowsAzure/Common/Internal/Authentication/OAuthScheme.php000064400000010450152214270100021646 0ustar00 * @copyright Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @link http://github.com/windowsazure/azure-sdk-for-php */ namespace WindowsAzure\Common\Internal\Authentication; use WindowsAzure\Common\Internal\Authentication\IAuthScheme; use WindowsAzure\Common\Internal\Resources; use WindowsAzure\Common\Internal\Utilities; use WindowsAzure\Common\Internal\Validate; use WindowsAzure\Common\Internal\OAuthRestProxy; use WindowsAzure\Common\Models\OAuthAccessToken; /** * Provides shared key authentication scheme for OAuth. * * @category Microsoft * @package WindowsAzure\Common\Internal\Authentication * @author Azure PHP SDK * @copyright Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @version Release: 0.4.1_2015-03 * @link http://github.com/windowsazure/azure-sdk-for-php */ class OAuthScheme implements IAuthScheme { /** * @var string */ protected $accountName; /** * @var string */ protected $accountKey; /** * @var WindowsAzure\Common\Models\OAuthAccessToken */ protected $accessToken; /** * @var WindowsAzure\Common\Internal\OAuthRestProxy */ protected $oauthService; /** * @var string */ protected $grantType; /** * @var string */ protected $scope; /** * Constructor. * * @param string $accountName account name. * @param string $accountKey account * secondary key. * * @param string $grantType grant type * for OAuth request. * * @param string $scope scope for * OAurh request. * * @param WindowsAzure\Common\Internal\OAuthRestProxy $oauthService account * primary or secondary key. */ public function __construct( $accountName, $accountKey, $grantType, $scope, $oauthService ) { Validate::isString($accountName, 'accountName'); Validate::isString($accountKey, 'accountKey'); Validate::isString($grantType, 'grantType'); Validate::isString($scope, 'scope'); Validate::notNull($oauthService, 'oauthService'); $this->accountName = $accountName; $this->accountKey = $accountKey; $this->grantType = $grantType; $this->scope = $scope; $this->oauthService = $oauthService; } /** * Returns authorization header to be included in the request. * * @param array $headers request headers. * @param string $url reuqest url. * @param array $queryParams query variables. * @param string $httpMethod request http method. * * @see Specifying the Authorization Header section at * http://msdn.microsoft.com/en-us/library/windowsazure/dd179428.aspx * * @return string */ public function getAuthorizationHeader($headers, $url, $queryParams, $httpMethod) { if (($this->accessToken == null) || ($this->accessToken->getExpiresIn() < time()) ) { $this->accessToken = $this->oauthService->getAccessToken( $this->grantType, $this->accountName, $this->accountKey, $this->scope ); } return Resources::OAUTH_ACCESS_TOKEN_PREFIX . $this->accessToken->getAccessToken(); } } includes/WindowsAzure/Common/Internal/Authentication/IAuthScheme.php000064400000003715152214270100021646 0ustar00 * @copyright Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @link https://github.com/windowsazure/azure-sdk-for-php */ namespace WindowsAzure\Common\Internal\Authentication; /** * Interface for azure authentication schemes. * * @category Microsoft * @package WindowsAzure\Common\Internal\Authentication * @author Azure PHP SDK * @copyright Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @version Release: 0.4.1_2015-03 * @link https://github.com/windowsazure/azure-sdk-for-php */ interface IAuthScheme { /** * Returns authorization header to be included in the request. * * @param array $headers request headers. * @param string $url reuqest url. * @param array $queryParams query variables. * @param string $httpMethod request http method. * * @see Specifying the Authorization Header section at * http://msdn.microsoft.com/en-us/library/windowsazure/dd179428.aspx * * @abstract * * @return string */ public function getAuthorizationHeader($headers, $url, $queryParams, $httpMethod ); } includes/WindowsAzure/Common/Internal/Authentication/StorageAuthScheme.php000064400000017106152214270100023061 0ustar00 * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @link https://github.com/windowsazure/azure-sdk-for-php */ namespace WindowsAzure\Common\Internal\Authentication; use WindowsAzure\Common\Internal\Resources; use WindowsAzure\Common\Internal\Utilities; use WindowsAzure\Common\Internal\Authentication\IAuthScheme; /** * Base class for azure authentication schemes. * * @category Microsoft * @package WindowsAzure\Common\Internal\Authentication * @author Azure PHP SDK * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @version Release: 0.4.1_2015-03 * @link https://github.com/windowsazure/azure-sdk-for-php */ abstract class StorageAuthScheme implements IAuthScheme { protected $accountName; protected $accountKey; /** * Constructor. * * @param string $accountName storage account name. * @param string $accountKey storage account primary or secondary key. * * @return * WindowsAzure\Common\Internal\Authentication\StorageAuthScheme */ public function __construct($accountName, $accountKey) { $this->accountKey = $accountKey; $this->accountName = $accountName; } /** * Computes canonicalized headers for headers array. * * @param array $headers request headers. * * @see Constructing the Canonicalized Headers String section at * http://msdn.microsoft.com/en-us/library/windowsazure/dd179428.aspx * * @return array */ protected function computeCanonicalizedHeaders($headers) { $canonicalizedHeaders = array(); $normalizedHeaders = array(); $validPrefix = Resources::X_MS_HEADER_PREFIX; if (is_null($normalizedHeaders)) { return $canonicalizedHeaders; } foreach ($headers as $header => $value) { // Convert header to lower case. $header = strtolower($header); // Retrieve all headers for the resource that begin with x-ms-, // including the x-ms-date header. if (Utilities::startsWith($header, $validPrefix)) { // Unfold the string by replacing any breaking white space // (meaning what splits the headers, which is \r\n) with a single // space. $value = str_replace("\r\n", ' ', $value); // Trim any white space around the colon in the header. $value = ltrim($value); $header = rtrim($header); $normalizedHeaders[$header] = $value; } } // Sort the headers lexicographically by header name, in ascending order. // Note that each header may appear only once in the string. ksort($normalizedHeaders); foreach ($normalizedHeaders as $key => $value) { $canonicalizedHeaders[] = $key . ':' . $value; } return $canonicalizedHeaders; } /** * Computes canonicalized resources from URL using Table formar * * @param string $url request url. * @param array $queryParams request query variables. * * @see Constructing the Canonicalized Resource String section at * http://msdn.microsoft.com/en-us/library/windowsazure/dd179428.aspx * * @return string */ protected function computeCanonicalizedResourceForTable($url, $queryParams) { $queryParams = array_change_key_case($queryParams); // 1. Beginning with an empty string (""), append a forward slash (/), // followed by the name of the account that owns the accessed resource. $canonicalizedResource = '/' . $this->accountName; // 2. Append the resource's encoded URI path, without any query parameters. $canonicalizedResource .= parse_url($url, PHP_URL_PATH); // 3. The query string should include the question mark and the comp // parameter (for example, ?comp=metadata). No other parameters should // be included on the query string. if (array_key_exists(Resources::QP_COMP, $queryParams)) { $canonicalizedResource .= '?' . Resources::QP_COMP . '='; $canonicalizedResource .= $queryParams[Resources::QP_COMP]; } return $canonicalizedResource; } /** * Computes canonicalized resources from URL. * * @param string $url request url. * @param array $queryParams request query variables. * * @see Constructing the Canonicalized Resource String section at * http://msdn.microsoft.com/en-us/library/windowsazure/dd179428.aspx * * @return string */ protected function computeCanonicalizedResource($url, $queryParams) { $queryParams = array_change_key_case($queryParams); // 1. Beginning with an empty string (""), append a forward slash (/), // followed by the name of the account that owns the accessed resource. $canonicalizedResource = '/' . $this->accountName; // 2. Append the resource's encoded URI path, without any query parameters. $canonicalizedResource .= parse_url($url, PHP_URL_PATH); // 3. Retrieve all query parameters on the resource URI, including the comp // parameter if it exists. // 4. Sort the query parameters lexicographically by parameter name, in // ascending order. if (count($queryParams) > 0) { ksort($queryParams); } // 5. Convert all parameter names to lowercase. // 6. URL-decode each query parameter name and value. // 7. Append each query parameter name and value to the string in the // following format: // parameter-name:parameter-value // 9. Group query parameters // 10. Append a new line character (\n) after each name-value pair. foreach ($queryParams as $key => $value) { // Grouping query parameters $values = explode(Resources::SEPARATOR, $value); sort($values); $separated = implode(Resources::SEPARATOR, $values); $canonicalizedResource .= "\n" . $key . ':' . $separated; } return $canonicalizedResource; } /** * Computes the authorization signature. * * @param array $headers request headers. * @param string $url reuqest url. * @param array $queryParams query variables. * @param string $httpMethod request http method. * * @see check all authentication schemes at * http://msdn.microsoft.com/en-us/library/windowsazure/dd179428.aspx * * @abstract * * @return string */ abstract protected function computeSignature($headers, $url, $queryParams, $httpMethod ); } includes/WindowsAzure/Common/Internal/Authentication/SharedKeyAuthScheme.php000064400000011570152214270100023333 0ustar00 * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @link https://github.com/windowsazure/azure-sdk-for-php */ namespace WindowsAzure\Common\Internal\Authentication; use WindowsAzure\Common\Internal\Authentication\StorageAuthScheme; use WindowsAzure\Common\Internal\Resources; use WindowsAzure\Common\Internal\Utilities; /** * Provides shared key authentication scheme for blob and queue. For more info * check: http://msdn.microsoft.com/en-us/library/windowsazure/dd179428.aspx * * @category Microsoft * @package WindowsAzure\Common\Internal\Authentication * @author Azure PHP SDK * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @version Release: 0.4.1_2015-03 * @link https://github.com/windowsazure/azure-sdk-for-php */ class SharedKeyAuthScheme extends StorageAuthScheme { protected $includedHeaders; /** * Constructor. * * @param string $accountName storage account name. * @param string $accountKey storage account primary or secondary key. * * @return * WindowsAzure\Common\Internal\Authentication\SharedKeyAuthScheme */ public function __construct($accountName, $accountKey) { parent::__construct($accountName, $accountKey); $this->includedHeaders = array(); $this->includedHeaders[] = Resources::CONTENT_ENCODING; $this->includedHeaders[] = Resources::CONTENT_LANGUAGE; $this->includedHeaders[] = Resources::CONTENT_LENGTH; $this->includedHeaders[] = Resources::CONTENT_MD5; $this->includedHeaders[] = Resources::CONTENT_TYPE; $this->includedHeaders[] = Resources::DATE; $this->includedHeaders[] = Resources::IF_MODIFIED_SINCE; $this->includedHeaders[] = Resources::IF_MATCH; $this->includedHeaders[] = Resources::IF_NONE_MATCH; $this->includedHeaders[] = Resources::IF_UNMODIFIED_SINCE; $this->includedHeaders[] = Resources::RANGE; } /** * Computes the authorization signature for blob and queue shared key. * * @param array $headers request headers. * @param string $url reuqest url. * @param array $queryParams query variables. * @param string $httpMethod request http method. * * @see Blob and Queue Services (Shared Key Authentication) at * http://msdn.microsoft.com/en-us/library/windowsazure/dd179428.aspx * * @return string */ protected function computeSignature($headers, $url, $queryParams, $httpMethod) { $canonicalizedHeaders = parent::computeCanonicalizedHeaders($headers); $canonicalizedResource = parent::computeCanonicalizedResource( $url, $queryParams ); $stringToSign = array(); $stringToSign[] = strtoupper($httpMethod); foreach ($this->includedHeaders as $header) { $stringToSign[] = Utilities::tryGetValue($headers, $header); } if (count($canonicalizedHeaders) > 0) { $stringToSign[] = implode("\n", $canonicalizedHeaders); } $stringToSign[] = $canonicalizedResource; $stringToSign = implode("\n", $stringToSign); return $stringToSign; } /** * Returns authorization header to be included in the request. * * @param array $headers request headers. * @param string $url reuqest url. * @param array $queryParams query variables. * @param string $httpMethod request http method. * * @see Specifying the Authorization Header section at * http://msdn.microsoft.com/en-us/library/windowsazure/dd179428.aspx * * @return string */ public function getAuthorizationHeader($headers, $url, $queryParams, $httpMethod) { $signature = $this->computeSignature( $headers, $url, $queryParams, $httpMethod ); return 'SharedKey ' . $this->accountName . ':' . base64_encode( hash_hmac('sha256', $signature, base64_decode($this->accountKey), true) ); } } includes/WindowsAzure/Common/Internal/Authentication/TableSharedKeyLiteAuthScheme.php000064400000007770152214270100025130 0ustar00 * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @link http://github.com/windowsazure/azure-sdk-for-php */ namespace WindowsAzure\Common\Internal\Authentication; use WindowsAzure\Common\Internal\Authentication\StorageAuthScheme; use WindowsAzure\Common\Internal\Resources; use WindowsAzure\Common\Internal\Utilities; /** * Provides shared key authentication scheme for blob and queue. For more info * check: http://msdn.microsoft.com/en-us/library/windowsazure/dd179428.aspx * * @category Microsoft * @package WindowsAzure\Common\Internal\Authentication * @author Azure PHP SDK * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @version Release: 0.4.1_2015-03 * @link http://github.com/windowsazure/azure-sdk-for-php */ class TableSharedKeyLiteAuthScheme extends StorageAuthScheme { protected $includedHeaders; /** * Constructor. * * @param string $accountName storage account name. * @param string $accountKey storage account primary or secondary key. * * @return TableSharedKeyLiteAuthScheme */ public function __construct($accountName, $accountKey) { parent::__construct($accountName, $accountKey); $this->includedHeaders = array(); $this->includedHeaders[] = Resources::DATE; } /** * Computes the authorization signature for blob and queue shared key. * * @param array $headers request headers. * @param string $url reuqest url. * @param array $queryParams query variables. * @param string $httpMethod request http method. * * @see Blob and Queue Services (Shared Key Authentication) at * http://msdn.microsoft.com/en-us/library/windowsazure/dd179428.aspx * * @return string */ protected function computeSignature($headers, $url, $queryParams, $httpMethod) { $canonicalizedResource = parent::computeCanonicalizedResourceForTable( $url, $queryParams ); $stringToSign = array(); foreach ($this->includedHeaders as $header) { $stringToSign[] = Utilities::tryGetValue($headers, $header); } $stringToSign[] = $canonicalizedResource; $stringToSign = implode("\n", $stringToSign); return $stringToSign; } /** * Returns authorization header to be included in the request. * * @param array $headers request headers. * @param string $url reuqest url. * @param array $queryParams query variables. * @param string $httpMethod request http method. * * @see Specifying the Authorization Header section at * http://msdn.microsoft.com/en-us/library/windowsazure/dd179428.aspx * * @return string */ public function getAuthorizationHeader($headers, $url, $queryParams, $httpMethod) { $signature = $this->computeSignature( $headers, $url, $queryParams, $httpMethod ); return 'SharedKeyLite ' . $this->accountName . ':' . base64_encode( hash_hmac('sha256', $signature, base64_decode($this->accountKey), true) ); } } includes/WindowsAzure/Common/Internal/Filters/ExponentialRetryPolicy.php000064400000010203152214270100022622 0ustar00 * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @link https://github.com/windowsazure/azure-sdk-for-php */ namespace WindowsAzure\Common\Internal\Filters; /** * The exponential retry policy. * * @category Microsoft * @package WindowsAzure\Common\Internal\Filters * @author Azure PHP SDK * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @version Release: 0.4.1_2015-03 * @link https://github.com/windowsazure/azure-sdk-for-php */ class ExponentialRetryPolicy extends RetryPolicy { /** * @var integer */ private $_deltaBackoffIntervalInMs; /** * @var integer */ private $_maximumAttempts; /** * @var integer */ private $_resolvedMaxBackoff; /** * @var integer */ private $_resolvedMinBackoff; /** * @var array */ private $_retryableStatusCodes; /** * Initializes new object from ExponentialRetryPolicy. * * @param array $retryableStatusCodes The retryable status codes. * @param integer $deltaBackoff The backoff time delta. * @param integer $maximumAttempts The number of max attempts. */ public function __construct($retryableStatusCodes, $deltaBackoff = parent::DEFAULT_CLIENT_BACKOFF, $maximumAttempts = parent::DEFAULT_CLIENT_RETRY_COUNT ) { $this->_deltaBackoffIntervalInMs = $deltaBackoff; $this->_maximumAttempts = $maximumAttempts; $this->_resolvedMaxBackoff = parent::DEFAULT_MAX_BACKOFF; $this->_resolvedMinBackoff = parent::DEFAULT_MIN_BACKOFF; $this->_retryableStatusCodes = $retryableStatusCodes; sort($retryableStatusCodes); } /** * Indicates if there should be a retry or not. * * @param integer $retryCount The retry count. * @param \HTTP_Request2_Response $response The HTTP response object. * * @return boolean */ public function shouldRetry($retryCount, $response) { if ( $retryCount >= $this->_maximumAttempts || array_search($response->getStatus(), $this->_retryableStatusCodes) || is_null($response) ) { return false; } else { return true; } } /** * Calculates the backoff for the retry policy. * * @param integer $retryCount The retry count. * @param \HTTP_Request2_Response $response The HTTP response object. * * @return integer */ public function calculateBackoff($retryCount, $response) { // Calculate backoff Interval between 80% and 120% of the desired // backoff, multiply by 2^n -1 for // exponential $incrementDelta = (int) (pow(2, $retryCount) - 1); $boundedRandDelta = (int) ($this->_deltaBackoffIntervalInMs * 0.8) + mt_rand( 0, (int) ($this->_deltaBackoffIntervalInMs * 1.2) - (int) ($this->_deltaBackoffIntervalInMs * 0.8) ); $incrementDelta *= $boundedRandDelta; // Enforce max / min backoffs return min( $this->_resolvedMinBackoff + $incrementDelta, $this->_resolvedMaxBackoff ); } } includes/WindowsAzure/Common/Internal/Filters/RetryPolicy.php000064400000004247152214270100020426 0ustar00 * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @link https://github.com/windowsazure/azure-sdk-for-php */ namespace WindowsAzure\Common\Internal\Filters; /** * The retry policy abstract class. * * @category Microsoft * @package WindowsAzure\Common\Internal\Filters * @author Azure PHP SDK * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @version Release: 0.4.1_2015-03 * @link https://github.com/windowsazure/azure-sdk-for-php */ abstract class RetryPolicy { const DEFAULT_CLIENT_BACKOFF = 30000; const DEFAULT_CLIENT_RETRY_COUNT = 3; const DEFAULT_MAX_BACKOFF = 90000; const DEFAULT_MIN_BACKOFF = 300; /** * Indicates if there should be a retry or not. * * @param integer $retryCount The retry count. * @param \HTTP_Request2_Response $response The HTTP response object. * * @return boolean */ public abstract function shouldRetry($retryCount, $response); /** * Calculates the backoff for the retry policy. * * @param integer $retryCount The retry count. * @param \HTTP_Request2_Response $response The HTTP response object. * * @return integer */ public abstract function calculateBackoff($retryCount, $response); } includes/WindowsAzure/Common/Internal/Filters/DateFilter.php000064400000004333152214270100020160 0ustar00 * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @link https://github.com/windowsazure/azure-sdk-for-php */ namespace WindowsAzure\Common\Internal\Filters; use WindowsAzure\Common\Internal\Resources; use WindowsAzure\Common\Internal\IServiceFilter; /** * Adds date header to the http request. * * @category Microsoft * @package WindowsAzure\Common\Internal\Filters * @author Azure PHP SDK * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @version Release: 0.4.1_2015-03 * @link https://github.com/windowsazure/azure-sdk-for-php */ class DateFilter implements IServiceFilter { /** * Adds date (in GMT format) header to the request headers. * * @param HttpClient $request HTTP channel object. * * @return \HTTP_Request2 */ public function handleRequest($request) { $date = gmdate(Resources::AZURE_DATE_FORMAT, time()); $request->setHeader(Resources::DATE, $date); return $request; } /** * Does nothing with the response. * * @param HttpClient $request HTTP channel object. * @param \HTTP_Request2_Response $response HTTP response object. * * @return \HTTP_Request2_Response */ public function handleResponse($request, $response) { // Do nothing with the response. return $response; } } includes/WindowsAzure/Common/Internal/Filters/AuthenticationFilter.php000064400000006021152214270100022256 0ustar00 * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @link https://github.com/windowsazure/azure-sdk-for-php */ namespace WindowsAzure\Common\Internal\Filters; use WindowsAzure\Common\Internal\Resources; use WindowsAzure\Common\Internal\IServiceFilter; use WindowsAzure\Common\Internal\Authentication\SharedKeyAuthScheme; use WindowsAzure\Common\Internal\Authentication\TableSharedKeyLiteAuthScheme; use WindowsAzure\Common\Internal\InvalidArgumentTypeException; /** * Adds authentication header to the http request object. * * @category Microsoft * @package WindowsAzure\Common\Internal\Filters * @author Azure PHP SDK * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @version Release: 0.4.1_2015-03 * @link https://github.com/windowsazure/azure-sdk-for-php */ class AuthenticationFilter implements IServiceFilter { /** * @var WindowsAzure\Common\Internal\Authentication\StorageAuthScheme */ private $_authenticationScheme; /** * Creates AuthenticationFilter with the passed scheme. * * @param StorageAuthScheme $authenticationScheme The authentication scheme. */ public function __construct($authenticationScheme) { $this->_authenticationScheme = $authenticationScheme; } /** * Adds authentication header to the request headers. * * @param HttpClient $request HTTP channel object. * * @return \HTTP_Request2 */ public function handleRequest($request) { $signedKey = $this->_authenticationScheme->getAuthorizationHeader( $request->getHeaders(), $request->getUrl(), $request->getUrl()->getQueryVariables(), $request->getMethod() ); $request->setHeader(Resources::AUTHENTICATION, $signedKey); return $request; } /** * Does nothing with the response. * * @param HttpClient $request HTTP channel object. * @param \HTTP_Request2_Response $response HTTP response object. * * @return \HTTP_Request2_Response */ public function handleResponse($request, $response) { // Do nothing with the response. return $response; } } includes/WindowsAzure/Common/Internal/Filters/WrapFilter.php000064400000006740152214270100020220 0ustar00 * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @link https://github.com/windowsazure/azure-sdk-for-php */ namespace WindowsAzure\Common\Internal\Filters; use WindowsAzure\Common\Internal\Resources; use WindowsAzure\Common\Internal\Validate; use WindowsAzure\Common\Internal\IServiceFilter; use WindowsAzure\Common\Internal\Authentication\SharedKeyAuthScheme; use WindowsAzure\Common\Internal\Authentication\TableSharedKeyLiteAuthScheme; use WindowsAzure\Common\Internal\InvalidArgumentTypeException; use WindowsAzure\ServiceBus\Internal\WrapTokenManager; /** * Adds WRAP authentication header to the http request object. * * @category Microsoft * @package WindowsAzure\Common\Internal\Filters * @author Azure PHP SDK * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @version Release: 0.4.1_2015-03 * @link https://github.com/windowsazure/azure-sdk-for-php */ class WrapFilter implements IServiceFilter { /** * @var WrapTokenManager */ private $_wrapTokenManager; /** * Creates a WrapFilter with specified WRAP parameters. * * @param string $wrapUri The URI of the WRAP service. * @param string $wrapUsername The user name of the WRAP account. * @param string $wrapPassword The password of the WRAP account. * @param IWrap $wrapRestProxy The WRAP service REST proxy. */ public function __construct( $wrapUri, $wrapUsername, $wrapPassword, $wrapRestProxy ) { $this->_wrapTokenManager = new WrapTokenManager( $wrapUri, $wrapUsername, $wrapPassword, $wrapRestProxy ); } /** * Adds WRAP authentication header to the request headers. * * @param HttpClient $request HTTP channel object. * * @return \HTTP_Request2 */ public function handleRequest($request) { Validate::notNull($request, 'request'); $wrapAccessToken = $this->_wrapTokenManager->getAccessToken( $request->getUrl() ); $authorization = sprintf( Resources::WRAP_AUTHORIZATION, $wrapAccessToken ); $request->setHeader(Resources::AUTHENTICATION, $authorization); return $request; } /** * Returns the original response. * * @param HttpClient $request A HTTP channel object. * @param \HTTP_Request2_Response $response A HTTP response object. * * @return \HTTP_Request2_Response */ public function handleResponse($request, $response) { return $response; } } includes/WindowsAzure/Common/Internal/Filters/HeadersFilter.php000064400000005176152214270100020664 0ustar00 * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @link https://github.com/windowsazure/azure-sdk-for-php */ namespace WindowsAzure\Common\Internal\Filters; use WindowsAzure\Common\Internal\Resources; use WindowsAzure\Common\Internal\IServiceFilter; /** * Adds all passed headers to the HTTP request headers. * * @category Microsoft * @package WindowsAzure\Common\Internal\Filters * @author Azure PHP SDK * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @version Release: 0.4.1_2015-03 * @link https://github.com/windowsazure/azure-sdk-for-php */ class HeadersFilter implements IServiceFilter { /** * @var array */ private $_headers; /** * Constructor * * @param array $headers static headers to be added. * * @return HeadersFilter */ public function __construct($headers) { $this->_headers = $headers; } /** * Adds static header(s) to the HTTP request headers * * @param HttpClient $request HTTP channel object. * * @return \HTTP_Request2 */ public function handleRequest($request) { foreach ($this->_headers as $key => $value) { $headers = $request->getHeaders(); if (!array_key_exists($key, $headers)) { $request->setHeader($key, $value); } } return $request; } /** * Does nothing with the response. * * @param HttpClient $request HTTP channel object. * @param \HTTP_Request2_Response $response HTTP response object. * * @return \HTTP_Request2_Response */ public function handleResponse($request, $response) { // Do nothing with the response. return $response; } } includes/WindowsAzure/Common/Internal/Filters/RetryPolicyFilter.php000064400000005527152214270100021576 0ustar00 * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @link https://github.com/windowsazure/azure-sdk-for-php */ namespace WindowsAzure\Common\Internal\Filters; use WindowsAzure\Common\Internal\IServiceFilter; /** * Short description * * @category Microsoft * @package WindowsAzure\Common\Internal\Filters * @author Azure PHP SDK * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @version Release: 0.4.1_2015-03 * @link https://github.com/windowsazure/azure-sdk-for-php */ class RetryPolicyFilter implements IServiceFilter { /** * @var RetryPolicy */ private $_retryPolicy; /** * Initializes new object from RetryPolicyFilter. * * @param RetryPolicy $retryPolicy The retry policy object. */ public function __construct($retryPolicy) { $this->_retryPolicy = $retryPolicy; } /** * Handles the request before sending. * * @param \HTTP_Request2 $request The HTTP request. * * @return \HTTP_Request2 */ public function handleRequest($request) { return $request; } /** * Handles the response after sending. * * @param \HTTP_Request2 $request The HTTP request. * @param \HTTP_Request2_Response $response The HTTP response. * * @return \HTTP_Request2_Response */ public function handleResponse($request, $response) { for ($retryCount = 0;; $retryCount++) { $shouldRetry = $this->_retryPolicy->shouldRetry( $retryCount, $response ); if (!$shouldRetry) { return $response; } // Backoff for some time according to retry policy $backoffTime = $this->_retryPolicy->calculateBackoff( $retryCount, $response ); sleep($backoffTime * 0.001); $response = $request->send(array()); } } } includes/WindowsAzure/Common/Internal/Http/BatchResponse.php000064400000007557152214270100020217 0ustar00 * @copyright Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @link https://github.com/windowsazure/azure-sdk-for-php */ namespace WindowsAzure\Common\Internal\Http; require_once 'PEAR.php'; require_once 'Mail/mimeDecode.php'; require_once 'HTTP/Request2/Response.php'; use WindowsAzure\Common\Internal\Resources; use WindowsAzure\Common\Internal\Validate; use WindowsAzure\Common\ServiceException; /** * Batch response parser * * @category Microsoft * @package WindowsAzure\Common\Internal * @author Azure PHP SDK * @copyright Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @version Release: 0.4.1_2015-03 * @link https://github.com/windowsazure/azure-sdk-for-php */ class BatchResponse { /** * Http responses list * * @var array */ private $_contexts; /** * Constructor * * @param string $content Http response * as string * * @param WindowsAzure\Common\Internal\Http\BatchRequest $request Source batch * request object */ public function __construct($content, $request = null) { $params['include_bodies'] = true; $params['input'] = $content; $mimeDecoder = new \Mail_mimeDecode($content); $structure = $mimeDecoder->decode($params); $parts = $structure->parts; $this->_contexts = array(); $requestContexts = null; if ($request != null) { Validate::isA( $request, 'WindowsAzure\Common\Internal\Http\BatchRequest', 'request' ); $requestContexts = $request->getContexts(); } $i = 0; foreach ($parts as $part) { if (!empty($part->body)) { $headerEndPos = strpos($part->body, "\r\n\r\n"); $header = substr($part->body, 0, $headerEndPos); $body = substr($part->body, $headerEndPos + 4); $headerStrings = explode("\r\n", $header); $response = new \HTTP_Request2_Response(array_shift($headerStrings)); foreach ($headerStrings as $headerString) { $response->parseHeaderLine($headerString); } $response->appendBody($body); $this->_contexts[] = $response; if (is_array($requestContexts)) { $expectedCodes = $requestContexts[$i]->getStatusCodes(); $statusCode = $response->getStatus(); if (!in_array($statusCode, $expectedCodes)) { $reason = $response->getReasonPhrase(); throw new ServiceException($statusCode, $reason, $body); } } $i++; } } } /** * Get parsed contexts as array * * @return array */ public function getContexts() { return $this->_contexts; } } includes/WindowsAzure/Common/Internal/Http/IHttpClient.php000064400000012326152214270100017634 0ustar00 * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @link https://github.com/windowsazure/azure-sdk-for-php */ namespace WindowsAzure\Common\Internal\Http; /** * Defines required methods for a HTTP client proxy. * * @category Microsoft * @package WindowsAzure\Common\Internal\Http * @author Azure PHP SDK * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @version Release: 0.4.1_2015-03 * @link https://github.com/windowsazure/azure-sdk-for-php */ interface IHttpClient { /** * Sets the request url. * * @param WindowsAzure\Common\Internal\Http\IUrl $url request url. * * @return none. */ public function setUrl($url); /** * Gets request url. * * @return WindowsAzure\Common\Internal\Http\IUrl */ public function getUrl(); /** * Sets request's HTTP method. * * @param string $method request's HTTP method. * * @return none. */ public function setMethod($method); /** * Gets request's HTTP method. * * @return string */ public function getMethod(); /** * Gets request's headers * * @return array */ public function getHeaders(); /** * Sets a an existing request header to value or creates a new one if the $header * doesn't exist. * * @param string $header header name. * @param string $value header value. * @param bool $replace whether to replace previous header with the same name * or append to its value (comma separated) * * @return none. */ public function setHeader($header, $value, $replace = false); /** * Sets request headers using array * * @param array $headers headers key-value array * * @return none. */ public function setHeaders($headers); /** * Sets HTTP POST parameters. * * @param array $postParameters The HTTP POST parameters. * * @return none */ public function setPostParameters($postParameters); /** * Processes the reuqest through HTTP pipeline with passed $filters, * sends HTTP request to the wire and process the response in the HTTP pipeline. * * @param array $filters HTTP filters which will be applied to the request before * send and then applied to the response. * @param IUrl $url Request url. * * @return string The response body. */ public function send($filters, $url = null); /** * Sets successful status code * * @param array|string $statusCodes successful status code. * * @return none. */ public function setExpectedStatusCode($statusCodes); /** * Gets successful status code * * @return array. */ public function getSuccessfulStatusCode(); /** * Sets a configuration element for the request. * * @param string $name configuration parameter name. * @param mix $value configuration parameter value. * * @return none. */ public function setConfig($name, $value = null); /** * Gets value for configuration parameter. * * @param string $name configuration parameter name. * * @return string. */ public function getConfig($name); /** * Sets the request body. * * @param string $body body to use. * * @return none. */ public function setBody($body); /** * Gets the request body. * * @return string. */ public function getBody(); /** * Makes deep copy from the current object. * * @return WindowsAzure\Common\Internal\Http\HttpClient */ public function __clone(); /** * Gets the response object. * * @return \HTTP_Request2_Response. */ public function getResponse(); /** * Throws ServiceException if the recieved status code is not expected. * * @param string $actual The received status code. * @param string $reason The reason phrase. * @param string $message The detailed message (if any). * @param array $expected The expected status codes. * * @return none * * @static * * @throws ServiceException */ public static function throwIfError($actual, $reason, $message, $expected); } includes/WindowsAzure/Common/Internal/Http/BatchRequest.php000064400000010020152214270100020024 0ustar00 * @copyright Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @link https://github.com/windowsazure/azure-sdk-for-php */ namespace WindowsAzure\Common\Internal\Http; require_once 'PEAR.php'; require_once 'Mail/mimePart.php'; use WindowsAzure\Common\Internal\Resources; use WindowsAzure\Common\Internal\Utilities; /** * Batch request marshaler * * @category Microsoft * @package WindowsAzure\Common\Internal * @author Azure PHP SDK * @copyright Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @version Release: 0.4.1_2015-03 * @link https://github.com/windowsazure/azure-sdk-for-php */ class BatchRequest { /** * Http call context list * * @var array */ private $_contexts; /** * Headers * * @var array */ private $_headers; /** * Request body * * @var string */ private $_body; /** * Constructor */ public function __construct() { $this->_contexts = array(); } /** * Append new context to batch request * * @param WindowsAzure\Common\Internal\Http\HttpCallContext $context Http call * context to add to batch request * * @return none */ public function appendContext($context) { $this->_contexts[] = $context; } /** * Encode contexts * * @return none */ public function encode() { $mimeType = Resources::MULTIPART_MIXED_TYPE; $batchGuid = Utilities::getGuid(); $batchId = sprintf('batch_%s', $batchGuid); $contentType1 = array('content_type' => "$mimeType"); $changeSetGuid = Utilities::getGuid(); $changeSetId = sprintf('changeset_%s', $changeSetGuid); $contentType2 = array('content_type' => "$mimeType; boundary=$changeSetId"); $options = array( 'encoding' => 'binary', 'content_type' => Resources::HTTP_TYPE ); // Create changeset MIME part $changeSet = new \Mail_mimePart(); $i = 1; foreach ($this->_contexts as $context) { $context->addHeader(Resources::CONTENT_ID, $i); $changeSet->addSubpart((string)$context, $options); $i++; } // Encode the changeset MIME part $changeSetEncoded = $changeSet->encode($changeSetId); // Create the batch MIME part $batch = new \Mail_mimePart(Resources::EMPTY_STRING, $contentType1); // Add changeset encoded to batch MIME part $batch->addSubpart($changeSetEncoded['body'], $contentType2); // Encode batch MIME part $batchEncoded = $batch->encode($batchId); $this->_headers = $batchEncoded['headers']; $this->_body = $batchEncoded['body']; } /** * Get "Request body" * * @return string */ public function getBody() { return $this->_body; } /** * Get "Headers" * * @return array */ public function getHeaders() { return $this->_headers; } /** * Get request contexts * * @return array */ public function getContexts() { return $this->_contexts; } } includes/WindowsAzure/Common/Internal/Http/Url.php000064400000011165152214270100016207 0ustar00 * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @link https://github.com/windowsazure/azure-sdk-for-php */ namespace WindowsAzure\Common\Internal\Http; require_once 'Net/URL2.php'; use WindowsAzure\Common\Internal\Validate; use WindowsAzure\Common\Internal\Resources; use WindowsAzure\Common\Internal\Http\IUrl; /** * Default IUrl implementation. * * @category Microsoft * @package WindowsAzure\Common\Internal\Http * @author Azure PHP SDK * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @version Release: 0.4.1_2015-03 * @link https://github.com/windowsazure/azure-sdk-for-php */ class Url implements IUrl { /** * @var \Net_URL2 */ private $_url; /** * Sets the url path to '/' if it's empty * * @param string $url the url string * * @return none. */ private function _setPathIfEmpty($url) { $path = parse_url($url, PHP_URL_PATH); if (empty($path)) { $this->setUrlPath('/'); } } /** * Constructor * * @param string $url the url to set. * * @return WindowsAzure\Common\Internal\Http\Url */ public function __construct($url) { $errorMessage = Resources::INVALID_URL_MSG; Validate::isTrue(filter_var($url, FILTER_VALIDATE_URL), $errorMessage); $this->_url = new \Net_URL2($url); $this->_setPathIfEmpty($url); } /** * Makes deep copy from the current object. * * @return WindowsAzure\Common\Internal\Http\Url */ public function __clone() { $this->_url = clone $this->_url; } /** * Returns the query portion of the url * * @return string */ public function getQuery() { return $this->_url->getQuery(); } /** * Returns the query portion of the url in array form * * @return array */ public function getQueryVariables() { return $this->_url->getQueryVariables(); } /** * Sets a an existing query parameter to value or creates a new one if the $key * doesn't exist. * * @param string $key query parameter name. * @param string $value query value. * * @return none */ public function setQueryVariable($key, $value) { Validate::isString($key, 'key'); Validate::isString($value, 'value'); $this->_url->setQueryVariable($key, $value); } /** * Gets actual URL string. * * @return string. */ public function getUrl() { return $this->_url->getURL(); } /** * Sets url path * * @param string $urlPath url path to set. * * @return none. */ public function setUrlPath($urlPath) { Validate::isString($urlPath, 'urlPath'); $this->_url->setPath($urlPath); } /** * Appends url path * * @param string $urlPath url path to append. * * @return none. */ public function appendUrlPath($urlPath) { Validate::isString($urlPath, 'urlPath'); $newUrlPath = parse_url($this->_url, PHP_URL_PATH) . $urlPath; $this->_url->setPath($newUrlPath); } /** * Gets actual URL string. * * @return string. */ public function __toString() { return $this->_url->getURL(); } /** * Sets the query string to the specified variables in $array * * @param array $array key/value representation of query variables. * * @return none. */ public function setQueryVariables($array) { foreach ($array as $key => $value) { $this->setQueryVariable($key, $value); } } } includes/WindowsAzure/Common/Internal/Http/HttpCallContext.php000064400000023007152214270100020523 0ustar00 * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @link https://github.com/windowsazure/azure-sdk-for-php */ namespace WindowsAzure\Common\Internal\Http; use WindowsAzure\Common\Internal\Utilities; use WindowsAzure\Common\Internal\Resources; use WindowsAzure\Common\Internal\Validate; use WindowsAzure\Common\Internal\Http\Url; /** * Holds basic elements for making HTTP call. * * @category Microsoft * @package WindowsAzure\Common\Internal\Http * @author Azure PHP SDK * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @version Release: 0.4.1_2015-03 * @link https://github.com/windowsazure/azure-sdk-for-php */ class HttpCallContext { /** * The HTTP method used to make this call. * * @var string */ private $_method; /** * HTTP request headers. * * @var array */ private $_headers; /** * The URI query parameters. * * @var array */ private $_queryParams; /** * The HTTP POST parameters. * * @var array. */ private $_postParameters; /** * @var string */ private $_uri; /** * The URI path. * * @var string */ private $_path; /** * The expected status codes. * * @var array */ private $_statusCodes; /** * The HTTP request body. * * @var string */ private $_body; /** * Default constructor. */ public function __construct() { $this->_method = null; $this->_body = null; $this->_path = null; $this->_uri = null; $this->_queryParams = array(); $this->_postParameters = array(); $this->_statusCodes = array(); $this->_headers = array(); } /** * Gets method. * * @return string */ public function getMethod() { return $this->_method; } /** * Sets method. * * @param string $method The method value. * * @return none */ public function setMethod($method) { Validate::isString($method, 'method'); $this->_method = $method; } /** * Gets headers. * * @return array */ public function getHeaders() { return $this->_headers; } /** * Sets headers. * * Ignores the header if its value is empty. * * @param array $headers The headers value. * * @return none */ public function setHeaders($headers) { $this->_headers = array(); foreach ($headers as $key => $value) { $this->addHeader($key, $value); } } /** * Gets queryParams. * * @return array */ public function getQueryParameters() { return $this->_queryParams; } /** * Sets queryParams. * * Ignores the query variable if its value is empty. * * @param array $queryParams The queryParams value. * * @return none */ public function setQueryParameters($queryParams) { $this->_queryParams = array(); foreach ($queryParams as $key => $value) { $this->addQueryParameter($key, $value); } } /** * Gets uri. * * @return string */ public function getUri() { return $this->_uri; } /** * Sets uri. * * @param string $uri The uri value. * * @return none */ public function setUri($uri) { Validate::isString($uri, 'uri'); $this->_uri = $uri; } /** * Gets path. * * @return string */ public function getPath() { return $this->_path; } /** * Sets path. * * @param string $path The path value. * * @return none */ public function setPath($path) { Validate::isString($path, 'path'); $this->_path = $path; } /** * Gets statusCodes. * * @return array */ public function getStatusCodes() { return $this->_statusCodes; } /** * Sets statusCodes. * * @param array $statusCodes The statusCodes value. * * @return none */ public function setStatusCodes($statusCodes) { $this->_statusCodes = array(); foreach ($statusCodes as $value) { $this->addStatusCode($value); } } /** * Gets body. * * @return string */ public function getBody() { return $this->_body; } /** * Sets body. * * @param string $body The body value. * * @return none */ public function setBody($body) { Validate::isString($body, 'body'); $this->_body = $body; } /** * Adds or sets header pair. * * @param string $name The HTTP header name. * @param string $value The HTTP header value. * * @return none */ public function addHeader($name, $value) { Validate::isString($name, 'name'); Validate::isString($value, 'value'); $this->_headers[$name] = $value; } /** * Adds or sets header pair. * * Ignores header if it's value satisfies empty(). * * @param string $name The HTTP header name. * @param string $value The HTTP header value. * * @return none */ public function addOptionalHeader($name, $value) { Validate::isString($name, 'name'); Validate::isString($value, 'value'); if (!empty($value)) { $this->_headers[$name] = $value; } } /** * Removes header from the HTTP request headers. * * @param string $name The HTTP header name. * * @return none */ public function removeHeader($name) { Validate::isString($name, 'name'); Validate::notNullOrEmpty($name, 'name'); unset($this->_headers[$name]); } /** * Adds or sets query parameter pair. * * @param string $name The URI query parameter name. * @param string $value The URI query parameter value. * * @return none */ public function addQueryParameter($name, $value) { Validate::isString($name, 'name'); Validate::isString($value, 'value'); $this->_queryParams[$name] = $value; } /** * Gets HTTP POST parameters. * * @return array */ public function getPostParameters() { return $this->_postParameters; } /** * Sets HTTP POST parameters. * * @param array $postParameters The HTTP POST parameters. * * @return none */ public function setPostParameters($postParameters) { Validate::isArray($postParameters, 'postParameters'); $this->_postParameters = $postParameters; } /** * Adds or sets query parameter pair. * * Ignores query parameter if it's value satisfies empty(). * * @param string $name The URI query parameter name. * @param string $value The URI query parameter value. * * @return none */ public function addOptionalQueryParameter($name, $value) { Validate::isString($name, 'name'); Validate::isString($value, 'value'); if (!empty($value)) { $this->_queryParams[$name] = $value; } } /** * Adds status code to the expected status codes. * * @param integer $statusCode The expected status code. * * @return none */ public function addStatusCode($statusCode) { Validate::isInteger($statusCode, 'statusCode'); $this->_statusCodes[] = $statusCode; } /** * Gets header value. * * @param string $name The header name. * * @return mix */ public function getHeader($name) { return Utilities::tryGetValue($this->_headers, $name); } /** * Converts the context object to string. * * @return string */ public function __toString() { $headers = Resources::EMPTY_STRING; $uri = new Url($this->_uri); $uri = $uri->getUrl(); foreach ($this->_headers as $key => $value) { $headers .= "$key: $value\n"; } $str = "$this->_method $uri$this->_path HTTP/1.1\n$headers\n"; $str .= "$this->_body"; return $str; } } includes/WindowsAzure/Common/Internal/Http/IUrl.php000064400000005614152214270100016322 0ustar00 * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @link https://github.com/windowsazure/azure-sdk-for-php */ namespace WindowsAzure\Common\Internal\Http; /** * Defines what are main url functionalities that should be supported * * @category Microsoft * @package WindowsAzure\Common\Internal\Http * @author Azure PHP SDK * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @version Release: 0.4.1_2015-03 * @link https://github.com/windowsazure/azure-sdk-for-php */ interface IUrl { /** * Returns the query portion of the url * * @return string */ public function getQuery(); /** * Returns the query portion of the url in array form * * @return array */ public function getQueryVariables(); /** * Sets a an existing query parameter to value or creates a new one if the $key * doesn't exist. * * @param string $key query parameter name. * @param string $value query value. * * @return none. */ public function setQueryVariable($key, $value); /** * Gets actual URL string. * * @return string. */ public function getUrl(); /** * Sets url path * * @param string $urlPath url path to set. * * @return none. */ public function setUrlPath($urlPath); /** * Appends url path * * @param string $urlPath url path to append. * * @return none. */ public function appendUrlPath($urlPath); /** * Gets actual URL string. * * @return string. */ public function __toString(); /** * Makes deep copy from the current object. * * @return WindowsAzure\Common\Internal\Http\Url */ public function __clone(); /** * Sets the query string to the specified variables in $array * * @param array $array key/value representation of query variables. * * @return none. */ public function setQueryVariables($array); } includes/WindowsAzure/Common/Internal/Http/HttpClient.php000064400000024422152214270100017523 0ustar00 * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @link https://github.com/windowsazure/azure-sdk-for-php */ namespace WindowsAzure\Common\Internal\Http; use WindowsAzure\Common\Internal\Http\IHttpClient; use WindowsAzure\Common\Internal\IServiceFilter; use WindowsAzure\Common\Internal\Resources; use WindowsAzure\Common\ServiceException; use WindowsAzure\Common\Internal\Validate; use WindowsAzure\Common\Internal\Http\IUrl; require_once 'HTTP/Request2.php'; /** * HTTP client which sends and receives HTTP requests and responses. * * @category Microsoft * @package WindowsAzure\Common\Internal\Http * @author Azure PHP SDK * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @version Release: 0.4.1_2015-03 * @link https://github.com/windowsazure/azure-sdk-for-php */ class HttpClient implements IHttpClient { /** * @var \HTTP_Request2 */ private $_request; /** * @var WindowsAzure\Common\Internal\Http\IUrl */ private $_requestUrl; /** * Holds the latest response object * * @var \HTTP_Request2_Response */ private $_response; /** * Holds expected status code after sending the request. * * @var array */ private $_expectedStatusCodes; /** * Initializes new HttpClient object. * * @param string $certificatePath The certificate path. * @param string $certificateAuthorityPath The path of the certificate authority. * * @return WindowsAzure\Common\Internal\Http\HttpClient */ function __construct( $certificatePath = Resources::EMPTY_STRING, $certificateAuthorityPath = Resources::EMPTY_STRING ) { $config = array( Resources::USE_BRACKETS => true, Resources::SSL_VERIFY_PEER => false, Resources::SSL_VERIFY_HOST => false ); if (!empty($certificatePath)) { $config[Resources::SSL_LOCAL_CERT] = $certificatePath; $config[Resources::SSL_VERIFY_HOST] = true; } if (!empty($certificateAuthorityPath)) { $config[Resources::SSL_CAFILE] = $certificateAuthorityPath; $config[Resources::SSL_VERIFY_PEER] = true; } $this->_request = new \HTTP_Request2( null, null, $config ); $this->setHeader('user-agent', null); $this->_requestUrl = null; $this->_response = null; $this->_expectedStatusCodes = array(); } /** * Makes deep copy from the current object. * * @return WindowsAzure\Common\Internal\Http\HttpClient */ public function __clone() { $this->_request = clone $this->_request; if (!is_null($this->_requestUrl)) { $this->_requestUrl = clone $this->_requestUrl; } } /** * Sets the request url. * * @param WindowsAzure\Common\Internal\Http\IUrl $url request url. * * @return none. */ public function setUrl($url) { $this->_requestUrl = $url; } /** * Gets request url. Note that you must check if the returned object is null or * not. * * @return WindowsAzure\Common\Internal\Http\IUrl */ public function getUrl() { return $this->_requestUrl; } /** * Sets request's HTTP method. You can use \HTTP_Request2 constants like * Resources::HTTP_GET or strings like 'GET'. * * @param string $method request's HTTP method. * * @return none */ public function setMethod($method) { $this->_request->setMethod($method); } /** * Gets request's HTTP method. * * @return string */ public function getMethod() { return $this->_request->getMethod(); } /** * Gets request's headers. The returned array key (header names) are all in * lower case even if they were set having some upper letters. * * @return array */ public function getHeaders() { return $this->_request->getHeaders(); } /** * Sets a an existing request header to value or creates a new one if the $header * doesn't exist. * * @param string $header header name. * @param string $value header value. * @param bool $replace whether to replace previous header with the same name * or append to its value (comma separated) * * @return none */ public function setHeader($header, $value, $replace = false) { Validate::isString($value, 'value'); $this->_request->setHeader($header, $value, $replace); } /** * Sets request headers using array * * @param array $headers headers key-value array * * @return none */ public function setHeaders($headers) { foreach ($headers as $key => $value) { $this->setHeader($key, $value); } } /** * Sets HTTP POST parameters. * * @param array $postParameters The HTTP POST parameters. * * @return none */ public function setPostParameters($postParameters) { $this->_request->addPostParameter($postParameters); } /** * Processes the reuqest through HTTP pipeline with passed $filters, * sends HTTP request to the wire and process the response in the HTTP pipeline. * * @param array $filters HTTP filters which will be applied to the request before * send and then applied to the response. * @param IUrl $url Request url. * * @throws WindowsAzure\Common\ServiceException * * @return string The response body */ public function send($filters, $url = null) { if (isset($url)) { $this->setUrl($url); $this->_request->setUrl($this->_requestUrl->getUrl()); } $contentLength = Resources::EMPTY_STRING; if ( strtoupper($this->getMethod()) != Resources::HTTP_GET && strtoupper($this->getMethod()) != Resources::HTTP_DELETE && strtoupper($this->getMethod()) != Resources::HTTP_HEAD ) { $contentLength = 0; if (!is_null($this->getBody())) { $contentLength = strlen($this->getBody()); } $this->_request->setHeader(Resources::CONTENT_LENGTH, $contentLength); } foreach ($filters as $filter) { $this->_request = $filter->handleRequest($this)->_request; } $this->_response = $this->_request->send(); $start = count($filters) - 1; for ($index = $start; $index >= 0; $index--) { $this->_response = $filters[$index]->handleResponse( $this, $this->_response ); } self::throwIfError( $this->_response->getStatus(), $this->_response->getReasonPhrase(), $this->_response->getBody(), $this->_expectedStatusCodes ); return $this->_response->getBody(); } /** * Sets successful status code * * @param array|string $statusCodes successful status code. * * @return none */ public function setExpectedStatusCode($statusCodes) { if (!is_array($statusCodes)) { $this->_expectedStatusCodes[] = $statusCodes; } else { $this->_expectedStatusCodes = $statusCodes; } } /** * Gets successful status code * * @return array */ public function getSuccessfulStatusCode() { return $this->_expectedStatusCodes; } /** * Sets configuration parameter. * * @param string $name The configuration parameter name. * @param mix $value The configuration parameter value. * * @return none */ public function setConfig($name, $value = null) { $this->_request->setConfig($name, $value); } /** * Gets value for configuration parameter. * * @param string $name configuration parameter name. * * @return string */ public function getConfig($name) { return $this->_request->getConfig($name); } /** * Sets the request body. * * @param string $body body to use. * * @return none */ public function setBody($body) { Validate::isString($body, 'body'); $this->_request->setBody($body); } /** * Gets the request body. * * @return string */ public function getBody() { return $this->_request->getBody(); } /** * Gets the response object. * * @return \HTTP_Request2_Response */ public function getResponse() { return $this->_response; } /** * Throws ServiceException if the recieved status code is not expected. * * @param string $actual The received status code. * @param string $reason The reason phrase. * @param string $message The detailed message (if any). * @param array $expected The expected status codes. * * @return none * * @static * * @throws ServiceException */ public static function throwIfError($actual, $reason, $message, $expected) { if (!in_array($actual, $expected)) { throw new ServiceException($actual, $reason, $message); } } } includes/WindowsAzure/Common/Internal/Serialization/JsonSerializer.php000064400000005623152214270100022310 0ustar00 * @copyright Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @link https://github.com/windowsazure/azure-sdk-for-php */ namespace WindowsAzure\Common\Internal\Serialization; use WindowsAzure\Common\Internal\Validate; /** * Perform JSON serialization / deserialization * * @category Microsoft * @package WindowsAzure\Common\Internal\Serialization * @author Azure PHP SDK * @copyright Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @version Release: 0.4.1_2015-03 * @link https://github.com/windowsazure/azure-sdk-for-php */ class JsonSerializer implements ISerializer { /** * Serialize an object with specified root element name. * * @param object $targetObject The target object. * @param string $rootName The name of the root element. * * @return string */ public static function objectSerialize($targetObject, $rootName) { Validate::notNull($targetObject, 'targetObject'); Validate::isString($rootName, 'rootName'); $contianer = new \stdClass(); $contianer->$rootName = $targetObject; return json_encode($contianer); } /** * Serializes given array. The array indices must be string to use them as * as element name. * * @param array $array The object to serialize represented in array. * @param array $properties The used properties in the serialization process. * * @return string */ public function serialize($array, $properties = null) { Validate::isArray($array, 'array'); return json_encode($array); } /** * Unserializes given serialized string to array. * * @param string $serialized The serialized object in string representation. * * @return array */ public function unserialize($serialized) { Validate::isString($serialized, 'serialized'); $json = json_decode($serialized); if ($json && !is_array($json)) { return get_object_vars($json); } else { return $json; } } } includes/WindowsAzure/Common/Internal/Serialization/ISerializer.php000064400000004374152214270100021571 0ustar00 * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @link https://github.com/windowsazure/azure-sdk-for-php */ namespace WindowsAzure\Common\Internal\Serialization; /** * The serialization interface. * * @category Microsoft * @package WindowsAzure\Common\Internal\Serialization * @author Azure PHP SDK * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @version Release: 0.4.1_2015-03 * @link https://github.com/windowsazure/azure-sdk-for-php */ interface ISerializer { /** * Serialize an object into a XML. * * @param Object $targetObject The target object to be serialized. * @param string $rootName The name of the root. * * @return string */ public static function objectSerialize($targetObject, $rootName); /** * Serializes given array. The array indices must be string to use them as * as element name. * * @param array $array The object to serialize represented in array. * @param array $properties The used properties in the serialization process. * * @return string */ public function serialize($array, $properties = null); /** * Unserializes given serialized string. * * @param string $serialized The serialized object in string representation. * * @return array */ public function unserialize($serialized); } includes/WindowsAzure/Common/Internal/Serialization/XmlSerializer.php000064400000017645152214270100022146 0ustar00 * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @link https://github.com/windowsazure/azure-sdk-for-php */ namespace WindowsAzure\Common\Internal\Serialization; use WindowsAzure\Common\Internal\Utilities; use WindowsAzure\Common\Internal\Resources; use WindowsAzure\Common\Internal\Validate; /** * Short description * * @category Microsoft * @package WindowsAzure\Common\Internal\Serialization * @author Azure PHP SDK * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @version Release: 0.4.1_2015-03 * @link https://github.com/windowsazure/azure-sdk-for-php */ class XmlSerializer implements ISerializer { const STANDALONE = 'standalone'; const ROOT_NAME = 'rootName'; const DEFAULT_TAG = 'defaultTag'; /** * Converts a SimpleXML object to an Array recursively * ensuring all sub-elements are arrays as well. * * @param string $sxml The SimpleXML object. * @param array $arr The array into which to store results. * * @return array */ private function _sxml2arr($sxml, $arr = null) { foreach ((array) $sxml as $key => $value) { if (is_object($value) || (is_array($value))) { $arr[$key] = $this->_sxml2arr($value); } else { $arr[$key] = $value; } } return $arr; } /** * Takes an array and produces XML based on it. * * @param XMLWriter $xmlw XMLWriter object that was previously instanted * and is used for creating the XML. * @param array $data Array to be converted to XML. * @param string $defaultTag Default XML tag to be used if none specified. * * @return void */ private function _arr2xml(\XMLWriter $xmlw, $data, $defaultTag = null) { foreach ($data as $key => $value) { if ($key === Resources::XTAG_ATTRIBUTES) { foreach ($value as $attributeName => $attributeValue) { $xmlw->writeAttribute($attributeName, $attributeValue); } } else if (is_array($value)) { if (!is_int($key)) { if ($key != Resources::EMPTY_STRING) { $xmlw->startElement($key); } else { $xmlw->startElement($defaultTag); } } $this->_arr2xml($xmlw, $value); if (!is_int($key)) { $xmlw->endElement(); } } else { $xmlw->writeElement($key, $value); } } } /** * Gets the attributes of a specified object if get attributes * method is exposed. * * @param object $targetObject The target object. * @param array $methodArray The array of method of the target object. * * @return mixed */ private static function _getInstanceAttributes($targetObject, $methodArray) { foreach ($methodArray as $method) { if ($method->name == 'getAttributes') { $classProperty = $method->invoke($targetObject); return $classProperty; } } return null; } /** * Serialize an object with specified root element name. * * @param object $targetObject The target object. * @param string $rootName The name of the root element. * * @return string */ public static function objectSerialize($targetObject, $rootName) { Validate::notNull($targetObject, 'targetObject'); Validate::isString($rootName, 'rootName'); $xmlWriter = new \XmlWriter(); $xmlWriter->openMemory(); $xmlWriter->setIndent(true); $reflectionClass = new \ReflectionClass($targetObject); $methodArray = $reflectionClass->getMethods(); $attributes = self::_getInstanceAttributes( $targetObject, $methodArray ); $xmlWriter->startElement($rootName); if (!is_null($attributes)) { foreach (array_keys($attributes) as $attributeKey) { $xmlWriter->writeAttribute( $attributeKey, $attributes[$attributeKey] ); } } foreach ($methodArray as $method) { if ((strpos($method->name, 'get') === 0) && $method->isPublic() && ($method->name != 'getAttributes') ) { $variableName = substr($method->name, 3); $variableValue = $method->invoke($targetObject); if (!empty($variableValue)) { if (gettype($variableValue) === 'object') { $xmlWriter->writeRaw( XmlSerializer::objectSerialize( $variableValue, $variableName ) ); } else { $xmlWriter->writeElement($variableName, $variableValue); } } } } $xmlWriter->endElement(); return $xmlWriter->outputMemory(true); } /** * Serializes given array. The array indices must be string to use them as * as element name. * * @param array $array The object to serialize represented in array. * @param array $properties The used properties in the serialization process. * * @return string */ public function serialize($array, $properties = null) { $xmlVersion = '1.0'; $xmlEncoding = 'UTF-8'; $standalone = Utilities::tryGetValue($properties, self::STANDALONE); $defaultTag = Utilities::tryGetValue($properties, self::DEFAULT_TAG); $rootName = Utilities::tryGetValue($properties, self::ROOT_NAME); $docNamespace = Utilities::tryGetValue( $array, Resources::XTAG_NAMESPACE, null ); if (!is_array($array)) { return false; } $xmlw = new \XmlWriter(); $xmlw->openMemory(); $xmlw->setIndent(true); $xmlw->startDocument($xmlVersion, $xmlEncoding, $standalone); if (is_null($docNamespace)) { $xmlw->startElement($rootName); } else { foreach ($docNamespace as $uri => $prefix) { $xmlw->startElementNS($prefix, $rootName, $uri); break; } } unset($array[Resources::XTAG_NAMESPACE]); self::_arr2xml($xmlw, $array, $defaultTag); $xmlw->endElement(); return $xmlw->outputMemory(true); } /** * Unserializes given serialized string. * * @param string $serialized The serialized object in string representation. * * @return array */ public function unserialize($serialized) { $sxml = new \SimpleXMLElement($serialized); return $this->_sxml2arr($sxml); } } includes/WindowsAzure/Common/Internal/ConnectionStringParser.php000064400000025211152214270100021166 0ustar00 * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @link https://github.com/windowsazure/azure-sdk-for-php */ namespace WindowsAzure\Common\Internal; /** * Helper methods for parsing connection strings. The rules for formatting connection * strings are defined here: * www.connectionstrings.com/articles/show/important-rules-for-connection-strings * * @category Microsoft * @package WindowsAzure\Common\Internal * @author Azure PHP SDK * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @version Release: 0.4.1_2015-03 * @link https://github.com/windowsazure/azure-sdk-for-php */ class ConnectionStringParser { /** * @var string */ private $_argumentName; /** * @var string */ private $_value; /** * @var integer */ private $_pos; /** * @var string */ private $_state; /** * Parses the connection string into a collection of key/value pairs. * * @param string $argumentName Name of the argument to be used in error * messages. * @param string $connectionString Connection string. * * @return array * * @static */ public static function parseConnectionString($argumentName, $connectionString) { Validate::isString($argumentName, 'argumentName'); Validate::notNullOrEmpty($argumentName, 'argumentName'); Validate::isString($connectionString, 'connectionString'); Validate::notNullOrEmpty($connectionString, 'connectionString'); $parser = new ConnectionStringParser($argumentName, $connectionString); return $parser->_parse(); } /** * Initializes the object. * * @param string $argumentName Name of the argument to be used in error * messages. * @param string $value Connection string. */ private function __construct($argumentName, $value) { $this->_argumentName = $argumentName; $this->_value = $value; $this->_pos = 0; $this->_state = ParserState::EXPECT_KEY; } /** * Parses the connection string. * * @return array * * @throws \RuntimeException */ private function _parse() { $key = null; $value = null; $connectionStringValues = array(); while (true) { $this->_skipWhiteSpaces(); if ( $this->_pos == strlen($this->_value) && $this->_state != ParserState::EXPECT_VALUE ) { // Not stopping after the end has been reached and a value is // expected results in creating an empty value, which we expect. break; } switch ($this->_state) { case ParserState::EXPECT_KEY: $key = $this->_extractKey(); $this->_state = ParserState::EXPECT_ASSIGNMENT; break; case ParserState::EXPECT_ASSIGNMENT: $this->_skipOperator('='); $this->_state = ParserState::EXPECT_VALUE; break; case ParserState::EXPECT_VALUE: $value = $this->_extractValue(); $this->_state = ParserState::EXPECT_SEPARATOR; $connectionStringValues[$key] = $value; $key = null; $value = null; break; default: $this->_skipOperator(';'); $this->_state = ParserState::EXPECT_KEY; break; } } // Must end parsing in the valid state (expected key or separator) if ($this->_state == ParserState::EXPECT_ASSIGNMENT) { throw $this->_createException( $this->_pos, Resources::MISSING_CONNECTION_STRING_CHAR, '=' ); } return $connectionStringValues; } /** *Generates an invalid connection string exception with the detailed error * message. * * @param integer $position The position of the error. * @param string $errorString The short error formatting string. * * @return \RuntimeException */ private function _createException($position, $errorString) { $arguments = func_get_args(); // Remove first argument (position) unset($arguments[0]); // Create a short error message. $errorString = sprintf($errorString, $arguments); // Add position. $errorString = sprintf( Resources::ERROR_PARSING_STRING, $errorString, $position ); // Create final error message. $errorString = sprintf( Resources::INVALID_CONNECTION_STRING, $this->_argumentName, $errorString ); return new \RuntimeException($errorString); } /** * Skips whitespaces at the current position. * * @return none */ private function _skipWhiteSpaces() { while ( $this->_pos < strlen($this->_value) && ctype_space($this->_value[$this->_pos]) ) { $this->_pos++; } } /** * Extracts the key's value. * * @return string */ private function _extractValue() { $value = Resources::EMPTY_STRING; if ($this->_pos < strlen($this->_value)) { $ch = $this->_value[$this->_pos]; if ($ch == '"' || $ch == '\'') { // Value is contained between double quotes or skipped single quotes. $this->_pos++; $value = $this->_extractString($ch); } else { $firstPos = $this->_pos; $isFound = false; while ($this->_pos < strlen($this->_value) && !$isFound) { $ch = $this->_value[$this->_pos]; if ($ch == ';') { $isFound = true; } else { $this->_pos++; } } $value = rtrim( substr($this->_value, $firstPos, $this->_pos - $firstPos) ); } } return $value; } /** * Extracts key at the current position. * * @return string */ private function _extractKey() { $key = null; $firstPos = $this->_pos; $ch = $this->_value[$this->_pos]; if ($ch == '"' || $ch == '\'') { $this->_pos++; $key = $this->_extractString($ch); } else if ($ch == ';' || $ch == '=') { // Key name was expected. throw $this->_createException( $firstPos, Resources::ERROR_CONNECTION_STRING_MISSING_KEY ); } else { while ($this->_pos < strlen($this->_value)) { $ch = $this->_value[$this->_pos]; // At this point we've read the key, break. if ($ch == '=') { break; } $this->_pos++; } $key = rtrim(substr($this->_value, $firstPos, $this->_pos - $firstPos)); } if (strlen($key) == 0) { // Empty key name. throw $this->_createException( $firstPos, Resources::ERROR_CONNECTION_STRING_EMPTY_KEY ); } return $key; } /** * Extracts the string until the given quotation mark. * * @param string $quote The quotation mark terminating the string. * * @return string */ private function _extractString($quote) { $firstPos = $this->_pos; while ( $this->_pos < strlen($this->_value) && $this->_value[$this->_pos] != $quote ) { $this->_pos++; } if ($this->_pos == strlen($this->_value)) { // Runaway string. throw $this->_createException( $this->_pos, Resources::ERROR_CONNECTION_STRING_MISSING_CHARACTER, $quote ); } return substr($this->_value, $firstPos, $this->_pos++ - $firstPos); } /** * Skips specified operator. * * @param string $operatorChar The operator character. * * @return none * * @throws \RuntimeException */ private function _skipOperator($operatorChar) { if ($this->_value[$this->_pos] != $operatorChar) { // Character was expected. throw $this->_createException( $this->_pos, Resources::MISSING_CONNECTION_STRING_CHAR, $operatorChar ); } $this->_pos++; } } /** * State of the connection string parser. * * @category Microsoft * @package WindowsAzure\Common\Internal * @author Azure PHP SDK * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @version Release: 0.4.1_2015-03 * @link https://github.com/windowsazure/azure-sdk-for-php */ class ParserState { const EXPECT_KEY = 'ExpectKey'; const EXPECT_ASSIGNMENT = 'ExpectAssignment'; const EXPECT_VALUE = 'ExpectValue'; const EXPECT_SEPARATOR = 'ExpectSeparator'; }includes/WindowsAzure/Common/Internal/Logger.php000064400000004312152214270100015741 0ustar00 * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @link https://github.com/windowsazure/azure-sdk-for-php */ namespace WindowsAzure\Common\Internal; /** * Logger class for debugging purpose. * * @category Microsoft * @package WindowsAzure\Common\Internal * @author Azure PHP SDK * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @version Release: 0.4.1_2015-03 * @link https://github.com/windowsazure/azure-sdk-for-php */ class Logger { /** * @var string */ private static $_filePath; /** * Logs $var to file. * * @param mix $var The data to log. * @param string $tip The help message. * * @static * * @return none */ public static function log($var, $tip = Resources::EMPTY_STRING) { if (!empty($tip)) { error_log($tip . "\n", 3, self::$_filePath); } if (is_array($var) || is_object($var)) { error_log(print_r($var, true), 3, self::$_filePath); } else { error_log($var . "\n", 3, self::$_filePath); } } /** * Sets file path to use. * * @param string $filePath The log file path. * * @static * * @return none */ public static function setLogFile($filePath) { self::$_filePath = $filePath; } } includes/WindowsAzure/Common/Internal/Resources.php000064400000060735152214270100016507 0ustar00 * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @link https://github.com/windowsazure/azure-sdk-for-php */ namespace WindowsAzure\Common\Internal; /** * Project resources. * * @category Microsoft * @package WindowsAzure\Common\Internal * @author Azure PHP SDK * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @version Release: 0.4.1_2015-03 * @link https://github.com/windowsazure/azure-sdk-for-php */ class Resources { // @codingStandardsIgnoreStart // Connection strings const USE_DEVELOPMENT_STORAGE_NAME = 'UseDevelopmentStorage'; const DEVELOPMENT_STORAGE_PROXY_URI_NAME = 'DevelopmentStorageProxyUri'; const DEFAULT_ENDPOINTS_PROTOCOL_NAME = 'DefaultEndpointsProtocol'; const ACCOUNT_NAME_NAME = 'AccountName'; const ACCOUNT_KEY_NAME = 'AccountKey'; const BLOB_ENDPOINT_NAME = 'BlobEndpoint'; const QUEUE_ENDPOINT_NAME = 'QueueEndpoint'; const TABLE_ENDPOINT_NAME = 'TableEndpoint'; const SHARED_ACCESS_SIGNATURE_NAME = 'SharedAccessSignature'; const DEV_STORE_NAME = 'devstoreaccount1'; const DEV_STORE_KEY = 'Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw=='; const BLOB_BASE_DNS_NAME = 'blob.core.windows.net'; const QUEUE_BASE_DNS_NAME = 'queue.core.windows.net'; const TABLE_BASE_DNS_NAME = 'table.core.windows.net'; const DEV_STORE_CONNECTION_STRING = 'BlobEndpoint=127.0.0.1:10000;QueueEndpoint=127.0.0.1:10001;TableEndpoint=127.0.0.1:10002;AccountName=devstoreaccount1;AccountKey=Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw=='; const SUBSCRIPTION_ID_NAME = 'SubscriptionID'; const CERTIFICATE_PATH_NAME = 'CertificatePath'; const SERVICE_MANAGEMENT_ENDPOINT_NAME = 'ServiceManagementEndpoint'; const SERVICE_BUS_ENDPOINT_NAME = 'Endpoint'; const SHARED_SECRET_ISSUER_NAME = 'SharedSecretIssuer'; const SHARED_SECRET_VALUE_NAME = 'SharedSecretValue'; const STS_ENDPOINT_NAME = 'StsEndpoint'; const MEDIA_SERVICES_ENDPOINT_URI_NAME = 'MediaServicesEndpoint'; const MEDIA_SERVICES_ACCOUNT_NAME = 'AccountName'; const MEDIA_SERVICES_ACCESS_KEY = 'AccessKey'; const MEDIA_SERVICES_OAUTH_ENDPOINT_URI_NAME = 'OAuthEndpoint'; // Messages const INVALID_TYPE_MSG = 'The provided variable should be of type: '; const INVALID_META_MSG = 'Metadata cannot contain newline characters.'; const AZURE_ERROR_MSG = "Fail:\nCode: %s\nValue: %s\ndetails (if any): %s."; const NOT_IMPLEMENTED_MSG = 'This method is not implemented.'; const NULL_OR_EMPTY_MSG = "'%s' can't be NULL or empty."; const NULL_MSG = "'%s' can't be NULL."; const INVALID_URL_MSG = 'Provided URL is invalid.'; const INVALID_HT_MSG = 'The header type provided is invalid.'; const INVALID_EDM_MSG = 'The provided EDM type is invalid.'; const INVALID_PROP_MSG = 'One of the provided properties is not an instance of class Property'; const INVALID_ENTITY_MSG = 'The provided entity object is invalid.'; const INVALID_VERSION_MSG = 'Server does not support any known protocol versions.'; const INVALID_BO_TYPE_MSG = 'Batch operation name is not supported or invalid.'; const INVALID_BO_PN_MSG = 'Batch operation parameter is not supported.'; const INVALID_OC_COUNT_MSG = 'Operations and contexts must be of same size.'; const INVALID_EXC_OBJ_MSG = 'Exception object type should be ServiceException.'; const NULL_TABLE_KEY_MSG = 'Partition and row keys can\'t be NULL.'; const BATCH_ENTITY_DEL_MSG = 'The entity was deleted successfully.'; const INVALID_PROP_VAL_MSG = "'%s' property value must satisfy %s."; const INVALID_PARAM_MSG = "The provided variable '%s' should be of type '%s'"; const INVALID_STRING_LENGTH = "The provided variable '%s' should be of %s characters long"; const INVALID_BTE_MSG = "The blob block type must exist in %s"; const INVALID_BLOB_PAT_MSG = 'The provided access type is invalid.'; const INVALID_SVC_PROP_MSG = 'The provided service properties is invalid.'; const UNKNOWN_SRILZER_MSG = 'The provided serializer type is unknown'; const INVALID_CREATE_SERVICE_OPTIONS_MSG = 'Must provide valid location or affinity group.'; const INVALID_UPDATE_SERVICE_OPTIONS_MSG = 'Must provide either description or label.'; const INVALID_CONFIG_MSG = 'Config object must be of type Configuration'; const INVALID_ACH_MSG = 'The provided access condition header is invalid'; const INVALID_RECEIVE_MODE_MSG = 'The receive message option is in neither RECEIVE_AND_DELETE nor PEEK_LOCK mode.'; const INVALID_CONFIG_URI = "The provided URI '%s' is invalid. It has to pass the check 'filter_var(, FILTER_VALIDATE_URL)'."; const INVALID_CONFIG_VALUE = "The provided config value '%s' does not belong to the valid values subset:\n%s"; const INVALID_ACCOUNT_KEY_FORMAT = "The provided account key '%s' is not a valid base64 string. It has to pass the check 'base64_decode(, true)'."; const MISSING_CONNECTION_STRING_SETTINGS = "The provided connection string '%s' does not have complete configuration settings."; const INVALID_CONNECTION_STRING_SETTING_KEY = "The setting key '%s' is not found in the expected configuration setting keys:\n%s"; const INVALID_CERTIFICATE_PATH = "The provided certificate path '%s' is invalid."; const INSTANCE_TYPE_VALIDATION_MSG = 'The type of %s is %s but is expected to be %s.'; const MISSING_CONNECTION_STRING_CHAR = "Missing %s character"; const ERROR_PARSING_STRING = "'%s' at position %d."; const INVALID_CONNECTION_STRING = "Argument '%s' is not a valid connection string: '%s'"; const ERROR_CONNECTION_STRING_MISSING_KEY = 'Missing key name'; const ERROR_CONNECTION_STRING_EMPTY_KEY = 'Empty key name'; const ERROR_CONNECTION_STRING_MISSING_CHARACTER = "Missing %s character"; const ERROR_EMPTY_SETTINGS = 'No keys were found in the connection string'; const MISSING_LOCK_LOCATION_MSG = 'The lock location of the brokered message is missing.'; const INVALID_SLOT = "The provided deployment slot '%s' is not valid. Only 'staging' and 'production' are accepted."; const INVALID_DEPLOYMENT_LOCATOR_MSG = 'A slot or deployment name must be provided.'; const INVALID_CHANGE_MODE_MSG = "The change mode must be 'Auto' or 'Manual'. Use Mode class constants for that purpose."; const INVALID_DEPLOYMENT_STATUS_MSG = "The change mode must be 'Running' or 'Suspended'. Use DeploymentStatus class constants for that purpose."; const ERROR_OAUTH_GET_ACCESS_TOKEN = 'Unable to get oauth access token for endpoint \'%s\', account name \'%s\''; const ERROR_OAUTH_SERVICE_MISSING = 'OAuth service missing for account name \'%s\''; const ERROR_METHOD_NOT_FOUND = 'Method \'%s\' not found in object class \'%s\''; const ERROR_INVALID_DATE_STRING = 'Parameter \'%s\' is not a date formatted string \'%s\''; // HTTP Headers const X_MS_HEADER_PREFIX = 'x-ms-'; const X_MS_META_HEADER_PREFIX = 'x-ms-meta-'; const X_MS_APPROXIMATE_MESSAGES_COUNT = 'x-ms-approximate-messages-count'; const X_MS_POPRECEIPT = 'x-ms-popreceipt'; const X_MS_TIME_NEXT_VISIBLE = 'x-ms-time-next-visible'; const X_MS_BLOB_PUBLIC_ACCESS = 'x-ms-blob-public-access'; const X_MS_VERSION = 'x-ms-version'; const X_MS_DATE = 'x-ms-date'; const X_MS_BLOB_SEQUENCE_NUMBER = 'x-ms-blob-sequence-number'; const X_MS_BLOB_SEQUENCE_NUMBER_ACTION = 'x-ms-sequence-number-action'; const X_MS_BLOB_TYPE = 'x-ms-blob-type'; const X_MS_BLOB_CONTENT_TYPE = 'x-ms-blob-content-type'; const X_MS_BLOB_CONTENT_ENCODING = 'x-ms-blob-content-encoding'; const X_MS_BLOB_CONTENT_LANGUAGE = 'x-ms-blob-content-language'; const X_MS_BLOB_CONTENT_MD5 = 'x-ms-blob-content-md5'; const X_MS_BLOB_CACHE_CONTROL = 'x-ms-blob-cache-control'; const X_MS_BLOB_CONTENT_LENGTH = 'x-ms-blob-content-length'; const X_MS_COPY_SOURCE = 'x-ms-copy-source'; const X_MS_RANGE = 'x-ms-range'; const X_MS_RANGE_GET_CONTENT_MD5 = 'x-ms-range-get-content-md5'; const X_MS_LEASE_DURATION = 'x-ms-lease-duration'; const X_MS_LEASE_ID = 'x-ms-lease-id'; const X_MS_LEASE_TIME = 'x-ms-lease-time'; const X_MS_LEASE_STATUS = 'x-ms-lease-status'; const X_MS_LEASE_ACTION = 'x-ms-lease-action'; const X_MS_DELETE_SNAPSHOTS = 'x-ms-delete-snapshots'; const X_MS_PAGE_WRITE = 'x-ms-page-write'; const X_MS_SNAPSHOT = 'x-ms-snapshot'; const X_MS_SOURCE_IF_MODIFIED_SINCE = 'x-ms-source-if-modified-since'; const X_MS_SOURCE_IF_UNMODIFIED_SINCE = 'x-ms-source-if-unmodified-since'; const X_MS_SOURCE_IF_MATCH = 'x-ms-source-if-match'; const X_MS_SOURCE_IF_NONE_MATCH = 'x-ms-source-if-none-match'; const X_MS_SOURCE_LEASE_ID = 'x-ms-source-lease-id'; const X_MS_CONTINUATION_NEXTTABLENAME = 'x-ms-continuation-nexttablename'; const X_MS_CONTINUATION_NEXTPARTITIONKEY = 'x-ms-continuation-nextpartitionkey'; const X_MS_CONTINUATION_NEXTROWKEY = 'x-ms-continuation-nextrowkey'; const X_MS_REQUEST_ID = 'x-ms-request-id'; const ETAG = 'etag'; const LAST_MODIFIED = 'last-modified'; const DATE = 'date'; const AUTHENTICATION = 'authorization'; const WRAP_AUTHORIZATION = 'WRAP access_token="%s"'; const CONTENT_ENCODING = 'content-encoding'; const CONTENT_LANGUAGE = 'content-language'; const CONTENT_LENGTH = 'content-length'; const CONTENT_LENGTH_NO_SPACE = 'contentlength'; const CONTENT_MD5 = 'content-md5'; const CONTENT_TYPE = 'content-type'; const CONTENT_ID = 'content-id'; const CONTENT_RANGE = 'content-range'; const CACHE_CONTROL = 'cache-control'; const IF_MODIFIED_SINCE = 'if-modified-since'; const IF_MATCH = 'if-match'; const IF_NONE_MATCH = 'if-none-match'; const IF_UNMODIFIED_SINCE = 'if-unmodified-since'; const RANGE = 'range'; const DATA_SERVICE_VERSION = 'dataserviceversion'; const MAX_DATA_SERVICE_VERSION = 'maxdataserviceversion'; const ACCEPT_HEADER = 'accept'; const ACCEPT_CHARSET = 'accept-charset'; const USER_AGENT = 'User-Agent'; // Type const QUEUE_TYPE_NAME = 'IQueue'; const BLOB_TYPE_NAME = 'IBlob'; const TABLE_TYPE_NAME = 'ITable'; const SERVICE_MANAGEMENT_TYPE_NAME = 'IServiceManagement'; const SERVICE_BUS_TYPE_NAME = 'IServiceBus'; const WRAP_TYPE_NAME = 'IWrap'; // WRAP const WRAP_ACCESS_TOKEN = 'wrap_access_token'; const WRAP_ACCESS_TOKEN_EXPIRES_IN = 'wrap_access_token_expires_in'; const WRAP_NAME = 'wrap_name'; const WRAP_PASSWORD = 'wrap_password'; const WRAP_SCOPE = 'wrap_scope'; // OAuth const OAUTH_GRANT_TYPE = 'grant_type'; const OAUTH_CLIENT_ID = 'client_id'; const OAUTH_CLIENT_SECRET = 'client_secret'; const OAUTH_SCOPE = 'scope'; const OAUTH_GT_CLIENT_CREDENTIALS = 'client_credentials'; const OAUTH_ACCESS_TOKEN = 'access_token'; const OAUTH_EXPIRES_IN = 'expires_in'; const OAUTH_ACCESS_TOKEN_PREFIX = 'Bearer '; // HTTP Methods const HTTP_GET = 'GET'; const HTTP_PUT = 'PUT'; const HTTP_POST = 'POST'; const HTTP_HEAD = 'HEAD'; const HTTP_DELETE = 'DELETE'; const HTTP_MERGE = 'MERGE'; // Misc const EMPTY_STRING = ''; const SEPARATOR = ','; const AZURE_DATE_FORMAT = 'D, d M Y H:i:s T'; const TIMESTAMP_FORMAT = 'Y-m-d H:i:s'; const EMULATED = 'EMULATED'; const EMULATOR_BLOB_URI = '127.0.0.1:10000'; const EMULATOR_QUEUE_URI = '127.0.0.1:10001'; const EMULATOR_TABLE_URI = '127.0.0.1:10002'; const ASTERISK = '*'; const SERVICE_MANAGEMENT_URL = 'https://management.core.windows.net'; const HTTP_SCHEME = 'http'; const HTTPS_SCHEME = 'https'; const SETTING_NAME = 'SettingName'; const SETTING_CONSTRAINT = 'SettingConstraint'; const DEV_STORE_URI = 'http://127.0.0.1'; const SERVICE_URI_FORMAT = "%s://%s.%s"; const WRAP_ENDPOINT_URI_FORMAT = "https://%s-sb.accesscontrol.windows.net/WRAPv0.9"; // Xml Namespaces const WA_XML_NAMESPACE = 'http://schemas.microsoft.com/windowsazure'; const ATOM_XML_NAMESPACE = 'http://www.w3.org/2005/Atom'; const DS_XML_NAMESPACE = 'http://schemas.microsoft.com/ado/2007/08/dataservices'; const DSM_XML_NAMESPACE = 'http://schemas.microsoft.com/ado/2007/08/dataservices/metadata'; const XSI_XML_NAMESPACE = 'http://www.w3.org/2001/XMLSchema-instance'; // Header values const SDK_USER_AGENT = 'Azure-SDK-For-PHP/0.4.1'; const STORAGE_API_LATEST_VERSION = '2014-02-14'; // was 2012-02-12; see HS#7569 const SM_API_LATEST_VERSION = '2011-10-01'; const DATA_SERVICE_VERSION_VALUE = '1.0;NetFx'; const MAX_DATA_SERVICE_VERSION_VALUE = '2.0;NetFx'; const ACCEPT_HEADER_VALUE = 'application/atom+xml,application/xml'; const ATOM_ENTRY_CONTENT_TYPE = 'application/atom+xml;type=entry;charset=utf-8'; const ATOM_FEED_CONTENT_TYPE = 'application/atom+xml;type=feed;charset=utf-8'; const ACCEPT_CHARSET_VALUE = 'utf-8'; const INT32_MAX = 2147483647; const MEDIA_SERVICES_API_LATEST_VERSION = '2.2'; const MEDIA_SERVICES_DATA_SERVICE_VERSION_VALUE = '3.0;NetFx'; const MEDIA_SERVICES_MAX_DATA_SERVICE_VERSION_VALUE = '3.0;NetFx'; // Query parameter names const QP_PREFIX = 'Prefix'; const QP_MAX_RESULTS = 'MaxResults'; const QP_METADATA = 'Metadata'; const QP_MARKER = 'Marker'; const QP_NEXT_MARKER = 'NextMarker'; const QP_COMP = 'comp'; const QP_VISIBILITY_TIMEOUT = 'visibilitytimeout'; const QP_POPRECEIPT = 'popreceipt'; const QP_NUM_OF_MESSAGES = 'numofmessages'; const QP_PEEK_ONLY = 'peekonly'; const QP_MESSAGE_TTL = 'messagettl'; const QP_INCLUDE = 'include'; const QP_TIMEOUT = 'timeout'; const QP_DELIMITER = 'Delimiter'; const QP_REST_TYPE = 'restype'; const QP_SNAPSHOT = 'snapshot'; const QP_BLOCKID = 'blockid'; const QP_BLOCK_LIST_TYPE = 'blocklisttype'; const QP_SELECT = '$select'; const QP_TOP = '$top'; const QP_SKIP = '$skip'; const QP_FILTER = '$filter'; const QP_NEXT_TABLE_NAME = 'NextTableName'; const QP_NEXT_PK = 'NextPartitionKey'; const QP_NEXT_RK = 'NextRowKey'; const QP_ACTION = 'action'; const QP_EMBED_DETAIL = 'embed-detail'; // Query parameter values const QPV_REGENERATE = 'regenerate'; const QPV_CONFIG = 'config'; const QPV_STATUS = 'status'; const QPV_UPGRADE = 'upgrade'; const QPV_WALK_UPGRADE_DOMAIN = 'walkupgradedomain'; const QPV_REBOOT = 'reboot'; const QPV_REIMAGE = 'reimage'; const QPV_ROLLBACK = 'rollback'; // Request body content types const URL_ENCODED_CONTENT_TYPE = 'application/x-www-form-urlencoded'; const XML_CONTENT_TYPE = 'application/xml'; const BINARY_FILE_TYPE = 'application/octet-stream'; const XML_ATOM_CONTENT_TYPE = 'application/atom+xml'; const HTTP_TYPE = 'application/http'; const MULTIPART_MIXED_TYPE = 'multipart/mixed'; // Common used XML tags const XTAG_ATTRIBUTES = '@attributes'; const XTAG_NAMESPACE = '@namespace'; const XTAG_LABEL = 'Label'; const XTAG_NAME = 'Name'; const XTAG_DESCRIPTION = 'Description'; const XTAG_LOCATION = 'Location'; const XTAG_AFFINITY_GROUP = 'AffinityGroup'; const XTAG_HOSTED_SERVICES = 'HostedServices'; const XTAG_STORAGE_SERVICES = 'StorageServices'; const XTAG_STORAGE_SERVICE = 'StorageService'; const XTAG_DISPLAY_NAME = 'DisplayName'; const XTAG_SERVICE_NAME = 'ServiceName'; const XTAG_URL = 'Url'; const XTAG_ID = 'ID'; const XTAG_STATUS = 'Status'; const XTAG_HTTP_STATUS_CODE = 'HttpStatusCode'; const XTAG_CODE = 'Code'; const XTAG_MESSAGE = 'Message'; const XTAG_STORAGE_SERVICE_PROPERTIES = 'StorageServiceProperties'; const XTAG_ENDPOINT = 'Endpoint'; const XTAG_ENDPOINTS = 'Endpoints'; const XTAG_PRIMARY = 'Primary'; const XTAG_SECONDARY = 'Secondary'; const XTAG_KEY_TYPE = 'KeyType'; const XTAG_STORAGE_SERVICE_KEYS = 'StorageServiceKeys'; const XTAG_ERROR = 'Error'; const XTAG_HOSTED_SERVICE = 'HostedService'; const XTAG_HOSTED_SERVICE_PROPERTIES = 'HostedServiceProperties'; const XTAG_CREATE_HOSTED_SERVICE = 'CreateHostedService'; const XTAG_CREATE_STORAGE_SERVICE_INPUT = 'CreateStorageServiceInput'; const XTAG_UPDATE_STORAGE_SERVICE_INPUT = 'UpdateStorageServiceInput'; const XTAG_CREATE_AFFINITY_GROUP = 'CreateAffinityGroup'; const XTAG_UPDATE_AFFINITY_GROUP = 'UpdateAffinityGroup'; const XTAG_UPDATE_HOSTED_SERVICE = 'UpdateHostedService'; const XTAG_PACKAGE_URL = 'PackageUrl'; const XTAG_CONFIGURATION = 'Configuration'; const XTAG_START_DEPLOYMENT = 'StartDeployment'; const XTAG_TREAT_WARNINGS_AS_ERROR = 'TreatWarningsAsError'; const XTAG_CREATE_DEPLOYMENT = 'CreateDeployment'; const XTAG_DEPLOYMENT_SLOT = 'DeploymentSlot'; const XTAG_PRIVATE_ID = 'PrivateID'; const XTAG_ROLE_INSTANCE_LIST = 'RoleInstanceList'; const XTAG_UPGRADE_DOMAIN_COUNT = 'UpgradeDomainCount'; const XTAG_ROLE_LIST = 'RoleList'; const XTAG_SDK_VERSION = 'SdkVersion'; const XTAG_INPUT_ENDPOINT_LIST = 'InputEndpointList'; const XTAG_LOCKED = 'Locked'; const XTAG_ROLLBACK_ALLOWED = 'RollbackAllowed'; const XTAG_UPGRADE_STATUS = 'UpgradeStatus'; const XTAG_UPGRADE_TYPE = 'UpgradeType'; const XTAG_CURRENT_UPGRADE_DOMAIN_STATE = 'CurrentUpgradeDomainState'; const XTAG_CURRENT_UPGRADE_DOMAIN = 'CurrentUpgradeDomain'; const XTAG_ROLE_NAME = 'RoleName'; const XTAG_INSTANCE_NAME = 'InstanceName'; const XTAG_INSTANCE_STATUS = 'InstanceStatus'; const XTAG_INSTANCE_UPGRADE_DOMAIN = 'InstanceUpgradeDomain'; const XTAG_INSTANCE_FAULT_DOMAIN = 'InstanceFaultDomain'; const XTAG_INSTANCE_SIZE = 'InstanceSize'; const XTAG_INSTANCE_STATE_DETAILS = 'InstanceStateDetails'; const XTAG_INSTANCE_ERROR_CODE = 'InstanceErrorCode'; const XTAG_OS_VERSION = 'OsVersion'; const XTAG_ROLE_INSTANCE = 'RoleInstance'; const XTAG_ROLE = 'Role'; const XTAG_INPUT_ENDPOINT = 'InputEndpoint'; const XTAG_VIP = 'Vip'; const XTAG_PORT = 'Port'; const XTAG_DEPLOYMENT = 'Deployment'; const XTAG_DEPLOYMENTS = 'Deployments'; const XTAG_REGENERATE_KEYS = 'RegenerateKeys'; const XTAG_SWAP = 'Swap'; const XTAG_PRODUCTION = 'Production'; const XTAG_SOURCE_DEPLOYMENT = 'SourceDeployment'; const XTAG_CHANGE_CONFIGURATION = 'ChangeConfiguration'; const XTAG_MODE = 'Mode'; const XTAG_UPDATE_DEPLOYMENT_STATUS = 'UpdateDeploymentStatus'; const XTAG_ROLE_TO_UPGRADE = 'RoleToUpgrade'; const XTAG_FORCE = 'Force'; const XTAG_UPGRADE_DEPLOYMENT = 'UpgradeDeployment'; const XTAG_UPGRADE_DOMAIN = 'UpgradeDomain'; const XTAG_WALK_UPGRADE_DOMAIN = 'WalkUpgradeDomain'; const XTAG_ROLLBACK_UPDATE_OR_UPGRADE = 'RollbackUpdateOrUpgrade'; const XTAG_CONTAINER_NAME = 'ContainerName'; const XTAG_ACCOUNT_NAME = 'AccountName'; // Service Bus const LIST_TOPICS_PATH = '$Resources/Topics'; const LIST_QUEUES_PATH = '$Resources/Queues'; const LIST_RULES_PATH = '%s/subscriptions/%s/rules'; const LIST_SUBSCRIPTIONS_PATH = '%s/subscriptions'; const RECEIVE_MESSAGE_PATH = '%s/messages/head'; const RECEIVE_SUBSCRIPTION_MESSAGE_PATH = '%s/subscriptions/%s/messages/head'; const SEND_MESSAGE_PATH = '%s/messages'; const RULE_PATH = '%s/subscriptions/%s/rules/%s'; const SUBSCRIPTION_PATH = '%s/subscriptions/%s'; const DEFAULT_RULE_NAME = '$Default'; const UNIQUE_ID_PREFIX = 'urn:uuid:'; const SERVICE_BUS_NAMESPACE = 'http://schemas.microsoft.com/netservices/2010/10/servicebus/connect'; const BROKER_PROPERTIES = 'BrokerProperties'; const XMLNS_ATOM = 'xmlns:atom'; const XMLNS = 'xmlns'; const ATOM_NAMESPACE = 'http://www.w3.org/2005/Atom'; // ATOM string const AUTHOR = 'author'; const CATEGORY = 'category'; const CONTRIBUTOR = 'contributor'; const ENTRY = 'entry'; const LINK = 'link'; const PROPERTIES = 'properties'; const ELEMENT = 'element'; // PHP URL Keys const PHP_URL_SCHEME = 'scheme'; const PHP_URL_HOST = 'host'; const PHP_URL_PORT = 'port'; const PHP_URL_USER = 'user'; const PHP_URL_PASS = 'pass'; const PHP_URL_PATH = 'path'; const PHP_URL_QUERY = 'query'; const PHP_URL_FRAGMENT = 'fragment'; // Status Codes const STATUS_OK = 200; const STATUS_CREATED = 201; const STATUS_ACCEPTED = 202; const STATUS_NO_CONTENT = 204; const STATUS_PARTIAL_CONTENT = 206; const STATUS_MOVED_PERMANENTLY = 301; // HTTP_Request2 config parameter names const USE_BRACKETS = 'use_brackets'; const SSL_VERIFY_PEER = 'ssl_verify_peer'; const SSL_VERIFY_HOST = 'ssl_verify_host'; const SSL_LOCAL_CERT = 'ssl_local_cert'; const SSL_CAFILE = 'ssl_cafile'; const CONNECT_TIMEOUT = 'connect_timeout'; // Media services const MEDIA_SERVICES_URL = 'https://media.windows.net/API/'; const MEDIA_SERVICES_OAUTH_URL = 'https://wamsprodglobal001acs.accesscontrol.windows.net/v2/OAuth2-13'; const MEDIA_SERVICES_OAUTH_SCOPE = 'urn:WindowsAzureMediaServices'; const MEDIA_SERVICES_INPUT_ASSETS_REL = 'http://schemas.microsoft.com/ado/2007/08/dataservices/related/InputMediaAssets'; const MEDIA_SERVICES_ASSET_REL = 'http://schemas.microsoft.com/ado/2007/08/dataservices/related/Asset'; const MEDIA_SERVICES_ENCRYPTION_VERSION = '1.0'; // @codingStandardsIgnoreEnd } includes/WindowsAzure/Common/Internal/Utilities.php000064400000050602152214270100016500 0ustar00 * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @link https://github.com/windowsazure/azure-sdk-for-php */ namespace WindowsAzure\Common\Internal; /** * Utilities for the project * * @category Microsoft * @package WindowsAzure\Common\Internal * @author Azure PHP SDK * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @version Release: 0.4.1_2015-03 * @link https://github.com/windowsazure/azure-sdk-for-php */ class Utilities { /** * Returns the specified value of the $key passed from $array and in case that * this $key doesn't exist, the default value is returned. * * @param array $array The array to be used. * @param mix $key The array key. * @param mix $default The value to return if $key is not found in $array. * * @static * * @return mix */ public static function tryGetValue($array, $key, $default = null) { return is_array($array) && array_key_exists($key, $array) ? $array[$key] : $default; } /** * Adds a url scheme if there is no scheme. * * @param string $url The URL. * @param string $scheme The scheme. By default HTTP * * @static * * @return string */ public static function tryAddUrlScheme($url, $scheme = 'http') { $urlScheme = parse_url($url, PHP_URL_SCHEME); if (empty($urlScheme)) { $url = "$scheme://" . $url; } return $url; } /** * tries to get nested array with index name $key from $array. * * Returns empty array object if the value is NULL. * * @param string $key The index name. * @param array $array The array object. * * @static * * @return array */ public static function tryGetArray($key, $array) { return Utilities::getArray(Utilities::tryGetValue($array, $key)); } /** * Adds the given key/value pair into array if the value doesn't satisfy empty(). * * This function just validates that the given $array is actually array. If it's * NULL the function treats it as array. * * @param string $key The key. * @param string $value The value. * @param array &$array The array. If NULL will be used as array. * * @static * * @return none */ public static function addIfNotEmpty($key, $value, &$array) { if (!is_null($array)) { Validate::isArray($array, 'array'); } if (!empty($value)) { $array[$key] = $value; } } /** * Returns the specified value of the key chain passed from $array and in case * that key chain doesn't exist, null is returned. * * @param array $array Array to be used. * * @static * * @return mix */ public static function tryGetKeysChainValue($array) { $arguments = func_get_args(); $numArguments = func_num_args(); $currentArray = $array; for ($i = 1; $i < $numArguments; $i++) { if (is_array($currentArray)) { if (array_key_exists($arguments[$i], $currentArray)) { $currentArray = $currentArray[$arguments[$i]]; } else { return null; } } else { return null; } } return $currentArray; } /** * Checks if the passed $string starts with $prefix * * @param string $string word to seaech in * @param string $prefix prefix to be matched * @param boolean $ignoreCase true to ignore case during the comparison; * otherwise, false * * @static * * @return boolean */ public static function startsWith($string, $prefix, $ignoreCase = false) { if ($ignoreCase) { $string = strtolower($string); $prefix = strtolower($prefix); } return ($prefix == substr($string, 0, strlen($prefix))); } /** * Returns grouped items from passed $var * * @param array $var item to group * * @static * * @return array */ public static function getArray($var) { if (is_null($var) || empty($var)) { return array(); } foreach ($var as $value) { if ((gettype($value) == 'object') && (get_class($value) == 'SimpleXMLElement') ) { return (array) $var; } else if (!is_array($value)) { return array($var); } } return $var; } /** * Unserializes the passed $xml into array. * * @param string $xml XML to be parsed. * * @static * * @return array */ public static function unserialize($xml) { $sxml = new \SimpleXMLElement($xml); return self::_sxml2arr($sxml); } /** * Converts a SimpleXML object to an Array recursively * ensuring all sub-elements are arrays as well. * * @param string $sxml SimpleXML object * @param array $arr Array into which to store results * * @static * * @return array */ private static function _sxml2arr($sxml, $arr = null) { foreach ((array) $sxml as $key => $value) { if (is_object($value) || (is_array($value))) { $arr[$key] = self::_sxml2arr($value); } else { $arr[$key] = $value; } } return $arr; } /** * Serializes given array into xml. The array indices must be string to use * them as XML tags. * * @param array $array object to serialize represented in array. * @param string $rootName name of the XML root element. * @param string $defaultTag default tag for non-tagged elements. * @param string $standalone adds 'standalone' header tag, values 'yes'/'no' * * @static * * @return string */ public static function serialize($array, $rootName, $defaultTag = null, $standalone = null ) { $xmlVersion = '1.0'; $xmlEncoding = 'UTF-8'; if (!is_array($array)) { return false; } $xmlw = new \XmlWriter(); $xmlw->openMemory(); $xmlw->startDocument($xmlVersion, $xmlEncoding, $standalone); $xmlw->startElement($rootName); self::_arr2xml($xmlw, $array, $defaultTag); $xmlw->endElement(); return $xmlw->outputMemory(true); } /** * Takes an array and produces XML based on it. * * @param XMLWriter $xmlw XMLWriter object that was previously instanted * and is used for creating the XML. * @param array $data Array to be converted to XML * @param string $defaultTag Default XML tag to be used if none specified. * * @static * * @return void */ private static function _arr2xml(\XMLWriter $xmlw, $data, $defaultTag = null) { foreach ($data as $key => $value) { if (strcmp($key, '@attributes') == 0) { foreach ($value as $attributeName => $attributeValue) { $xmlw->writeAttribute($attributeName, $attributeValue); } } else if (is_array($value)) { if (!is_int($key)) { if ($key != Resources::EMPTY_STRING) { $xmlw->startElement($key); } else { $xmlw->startElement($defaultTag); } } self::_arr2xml($xmlw, $value); if (!is_int($key)) { $xmlw->endElement(); } continue; } else { $xmlw->writeElement($key, $value); } } } /** * Converts string into boolean value. * * @param string $obj boolean value in string format. * * @static * * @return bool */ public static function toBoolean($obj) { return filter_var($obj, FILTER_VALIDATE_BOOLEAN); } /** * Converts string into boolean value. * * @param bool $obj boolean value to convert. * * @static * * @return string */ public static function booleanToString($obj) { return $obj ? 'true' : 'false'; } /** * Converts a given date string into \DateTime object * * @param string $date windows azure date ins string represntation. * * @static * * @return \DateTime */ public static function rfc1123ToDateTime($date) { $timeZone = new \DateTimeZone('GMT'); $format = Resources::AZURE_DATE_FORMAT; return \DateTime::createFromFormat($format, $date, $timeZone); } /** * Generate ISO 8601 compliant date string in UTC time zone * * @param int $timestamp The unix timestamp to convert * (for DateTime check date_timestamp_get). * * @static * * @return string */ public static function isoDate($timestamp = null) { $tz = date_default_timezone_get(); date_default_timezone_set('UTC'); if (is_null($timestamp)) { $timestamp = time(); } $returnValue = str_replace( '+00:00', '.0000000Z', date('c', $timestamp) ); date_default_timezone_set($tz); return $returnValue; } /** * Converts a DateTime object into an Edm.DaeTime value in UTC timezone, * represented as a string. * * @param \DateTime $value The datetime value. * * @static * * @return string */ public static function convertToEdmDateTime($value) { if (empty($value)) { return $value; } if (is_string($value)) { $value = self::convertToDateTime($value); } Validate::isDate($value); $cloned = clone $value; $cloned->setTimezone(new \DateTimeZone('UTC')); return str_replace('+0000', 'Z', $cloned->format(\DateTime::ISO8601)); } /** * Converts a string to a \DateTime object. Returns false on failure. * * @param string $value The string value to parse. * * @static * * @return \DateTime */ public static function convertToDateTime($value) { if ($value instanceof \DateTime) { return $value; } if (substr($value, -1) == 'Z') { $value = substr($value, 0, strlen($value) - 1); } return new \DateTime($value, new \DateTimeZone('UTC')); } /** * Converts string to stream handle. * * @param type $string The string contents. * * @static * * @return resource */ public static function stringToStream($string) { return fopen('data://text/plain,' . urlencode($string), 'rb'); } /** * Sorts an array based on given keys order. * * @param array $array The array to sort. * @param array $order The keys order array. * * @return array */ public static function orderArray($array, $order) { $ordered = array(); foreach ($order as $key) { if (array_key_exists($key, $array)) { $ordered[$key] = $array[$key]; } } return $ordered; } /** * Checks if a value exists in an array. The comparison is done in a case * insensitive manner. * * @param string $needle The searched value. * @param array $haystack The array. * * @static * * @return boolean */ public static function inArrayInsensitive($needle, $haystack) { return in_array(strtolower($needle), array_map('strtolower', $haystack)); } /** * Checks if the given key exists in the array. The comparison is done in a case * insensitive manner. * * @param string $key The value to check. * @param array $search The array with keys to check. * * @static * * @return boolean */ public static function arrayKeyExistsInsensitive($key, $search) { return array_key_exists(strtolower($key), array_change_key_case($search)); } /** * Returns the specified value of the $key passed from $array and in case that * this $key doesn't exist, the default value is returned. The key matching is * done in a case insensitive manner. * * @param string $key The array key. * @param array $haystack The array to be used. * @param mix $default The value to return if $key is not found in $array. * * @static * * @return mix */ public static function tryGetValueInsensitive($key, $haystack, $default = null) { $array = array_change_key_case($haystack); return Utilities::tryGetValue($array, strtolower($key), $default); } /** * Returns a string representation of a version 4 GUID, which uses random * numbers.There are 6 reserved bits, and the GUIDs have this format: * xxxxxxxx-xxxx-4xxx-[8|9|a|b]xxx-xxxxxxxxxxxx * where 'x' is a hexadecimal digit, 0-9a-f. * * See http://tools.ietf.org/html/rfc4122 for more information. * * Note: This function is available on all platforms, while the * com_create_guid() is only available for Windows. * * @static * * @return string A new GUID. */ public static function getGuid() { // @codingStandardsIgnoreStart return sprintf( '%04x%04x-%04x-%04x-%02x%02x-%04x%04x%04x', mt_rand(0, 65535), mt_rand(0, 65535), // 32 bits for "time_low" mt_rand(0, 65535), // 16 bits for "time_mid" mt_rand(0, 4096) + 16384, // 16 bits for "time_hi_and_version", with // the most significant 4 bits being 0100 // to indicate randomly generated version mt_rand(0, 64) + 128, // 8 bits for "clock_seq_hi", with // the most significant 2 bits being 10, // required by version 4 GUIDs. mt_rand(0, 256), // 8 bits for "clock_seq_low" mt_rand(0, 65535), // 16 bits for "node 0" and "node 1" mt_rand(0, 65535), // 16 bits for "node 2" and "node 3" mt_rand(0, 65535) // 16 bits for "node 4" and "node 5" ); // @codingStandardsIgnoreEnd } /** * Creates a list of objects of type $class from the provided array using static * create method. * * @param array $parsed The object in array representation * @param string $class The class name. Must have static method create. * * @static * * @return array */ public static function createInstanceList($parsed, $class) { $list = array(); foreach ($parsed as $value) { // We don't use this SDK on PHP 5.2 // @codingStandardsIgnoreLine $list[] = $class::create($value); } return $list; } /** * Takes a string and return if it ends with the specified character/string. * * @param string $haystack The string to search in. * @param string $needle postfix to match. * @param boolean $ignoreCase Set true to ignore case during the comparison; * otherwise, false * * @static * * @return boolean */ public static function endsWith($haystack, $needle, $ignoreCase = false) { if ($ignoreCase) { $haystack = strtolower($haystack); $needle = strtolower($needle); } $length = strlen($needle); if ($length == 0) { return true; } return (substr($haystack, -$length) === $needle); } /** * Get id from entity object or string. * If entity is object than validate type and return $entity->$method() * If entity is string than return this string * * @param object|string $entity Entity with id property * @param string $type Entity type to validate * @param string $method Methods that gets id (getId by default) * * @return string */ public static function getEntityId($entity, $type, $method = 'getId') { if (is_string($entity)) { return $entity; } else { Validate::isA($entity, $type, 'entity'); Validate::methodExists($entity, $method, $type); return $entity->$method(); } } /** * Generate a pseudo-random string of bytes using a cryptographically strong * algorithm. * * @param int $length Length of the string in bytes * * @return string|boolean Generated string of bytes on success, or FALSE on * failure. */ public static function generateCryptoKey($length) { return openssl_random_pseudo_bytes($length); } /** * Encrypts $data with CTR encryption * * @param string $data Data to be encrypted * @param string $key AES Encryption key * @param string $initializationVector Initialization vector * * We ignore it for standards purposes because the function is apparently nowhere called * @codingStandardsIgnoreStart * * @return string Encrypted data */ public static function ctrCrypt($data, $key, $initializationVector) { error_log("WindowsAzure\Common\Internal\Utilities::ctrCrypt called - code path thought to be impossible; linting needs re-enabling"); Validate::isString($data, 'data'); Validate::isString($key, 'key'); Validate::isString($initializationVector, 'initializationVector'); Validate::isTrue( (strlen($key) == 16 || strlen($key) == 24 || strlen($key) == 32), sprintf(Resources::INVALID_STRING_LENGTH, 'key', '16, 24, 32') ); Validate::isTrue( (strlen($initializationVector) == 16), sprintf(Resources::INVALID_STRING_LENGTH, 'initializationVector', '16') ); $blockCount = ceil(strlen($data) / 16); $ctrData = ''; for ($i = 0; $i < $blockCount; ++$i) { $ctrData .= $initializationVector; // increment Initialization Vector $j = 15; do { $digit = ord($initializationVector[$j]) + 1; $initializationVector[$j] = chr($digit & 0xFF); $j--; } while (($digit == 0x100) && ($j >= 0)); } $encryptCtrData = mcrypt_encrypt( MCRYPT_RIJNDAEL_128, $key, $ctrData, MCRYPT_MODE_ECB ); return $data ^ $encryptCtrData; } /** * Convert base 256 number to decimal number. * * @codingStandardsIgnoreEnd * * @param string $number Base 256 number * * @return string Decimal number */ public static function base256ToDec($number) { Validate::isString($number, 'number'); $result = 0; $base = 1; for ($i = strlen($number) - 1; $i >= 0; $i--) { $result = bcadd($result, bcmul(ord($number[$i]), $base)); $base = bcmul($base, 256); } return $result; } } includes/WindowsAzure/Common/Internal/InvalidArgumentTypeException.php000064400000003617152214270100022343 0ustar00 * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @link https://github.com/windowsazure/azure-sdk-for-php */ namespace WindowsAzure\Common\Internal; use WindowsAzure\Common\Internal\Resources; /** * Exception thrown if an argument type does not match with the expected type. * * @category Microsoft * @package WindowsAzure\Common\Internal * @author Azure PHP SDK * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @version Release: 0.4.1_2015-03 * @link https://github.com/windowsazure/azure-sdk-for-php */ class InvalidArgumentTypeException extends \InvalidArgumentException { /** * Constructor. * * @param string $validType The valid type that should be provided by the user. * @param string $name The parameter name. * * @return WindowsAzure\Common\Internal\InvalidArgumentTypeException */ public function __construct($validType, $name = null) { parent::__construct( sprintf(Resources::INVALID_PARAM_MSG, $name, $validType) ); } } includes/WindowsAzure/Common/Internal/IServiceFilter.php000064400000003600152214270100017400 0ustar00 * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @link https://github.com/windowsazure/azure-sdk-for-php */ namespace WindowsAzure\Common\Internal; /** * ServceFilter is called when the sending the request and after receiving the * response. * * @category Microsoft * @package WindowsAzure\Common\Internal * @author Azure PHP SDK * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @version Release: 0.4.1_2015-03 * @link https://github.com/windowsazure/azure-sdk-for-php */ interface IServiceFilter { /** * Processes HTTP request before send. * * @param mix $request HTTP request object. * * @return mix processed HTTP request object. */ public function handleRequest($request); /** * Processes HTTP response after send. * * @param mix $request HTTP request object. * @param mix $response HTTP response object. * * @return mix processed HTTP response object. */ public function handleResponse($request, $response); } includes/WindowsAzure/Common/Internal/ServiceRestProxy.php000064400000024765152214270100020040 0ustar00 * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @link https://github.com/windowsazure/azure-sdk-for-php */ namespace WindowsAzure\Common\Internal; use WindowsAzure\Common\Internal\Resources; use WindowsAzure\Common\Internal\Validate; use WindowsAzure\Common\Internal\Utilities; use WindowsAzure\Common\Internal\RestProxy; use WindowsAzure\Common\Internal\Http\Url; use WindowsAzure\Common\Internal\Http\HttpCallContext; /** * Base class for all services rest proxies. * * @category Microsoft * @package WindowsAzure\Common\Internal * @author Azure PHP SDK * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @version Release: 0.4.1_2015-03 * @link https://github.com/windowsazure/azure-sdk-for-php */ class ServiceRestProxy extends RestProxy { /** * @var string */ private $_accountName; /** * Initializes new ServiceRestProxy object. * * @param IHttpClient $channel The HTTP client used to send HTTP requests. * @param string $uri The storage account uri. * @param string $accountName The name of the account. * @param ISerializer $dataSerializer The data serializer. */ public function __construct($channel, $uri, $accountName, $dataSerializer) { parent::__construct($channel, $dataSerializer, $uri); $this->_accountName = $accountName; } /** * Gets the account name. * * @return string */ public function getAccountName() { return $this->_accountName; } /** * Sends HTTP request with the specified HTTP call context. * * @param WindowsAzure\Common\Internal\Http\HttpCallContext $context The HTTP * call context. * * @return \HTTP_Request2_Response */ protected function sendContext($context) { $context->setUri($this->getUri()); return parent::sendContext($context); } /** * Sends HTTP request with the specified parameters. * * @param string $method HTTP method used in the request * @param array $headers HTTP headers. * @param array $queryParams URL query parameters. * @param array $postParameters The HTTP POST parameters. * @param string $path URL path * @param int $statusCode Expected status code received in the response * @param string $body Request body * * @return \HTTP_Request2_Response */ protected function send( $method, $headers, $queryParams, $postParameters, $path, $statusCode, $body = Resources::EMPTY_STRING ) { $context = new HttpCallContext(); $context->setBody($body); $context->setHeaders($headers); $context->setMethod($method); $context->setPath($path); $context->setQueryParameters($queryParams); $context->setPostParameters($postParameters); if (is_array($statusCode)) { $context->setStatusCodes($statusCode); } else { $context->addStatusCode($statusCode); } return $this->sendContext($context); } /** * Adds optional header to headers if set * * @param array $headers The array of request headers. * @param AccessCondition $accessCondition The access condition object. * * @return array */ public function addOptionalAccessConditionHeader($headers, $accessCondition) { if (!is_null($accessCondition)) { $header = $accessCondition->getHeader(); if ($header != Resources::EMPTY_STRING) { $value = $accessCondition->getValue(); if ($value instanceof \DateTime) { $value = gmdate( Resources::AZURE_DATE_FORMAT, $value->getTimestamp() ); } $headers[$header] = $value; } } return $headers; } /** * Adds optional header to headers if set * * @param array $headers The array of request headers. * @param AccessCondition $accessCondition The access condition object. * * @return array */ public function addOptionalSourceAccessConditionHeader( $headers, $accessCondition ) { if (!is_null($accessCondition)) { $header = $accessCondition->getHeader(); $headerName = null; if (!empty($header)) { switch($header) { case Resources::IF_MATCH: $headerName = Resources::X_MS_SOURCE_IF_MATCH; break; case Resources::IF_UNMODIFIED_SINCE: $headerName = Resources::X_MS_SOURCE_IF_UNMODIFIED_SINCE; break; case Resources::IF_MODIFIED_SINCE: $headerName = Resources::X_MS_SOURCE_IF_MODIFIED_SINCE; break; case Resources::IF_NONE_MATCH: $headerName = Resources::X_MS_SOURCE_IF_NONE_MATCH; break; default: throw new \Exception(Resources::INVALID_ACH_MSG); break; } } $value = $accessCondition->getValue(); if ($value instanceof \DateTime) { $value = gmdate( Resources::AZURE_DATE_FORMAT, $value->getTimestamp() ); } $this->addOptionalHeader($headers, $headerName, $value); } return $headers; } /** * Adds HTTP POST parameter to the specified * * @param array $postParameters An array of HTTP POST parameters. * @param string $key The key of a HTTP POST parameter. * @param string $value the value of a HTTP POST parameter. * * @return array */ public function addPostParameter( $postParameters, $key, $value ) { Validate::isArray($postParameters, 'postParameters'); $postParameters[$key] = $value; return $postParameters; } /** * Groups set of values into one value separated with Resources::SEPARATOR * * @param array $values array of values to be grouped. * * @return string */ public function groupQueryValues($values) { Validate::isArray($values, 'values'); $joined = Resources::EMPTY_STRING; foreach ($values as $value) { if (!is_null($value) && !empty($value)) { $joined .= $value . Resources::SEPARATOR; } } return trim($joined, Resources::SEPARATOR); } /** * Adds metadata elements to headers array * * @param array $headers HTTP request headers * @param array $metadata user specified metadata * * @return array */ protected function addMetadataHeaders($headers, $metadata) { $this->validateMetadata($metadata); $metadata = $this->generateMetadataHeaders($metadata); $headers = array_merge($headers, $metadata); return $headers; } /** * Generates metadata headers by prefixing each element with 'x-ms-meta'. * * @param array $metadata user defined metadata. * * @return array. */ public function generateMetadataHeaders($metadata) { $metadataHeaders = array(); if (is_array($metadata) && !is_null($metadata)) { foreach ($metadata as $key => $value) { $headerName = Resources::X_MS_META_HEADER_PREFIX; if ( strpos($value, "\r") !== false || strpos($value, "\n") !== false ) { throw new \InvalidArgumentException(Resources::INVALID_META_MSG); } $headerName .= strtolower($key); $metadataHeaders[$headerName] = $value; } } return $metadataHeaders; } /** * Gets metadata array by parsing them from given headers. * * @param array $headers HTTP headers containing metadata elements. * * @return array. */ public function getMetadataArray($headers) { $metadata = array(); foreach ($headers as $key => $value) { $isMetadataHeader = Utilities::startsWith( strtolower($key), Resources::X_MS_META_HEADER_PREFIX ); if ($isMetadataHeader) { $MetadataName = str_replace( Resources::X_MS_META_HEADER_PREFIX, Resources::EMPTY_STRING, strtolower($key) ); $metadata[$MetadataName] = $value; } } return $metadata; } /** * Validates the provided metadata array. * * @param mix $metadata The metadata array. * * @return none */ public function validateMetadata($metadata) { if (!is_null($metadata)) { Validate::isArray($metadata, 'metadata'); } else { $metadata = array(); } foreach ($metadata as $key => $value) { Validate::isString($key, 'metadata key'); Validate::isString($value, 'metadata value'); } } } includes/WindowsAzure/Common/Internal/StorageServiceSettings.php000064400000034265152214270100021202 0ustar00 * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @link https://github.com/windowsazure/azure-sdk-for-php */ namespace WindowsAzure\Common\Internal; use WindowsAzure\Common\Internal\ConnectionStringParser; use WindowsAzure\Common\Internal\Resources; /** * Represents the settings used to sign and access a request against the storage * service. For more information about storage service connection strings check this * page: http://msdn.microsoft.com/en-us/library/ee758697 * * @category Microsoft * @package WindowsAzure\Common\Internal * @author Azure PHP SDK * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @version Release: 0.4.1_2015-03 * @link https://github.com/windowsazure/azure-sdk-for-php */ class StorageServiceSettings extends ServiceSettings { /** * The storage service name. * * @var string */ private $_name; /** * A base64 representation. * * @var string */ private $_key; /** * The endpoint for the blob service. * * @var string */ private $_blobEndpointUri; /** * The endpoint for the queue service. * * @var string */ private $_queueEndpointUri; /** * The endpoint for the table service. * * @var string */ private $_tableEndpointUri; /** * @var StorageServiceSettings */ private static $_devStoreAccount; /** * Validator for the UseDevelopmentStorage setting. Must be "true". * * @var array */ private static $_useDevelopmentStorageSetting; /** * Validator for the DevelopmentStorageProxyUri setting. Must be a valid Uri. * * @var array */ private static $_developmentStorageProxyUriSetting; /** * Validator for the DefaultEndpointsProtocol setting. Must be either "http" * or "https". * * @var array */ private static $_defaultEndpointsProtocolSetting; /** * Validator for the AccountName setting. No restrictions. * * @var array */ private static $_accountNameSetting; /** * Validator for the AccountKey setting. Must be a valid base64 string. * * @var array */ private static $_accountKeySetting; /** * Validator for the BlobEndpoint setting. Must be a valid Uri. * * @var array */ private static $_blobEndpointSetting; /** * Validator for the QueueEndpoint setting. Must be a valid Uri. * * @var array */ private static $_queueEndpointSetting; /** * Validator for the TableEndpoint setting. Must be a valid Uri. * * @var array */ private static $_tableEndpointSetting; /** * @var boolean */ protected static $isInitialized = false; /** * Holds the expected setting keys. * * @var array */ protected static $validSettingKeys = array(); /** * Initializes static members of the class. * * @return none */ protected static function init() { self::$_useDevelopmentStorageSetting = self::setting( Resources::USE_DEVELOPMENT_STORAGE_NAME, 'true' ); self::$_developmentStorageProxyUriSetting = self::settingWithFunc( Resources::DEVELOPMENT_STORAGE_PROXY_URI_NAME, Validate::getIsValidUri() ); self::$_defaultEndpointsProtocolSetting = self::setting( Resources::DEFAULT_ENDPOINTS_PROTOCOL_NAME, 'http', 'https' ); self::$_accountNameSetting = self::setting(Resources::ACCOUNT_NAME_NAME); self::$_accountKeySetting = self::settingWithFunc( Resources::ACCOUNT_KEY_NAME, // base64_decode will return false if the $key is not in base64 format. function ($key) { $isValidBase64String = base64_decode($key, true); if ($isValidBase64String) { return true; } else { throw new \RuntimeException( sprintf(Resources::INVALID_ACCOUNT_KEY_FORMAT, $key) ); } } ); self::$_blobEndpointSetting = self::settingWithFunc( Resources::BLOB_ENDPOINT_NAME, Validate::getIsValidUri() ); self::$_queueEndpointSetting = self::settingWithFunc( Resources::QUEUE_ENDPOINT_NAME, Validate::getIsValidUri() ); self::$_tableEndpointSetting = self::settingWithFunc( Resources::TABLE_ENDPOINT_NAME, Validate::getIsValidUri() ); self::$validSettingKeys[] = Resources::USE_DEVELOPMENT_STORAGE_NAME; self::$validSettingKeys[] = Resources::DEVELOPMENT_STORAGE_PROXY_URI_NAME; self::$validSettingKeys[] = Resources::DEFAULT_ENDPOINTS_PROTOCOL_NAME; self::$validSettingKeys[] = Resources::ACCOUNT_NAME_NAME; self::$validSettingKeys[] = Resources::ACCOUNT_KEY_NAME; self::$validSettingKeys[] = Resources::BLOB_ENDPOINT_NAME; self::$validSettingKeys[] = Resources::QUEUE_ENDPOINT_NAME; self::$validSettingKeys[] = Resources::TABLE_ENDPOINT_NAME; } /** * Creates new storage service settings instance. * * @param string $name The storage service name. * @param string $key The storage service key. * @param string $blobEndpointUri The sotrage service blob endpoint. * @param string $queueEndpointUri The sotrage service queue endpoint. * @param string $tableEndpointUri The sotrage service table endpoint. */ public function __construct( $name, $key, $blobEndpointUri, $queueEndpointUri, $tableEndpointUri ) { $this->_name = $name; $this->_key = $key; $this->_blobEndpointUri = $blobEndpointUri; $this->_queueEndpointUri = $queueEndpointUri; $this->_tableEndpointUri = $tableEndpointUri; } /** * Returns a StorageServiceSettings with development storage credentials using * the specified proxy Uri. * * @param string $proxyUri The proxy endpoint to use. * * @return StorageServiceSettings */ private static function _getDevelopmentStorageAccount($proxyUri) { if (is_null($proxyUri)) { return self::developmentStorageAccount(); } $scheme = parse_url($proxyUri, PHP_URL_SCHEME); $host = parse_url($proxyUri, PHP_URL_HOST); $prefix = $scheme . "://" . $host; return new StorageServiceSettings( Resources::DEV_STORE_NAME, Resources::DEV_STORE_KEY, $prefix . ':10000/devstoreaccount1/', $prefix . ':10001/devstoreaccount1/', $prefix . ':10002/devstoreaccount1/' ); } /** * Gets a StorageServiceSettings object that references the development storage * account. * * @return StorageServiceSettings */ public static function developmentStorageAccount() { if (is_null(self::$_devStoreAccount)) { self::$_devStoreAccount = self::_getDevelopmentStorageAccount( Resources::DEV_STORE_URI ); } return self::$_devStoreAccount; } /** * Gets the default service endpoint using the specified protocol and account * name. * * @param array $settings The service settings. * @param string $dns The service DNS. * * @return string */ private static function _getDefaultServiceEndpoint($settings, $dns) { $scheme = Utilities::tryGetValueInsensitive( Resources::DEFAULT_ENDPOINTS_PROTOCOL_NAME, $settings ); $accountName = Utilities::tryGetValueInsensitive( Resources::ACCOUNT_NAME_NAME, $settings ); return sprintf(Resources::SERVICE_URI_FORMAT, $scheme, $accountName, $dns); } /** * Creates StorageServiceSettings object given endpoints uri. * * @param array $settings The service settings. * @param string $blobEndpointUri The blob endpoint uri. * @param string $queueEndpointUri The queue endpoint uri. * @param string $tableEndpointUri The table endpoint uri. * * @return \WindowsAzure\Common\Internal\StorageServiceSettings */ private static function _createStorageServiceSettings( $settings, $blobEndpointUri = null, $queueEndpointUri = null, $tableEndpointUri = null ) { $blobEndpointUri = Utilities::tryGetValueInsensitive( Resources::BLOB_ENDPOINT_NAME, $settings, $blobEndpointUri ); $queueEndpointUri = Utilities::tryGetValueInsensitive( Resources::QUEUE_ENDPOINT_NAME, $settings, $queueEndpointUri ); $tableEndpointUri = Utilities::tryGetValueInsensitive( Resources::TABLE_ENDPOINT_NAME, $settings, $tableEndpointUri ); $accountName = Utilities::tryGetValueInsensitive( Resources::ACCOUNT_NAME_NAME, $settings ); $accountKey = Utilities::tryGetValueInsensitive( Resources::ACCOUNT_KEY_NAME, $settings ); return new StorageServiceSettings( $accountName, $accountKey, $blobEndpointUri, $queueEndpointUri, $tableEndpointUri ); } /** * Creates a StorageServiceSettings object from the given connection string. * * @param string $connectionString The storage settings connection string. * @param string $endpoint Azure BLOB storage endpoint * * @return StorageServiceSettings */ public static function createFromConnectionString($connectionString, $endpoint = 'blob.core.windows.net') { $tokenizedSettings = self::parseAndValidateKeys($connectionString); // Devstore case $matchedSpecs = self::matchedSpecification( $tokenizedSettings, self::allRequired(self::$_useDevelopmentStorageSetting), self::optional(self::$_developmentStorageProxyUriSetting) ); if ($matchedSpecs) { $proxyUri = Utilities::tryGetValueInsensitive( Resources::DEVELOPMENT_STORAGE_PROXY_URI_NAME, $tokenizedSettings ); return self::_getDevelopmentStorageAccount($proxyUri); } // Automatic case $matchedSpecs = self::matchedSpecification( $tokenizedSettings, self::allRequired( self::$_defaultEndpointsProtocolSetting, self::$_accountNameSetting, self::$_accountKeySetting ), self::optional( self::$_blobEndpointSetting, self::$_queueEndpointSetting, self::$_tableEndpointSetting ) ); if ($matchedSpecs) { return self::_createStorageServiceSettings( $tokenizedSettings, self::_getDefaultServiceEndpoint( $tokenizedSettings, // Changed in library from UpdraftPlus for compatibility with German Azure $endpoint ), self::_getDefaultServiceEndpoint( $tokenizedSettings, Resources::QUEUE_BASE_DNS_NAME ), self::_getDefaultServiceEndpoint( $tokenizedSettings, Resources::TABLE_BASE_DNS_NAME ) ); } // Explicit case $matchedSpecs = self::matchedSpecification( $tokenizedSettings, self::atLeastOne( self::$_blobEndpointSetting, self::$_queueEndpointSetting, self::$_tableEndpointSetting ), self::allRequired( self::$_accountNameSetting, self::$_accountKeySetting ) ); if ($matchedSpecs) { return self::_createStorageServiceSettings($tokenizedSettings); } self::noMatch($connectionString); } /** * Gets storage service name. * * @return string */ public function getName() { return $this->_name; } /** * Gets storage service key. * * @return string */ public function getKey() { return $this->_key; } /** * Gets storage service blob endpoint uri. * * @return string */ public function getBlobEndpointUri() { return $this->_blobEndpointUri; } /** * Gets storage service queue endpoint uri. * * @return string */ public function getQueueEndpointUri() { return $this->_queueEndpointUri; } /** * Gets storage service table endpoint uri. * * @return string */ public function getTableEndpointUri() { return $this->_tableEndpointUri; } } includes/WindowsAzure/Common/Internal/FilterableService.php000064400000003165152214270100020121 0ustar00 * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @link https://github.com/windowsazure/azure-sdk-for-php */ namespace WindowsAzure\Common\Internal; /** * Interface for service with filers. * * @category Microsoft * @package WindowsAzure\Common\Internal * @author Azure PHP SDK * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @version Release: 0.4.1_2015-03 * @link https://github.com/windowsazure/azure-sdk-for-php */ interface FilterableService { /** * Adds new filter to proxy object and returns new BlobRestProxy with * that filter. * * @param WindowsAzure\Common\Internal\IServiceFilter $filter Filter to add for * the pipeline. * * @return mix. */ public function withFilter($filter); } includes/WindowsAzure/Common/Internal/ServiceBusSettings.php000064400000016213152214270100020320 0ustar00 * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @link https://github.com/windowsazure/azure-sdk-for-php */ namespace WindowsAzure\Common\Internal; use WindowsAzure\Common\Internal\Resources; /** * Represents the settings used to sign and access a request against the service * bus. * * @category Microsoft * @package WindowsAzure\Common\Internal * @author Azure PHP SDK * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @version Release: 0.4.1_2015-03 * @link https://github.com/windowsazure/azure-sdk-for-php */ class ServiceBusSettings extends ServiceSettings { /** * @var string */ private $_serviceBusEndpointUri; /** * @var string */ private $_wrapEndpointUri; /** * @var string */ private $_wrapName; /** * @var string */ private $_wrapPassword; /** * @var string */ private $_namespace; /** * Validator for the SharedSecretValue setting. It has to be provided. * * @var array */ private static $_wrapPasswordSetting; /** * Validator for the SharedSecretIssuer setting. It has to be provided. * * @var array */ private static $_wrapNameSetting; /** * Validator for the Endpoint setting. Must be a valid Uri. * * @var array */ private static $_serviceBusEndpointSetting; /** * Validator for the StsEndpoint setting. Must be a valid Uri. * * @var array */ private static $_wrapEndpointUriSetting; /** * @var boolean */ protected static $isInitialized = false; /** * Holds the expected setting keys. * * @var array */ protected static $validSettingKeys = array(); /** * Initializes static members of the class. * * @return none */ protected static function init() { self::$_serviceBusEndpointSetting = self::settingWithFunc( Resources::SERVICE_BUS_ENDPOINT_NAME, Validate::getIsValidUri() ); self::$_wrapNameSetting = self::setting( Resources::SHARED_SECRET_ISSUER_NAME ); self::$_wrapPasswordSetting = self::setting( Resources::SHARED_SECRET_VALUE_NAME ); self::$_wrapEndpointUriSetting = self::settingWithFunc( Resources::STS_ENDPOINT_NAME, Validate::getIsValidUri() ); self::$validSettingKeys[] = Resources::SERVICE_BUS_ENDPOINT_NAME; self::$validSettingKeys[] = Resources::SHARED_SECRET_ISSUER_NAME; self::$validSettingKeys[] = Resources::SHARED_SECRET_VALUE_NAME; self::$validSettingKeys[] = Resources::STS_ENDPOINT_NAME; } /** * Creates new Service Bus settings instance. * * @param string $serviceBusEndpoint The Service Bus endpoint uri. * @param string $namespace The service namespace. * @param string $wrapName The wrap name. * @param string $wrapPassword The wrap password. */ public function __construct( $serviceBusEndpoint, $namespace, $wrapEndpointUri, $wrapName, $wrapPassword ) { $this->_namespace = $namespace; $this->_serviceBusEndpointUri = $serviceBusEndpoint; $this->_wrapEndpointUri = $wrapEndpointUri; $this->_wrapName = $wrapName; $this->_wrapPassword = $wrapPassword; } /** * Creates a ServiceBusSettings object from the given connection string. * * @param string $connectionString The storage settings connection string. * * @return ServiceBusSettings */ public static function createFromConnectionString($connectionString) { $tokenizedSettings = self::parseAndValidateKeys($connectionString); $matchedSpecs = self::matchedSpecification( $tokenizedSettings, self::allRequired( self::$_serviceBusEndpointSetting, self::$_wrapNameSetting, self::$_wrapPasswordSetting ), self::optional(self::$_wrapEndpointUriSetting) ); if ($matchedSpecs) { $endpoint = Utilities::tryGetValueInsensitive( Resources::SERVICE_BUS_ENDPOINT_NAME, $tokenizedSettings ); // Parse the namespace part from the URI $namespace = explode('.', parse_url($endpoint, PHP_URL_HOST)); $namespace = $namespace[0]; $wrapEndpointUri = Utilities::tryGetValueInsensitive( Resources::STS_ENDPOINT_NAME, $tokenizedSettings, sprintf(Resources::WRAP_ENDPOINT_URI_FORMAT, $namespace) ); $issuerName = Utilities::tryGetValueInsensitive( Resources::SHARED_SECRET_ISSUER_NAME, $tokenizedSettings ); $issuerValue = Utilities::tryGetValueInsensitive( Resources::SHARED_SECRET_VALUE_NAME, $tokenizedSettings ); return new ServiceBusSettings( $endpoint, $namespace, $wrapEndpointUri, $issuerName, $issuerValue ); } self::noMatch($connectionString); } /** * Gets the Service Bus endpoint URI. * * @return string */ public function getServiceBusEndpointUri() { return $this->_serviceBusEndpointUri; } /** * Gets the wrap endpoint URI. * * @return string */ public function getWrapEndpointUri() { return $this->_wrapEndpointUri; } /** * Gets the wrap name. * * @return string */ public function getWrapName() { return $this->_wrapName; } /** * Gets the wrap password. * * @return string */ public function getWrapPassword() { return $this->_wrapPassword; } /** * Gets the namespace name. * * @return string */ public function getNamespace() { return $this->_namespace; } } includes/WindowsAzure/Common/Internal/MediaServicesSettings.php000064400000016452152214270100020776 0ustar00 * @copyright Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @link https://github.com/windowsazure/azure-sdk-for-php */ namespace WindowsAzure\Common\Internal; use WindowsAzure\Common\Internal\Resources; /** * Represents the settings used to sign and access a request against the service * management. * * @category Microsoft * @package WindowsAzure\Common\Internal * @author Azure PHP SDK * @copyright Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @version Release: 0.4.1_2015-03 * @link https://github.com/windowsazure/azure-sdk-for-php */ class MediaServicesSettings extends ServiceSettings { /** * @var string */ private $_accountName; /** * @var string */ private $_accessKey; /** * @var string */ private $_endpointUri; /** * @var string */ private $_oauthEndpointUri; /** * Validator for the MediaServicesAccountName setting. It has to be provided. * * @var array */ private static $_accountNameSetting; /** * Validator for the MediaServicesAccessKey setting. It has to be provided. * * @var array */ private static $_accessKeySetting; /** * Validator for the MediaServicesEndpoint setting. Must be a valid Uri. * * @var array */ private static $_endpointUriSetting; /** * Validator for the MediaServicesOAuthEndpoint setting. Must be a valid Uri. * * @var array */ private static $_oauthEndpointUriSetting; /** * @var boolean */ protected static $isInitialized = false; /** * Holds the expected setting keys. * * @var array */ protected static $validSettingKeys = array(); /** * Initializes static members of the class. * * @return none */ protected static function init() { self::$_endpointUriSetting = self::settingWithFunc( Resources::MEDIA_SERVICES_ENDPOINT_URI_NAME, Validate::getIsValidUri() ); self::$_oauthEndpointUriSetting = self::settingWithFunc( Resources::MEDIA_SERVICES_OAUTH_ENDPOINT_URI_NAME, Validate::getIsValidUri() ); self::$_accountNameSetting = self::setting( Resources::MEDIA_SERVICES_ACCOUNT_NAME ); self::$_accessKeySetting = self::setting( Resources::MEDIA_SERVICES_ACCESS_KEY ); self::$validSettingKeys[] = Resources::MEDIA_SERVICES_ENDPOINT_URI_NAME; self::$validSettingKeys[] = Resources::MEDIA_SERVICES_OAUTH_ENDPOINT_URI_NAME; self::$validSettingKeys[] = Resources::MEDIA_SERVICES_ACCOUNT_NAME; self::$validSettingKeys[] = Resources::MEDIA_SERVICES_ACCESS_KEY; } /** * Creates new media services settings instance. * * @param string $accountName The user provided account name. * @param string $accessKey The user provided primary access key * @param string $endpointUri The service management endpoint uri. * @param string $oauthEndpointUri The OAuth service endpoint uri. */ public function __construct( $accountName, $accessKey, $endpointUri = null, $oauthEndpointUri = null ) { Validate::notNullOrEmpty($accountName, 'accountName'); Validate::notNullOrEmpty($accessKey, 'accountKey'); Validate::isString($accountName, 'accountName'); Validate::isString($accessKey, 'accountKey'); if ($endpointUri != null) { Validate::isValidUri($endpointUri); } else { $endpointUri = Resources::MEDIA_SERVICES_URL; } if ($oauthEndpointUri != null) { Validate::isValidUri($oauthEndpointUri); } else { $oauthEndpointUri = Resources::MEDIA_SERVICES_OAUTH_URL; } $this->_accountName = $accountName; $this->_accessKey = $accessKey; $this->_endpointUri = $endpointUri; $this->_oauthEndpointUri = $oauthEndpointUri; } /** * Creates a MediaServicesSettings object from the given connection string. * * @param string $connectionString The media services settings connection string. * * @return MediaServicesSettings */ public static function createFromConnectionString($connectionString) { $tokenizedSettings = self::parseAndValidateKeys($connectionString); $matchedSpecs = self::matchedSpecification( $tokenizedSettings, self::allRequired( self::$_accountNameSetting, self::$_accessKeySetting ), self::optional( self::$_endpointUriSetting, self::$_oauthEndpointUriSetting ) ); if ($matchedSpecs) { $endpointUri = Utilities::tryGetValueInsensitive( Resources::MEDIA_SERVICES_ENDPOINT_URI_NAME, $tokenizedSettings, Resources::MEDIA_SERVICES_URL ); $oauthEndpointUri = Utilities::tryGetValueInsensitive( Resources::MEDIA_SERVICES_OAUTH_ENDPOINT_URI_NAME, $tokenizedSettings, Resources::MEDIA_SERVICES_OAUTH_URL ); $accountName = Utilities::tryGetValueInsensitive( Resources::MEDIA_SERVICES_ACCOUNT_NAME, $tokenizedSettings ); $accessKey = Utilities::tryGetValueInsensitive( Resources::MEDIA_SERVICES_ACCESS_KEY, $tokenizedSettings ); return new MediaServicesSettings( $accountName, $accessKey, $endpointUri, $oauthEndpointUri ); } self::noMatch($connectionString); } /** * Gets media services account name. * * @return string */ public function getAccountName() { return $this->_accountName; } /** * Gets media services access key. * * @return string */ public function getAccessKey() { return $this->_accessKey; } /** * Gets media services endpoint uri. * * @return string */ public function getEndpointUri() { return $this->_endpointUri; } /** * Gets media services OAuth endpoint uri. * * @return string */ public function getOAuthEndpointUri() { return $this->_oauthEndpointUri; } } includes/WindowsAzure/Common/Internal/OAuthRestProxy.php000064400000007070152214270100017446 0ustar00 * @copyright Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @link https://github.com/windowsazure/azure-sdk-for-php */ namespace WindowsAzure\Common\Internal; use WindowsAzure\Common\Internal\Resources; use WindowsAzure\Common\Internal\ServiceRestProxy; use WindowsAzure\Common\Models\OAuthAccessToken; use WindowsAzure\Common\Internal\Serialization\JsonSerializer; /** * OAuth rest proxy. * * @category Microsoft * @package WindowsAzure\Common\Internal * @author Azure PHP SDK * @copyright Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @version Release: 0.4.1_2015-03 * @link https://github.com/windowsazure/azure-sdk-for-php */ class OAuthRestProxy extends ServiceRestProxy { /** * Initializes new OAuthRestProxy object. * * @param IHttpClient $channel The HTTP client used to send HTTP requests. * @param string $uri The storage account uri. */ public function __construct($channel, $uri) { parent::__construct( $channel, $uri, Resources::EMPTY_STRING, new JsonSerializer() ); } /** * Get OAuth access token. * * @param string $grantType OAuth request grant_type field value. * @param string $clientId OAuth request clent_id field value. * @param string $clientSecret OAuth request clent_secret field value. * @param string $scope OAuth request scope field value. * * @return WindowsAzure\Common\Internal\Models\OAuthAccessToken */ public function getAccessToken($grantType, $clientId, $clientSecret, $scope) { $method = Resources::HTTP_POST; $headers = array(); $queryParams = array(); $postParameters = array(); $statusCode = Resources::STATUS_OK; $postParameters = $this->addPostParameter( $postParameters, Resources::OAUTH_GRANT_TYPE, $grantType ); $postParameters = $this->addPostParameter( $postParameters, Resources::OAUTH_CLIENT_ID, $clientId ); $postParameters = $this->addPostParameter( $postParameters, Resources::OAUTH_CLIENT_SECRET, $clientSecret ); $postParameters = $this->addPostParameter( $postParameters, Resources::OAUTH_SCOPE, $scope ); $response = $this->send( $method, $headers, $queryParams, $postParameters, Resources::EMPTY_STRING, $statusCode ); return OAuthAccessToken::create( $this->dataSerializer->unserialize($response->getBody()) ); } } includes/WindowsAzure/Common/Internal/ServiceSettings.php000064400000023005152214270100017643 0ustar00 * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @link https://github.com/windowsazure/azure-sdk-for-php */ namespace WindowsAzure\Common\Internal; use WindowsAzure\Common\Internal\Resources; /** * Base class for all REST services settings. * * Derived classes must implement the following members: * 1- $isInitialized: A static property that indicates whether the class's static * members have been initialized. * 2- init(): A protected static method that initializes static members. * 3- $validSettingKeys: A static property that contains valid setting keys for this * service. * 4- createFromConnectionString($connectionString): A public static function that * takes a connection string and returns the created settings object. * * @category Microsoft * @package WindowsAzure\Common\Internal * @author Azure PHP SDK * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @version Release: 0.4.1_2015-03 * @link https://github.com/windowsazure/azure-sdk-for-php */ abstract class ServiceSettings { /** * Throws an exception if the connection string format does not match any of the * available formats. * * @param type $connectionString The invalid formatted connection string. * * @return none * * @throws \RuntimeException */ protected static function noMatch($connectionString) { throw new \RuntimeException( sprintf(Resources::MISSING_CONNECTION_STRING_SETTINGS, $connectionString) ); } /** * Parses the connection string and then validate that the parsed keys belong to * the $validSettingKeys * * @param string $connectionString The user provided connection string. * * @return array The tokenized connection string keys. * * @throws \RuntimeException */ protected static function parseAndValidateKeys($connectionString) { // Initialize the static values if they are not initialized yet. if (!static::$isInitialized) { static::init(); static::$isInitialized = true; } $tokenizedSettings = ConnectionStringParser::parseConnectionString( 'connectionString', $connectionString ); // Assure that all given keys are valid. foreach ($tokenizedSettings as $key => $value) { if (!Utilities::inArrayInsensitive($key, static::$validSettingKeys) ) { throw new \RuntimeException( sprintf( Resources::INVALID_CONNECTION_STRING_SETTING_KEY, $key, implode("\n", static::$validSettingKeys) ) ); } } return $tokenizedSettings; } /** * Creates an anonymous function that acts as predicate. * * @param array $requirements The array of conditions to satisfy. * @param boolean $isRequired Either these conditions are all required or all * optional. * @param boolean $atLeastOne Indicates that at least one requirement must * succeed. * * @return callable */ protected static function getValidator($requirements, $isRequired, $atLeastOne) { // @codingStandardsIgnoreStart return function ($userSettings) use ($requirements, $isRequired, $atLeastOne) { $oneFound = false; $result = array_change_key_case($userSettings); foreach ($requirements as $requirement) { $settingName = strtolower($requirement[Resources::SETTING_NAME]); // Check if the setting name exists in the provided user settings. if (array_key_exists($settingName, $result)) { // Check if the provided user setting value is valid. $validationFunc = $requirement[Resources::SETTING_CONSTRAINT]; $isValid = $validationFunc($result[$settingName]); if ($isValid) { // Remove the setting as indicator for successful validation. unset($result[$settingName]); $oneFound = true; } } else { // If required then fail because the setting does not exist if ($isRequired) { return null; } } } if ($atLeastOne) { // At least one requirement must succeed, otherwise fail. return $oneFound ? $result : null; } else { return $result; } }; // @codingStandardsIgnoreEnd } /** * Creates at lease one succeed predicate for the provided list of requirements. * * @return callable */ protected static function atLeastOne() { $allSettings = func_get_args(); return self::getValidator($allSettings, false, true); } /** * Creates an optional predicate for the provided list of requirements. * * @return callable */ protected static function optional() { $optionalSettings = func_get_args(); return self::getValidator($optionalSettings, false, false); } /** * Creates an required predicate for the provided list of requirements. * * @return callable */ protected static function allRequired() { $requiredSettings = func_get_args(); return self::getValidator($requiredSettings, true, false); } /** * Creates a setting value condition using the passed predicate. * * @param string $name The setting key name. * @param callable $predicate The setting value predicate. * * @return array */ protected static function settingWithFunc($name, $predicate) { $requirement = array(); $requirement[Resources::SETTING_NAME] = $name; $requirement[Resources::SETTING_CONSTRAINT] = $predicate; return $requirement; } /** * Creates a setting value condition that validates it is one of the * passed valid values. * * @param string $name The setting key name. * * @return array */ protected static function setting($name) { $validValues = func_get_args(); // Remove $name argument. unset($validValues[0]); $validValuesCount = func_num_args(); $predicate = function ($settingValue) use ($validValuesCount, $validValues) { if (empty($validValues)) { // No restrictions, succeed, return true; } // Check to find if the $settingValue is valid or not. The index must // start from 1 as unset deletes the value but does not update the array // indecies. for ($index = 1; $index < $validValuesCount; $index++) { if ($settingValue == $validValues[$index]) { // $settingValue is found in valid values set, succeed. return true; } } throw new \RuntimeException( sprintf( Resources::INVALID_CONFIG_VALUE, $settingValue, implode("\n", $validValues) ) ); // $settingValue is missing in valid values set, fail. return false; }; return self::settingWithFunc($name, $predicate); } /** * Tests to see if a given list of settings matches a set of filters exactly. * * @param array $settings The settings to check. * * @return boolean If any filter returns null, false. If there are any settings * left over after all filters are processed, false. Otherwise true. */ protected static function matchedSpecification($settings) { $constraints = func_get_args(); // Remove first element which corresponds to $settings unset($constraints[0]); foreach ($constraints as $constraint) { $remainingSettings = $constraint($settings); if (is_null($remainingSettings)) { return false; } else { $settings = $remainingSettings; } } if (empty($settings)) { return true; } return false; } }includes/WindowsAzure/Common/Internal/ServiceManagementSettings.php000064400000013542152214270100021645 0ustar00 * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @link https://github.com/windowsazure/azure-sdk-for-php */ namespace WindowsAzure\Common\Internal; use WindowsAzure\Common\Internal\Resources; /** * Represents the settings used to sign and access a request against the service * management. For more information about service management connection strings check * this page: http://msdn.microsoft.com/en-us/library/windowsazure/gg466228.aspx * * @category Microsoft * @package WindowsAzure\Common\Internal * @author Azure PHP SDK * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @version Release: 0.4.1_2015-03 * @link https://github.com/windowsazure/azure-sdk-for-php */ class ServiceManagementSettings extends ServiceSettings { /** * @var string */ private $_subscriptionId; /** * @var string */ private $_certificatePath; /** * @var string */ private $_endpointUri; /** * Validator for the ServiceManagementEndpoint setting. Must be a valid Uri. * * @var array */ private static $_endpointSetting; /** * Validator for the CertificatePath setting. It has to be provided. * * @var array */ private static $_certificatePathSetting; /** * Validator for the SubscriptionId setting. It has to be provided. * * @var array */ private static $_subscriptionIdSetting; /** * @var boolean */ protected static $isInitialized = false; /** * Holds the expected setting keys. * * @var array */ protected static $validSettingKeys = array(); /** * Initializes static members of the class. * * @return none */ protected static function init() { self::$_endpointSetting = self::settingWithFunc( Resources::SERVICE_MANAGEMENT_ENDPOINT_NAME, Validate::getIsValidUri() ); self::$_certificatePathSetting = self::setting( Resources::CERTIFICATE_PATH_NAME ); self::$_subscriptionIdSetting = self::setting( Resources::SUBSCRIPTION_ID_NAME ); self::$validSettingKeys[] = Resources::SUBSCRIPTION_ID_NAME; self::$validSettingKeys[] = Resources::CERTIFICATE_PATH_NAME; self::$validSettingKeys[] = Resources::SERVICE_MANAGEMENT_ENDPOINT_NAME; } /** * Creates new service management settings instance. * * @param string $subscriptionId The user provided subscription id. * @param string $endpointUri The service management endpoint uri. * @param string $certificatePath The management certificate path. */ public function __construct($subscriptionId, $endpointUri, $certificatePath) { $this->_certificatePath = $certificatePath; $this->_endpointUri = $endpointUri; $this->_subscriptionId = $subscriptionId; } /** * Creates a ServiceManagementSettings object from the given connection string. * * @param string $connectionString The storage settings connection string. * * @return ServiceManagementSettings */ public static function createFromConnectionString($connectionString) { $tokenizedSettings = self::parseAndValidateKeys($connectionString); $matchedSpecs = self::matchedSpecification( $tokenizedSettings, self::allRequired( self::$_subscriptionIdSetting, self::$_certificatePathSetting ), self::optional( self::$_endpointSetting ) ); if ($matchedSpecs) { $endpointUri = Utilities::tryGetValueInsensitive( Resources::SERVICE_MANAGEMENT_ENDPOINT_NAME, $tokenizedSettings, Resources::SERVICE_MANAGEMENT_URL ); $subscriptionId = Utilities::tryGetValueInsensitive( Resources::SUBSCRIPTION_ID_NAME, $tokenizedSettings ); $certificatePath = Utilities::tryGetValueInsensitive( Resources::CERTIFICATE_PATH_NAME, $tokenizedSettings ); return new ServiceManagementSettings( $subscriptionId, $endpointUri, $certificatePath ); } self::noMatch($connectionString); } /** * Gets service management endpoint uri. * * @return string */ public function getEndpointUri() { return $this->_endpointUri; } /** * Gets the subscription id. * * @return string */ public function getSubscriptionId() { return $this->_subscriptionId; } /** * Gets the certificate path. * * @return string */ public function getCertificatePath() { return $this->_certificatePath; } } includes/WindowsAzure/Common/Internal/ConnectionStringSource.php000064400000005130152214270100021170 0ustar00 * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @link https://github.com/windowsazure/azure-sdk-for-php */ namespace WindowsAzure\Common\Internal; /** * Holder for default connection string sources used in CloudConfigurationManager. * * @category Microsoft * @package WindowsAzure\Common\Internal * @author Azure PHP SDK * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @version Release: 0.4.1_2015-03 * @link https://github.com/windowsazure/azure-sdk-for-php */ class ConnectionStringSource { /** * The list of all sources which comes as default. * * @var type */ private static $_defaultSources; /** * @var boolean */ private static $_isInitialized; /** * Environment variable source name. */ const ENVIRONMENT_SOURCE = 'environment_source'; /** * Initializes the default sources. * * @return none */ private static function _init() { if (!self::$_isInitialized) { self::$_defaultSources = array( self::ENVIRONMENT_SOURCE => array(__CLASS__, 'environmentSource') ); self::$_isInitialized = true; } } /** * Gets a connection string value from the system environment. * * @param string $key The connection string name. * * @return string */ public static function environmentSource($key) { Validate::isString($key, 'key'); return getenv($key); } /** * Gets list of default sources. * * @return array */ public static function getDefaultSources() { self::_init(); return self::$_defaultSources; } } includes/WindowsAzure/Common/Internal/Validate.php000064400000025236152214270100016263 0ustar00 * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @link https://github.com/windowsazure/azure-sdk-for-php */ namespace WindowsAzure\Common\Internal; use WindowsAzure\Common\Internal\InvalidArgumentTypeException; use WindowsAzure\Common\Internal\Resources; /** * Validates aganist a condition and throws an exception in case of failure. * * @category Microsoft * @package WindowsAzure\Common\Internal * @author Azure PHP SDK * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @version Release: 0.4.1_2015-03 * @link https://github.com/windowsazure/azure-sdk-for-php */ class Validate { /** * Throws exception if the provided variable type is not array. * * @param mix $var The variable to check. * @param string $name The parameter name. * * @throws InvalidArgumentTypeException. * * @return none */ public static function isArray($var, $name) { if (!is_array($var)) { throw new InvalidArgumentTypeException(gettype(array()), $name); } } /** * Throws exception if the provided variable type is not string. * * @param mix $var The variable to check. * @param string $name The parameter name. * * @throws InvalidArgumentTypeException * * @return none */ public static function isString($var, $name) { try { (string)$var; } catch (\Exception $e) { throw new InvalidArgumentTypeException(gettype(''), $name); } } /** * Throws exception if the provided variable type is not boolean. * * @param mix $var variable to check against. * * @throws InvalidArgumentTypeException * * @return none */ public static function isBoolean($var) { (bool)$var; } /** * Throws exception if the provided variable is set to null. * * @param mix $var The variable to check. * @param string $name The parameter name. * * @throws \InvalidArgumentException * * @return none */ public static function notNullOrEmpty($var, $name) { if (is_null($var) || empty($var)) { throw new \InvalidArgumentException( sprintf(Resources::NULL_OR_EMPTY_MSG, $name) ); } } /** * Throws exception if the provided variable is not double. * * @param mix $var The variable to check. * @param string $name The parameter name. * * @throws \InvalidArgumentException * * @return none */ public static function isDouble($var, $name) { if (!is_numeric($var)) { throw new InvalidArgumentTypeException('double', $name); } } /** * Throws exception if the provided variable type is not integer. * * @param mix $var The variable to check. * @param string $name The parameter name. * * @throws InvalidArgumentTypeException * * @return none */ public static function isInteger($var, $name) { try { (int)$var; } catch (\Exception $e) { throw new InvalidArgumentTypeException(gettype(123), $name); } } /** * Returns whether the variable is an empty or null string. * * @param string $var value. * * @return boolean */ public static function isNullOrEmptyString($var) { try { (string)$var; } catch (\Exception $e) { return false; } return (!isset($var) || trim($var)===''); } /** * Throws exception if the provided condition is not satisfied. * * @param bool $isSatisfied condition result. * @param string $failureMessage the exception message * * @throws \Exception * * @return none */ public static function isTrue($isSatisfied, $failureMessage) { if (!$isSatisfied) { throw new \InvalidArgumentException($failureMessage); } } /** * Throws exception if the provided $date is not of type \DateTime * * @param mix $date variable to check against. * * @throws WindowsAzure\Common\Internal\InvalidArgumentTypeException * * @return none */ public static function isDate($date) { if (gettype($date) != 'object' || get_class($date) != 'DateTime') { throw new InvalidArgumentTypeException('DateTime'); } } /** * Throws exception if the provided variable is set to null. * * @param mix $var The variable to check. * @param string $name The parameter name. * * @throws \InvalidArgumentException * * @return none */ public static function notNull($var, $name) { if (is_null($var)) { throw new \InvalidArgumentException(sprintf(Resources::NULL_MSG, $name)); } } /** * Throws exception if the object is not of the specified class type. * * @param mixed $objectInstance An object that requires class type validation. * @param mixed $classInstance The instance of the class the the * object instance should be. * @param string $name The name of the object. * * @throws \InvalidArgumentException * * @return none */ public static function isInstanceOf($objectInstance, $classInstance, $name) { Validate::notNull($classInstance, 'classInstance'); if (is_null($objectInstance)) { return true; } $objectType = gettype($objectInstance); $classType = gettype($classInstance); if ($objectType === $classType) { return true; } else { throw new \InvalidArgumentException( sprintf( Resources::INSTANCE_TYPE_VALIDATION_MSG, $name, $objectType, $classType ) ); } } /** * Creates a anonymous function that check if the given uri is valid or not. * * @return callable */ public static function getIsValidUri() { return function ($uri) { return Validate::isValidUri($uri); }; } /** * Throws exception if the string is not of a valid uri. * * @param string $uri String to check. * * @throws \InvalidArgumentException * * @return boolean */ public static function isValidUri($uri) { $isValid = filter_var($uri, FILTER_VALIDATE_URL); if ($isValid) { return true; } else { throw new \RuntimeException( sprintf(Resources::INVALID_CONFIG_URI, $uri) ); } } /** * Throws exception if the provided variable type is not object. * * @param mix $var The variable to check. * @param string $name The parameter name. * * @throws InvalidArgumentTypeException. * * @return boolean */ public static function isObject($var, $name) { if (!is_object($var)) { throw new InvalidArgumentTypeException('object', $name); } return true; } /** * Throws exception if the object is not of the specified class type. * * @param mixed $objectInstance An object that requires class type validation. * @param string $class The class the object instance should be. * @param string $name The parameter name. * * @throws \InvalidArgumentException * * @return boolean */ public static function isA($objectInstance, $class, $name) { Validate::isString($class, 'class'); Validate::notNull($objectInstance, 'objectInstance'); Validate::isObject($objectInstance, 'objectInstance'); $objectType = get_class($objectInstance); if (is_a($objectInstance, $class)) { return true; } else { throw new \InvalidArgumentException( sprintf( Resources::INSTANCE_TYPE_VALIDATION_MSG, $name, $objectType, $class ) ); } } /** * Validate if method exists in object * * @param object $objectInstance An object that requires method existing * validation * @param string $method Method name * @param string $name The parameter name * * @return boolean */ public static function methodExists($objectInstance, $method, $name) { Validate::isString($method, 'method'); Validate::notNull($objectInstance, 'objectInstance'); Validate::isObject($objectInstance, 'objectInstance'); if (method_exists($objectInstance, $method)) { return true; } else { throw new \InvalidArgumentException( sprintf( Resources::ERROR_METHOD_NOT_FOUND, $method, $name ) ); } } /** * Validate if string is date formatted * * @param string $value Value to validate * @param string $name Name of parameter to insert in erro message * * @throws \InvalidArgumentException * * @return boolean */ public static function isDateString($value, $name) { Validate::isString($value, 'value'); try { new \DateTime($value); return true; } catch (\Exception $e) { throw new \InvalidArgumentException( sprintf( Resources::ERROR_INVALID_DATE_STRING, $name, $value ) ); } } } includes/WindowsAzure/Common/Internal/RestProxy.php000064400000013605152214270100016506 0ustar00 * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @link https://github.com/windowsazure/azure-sdk-for-php */ namespace WindowsAzure\Common\Internal; use WindowsAzure\Common\Internal\Resources; use WindowsAzure\Common\Internal\Validate; use WindowsAzure\Common\Internal\Http\Url; /** * Base class for all REST proxies. * * @category Microsoft * @package WindowsAzure\Common\Internal * @author Azure PHP SDK * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @version Release: 0.4.1_2015-03 * @link https://github.com/windowsazure/azure-sdk-for-php */ class RestProxy { /** * @var WindowsAzure\Common\Internal\Http\IHttpClient */ private $_channel; /** * @var array */ private $_filters; /** * @var WindowsAzure\Common\Internal\Serialization\ISerializer */ protected $dataSerializer; /** * @var string */ private $_uri; /** * Initializes new RestProxy object. * * @param IHttpClient $channel The HTTP client used to send HTTP requests. * @param ISerializer $dataSerializer The data serializer. * @param string $uri The uri of the service. */ public function __construct($channel, $dataSerializer, $uri) { $this->_channel = $channel; $this->_filters = array(); $this->dataSerializer = $dataSerializer; $this->_uri = $uri; } /** * Gets HTTP filters that will process each request. * * @return array */ public function getFilters() { return $this->_filters; } /** * Gets the Uri of the service. * * @return string */ public function getUri() { return $this->_uri; } /** * Sets the Uri of the service. * * @param string $uri The URI of the request. * * @return none */ public function setUri($uri) { $this->_uri = $uri; } /** * Sends HTTP request with the specified HTTP call context. * * @param WindowsAzure\Common\Internal\Http\HttpCallContext $context The HTTP * call context. * * @return \HTTP_Request2_Response */ protected function sendContext($context) { $channel = clone $this->_channel; $contextUrl = $context->getUri(); $url = new Url(empty($contextUrl) ? $this->_uri : $contextUrl); $headers = $context->getHeaders(); $statusCodes = $context->getStatusCodes(); $body = $context->getBody(); $queryParams = $context->getQueryParameters(); $postParameters = $context->getPostParameters(); $path = $context->getPath(); $channel->setMethod($context->getMethod()); $channel->setExpectedStatusCode($statusCodes); $channel->setBody($body); $channel->setHeaders($headers); if (count($postParameters) > 0) { $channel->setPostParameters($postParameters); } $url->setQueryVariables($queryParams); $url->appendUrlPath($path); $channel->send($this->_filters, $url); return $channel->getResponse(); } /** * Adds new filter to new service rest proxy object and returns that object back. * * @param WindowsAzure\Common\Internal\IServiceFilter $filter Filter to add for * the pipeline. * * @return RestProxy. */ public function withFilter($filter) { $serviceProxyWithFilter = clone $this; $serviceProxyWithFilter->_filters[] = $filter; return $serviceProxyWithFilter; } /** * Adds optional query parameter. * * Doesn't add the value if it satisfies empty(). * * @param array &$queryParameters The query parameters. * @param string $key The query variable name. * @param string $value The query variable value. * * @return none */ protected function addOptionalQueryParam(&$queryParameters, $key, $value) { Validate::isArray($queryParameters, 'queryParameters'); Validate::isString($key, 'key'); Validate::isString($value, 'value'); if (!is_null($value) && Resources::EMPTY_STRING !== $value) { $queryParameters[$key] = $value; } } /** * Adds optional header. * * Doesn't add the value if it satisfies empty(). * * @param array &$headers The HTTP header parameters. * @param string $key The HTTP header name. * @param string $value The HTTP header value. * * @return none */ protected function addOptionalHeader(&$headers, $key, $value) { Validate::isArray($headers, 'headers'); Validate::isString($key, 'key'); Validate::isString($value, 'value'); if (!is_null($value) && Resources::EMPTY_STRING !== $value) { $headers[$key] = $value; } } } includes/WindowsAzure/Common/Models/ServiceProperties.php000064400000007310152214270100017647 0ustar00 * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @link https://github.com/windowsazure/azure-sdk-for-php */ namespace WindowsAzure\Common\Models; use WindowsAzure\Common\Internal\Utilities; use WindowsAzure\Common\Models\Logging; use WindowsAzure\Common\Models\Metrics; use WindowsAzure\Common\Internal\Serialization\XmlSerializer; /** * Encapsulates service properties * * @category Microsoft * @package WindowsAzure\Common\Models * @author Azure PHP SDK * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @version Release: 0.4.1_2015-03 * @link https://github.com/windowsazure/azure-sdk-for-php */ class ServiceProperties { private $_logging; private $_metrics; public static $xmlRootName = 'StorageServiceProperties'; /** * Creates ServiceProperties object from parsed XML response. * * @param array $parsedResponse XML response parsed into array. * * @return WindowsAzure\Common\Models\ServiceProperties. */ public static function create($parsedResponse) { $result = new ServiceProperties(); $result->setLogging(Logging::create($parsedResponse['Logging'])); $result->setMetrics(Metrics::create($parsedResponse['Metrics'])); return $result; } /** * Gets logging element. * * @return WindowsAzure\Common\Models\Logging. */ public function getLogging() { return $this->_logging; } /** * Sets logging element. * * @param WindowsAzure\Common\Models\Logging $logging new element. * * @return none. */ public function setLogging($logging) { $this->_logging = clone $logging; } /** * Gets metrics element. * * @return WindowsAzure\Common\Models\Metrics. */ public function getMetrics() { return $this->_metrics; } /** * Sets metrics element. * * @param WindowsAzure\Common\Models\Metrics $metrics new element. * * @return none. */ public function setMetrics($metrics) { $this->_metrics = clone $metrics; } /** * Converts this object to array with XML tags * * @return array. */ public function toArray() { return array( 'Logging' => !empty($this->_logging) ? $this->_logging->toArray() : null, 'Metrics' => !empty($this->_metrics) ? $this->_metrics->toArray() : null ); } /** * Converts this current object to XML representation. * * @param XmlSerializer $xmlSerializer The XML serializer. * * @return string */ public function toXml($xmlSerializer) { $properties = array(XmlSerializer::ROOT_NAME => self::$xmlRootName); return $xmlSerializer->serialize($this->toArray(), $properties); } } includes/WindowsAzure/Common/Models/Logging.php000064400000012371152214270100015563 0ustar00 * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @link https://github.com/windowsazure/azure-sdk-for-php */ namespace WindowsAzure\Common\Models; use WindowsAzure\Common\Models\RetentionPolicy; use WindowsAzure\Common\Internal\Utilities; /** * Holds elements of queue properties logging field. * * @category Microsoft * @package WindowsAzure\Common\Models * @author Azure PHP SDK * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @version Release: 0.4.1_2015-03 * @link https://github.com/windowsazure/azure-sdk-for-php */ class Logging { /** * The version of Storage Analytics to configure * * @var string */ private $_version; /** * Applies only to logging configuration. Indicates whether all delete requests * should be logged. * * @var bool */ private $_delete; /** * Applies only to logging configuration. Indicates whether all read requests * should be logged. * * @var bool. */ private $_read; /** * Applies only to logging configuration. Indicates whether all write requests * should be logged. * * @var bool */ private $_write; /** * @var WindowsAzure\Common\Models\RetentionPolicy */ private $_retentionPolicy; /** * Creates object from $parsedResponse. * * @param array $parsedResponse XML response parsed into array. * * @return WindowsAzure\Common\Models\Logging */ public static function create($parsedResponse) { $result = new Logging(); $result->setVersion($parsedResponse['Version']); $result->setDelete(Utilities::toBoolean($parsedResponse['Delete'])); $result->setRead(Utilities::toBoolean($parsedResponse['Read'])); $result->setWrite(Utilities::toBoolean($parsedResponse['Write'])); $result->setRetentionPolicy( RetentionPolicy::create($parsedResponse['RetentionPolicy']) ); return $result; } /** * Gets retention policy * * @return WindowsAzure\Common\Models\RetentionPolicy * */ public function getRetentionPolicy() { return $this->_retentionPolicy; } /** * Sets retention policy * * @param RetentionPolicy $policy object to use * * @return none. */ public function setRetentionPolicy($policy) { $this->_retentionPolicy = $policy; } /** * Gets write * * @return bool. */ public function getWrite() { return $this->_write; } /** * Sets write * * @param bool $write new value. * * @return none. */ public function setWrite($write) { $this->_write = $write; } /** * Gets read * * @return bool. */ public function getRead() { return $this->_read; } /** * Sets read * * @param bool $read new value. * * @return none. */ public function setRead($read) { $this->_read = $read; } /** * Gets delete * * @return bool. */ public function getDelete() { return $this->_delete; } /** * Sets delete * * @param bool $delete new value. * * @return none. */ public function setDelete($delete) { $this->_delete = $delete; } /** * Gets version * * @return string. */ public function getVersion() { return $this->_version; } /** * Sets version * * @param string $version new value. * * @return none. */ public function setVersion($version) { $this->_version = $version; } /** * Converts this object to array with XML tags * * @return array. */ public function toArray() { return array( 'Version' => $this->_version, 'Delete' => Utilities::booleanToString($this->_delete), 'Read' => Utilities::booleanToString($this->_read), 'Write' => Utilities::booleanToString($this->_write), 'RetentionPolicy' => !empty($this->_retentionPolicy) ? $this->_retentionPolicy->toArray() : null ); } } includes/WindowsAzure/Common/Models/Metrics.php000064400000011345152214270100015603 0ustar00 * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @link https://github.com/windowsazure/azure-sdk-for-php */ namespace WindowsAzure\Common\Models; use WindowsAzure\Common\Internal\Utilities; /** * Holds elements of queue properties metrics field. * * @category Microsoft * @package WindowsAzure\Common\Models * @author Azure PHP SDK * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @version Release: 0.4.1_2015-03 * @link https://github.com/windowsazure/azure-sdk-for-php */ class Metrics { /** * The version of Storage Analytics to configure * * @var string */ private $_version; /** * Indicates whether metrics is enabled for the storage service * * @var bool */ private $_enabled; /** * Indicates whether a retention policy is enabled for the storage service * * @var bool */ private $_includeAPIs; /** * @var WindowsAzure\Common\Models\RetentionPolicy */ private $_retentionPolicy; /** * Creates object from $parsedResponse. * * @param array $parsedResponse XML response parsed into array. * * @return WindowsAzure\Common\Models\Metrics */ public static function create($parsedResponse) { $result = new Metrics(); $result->setVersion($parsedResponse['Version']); $result->setEnabled(Utilities::toBoolean($parsedResponse['Enabled'])); if ($result->getEnabled()) { $result->setIncludeAPIs( Utilities::toBoolean($parsedResponse['IncludeAPIs']) ); } $result->setRetentionPolicy( RetentionPolicy::create($parsedResponse['RetentionPolicy']) ); return $result; } /** * Gets retention policy * * @return WindowsAzure\Common\Models\RetentionPolicy * */ public function getRetentionPolicy() { return $this->_retentionPolicy; } /** * Sets retention policy * * @param RetentionPolicy $policy object to use * * @return none. */ public function setRetentionPolicy($policy) { $this->_retentionPolicy = $policy; } /** * Gets include APIs. * * @return bool. */ public function getIncludeAPIs() { return $this->_includeAPIs; } /** * Sets include APIs. * * @param $bool $includeAPIs value to use. * * @return none. */ public function setIncludeAPIs($includeAPIs) { $this->_includeAPIs = $includeAPIs; } /** * Gets enabled. * * @return bool. */ public function getEnabled() { return $this->_enabled; } /** * Sets enabled. * * @param bool $enabled value to use. * * @return none. */ public function setEnabled($enabled) { $this->_enabled = $enabled; } /** * Gets version * * @return string. */ public function getVersion() { return $this->_version; } /** * Sets version * * @param string $version new value. * * @return none. */ public function setVersion($version) { $this->_version = $version; } /** * Converts this object to array with XML tags * * @return array. */ public function toArray() { $array = array( 'Version' => $this->_version, 'Enabled' => Utilities::booleanToString($this->_enabled) ); if ($this->_enabled) { $array['IncludeAPIs'] = Utilities::booleanToString($this->_includeAPIs); } $array['RetentionPolicy'] = !empty($this->_retentionPolicy) ? $this->_retentionPolicy->toArray() : null; return $array; } } includes/WindowsAzure/Common/Models/OAuthAccessToken.php000064400000006577152214270100017353 0ustar00 * @copyright Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @link https://github.com/windowsazure/azure-sdk-for-php */ namespace WindowsAzure\Common\Models; use WindowsAzure\Common\Internal\Resources; /** * Holds OAuth access token data. * * @category Microsoft * @package WindowsAzure\Common\Models * @author Azure PHP SDK * @copyright Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @version Release: 0.4.1_2015-03 * @link https://github.com/windowsazure/azure-sdk-for-php */ class OAuthAccessToken { /** * Access token itself * * @var string */ private $_accessToken; /** * Unix time the access token valid before. * * @var int */ private $_expiresIn; /** * Scope of access token * * @var string. */ private $_scope; /** * Creates object from $parsedResponse. * * @param array $parsedResponse JSON response parsed into array. * * @return WindowsAzure\Common\Models\OAuthAccessToken */ public static function create($parsedResponse) { $result = new OAuthAccessToken(); $result->setAccessToken($parsedResponse[Resources::OAUTH_ACCESS_TOKEN]); $result->setExpiresIn($parsedResponse[Resources::OAUTH_EXPIRES_IN] + time()); $result->setScope($parsedResponse[Resources::OAUTH_SCOPE]); return $result; } /** * Gets access token * * @return string */ public function getAccessToken() { return $this->_accessToken; } /** * Sets access token * * @param string $accessToken OAuth access token * * @return none */ public function setAccessToken($accessToken) { $this->_accessToken = $accessToken; } /** * Gets expired date of access token in unixdate * * @return int * */ public function getExpiresIn() { return $this->_expiresIn; } /** * Sets access token expires date * * @param int $expiresIn OAuth access token expire date * * @return none */ public function setExpiresIn($expiresIn) { $this->_expiresIn = $expiresIn; } /** * Gets access token scope * * @return string * */ public function getScope() { return $this->_scope; } /** * Sets access token scope * * @param string $scope OAuth access token scope * * @return none */ public function setScope($scope) { $this->_scope = $scope; } } includes/WindowsAzure/Common/Models/RetentionPolicy.php000064400000006642152214270100017330 0ustar00 * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @link https://github.com/windowsazure/azure-sdk-for-php */ namespace WindowsAzure\Common\Models; use WindowsAzure\Common\Internal\Utilities; /** * Holds elements of queue properties retention policy field. * * @category Microsoft * @package WindowsAzure\Common\Models * @author Azure PHP SDK * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @version Release: 0.4.1_2015-03 * @link https://github.com/windowsazure/azure-sdk-for-php */ class RetentionPolicy { /** * Indicates whether a retention policy is enabled for the storage service * * @var bool. */ private $_enabled; /** * If $_enabled is true then this field indicates the number of days that metrics * or logging data should be retained. All data older than this value will be * deleted. The minimum value you can specify is 1; * the largest value is 365 (one year) * * @var int */ private $_days; /** * Creates object from $parsedResponse. * * @param array $parsedResponse XML response parsed into array. * * @return WindowsAzure\Common\Models\RetentionPolicy */ public static function create($parsedResponse) { $result = new RetentionPolicy(); $result->setEnabled(Utilities::toBoolean($parsedResponse['Enabled'])); if ($result->getEnabled()) { $result->setDays(intval($parsedResponse['Days'])); } return $result; } /** * Gets enabled. * * @return bool. */ public function getEnabled() { return $this->_enabled; } /** * Sets enabled. * * @param bool $enabled value to use. * * @return none. */ public function setEnabled($enabled) { $this->_enabled = $enabled; } /** * Gets days field. * * @return int */ public function getDays() { return $this->_days; } /** * Sets days field. * * @param int $days value to use. * * @return none */ public function setDays($days) { $this->_days = $days; } /** * Converts this object to array with XML tags * * @return array. */ public function toArray() { $array = array('Enabled' => Utilities::booleanToString($this->_enabled)); if (isset($this->_days)) { $array['Days'] = strval($this->_days); } return $array; } } includes/WindowsAzure/Common/Models/GetServicePropertiesResult.php000064400000004604152214270100021511 0ustar00 * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @link https://github.com/windowsazure/azure-sdk-for-php */ namespace WindowsAzure\Common\Models; use WindowsAzure\Common\Models\ServiceProperties; /** * Result from calling GetQueueProperties REST wrapper. * * @category Microsoft * @package WindowsAzure\Common\Models * @author Azure PHP SDK * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @version Release: 0.4.1_2015-03 * @link https://github.com/windowsazure/azure-sdk-for-php */ class GetServicePropertiesResult { private $_serviceProperties; /** * Creates object from $parsedResponse. * * @param array $parsedResponse XML response parsed into array. * * @return WindowsAzure\Common\Models\GetServicePropertiesResult */ public static function create($parsedResponse) { $result = new GetServicePropertiesResult(); $result->_serviceProperties = ServiceProperties::create($parsedResponse); return $result; } /** * Gets service properties object. * * @return WindowsAzure\Common\Models\ServiceProperties */ public function getValue() { return $this->_serviceProperties; } /** * Sets service properties object. * * @param ServiceProperties $serviceProperties object to use. * * @return none */ public function setValue($serviceProperties) { $this->_serviceProperties = clone $serviceProperties; } } includes/WindowsAzure/Common/ServicesBuilder.php000064400000040023152214270100016037 0ustar00 * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @link https://github.com/windowsazure/azure-sdk-for-php */ namespace WindowsAzure\Common; use WindowsAzure\Blob\BlobRestProxy; use WindowsAzure\Common\Internal\Resources; use WindowsAzure\Common\Internal\Validate; use WindowsAzure\Common\Internal\Utilities; use WindowsAzure\Common\Internal\Http\HttpClient; use WindowsAzure\Common\Internal\Filters\DateFilter; use WindowsAzure\Common\Internal\Filters\HeadersFilter; use WindowsAzure\Common\Internal\Filters\AuthenticationFilter; use WindowsAzure\Common\Internal\Filters\WrapFilter; use WindowsAzure\Common\Internal\InvalidArgumentTypeException; use WindowsAzure\Common\Internal\Serialization\XmlSerializer; use WindowsAzure\Common\Internal\Authentication\SharedKeyAuthScheme; use WindowsAzure\Common\Internal\Authentication\TableSharedKeyLiteAuthScheme; use WindowsAzure\Common\Internal\StorageServiceSettings; use WindowsAzure\Common\Internal\ServiceManagementSettings; use WindowsAzure\Common\Internal\ServiceBusSettings; use WindowsAzure\Common\Internal\MediaServicesSettings; use WindowsAzure\Queue\QueueRestProxy; use WindowsAzure\ServiceBus\ServiceBusRestProxy; use WindowsAzure\ServiceBus\Internal\WrapRestProxy; use WindowsAzure\ServiceManagement\ServiceManagementRestProxy; use WindowsAzure\Table\TableRestProxy; use WindowsAzure\Table\Internal\AtomReaderWriter; use WindowsAzure\Table\Internal\MimeReaderWriter; use WindowsAzure\MediaServices\MediaServicesRestProxy; use WindowsAzure\Common\Internal\OAuthRestProxy; use WindowsAzure\Common\Internal\Authentication\OAuthScheme; /** * Builds azure service objects. * * @category Microsoft * @package WindowsAzure\Common * @author Azure PHP SDK * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @version Release: 0.4.1_2015-03 * @link https://github.com/windowsazure/azure-sdk-for-php */ class ServicesBuilder { /** * @var ServicesBuilder */ private static $_instance = null; /** * Gets the HTTP client used in the REST services construction. * * @return WindowsAzure\Common\Internal\Http\IHttpClient */ protected function httpClient() { return new HttpClient(); } /** * Gets the serializer used in the REST services construction. * * @return WindowsAzure\Common\Internal\Serialization\ISerializer */ protected function serializer() { return new XmlSerializer(); } /** * Gets the MIME serializer used in the REST services construction. * * @return \WindowsAzure\Table\Internal\IMimeReaderWriter */ protected function mimeSerializer() { return new MimeReaderWriter(); } /** * Gets the Atom serializer used in the REST services construction. * * @return \WindowsAzure\Table\Internal\IAtomReaderWriter */ protected function atomSerializer() { return new AtomReaderWriter(); } /** * Gets the Queue authentication scheme. * * @param string $accountName The account name. * @param string $accountKey The account key. * * @return \WindowsAzure\Common\Internal\Authentication\StorageAuthScheme */ protected function queueAuthenticationScheme($accountName, $accountKey) { return new SharedKeyAuthScheme($accountName, $accountKey); } /** * Gets the Blob authentication scheme. * * @param string $accountName The account name. * @param string $accountKey The account key. * * @return \WindowsAzure\Common\Internal\Authentication\StorageAuthScheme */ protected function blobAuthenticationScheme($accountName, $accountKey) { return new SharedKeyAuthScheme($accountName, $accountKey); } /** * Gets the Table authentication scheme. * * @param string $accountName The account name. * @param string $accountKey The account key. * * @return TableSharedKeyLiteAuthScheme */ protected function tableAuthenticationScheme($accountName, $accountKey) { return new TableSharedKeyLiteAuthScheme($accountName, $accountKey); } /** * Builds a WRAP client. * * @param string $wrapEndpointUri The WRAP endpoint uri. * * @return WindowsAzure\ServiceBus\Internal\IWrap */ protected function createWrapService($wrapEndpointUri) { $httpClient = $this->httpClient(); $wrapWrapper = new WrapRestProxy($httpClient, $wrapEndpointUri); return $wrapWrapper; } /** * Builds a queue object. * * @param string $connectionString The configuration connection string. * * @return WindowsAzure\Queue\Internal\IQueue */ public function createQueueService($connectionString) { $settings = StorageServiceSettings::createFromConnectionString( $connectionString ); $httpClient = $this->httpClient(); $serializer = $this->serializer(); $uri = Utilities::tryAddUrlScheme( $settings->getQueueEndpointUri() ); $queueWrapper = new QueueRestProxy( $httpClient, $uri, $settings->getName(), $serializer ); // Adding headers filter $headers = array( Resources::USER_AGENT => Resources::SDK_USER_AGENT, ); $headers[Resources::X_MS_VERSION] = Resources::STORAGE_API_LATEST_VERSION; $headersFilter = new HeadersFilter($headers); $queueWrapper = $queueWrapper->withFilter($headersFilter); // Adding date filter $dateFilter = new DateFilter(); $queueWrapper = $queueWrapper->withFilter($dateFilter); // Adding authentication filter $authFilter = new AuthenticationFilter( $this->queueAuthenticationScheme( $settings->getName(), $settings->getKey() ) ); $queueWrapper = $queueWrapper->withFilter($authFilter); return $queueWrapper; } /** * Builds a blob object. * * @param string $connectionString The configuration connection string. * @param string $endpoint Azure BLOB storage endpoint * * @return WindowsAzure\Blob\Internal\IBlob */ public function createBlobService($connectionString, $endpoint) { $settings = StorageServiceSettings::createFromConnectionString( $connectionString, $endpoint ); $httpClient = $this->httpClient(); $serializer = $this->serializer(); $uri = Utilities::tryAddUrlScheme( $settings->getBlobEndpointUri() ); $blobWrapper = new BlobRestProxy( $httpClient, $uri, $settings->getName(), $serializer ); // Adding headers filter $headers = array( Resources::USER_AGENT => Resources::SDK_USER_AGENT, ); $headers[Resources::X_MS_VERSION] = Resources::STORAGE_API_LATEST_VERSION; $headersFilter = new HeadersFilter($headers); $blobWrapper = $blobWrapper->withFilter($headersFilter); // Adding date filter $dateFilter = new DateFilter(); $blobWrapper = $blobWrapper->withFilter($dateFilter); $authFilter = new AuthenticationFilter( $this->blobAuthenticationScheme( $settings->getName(), $settings->getKey() ) ); $blobWrapper = $blobWrapper->withFilter($authFilter); return $blobWrapper; } /** * Builds a table object. * * @param string $connectionString The configuration connection string. * * @return WindowsAzure\Table\Internal\ITable */ public function createTableService($connectionString) { $settings = StorageServiceSettings::createFromConnectionString( $connectionString ); $httpClient = $this->httpClient(); $atomSerializer = $this->atomSerializer(); $mimeSerializer = $this->mimeSerializer(); $serializer = $this->serializer(); $uri = Utilities::tryAddUrlScheme( $settings->getTableEndpointUri() ); $tableWrapper = new TableRestProxy( $httpClient, $uri, $atomSerializer, $mimeSerializer, $serializer ); // Adding headers filter $headers = array(); $latestServicesVersion = Resources::STORAGE_API_LATEST_VERSION; $currentVersion = Resources::DATA_SERVICE_VERSION_VALUE; $maxVersion = Resources::MAX_DATA_SERVICE_VERSION_VALUE; $accept = Resources::ACCEPT_HEADER_VALUE; $acceptCharset = Resources::ACCEPT_CHARSET_VALUE; $userAgent = Resources::SDK_USER_AGENT; $headers[Resources::X_MS_VERSION] = $latestServicesVersion; $headers[Resources::DATA_SERVICE_VERSION] = $currentVersion; $headers[Resources::MAX_DATA_SERVICE_VERSION] = $maxVersion; $headers[Resources::MAX_DATA_SERVICE_VERSION] = $maxVersion; $headers[Resources::ACCEPT_HEADER] = $accept; $headers[Resources::ACCEPT_CHARSET] = $acceptCharset; $headers[Resources::USER_AGENT] = $userAgent; $headersFilter = new HeadersFilter($headers); $tableWrapper = $tableWrapper->withFilter($headersFilter); // Adding date filter $dateFilter = new DateFilter(); $tableWrapper = $tableWrapper->withFilter($dateFilter); // Adding authentication filter $authFilter = new AuthenticationFilter( $this->tableAuthenticationScheme( $settings->getName(), $settings->getKey() ) ); $tableWrapper = $tableWrapper->withFilter($authFilter); return $tableWrapper; } /** * Builds a Service Bus object. * * @param string $connectionString The configuration connection string. * * @return WindowsAzure\ServiceBus\Internal\IServiceBus */ public function createServiceBusService($connectionString) { $settings = ServiceBusSettings::createFromConnectionString( $connectionString ); $httpClient = $this->httpClient(); $serializer = $this->serializer(); $serviceBusWrapper = new ServiceBusRestProxy( $httpClient, $settings->getServiceBusEndpointUri(), $serializer ); // Adding headers filter $headers = array( Resources::USER_AGENT => Resources::SDK_USER_AGENT, ); $headersFilter = new HeadersFilter($headers); $serviceBusWrapper = $serviceBusWrapper->withFilter($headersFilter); $wrapFilter = new WrapFilter( $settings->getWrapEndpointUri(), $settings->getWrapName(), $settings->getWrapPassword(), $this->createWrapService($settings->getWrapEndpointUri()) ); return $serviceBusWrapper->withFilter($wrapFilter); } /** * Builds a service management object. * * @param string $connectionString The configuration connection string. * * @return WindowsAzure\ServiceManagement\Internal\IServiceManagement */ public function createServiceManagementService($connectionString) { $settings = ServiceManagementSettings::createFromConnectionString( $connectionString ); $certificatePath = $settings->getCertificatePath(); $httpClient = new HttpClient($certificatePath); $serializer = $this->serializer(); $uri = Utilities::tryAddUrlScheme( $settings->getEndpointUri(), Resources::HTTPS_SCHEME ); $serviceManagementWrapper = new ServiceManagementRestProxy( $httpClient, $settings->getSubscriptionId(), $uri, $serializer ); // Adding headers filter $headers = array( Resources::USER_AGENT => Resources::SDK_USER_AGENT ); $headers[Resources::X_MS_VERSION] = Resources::SM_API_LATEST_VERSION; $headersFilter = new HeadersFilter($headers); $serviceManagementWrapper = $serviceManagementWrapper->withFilter( $headersFilter ); return $serviceManagementWrapper; } /** * Builds a media services object. * * @param WindowsAzure\Common\Internal\MediaServicesSettings $settings The media * services configuration settings. * * @return WindowsAzure\MediaServices\Internal\IMediaServices */ public function createMediaServicesService($settings) { Validate::isA( $settings, 'WindowsAzure\Common\Internal\MediaServicesSettings', 'settings' ); $httpClient = new HttpClient(); $serializer = $this->serializer(); $uri = Utilities::tryAddUrlScheme( $settings->getEndpointUri(), Resources::HTTPS_SCHEME ); $mediaServicesWrapper = new MediaServicesRestProxy( $httpClient, $uri, $settings->getAccountName(), $serializer ); // Adding headers filter $xMSVersion = Resources::MEDIA_SERVICES_API_LATEST_VERSION; $dataVersion = Resources::MEDIA_SERVICES_DATA_SERVICE_VERSION_VALUE; $dataMaxVersion = Resources::MEDIA_SERVICES_MAX_DATA_SERVICE_VERSION_VALUE; $accept = Resources::ACCEPT_HEADER_VALUE; $contentType = Resources::ATOM_ENTRY_CONTENT_TYPE; $userAgent = Resources::SDK_USER_AGENT; $headers = array( Resources::X_MS_VERSION => $xMSVersion, Resources::DATA_SERVICE_VERSION => $dataVersion, Resources::MAX_DATA_SERVICE_VERSION => $dataMaxVersion, Resources::ACCEPT_HEADER => $accept, Resources::CONTENT_TYPE => $contentType, Resources::USER_AGENT => $userAgent, ); $headersFilter = new HeadersFilter($headers); $mediaServicesWrapper = $mediaServicesWrapper->withFilter($headersFilter); // Adding OAuth filter $oauthService = new OAuthRestProxy( new HttpClient(), $settings->getOAuthEndpointUri() ); $authentification = new OAuthScheme( $settings->getAccountName(), $settings->getAccessKey(), Resources::OAUTH_GT_CLIENT_CREDENTIALS, Resources::MEDIA_SERVICES_OAUTH_SCOPE, $oauthService ); $authentificationFilter = new AuthenticationFilter($authentification); $mediaServicesWrapper = $mediaServicesWrapper->withFilter( $authentificationFilter ); return $mediaServicesWrapper; } /** * Gets the static instance of this class. * * @return ServicesBuilder */ public static function getInstance() { if (!isset(self::$instance)) { self::$_instance = new ServicesBuilder(); } return self::$_instance; } }includes/WindowsAzure/Common/ServiceException.php000064400000004476152214270100016240 0ustar00 * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @link https://github.com/windowsazure/azure-sdk-for-php */ namespace WindowsAzure\Common; use WindowsAzure\Common\Internal\Resources; /** * Fires when the response code is incorrect. * * @category Microsoft * @package WindowsAzure\Common * @author Azure PHP SDK * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @version Release: 0.4.1_2015-03 * @link https://github.com/windowsazure/azure-sdk-for-php */ class ServiceException extends \LogicException { private $_error; private $_reason; /** * Constructor * * @param string $errorCode status error code. * @param string $error string value of the error code. * @param string $reason detailed message for the error. * * @return WindowsAzure\Common\ServiceException */ public function __construct($errorCode, $error = null, $reason = null) { parent::__construct( sprintf(Resources::AZURE_ERROR_MSG, $errorCode, $error, $reason) ); $this->code = $errorCode; $this->_error = $error; $this->_reason = $reason; } /** * Gets error text. * * @return string */ public function getErrorText() { return $this->_error; } /** * Gets detailed error reason. * * @return string */ public function getErrorReason() { return $this->_reason; } } includes/WindowsAzure/Common/CloudConfigurationManager.php000064400000011526152214270100020044 0ustar00 * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @link https://github.com/windowsazure/azure-sdk-for-php */ namespace WindowsAzure\Common; use WindowsAzure\Common\Internal\Utilities; use WindowsAzure\Common\Internal\Validate; use WindowsAzure\Common\Internal\Resources; use WindowsAzure\Common\Internal\ConnectionStringSource; /** * Configuration manager for accessing Windows Azure settings. * * @category Microsoft * @package WindowsAzure\Common * @author Azure PHP SDK * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @version Release: 0.4.1_2015-03 * @link https://github.com/windowsazure/azure-sdk-for-php */ class CloudConfigurationManager { /** * @var boolean */ private static $_isInitialized = false; /** * The list of connection string sources. * * @var array */ private static $_sources; /** * Restrict users from creating instances from this class */ private function __construct() { } /** * Initializes the connection string source providers. * * @return none */ private static function _init() { if (!self::$_isInitialized) { self::$_sources = array(); // Get list of default connection string sources. $default = ConnectionStringSource::getDefaultSources(); foreach ($default as $name => $provider) { self::$_sources[$name] = $provider; } self::$_isInitialized = true; } } /** * Gets a connection string from all available sources. * * @param string $key The connection string key name. * * @return string If the key does not exist return null. */ public static function getConnectionString($key) { Validate::isString($key, 'key'); self::_init(); $value = null; foreach (self::$_sources as $source) { $value = call_user_func_array($source, array($key)); if (!empty($value)) { break; } } return $value; } /** * Registers a new connection string source provider. If the source to get * registered is a default source, only the name of the source is required. * * @param string $name The source name. * @param callable $provider The source callback. * @param boolean $prepend When true, the $provider is processed first when * calling getConnectionString. When false (the default) the $provider is * processed after the existing callbacks. * * @return none */ public static function registerSource($name, $provider = null, $prepend = false) { Validate::isString($name, 'name'); Validate::notNullOrEmpty($name, 'name'); self::_init(); $default = ConnectionStringSource::getDefaultSources(); // Try to get callback if the user is trying to register a default source. $provider = Utilities::tryGetValue($default, $name, $provider); Validate::notNullOrEmpty($provider, 'callback'); if ($prepend) { self::$_sources = array_merge( array($name => $provider), self::$_sources ); } else { self::$_sources[$name] = $provider; } } /** * Unregisters a connection string source. * * @param string $name The source name. * * @return callable */ public static function unregisterSource($name) { Validate::isString($name, 'name'); Validate::notNullOrEmpty($name, 'name'); self::_init(); $sourceCallback = Utilities::tryGetValue(self::$_sources, $name); if (!is_null($sourceCallback)) { unset(self::$_sources[$name]); } return $sourceCallback; } }includes/WindowsAzure/WindowsAzure.php000064400000103704152214270100014164 0ustar00 * @copyright 2012 Microsoft Corporation * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 * @link https://github.com/windowsazure/azure-sdk-for-php */ spl_autoload_register( function($class) { static $classes = null; if ($classes === null) { $classes = array( 'windowsazure\\blob\\blobrestproxy' => '/Blob/BlobRestProxy.php', 'windowsazure\\blob\\internal\\iblob' => '/Blob/Internal/IBlob.php', 'windowsazure\\blob\\models\\accesscondition' => '/Blob/Models/AccessCondition.php', 'windowsazure\\blob\\models\\accesspolicy' => '/Blob/Models/AccessPolicy.php', 'windowsazure\\blob\\models\\acquireleaseoptions' => '/Blob/Models/AcquireLeaseOptions.php', 'windowsazure\\blob\\models\\acquireleaseresult' => '/Blob/Models/AcquireLeaseResult.php', 'windowsazure\\blob\\models\\blob' => '/Blob/Models/Blob.php', 'windowsazure\\blob\\models\\blobblocktype' => '/Blob/Models/BlobBlockType.php', 'windowsazure\\blob\\models\\blobprefix' => '/Blob/Models/BlobPrefix.php', 'windowsazure\\blob\\models\\blobproperties' => '/Blob/Models/BlobProperties.php', 'windowsazure\\blob\\models\\blobserviceoptions' => '/Blob/Models/BlobServiceOptions.php', 'windowsazure\\blob\\models\\blobtype' => '/Blob/Models/BlobType.php', 'windowsazure\\blob\\models\\block' => '/Blob/Models/Block.php', 'windowsazure\\blob\\models\\blocklist' => '/Blob/Models/BlockList.php', 'windowsazure\\blob\\models\\breakleaseresult' => '/Blob/Models/BreakLeaseResult.php', 'windowsazure\\blob\\models\\commitblobblocksoptions' => '/Blob/Models/CommitBlobBlocksOptions.php', 'windowsazure\\blob\\models\\container' => '/Blob/Models/Container.php', 'windowsazure\\blob\\models\\containeracl' => '/Blob/Models/ContainerACL.php', 'windowsazure\\blob\\models\\containerproperties' => '/Blob/Models/ContainerProperties.php', 'windowsazure\\blob\\models\\copybloboptions' => '/Blob/Models/CopyBlobOptions.php', 'windowsazure\\blob\\models\\copyblobresult' => '/Blob/Models/CopyBlobResult.php', 'windowsazure\\blob\\models\\createblobblockoptions' => '/Blob/Models/CreateBlobBlockOptions.php', 'windowsazure\\blob\\models\\createbloboptions' => '/Blob/Models/CreateBlobOptions.php', 'windowsazure\\blob\\models\\createblobpagesoptions' => '/Blob/Models/CreateBlobPagesOptions.php', 'windowsazure\\blob\\models\\createblobpagesresult' => '/Blob/Models/CreateBlobPagesResult.php', 'windowsazure\\blob\\models\\createblobsnapshotoptions' => '/Blob/Models/CreateBlobSnapshotOptions.php', 'windowsazure\\blob\\models\\createblobsnapshotresult' => '/Blob/Models/CreateBlobSnapshotResult.php', 'windowsazure\\blob\\models\\createcontaineroptions' => '/Blob/Models/CreateContainerOptions.php', 'windowsazure\\blob\\models\\deletebloboptions' => '/Blob/Models/DeleteBlobOptions.php', 'windowsazure\\blob\\models\\deletecontaineroptions' => '/Blob/Models/DeleteContainerOptions.php', 'windowsazure\\blob\\models\\getblobmetadataoptions' => '/Blob/Models/GetBlobMetadataOptions.php', 'windowsazure\\blob\\models\\getblobmetadataresult' => '/Blob/Models/GetBlobMetadataResult.php', 'windowsazure\\blob\\models\\getbloboptions' => '/Blob/Models/GetBlobOptions.php', 'windowsazure\\blob\\models\\getblobpropertiesoptions' => '/Blob/Models/GetBlobPropertiesOptions.php', 'windowsazure\\blob\\models\\getblobpropertiesresult' => '/Blob/Models/GetBlobPropertiesResult.php', 'windowsazure\\blob\\models\\getblobresult' => '/Blob/Models/GetBlobResult.php', 'windowsazure\\blob\\models\\getcontaineraclresult' => '/Blob/Models/GetContainerACLResult.php', 'windowsazure\\blob\\models\\getcontainerpropertiesresult' => '/Blob/Models/GetContainerPropertiesResult.php', 'windowsazure\\blob\\models\\leasemode' => '/Blob/Models/LeaseMode.php', 'windowsazure\\blob\\models\\listblobblocksoptions' => '/Blob/Models/ListBlobBlocksOptions.php', 'windowsazure\\blob\\models\\listblobblocksresult' => '/Blob/Models/ListBlobBlocksResult.php', 'windowsazure\\blob\\models\\listblobsoptions' => '/Blob/Models/ListBlobsOptions.php', 'windowsazure\\blob\\models\\listblobsresult' => '/Blob/Models/ListBlobsResult.php', 'windowsazure\\blob\\models\\listcontainersoptions' => '/Blob/Models/ListContainersOptions.php', 'windowsazure\\blob\\models\\listcontainersresult' => '/Blob/Models/ListContainersResult.php', 'windowsazure\\blob\\models\\listpageblobrangesoptions' => '/Blob/Models/ListPageBlobRangesOptions.php', 'windowsazure\\blob\\models\\listpageblobrangesresult' => '/Blob/Models/ListPageBlobRangesResult.php', 'windowsazure\\blob\\models\\pagerange' => '/Blob/Models/PageRange.php', 'windowsazure\\blob\\models\\pagewriteoption' => '/Blob/Models/PageWriteOption.php', 'windowsazure\\blob\\models\\publicaccesstype' => '/Blob/Models/PublicAccessType.php', 'windowsazure\\blob\\models\\setblobmetadataoptions' => '/Blob/Models/SetBlobMetadataOptions.php', 'windowsazure\\blob\\models\\setblobmetadataresult' => '/Blob/Models/SetBlobMetadataResult.php', 'windowsazure\\blob\\models\\setblobpropertiesoptions' => '/Blob/Models/SetBlobPropertiesOptions.php', 'windowsazure\\blob\\models\\setblobpropertiesresult' => '/Blob/Models/SetBlobPropertiesResult.php', 'windowsazure\\blob\\models\\setcontainermetadataoptions' => '/Blob/Models/SetContainerMetadataOptions.php', 'windowsazure\\blob\\models\\signedidentifier' => '/Blob/Models/SignedIdentifier.php', 'windowsazure\\common\\cloudconfigurationmanager' => '/Common/CloudConfigurationManager.php', 'windowsazure\\common\\internal\\atom\\atombase' => '/Common/Internal/Atom/AtomBase.php', 'windowsazure\\common\\internal\\atom\\atomlink' => '/Common/Internal/Atom/AtomLink.php', 'windowsazure\\common\\internal\\atom\\category' => '/Common/Internal/Atom/Category.php', 'windowsazure\\common\\internal\\atom\\content' => '/Common/Internal/Atom/Content.php', 'windowsazure\\common\\internal\\atom\\entry' => '/Common/Internal/Atom/Entry.php', 'windowsazure\\common\\internal\\atom\\feed' => '/Common/Internal/Atom/Feed.php', 'windowsazure\\common\\internal\\atom\\generator' => '/Common/Internal/Atom/Generator.php', 'windowsazure\\common\\internal\\atom\\person' => '/Common/Internal/Atom/Person.php', 'windowsazure\\common\\internal\\atom\\source' => '/Common/Internal/Atom/Source.php', 'windowsazure\\common\\internal\\authentication\\iauthscheme' => '/Common/Internal/Authentication/IAuthScheme.php', 'windowsazure\\common\\internal\\authentication\\oauthscheme' => '/Common/Internal/Authentication/OAuthScheme.php', 'windowsazure\\common\\internal\\authentication\\sharedkeyauthscheme' => '/Common/Internal/Authentication/SharedKeyAuthScheme.php', 'windowsazure\\common\\internal\\authentication\\storageauthscheme' => '/Common/Internal/Authentication/StorageAuthScheme.php', 'windowsazure\\common\\internal\\authentication\\tablesharedkeyliteauthscheme' => '/Common/Internal/Authentication/TableSharedKeyLiteAuthScheme.php', 'windowsazure\\common\\internal\\connectionstringparser' => '/Common/Internal/ConnectionStringParser.php', 'windowsazure\\common\\internal\\connectionstringsource' => '/Common/Internal/ConnectionStringSource.php', 'windowsazure\\common\\internal\\filterableservice' => '/Common/Internal/FilterableService.php', 'windowsazure\\common\\internal\\filters\\authenticationfilter' => '/Common/Internal/Filters/AuthenticationFilter.php', 'windowsazure\\common\\internal\\filters\\datefilter' => '/Common/Internal/Filters/DateFilter.php', 'windowsazure\\common\\internal\\filters\\exponentialretrypolicy' => '/Common/Internal/Filters/ExponentialRetryPolicy.php', 'windowsazure\\common\\internal\\filters\\headersfilter' => '/Common/Internal/Filters/HeadersFilter.php', 'windowsazure\\common\\internal\\filters\\retrypolicy' => '/Common/Internal/Filters/RetryPolicy.php', 'windowsazure\\common\\internal\\filters\\retrypolicyfilter' => '/Common/Internal/Filters/RetryPolicyFilter.php', 'windowsazure\\common\\internal\\filters\\wrapfilter' => '/Common/Internal/Filters/WrapFilter.php', 'windowsazure\\common\\internal\\http\\batchrequest' => '/Common/Internal/Http/BatchRequest.php', 'windowsazure\\common\\internal\\http\\batchresponse' => '/Common/Internal/Http/BatchResponse.php', 'windowsazure\\common\\internal\\http\\httpcallcontext' => '/Common/Internal/Http/HttpCallContext.php', 'windowsazure\\common\\internal\\http\\httpclient' => '/Common/Internal/Http/HttpClient.php', 'windowsazure\\common\\internal\\http\\ihttpclient' => '/Common/Internal/Http/IHttpClient.php', 'windowsazure\\common\\internal\\http\\iurl' => '/Common/Internal/Http/IUrl.php', 'windowsazure\\common\\internal\\http\\url' => '/Common/Internal/Http/Url.php', 'windowsazure\\common\\internal\\invalidargumenttypeexception' => '/Common/Internal/InvalidArgumentTypeException.php', 'windowsazure\\common\\internal\\iservicefilter' => '/Common/Internal/IServiceFilter.php', 'windowsazure\\common\\internal\\logger' => '/Common/Internal/Logger.php', 'windowsazure\\common\\internal\\mediaservicessettings' => '/Common/Internal/MediaServicesSettings.php', 'windowsazure\\common\\internal\\oauthrestproxy' => '/Common/Internal/OAuthRestProxy.php', 'windowsazure\\common\\internal\\parserstate' => '/Common/Internal/ConnectionStringParser.php', 'windowsazure\\common\\internal\\resources' => '/Common/Internal/Resources.php', 'windowsazure\\common\\internal\\restproxy' => '/Common/Internal/RestProxy.php', 'windowsazure\\common\\internal\\serialization\\iserializer' => '/Common/Internal/Serialization/ISerializer.php', 'windowsazure\\common\\internal\\serialization\\jsonserializer' => '/Common/Internal/Serialization/JsonSerializer.php', 'windowsazure\\common\\internal\\serialization\\xmlserializer' => '/Common/Internal/Serialization/XmlSerializer.php', 'windowsazure\\common\\internal\\servicebussettings' => '/Common/Internal/ServiceBusSettings.php', 'windowsazure\\common\\internal\\servicemanagementsettings' => '/Common/Internal/ServiceManagementSettings.php', 'windowsazure\\common\\internal\\servicerestproxy' => '/Common/Internal/ServiceRestProxy.php', 'windowsazure\\common\\internal\\servicesettings' => '/Common/Internal/ServiceSettings.php', 'windowsazure\\common\\internal\\storageservicesettings' => '/Common/Internal/StorageServiceSettings.php', 'windowsazure\\common\\internal\\utilities' => '/Common/Internal/Utilities.php', 'windowsazure\\common\\internal\\validate' => '/Common/Internal/Validate.php', 'windowsazure\\common\\models\\getservicepropertiesresult' => '/Common/Models/GetServicePropertiesResult.php', 'windowsazure\\common\\models\\logging' => '/Common/Models/Logging.php', 'windowsazure\\common\\models\\metrics' => '/Common/Models/Metrics.php', 'windowsazure\\common\\models\\oauthaccesstoken' => '/Common/Models/OAuthAccessToken.php', 'windowsazure\\common\\models\\retentionpolicy' => '/Common/Models/RetentionPolicy.php', 'windowsazure\\common\\models\\serviceproperties' => '/Common/Models/ServiceProperties.php', 'windowsazure\\common\\serviceexception' => '/Common/ServiceException.php', 'windowsazure\\common\\servicesbuilder' => '/Common/ServicesBuilder.php', 'windowsazure\\mediaservices\\internal\\contentpropertiesserializer' => '/MediaServices/Internal/ContentPropertiesSerializer.php', 'windowsazure\\mediaservices\\internal\\imediaservices' => '/MediaServices/Internal/IMediaServices.php', 'windowsazure\\mediaservices\\mediaservicesrestproxy' => '/MediaServices/MediaServicesRestProxy.php', 'windowsazure\\mediaservices\\models\\accesspolicy' => '/MediaServices/Models/AccessPolicy.php', 'windowsazure\\mediaservices\\models\\asset' => '/MediaServices/Models/Asset.php', 'windowsazure\\mediaservices\\models\\assetfile' => '/MediaServices/Models/AssetFile.php', 'windowsazure\\mediaservices\\models\\contentkey' => '/MediaServices/Models/ContentKey.php', 'windowsazure\\mediaservices\\models\\contentkeytypes' => '/MediaServices/Models/ContentKeyTypes.php', 'windowsazure\\mediaservices\\models\\encryptionschemes' => '/MediaServices/Models/EncryptionSchemes.php', 'windowsazure\\mediaservices\\models\\errordetail' => '/MediaServices/Models/ErrorDetail.php', 'windowsazure\\mediaservices\\models\\ingestmanifest' => '/MediaServices/Models/IngestManifest.php', 'windowsazure\\mediaservices\\models\\ingestmanifestasset' => '/MediaServices/Models/IngestManifestAsset.php', 'windowsazure\\mediaservices\\models\\ingestmanifestfile' => '/MediaServices/Models/IngestManifestFile.php', 'windowsazure\\mediaservices\\models\\ingestmanifeststatistics' => '/MediaServices/Models/IngestManifestStatistics.php', 'windowsazure\\mediaservices\\models\\job' => '/MediaServices/Models/Job.php', 'windowsazure\\mediaservices\\models\\jobtemplate' => '/MediaServices/Models/JobTemplate.php', 'windowsazure\\mediaservices\\models\\locator' => '/MediaServices/Models/Locator.php', 'windowsazure\\mediaservices\\models\\mediaprocessor' => '/MediaServices/Models/MediaProcessor.php', 'windowsazure\\mediaservices\\models\\protectionkeytypes' => '/MediaServices/Models/ProtectionKeyTypes.php', 'windowsazure\\mediaservices\\models\\storageaccount' => '/MediaServices/Models/StorageAccount.php', 'windowsazure\\mediaservices\\models\\task' => '/MediaServices/Models/Task.php', 'windowsazure\\mediaservices\\models\\taskhistoricalevent' => '/MediaServices/Models/TaskHistoricalEvent.php', 'windowsazure\\mediaservices\\models\\taskoptions' => '/MediaServices/Models/TaskOptions.php', 'windowsazure\\mediaservices\\models\\tasktemplate' => '/MediaServices/Models/TaskTemplate.php', 'windowsazure\\queue\\internal\\iqueue' => '/Queue/Internal/IQueue.php', 'windowsazure\\queue\\models\\createmessageoptions' => '/Queue/Models/CreateMessageOptions.php', 'windowsazure\\queue\\models\\createqueueoptions' => '/Queue/Models/CreateQueueOptions.php', 'windowsazure\\queue\\models\\getqueuemetadataresult' => '/Queue/Models/GetQueueMetadataResult.php', 'windowsazure\\queue\\models\\listmessagesoptions' => '/Queue/Models/ListMessagesOptions.php', 'windowsazure\\queue\\models\\listmessagesresult' => '/Queue/Models/ListMessagesResult.php', 'windowsazure\\queue\\models\\listqueuesoptions' => '/Queue/Models/ListQueuesOptions.php', 'windowsazure\\queue\\models\\listqueuesresult' => '/Queue/Models/ListQueuesResult.php', 'windowsazure\\queue\\models\\peekmessagesoptions' => '/Queue/Models/PeekMessagesOptions.php', 'windowsazure\\queue\\models\\peekmessagesresult' => '/Queue/Models/PeekMessagesResult.php', 'windowsazure\\queue\\models\\queue' => '/Queue/Models/Queue.php', 'windowsazure\\queue\\models\\queuemessage' => '/Queue/Models/QueueMessage.php', 'windowsazure\\queue\\models\\queueserviceoptions' => '/Queue/Models/QueueServiceOptions.php', 'windowsazure\\queue\\models\\updatemessageresult' => '/Queue/Models/UpdateMessageResult.php', 'windowsazure\\queue\\models\\windowsazurequeuemessage' => '/Queue/Models/WindowsAzureQueueMessage.php', 'windowsazure\\queue\\queuerestproxy' => '/Queue/QueueRestProxy.php', 'windowsazure\\servicebus\\internal\\action' => '/ServiceBus/Internal/Action.php', 'windowsazure\\servicebus\\internal\\activetoken' => '/ServiceBus/Internal/ActiveToken.php', 'windowsazure\\servicebus\\internal\\filter' => '/ServiceBus/Internal/Filter.php', 'windowsazure\\servicebus\\internal\\iservicebus' => '/ServiceBus/Internal/IServiceBus.php', 'windowsazure\\servicebus\\internal\\iwrap' => '/ServiceBus/Internal/IWrap.php', 'windowsazure\\servicebus\\internal\\wrapaccesstokenresult' => '/ServiceBus/Internal/WrapAccessTokenResult.php', 'windowsazure\\servicebus\\internal\\wraprestproxy' => '/ServiceBus/Internal/WrapRestProxy.php', 'windowsazure\\servicebus\\internal\\wraptokenmanager' => '/ServiceBus/Internal/WrapTokenManager.php', 'windowsazure\\servicebus\\models\\brokeredmessage' => '/ServiceBus/Models/BrokeredMessage.php', 'windowsazure\\servicebus\\models\\brokerproperties' => '/ServiceBus/Models/BrokerProperties.php', 'windowsazure\\servicebus\\models\\correlationfilter' => '/ServiceBus/Models/CorrelationFilter.php', 'windowsazure\\servicebus\\models\\emptyruleaction' => '/ServiceBus/Models/EmptyRuleAction.php', 'windowsazure\\servicebus\\models\\falsefilter' => '/ServiceBus/Models/FalseFilter.php', 'windowsazure\\servicebus\\models\\listoptions' => '/ServiceBus/Models/ListOptions.php', 'windowsazure\\servicebus\\models\\listqueuesoptions' => '/ServiceBus/Models/ListQueuesOptions.php', 'windowsazure\\servicebus\\models\\listqueuesresult' => '/ServiceBus/Models/ListQueuesResult.php', 'windowsazure\\servicebus\\models\\listrulesoptions' => '/ServiceBus/Models/ListRulesOptions.php', 'windowsazure\\servicebus\\models\\listrulesresult' => '/ServiceBus/Models/ListRulesResult.php', 'windowsazure\\servicebus\\models\\listsubscriptionsoptions' => '/ServiceBus/Models/ListSubscriptionsOptions.php', 'windowsazure\\servicebus\\models\\listsubscriptionsresult' => '/ServiceBus/Models/ListSubscriptionsResult.php', 'windowsazure\\servicebus\\models\\listtopicsoptions' => '/ServiceBus/Models/ListTopicsOptions.php', 'windowsazure\\servicebus\\models\\listtopicsresult' => '/ServiceBus/Models/ListTopicsResult.php', 'windowsazure\\servicebus\\models\\queuedescription' => '/ServiceBus/Models/QueueDescription.php', 'windowsazure\\servicebus\\models\\queueinfo' => '/ServiceBus/Models/QueueInfo.php', 'windowsazure\\servicebus\\models\\receivemessageoptions' => '/ServiceBus/Models/ReceiveMessageOptions.php', 'windowsazure\\servicebus\\models\\receivemode' => '/ServiceBus/Models/ReceiveMode.php', 'windowsazure\\servicebus\\models\\ruledescription' => '/ServiceBus/Models/RuleDescription.php', 'windowsazure\\servicebus\\models\\ruleinfo' => '/ServiceBus/Models/RuleInfo.php', 'windowsazure\\servicebus\\models\\sqlfilter' => '/ServiceBus/Models/SqlFilter.php', 'windowsazure\\servicebus\\models\\sqlruleaction' => '/ServiceBus/Models/SqlRuleAction.php', 'windowsazure\\servicebus\\models\\subscriptiondescription' => '/ServiceBus/Models/SubscriptionDescription.php', 'windowsazure\\servicebus\\models\\subscriptioninfo' => '/ServiceBus/Models/SubscriptionInfo.php', 'windowsazure\\servicebus\\models\\topicdescription' => '/ServiceBus/Models/TopicDescription.php', 'windowsazure\\servicebus\\models\\topicinfo' => '/ServiceBus/Models/TopicInfo.php', 'windowsazure\\servicebus\\models\\truefilter' => '/ServiceBus/Models/TrueFilter.php', 'windowsazure\\servicebus\\servicebusrestproxy' => '/ServiceBus/ServiceBusRestProxy.php', 'windowsazure\\servicemanagement\\internal\\iservicemanagement' => '/ServiceManagement/Internal/IServiceManagement.php', 'windowsazure\\servicemanagement\\internal\\service' => '/ServiceManagement/Internal/Service.php', 'windowsazure\\servicemanagement\\internal\\windowsazureservice' => '/ServiceManagement/Internal/WindowsAzureService.php', 'windowsazure\\servicemanagement\\models\\affinitygroup' => '/ServiceManagement/Models/AffinityGroup.php', 'windowsazure\\servicemanagement\\models\\asynchronousoperationresult' => '/ServiceManagement/Models/AsynchronousOperationResult.php', 'windowsazure\\servicemanagement\\models\\changedeploymentconfigurationoptions' => '/ServiceManagement/Models/ChangeDeploymentConfigurationOptions.php', 'windowsazure\\servicemanagement\\models\\createaffinitygroupoptions' => '/ServiceManagement/Models/CreateAffinityGroupOptions.php', 'windowsazure\\servicemanagement\\models\\createdeploymentoptions' => '/ServiceManagement/Models/CreateDeploymentOptions.php', 'windowsazure\\servicemanagement\\models\\createserviceoptions' => '/ServiceManagement/Models/CreateServiceOptions.php', 'windowsazure\\servicemanagement\\models\\deployment' => '/ServiceManagement/Models/Deployment.php', 'windowsazure\\servicemanagement\\models\\deploymentslot' => '/ServiceManagement/Models/DeploymentSlot.php', 'windowsazure\\servicemanagement\\models\\deploymentstatus' => '/ServiceManagement/Models/DeploymentStatus.php', 'windowsazure\\servicemanagement\\models\\getaffinitygrouppropertiesresult' => '/ServiceManagement/Models/GetAffinityGroupPropertiesResult.php', 'windowsazure\\servicemanagement\\models\\getdeploymentoptions' => '/ServiceManagement/Models/GetDeploymentOptions.php', 'windowsazure\\servicemanagement\\models\\getdeploymentresult' => '/ServiceManagement/Models/GetDeploymentResult.php', 'windowsazure\\servicemanagement\\models\\gethostedservicepropertiesoptions' => '/ServiceManagement/Models/GetHostedServicePropertiesOptions.php', 'windowsazure\\servicemanagement\\models\\gethostedservicepropertiesresult' => '/ServiceManagement/Models/GetHostedServicePropertiesResult.php', 'windowsazure\\servicemanagement\\models\\getoperationstatusresult' => '/ServiceManagement/Models/GetOperationStatusResult.php', 'windowsazure\\servicemanagement\\models\\getstorageservicekeysresult' => '/ServiceManagement/Models/GetStorageServiceKeysResult.php', 'windowsazure\\servicemanagement\\models\\getstorageservicepropertiesresult' => '/ServiceManagement/Models/GetStorageServicePropertiesResult.php', 'windowsazure\\servicemanagement\\models\\hostedservice' => '/ServiceManagement/Models/HostedService.php', 'windowsazure\\servicemanagement\\models\\inputendpoint' => '/ServiceManagement/Models/InputEndpoint.php', 'windowsazure\\servicemanagement\\models\\keytype' => '/ServiceManagement/Models/KeyType.php', 'windowsazure\\servicemanagement\\models\\listaffinitygroupsresult' => '/ServiceManagement/Models/ListAffinityGroupsResult.php', 'windowsazure\\servicemanagement\\models\\listhostedservicesresult' => '/ServiceManagement/Models/ListHostedServicesResult.php', 'windowsazure\\servicemanagement\\models\\listlocationsresult' => '/ServiceManagement/Models/ListLocationsResult.php', 'windowsazure\\servicemanagement\\models\\liststorageservicesresult' => '/ServiceManagement/Models/ListStorageServicesResult.php', 'windowsazure\\servicemanagement\\models\\location' => '/ServiceManagement/Models/Location.php', 'windowsazure\\servicemanagement\\models\\mode' => '/ServiceManagement/Models/Mode.php', 'windowsazure\\servicemanagement\\models\\operationstatus' => '/ServiceManagement/Models/OperationStatus.php', 'windowsazure\\servicemanagement\\models\\role' => '/ServiceManagement/Models/Role.php', 'windowsazure\\servicemanagement\\models\\roleinstance' => '/ServiceManagement/Models/RoleInstance.php', 'windowsazure\\servicemanagement\\models\\storageservice' => '/ServiceManagement/Models/StorageService.php', 'windowsazure\\servicemanagement\\models\\updateserviceoptions' => '/ServiceManagement/Models/UpdateServiceOptions.php', 'windowsazure\\servicemanagement\\models\\upgradedeploymentoptions' => '/ServiceManagement/Models/UpgradeDeploymentOptions.php', 'windowsazure\\servicemanagement\\models\\upgradestatus' => '/ServiceManagement/Models/UpgradeStatus.php', 'windowsazure\\servicemanagement\\servicemanagementrestproxy' => '/ServiceManagement/ServiceManagementRestProxy.php', 'windowsazure\\serviceruntime\\internal\\acquirecurrentstate' => '/ServiceRuntime/Internal/AcquireCurrentState.php', 'windowsazure\\serviceruntime\\internal\\channelnotavailableexception' => '/ServiceRuntime/Internal/ChannelNotAvailableException.php', 'windowsazure\\serviceruntime\\internal\\chunkedgoalstatedeserializer' => '/ServiceRuntime/Internal/ChunkedGoalStateDeserializer.php', 'windowsazure\\serviceruntime\\internal\\currentstate' => '/ServiceRuntime/Internal/CurrentState.php', 'windowsazure\\serviceruntime\\internal\\currentstatus' => '/ServiceRuntime/Internal/CurrentStatus.php', 'windowsazure\\serviceruntime\\internal\\fileinputchannel' => '/ServiceRuntime/Internal/FileInputChannel.php', 'windowsazure\\serviceruntime\\internal\\fileoutputchannel' => '/ServiceRuntime/Internal/FileOutputChannel.php', 'windowsazure\\serviceruntime\\internal\\goalstate' => '/ServiceRuntime/Internal/GoalState.php', 'windowsazure\\serviceruntime\\internal\\icurrentstateserializer' => '/ServiceRuntime/Internal/ICurrentStateSerializer.php', 'windowsazure\\serviceruntime\\internal\\igoalstatedeserializer' => '/ServiceRuntime/Internal/IGoalStateDeserializer.php', 'windowsazure\\serviceruntime\\internal\\iinputchannel' => '/ServiceRuntime/Internal/IInputChannel.php', 'windowsazure\\serviceruntime\\internal\\ioutputchannel' => '/ServiceRuntime/Internal/IOutputChannel.php', 'windowsazure\\serviceruntime\\internal\\iroleenvironmentchange' => '/ServiceRuntime/Internal/IRoleEnvironmentChange.php', 'windowsazure\\serviceruntime\\internal\\iroleenvironmentdatadeserializer' => '/ServiceRuntime/Internal/IRoleEnvironmentDataDeserializer.php', 'windowsazure\\serviceruntime\\internal\\iruntimeclient' => '/ServiceRuntime/Internal/IRuntimeClient.php', 'windowsazure\\serviceruntime\\internal\\iruntimeclientfactory' => '/ServiceRuntime/Internal/IRuntimeClientFactory.php', 'windowsazure\\serviceruntime\\internal\\iruntimecurrentstateclient' => '/ServiceRuntime/Internal/IRuntimeCurrentStateClient.php', 'windowsazure\\serviceruntime\\internal\\iruntimegoalstateclient' => '/ServiceRuntime/Internal/IRuntimeGoalStateClient.php', 'windowsazure\\serviceruntime\\internal\\localresource' => '/ServiceRuntime/Internal/LocalResource.php', 'windowsazure\\serviceruntime\\internal\\protocol1runtimeclient' => '/ServiceRuntime/Internal/Protocol1RuntimeClient.php', 'windowsazure\\serviceruntime\\internal\\protocol1runtimeclientfactory' => '/ServiceRuntime/Internal/Protocol1RuntimeClientFactory.php', 'windowsazure\\serviceruntime\\internal\\protocol1runtimecurrentstateclient' => '/ServiceRuntime/Internal/Protocol1RuntimeCurrentStateClient.php', 'windowsazure\\serviceruntime\\internal\\protocol1runtimegoalstateclient' => '/ServiceRuntime/Internal/Protocol1RuntimeGoalStateClient.php', 'windowsazure\\serviceruntime\\internal\\releasecurrentstate' => '/ServiceRuntime/Internal/ReleaseCurrentState.php', 'windowsazure\\serviceruntime\\internal\\role' => '/ServiceRuntime/Internal/Role.php', 'windowsazure\\serviceruntime\\internal\\roleenvironmentconfigurationsettingchange' => '/ServiceRuntime/Internal/RoleEnvironmentConfigurationSettingChange.php', 'windowsazure\\serviceruntime\\internal\\roleenvironmentdata' => '/ServiceRuntime/Internal/RoleEnvironmentData.php', 'windowsazure\\serviceruntime\\internal\\roleenvironmentnotavailableexception' => '/ServiceRuntime/Internal/RoleEnvironmentNotAvailableException.php', 'windowsazure\\serviceruntime\\internal\\roleenvironmenttopologychange' => '/ServiceRuntime/Internal/RoleEnvironmentTopologyChange.php', 'windowsazure\\serviceruntime\\internal\\roleinstance' => '/ServiceRuntime/Internal/RoleInstance.php', 'windowsazure\\serviceruntime\\internal\\roleinstanceendpoint' => '/ServiceRuntime/Internal/RoleInstanceEndpoint.php', 'windowsazure\\serviceruntime\\internal\\roleinstancestatus' => '/ServiceRuntime/Internal/RoleInstanceStatus.php', 'windowsazure\\serviceruntime\\internal\\runtimekernel' => '/ServiceRuntime/Internal/RuntimeKernel.php', 'windowsazure\\serviceruntime\\internal\\runtimeversionmanager' => '/ServiceRuntime/Internal/RuntimeVersionManager.php', 'windowsazure\\serviceruntime\\internal\\runtimeversionprotocolclient' => '/ServiceRuntime/Internal/RuntimeVersionProtocolClient.php', 'windowsazure\\serviceruntime\\internal\\xmlcurrentstateserializer' => '/ServiceRuntime/Internal/XmlCurrentStateSerializer.php', 'windowsazure\\serviceruntime\\internal\\xmlgoalstatedeserializer' => '/ServiceRuntime/Internal/XmlGoalStateDeserializer.php', 'windowsazure\\serviceruntime\\internal\\xmlroleenvironmentdatadeserializer' => '/ServiceRuntime/Internal/XmlRoleEnvironmentDataDeserializer.php', 'windowsazure\\serviceruntime\\roleenvironment' => '/ServiceRuntime/RoleEnvironment.php', 'windowsazure\\table\\internal\\atomreaderwriter' => '/Table/Internal/AtomReaderWriter.php', 'windowsazure\\table\\internal\\iatomreaderwriter' => '/Table/Internal/IAtomReaderWriter.php', 'windowsazure\\table\\internal\\imimereaderwriter' => '/Table/Internal/IMimeReaderWriter.php', 'windowsazure\\table\\internal\\itable' => '/Table/Internal/ITable.php', 'windowsazure\\table\\internal\\mimereaderwriter' => '/Table/Internal/MimeReaderWriter.php', 'windowsazure\\table\\models\\batcherror' => '/Table/Models/BatchError.php', 'windowsazure\\table\\models\\batchoperation' => '/Table/Models/BatchOperation.php', 'windowsazure\\table\\models\\batchoperationparametername' => '/Table/Models/BatchOperationParameterName.php', 'windowsazure\\table\\models\\batchoperations' => '/Table/Models/BatchOperations.php', 'windowsazure\\table\\models\\batchoperationtype' => '/Table/Models/BatchOperationType.php', 'windowsazure\\table\\models\\batchresult' => '/Table/Models/BatchResult.php', 'windowsazure\\table\\models\\deleteentityoptions' => '/Table/Models/DeleteEntityOptions.php', 'windowsazure\\table\\models\\edmtype' => '/Table/Models/EdmType.php', 'windowsazure\\table\\models\\entity' => '/Table/Models/Entity.php', 'windowsazure\\table\\models\\filters\\binaryfilter' => '/Table/Models/Filters/BinaryFilter.php', 'windowsazure\\table\\models\\filters\\constantfilter' => '/Table/Models/Filters/ConstantFilter.php', 'windowsazure\\table\\models\\filters\\filter' => '/Table/Models/Filters/Filter.php', 'windowsazure\\table\\models\\filters\\propertynamefilter' => '/Table/Models/Filters/PropertyNameFilter.php', 'windowsazure\\table\\models\\filters\\querystringfilter' => '/Table/Models/Filters/QueryStringFilter.php', 'windowsazure\\table\\models\\filters\\unaryfilter' => '/Table/Models/Filters/UnaryFilter.php', 'windowsazure\\table\\models\\getentityresult' => '/Table/Models/GetEntityResult.php', 'windowsazure\\table\\models\\gettableresult' => '/Table/Models/GetTableResult.php', 'windowsazure\\table\\models\\insertentityresult' => '/Table/Models/InsertEntityResult.php', 'windowsazure\\table\\models\\property' => '/Table/Models/Property.php', 'windowsazure\\table\\models\\query' => '/Table/Models/Query.php', 'windowsazure\\table\\models\\queryentitiesoptions' => '/Table/Models/QueryEntitiesOptions.php', 'windowsazure\\table\\models\\queryentitiesresult' => '/Table/Models/QueryEntitiesResult.php', 'windowsazure\\table\\models\\querytablesoptions' => '/Table/Models/QueryTablesOptions.php', 'windowsazure\\table\\models\\querytablesresult' => '/Table/Models/QueryTablesResult.php', 'windowsazure\\table\\models\\tableserviceoptions' => '/Table/Models/TableServiceOptions.php', 'windowsazure\\table\\models\\updateentityresult' => '/Table/Models/UpdateEntityResult.php', 'windowsazure\\table\\tablerestproxy' => '/Table/TableRestProxy.php' ); } $cn = strtolower($class); if (isset($classes[$cn])) { require __DIR__ . $classes[$cn]; } } ); includes/blockui/jquery.blockUI.js000064400000047433152214270100013213 0ustar00/*! * jQuery blockUI plugin * Version 2.71.0-2020.12.08 * Requires jQuery v1.12 or later * * Examples at: http://malsup.com/jquery/block/ * Copyright (c) 2007-2013 M. Alsup * Dual licensed under the MIT and GPL licenses: * http://www.opensource.org/licenses/mit-license.php * http://www.gnu.org/licenses/gpl.html * * Thanks to Amir-Hossein Sobhi for some excellent contributions! */ ;(function() { /*jshint eqeqeq:false curly:false latedef:false */ "use strict"; function setup($) { var migrateDeduplicateWarnings = jQuery.migrateDeduplicateWarnings || false; jQuery.migrateDeduplicateWarnings = false; $.fn._fadeIn = $.fn.fadeIn; var noOp = $.noop || function() {}; // this bit is to ensure we don't call setExpression when we shouldn't (with extra muscle to handle // confusing userAgent strings on Vista) var msie = /MSIE/.test(navigator.userAgent); var ie6 = /MSIE 6.0/.test(navigator.userAgent) && ! /MSIE 8.0/.test(navigator.userAgent); var mode = document.documentMode || 0; var setExpr = "function" === typeof document.createElement('div').style.setExpression; // global $ methods for blocking/unblocking the entire page $.blockUI = function(opts) { install(window, opts); }; $.unblockUI = function(opts) { remove(window, opts); }; // convenience method for quick growl-like notifications (http://www.google.com/search?q=growl) $.growlUI = function(title, message, timeout, onClose) { var $m = $('

'); if (title) $m.append('

'+title+'

'); if (message) $m.append('

'+message+'

'); if (timeout === undefined) timeout = 3000; // Added by konapun: Set timeout to 30 seconds if this growl is moused over, like normal toast notifications var callBlock = function(opts) { opts = opts || {}; $.blockUI({ message: $m, fadeIn : typeof opts.fadeIn !== 'undefined' ? opts.fadeIn : 700, fadeOut: typeof opts.fadeOut !== 'undefined' ? opts.fadeOut : 1000, timeout: typeof opts.timeout !== 'undefined' ? opts.timeout : timeout, centerY: false, showOverlay: false, onUnblock: onClose, css: $.blockUI.defaults.growlCSS }); }; callBlock(); var nonmousedOpacity = $m.css('opacity'); $m.on('mouseover', function() { callBlock({ fadeIn: 0, timeout: 30000 }); var displayBlock = $('.blockMsg'); displayBlock.stop(); // cancel fadeout if it has started displayBlock.fadeTo(300, 1); // make it easier to read the message by removing transparency }).on('mouseout', function() { $('.blockMsg').fadeOut(1000); }); // End konapun additions }; // plugin method for blocking element content $.fn.block = function(opts) { if ( this[0] === window ) { $.blockUI( opts ); return this; } var fullOpts = $.extend({}, $.blockUI.defaults, opts || {}); this.each(function() { var $el = $(this); if (fullOpts.ignoreIfBlocked && $el.data('blockUI.isBlocked')) return; $el.unblock({ fadeOut: 0 }); }); return this.each(function() { if ($.css(this,'position') == 'static') { this.style.position = 'relative'; $(this).data('blockUI.static', true); } this.style.zoom = 1; // force 'hasLayout' in ie install(this, opts); }); }; // plugin method for unblocking element content $.fn.unblock = function(opts) { if ( this[0] === window ) { $.unblockUI( opts ); return this; } return this.each(function() { remove(this, opts); }); }; $.blockUI.version = 2.70; // 2nd generation blocking at no extra cost! // override these in your code to change the default behavior and style $.blockUI.defaults = { // message displayed when blocking (use null for no message) message: '

Please wait...

', title: null, // title string; only used when theme == true draggable: true, // only used when theme == true (requires jquery-ui.js to be loaded) theme: false, // set to true to use with jQuery UI themes // styles for the message when blocking; if you wish to disable // these and use an external stylesheet then do this in your code: // $.blockUI.defaults.css = {}; css: { padding: 0, margin: 0, width: '30%', top: '40%', left: '35%', textAlign: 'center', color: '#000', border: '3px solid #aaa', backgroundColor:'#fff', cursor: 'wait' }, // minimal style set used when themes are used themedCSS: { width: '30%', top: '40%', left: '35%' }, // styles for the overlay overlayCSS: { backgroundColor: '#000', opacity: 0.6, cursor: 'wait' }, // style to replace wait cursor before unblocking to correct issue // of lingering wait cursor cursorReset: 'default', // styles applied when using $.growlUI growlCSS: { width: '350px', top: '10px', left: '', right: '10px', border: 'none', padding: '5px', opacity: 0.6, cursor: 'default', color: '#fff', backgroundColor: '#000', '-webkit-border-radius':'10px', '-moz-border-radius': '10px', 'border-radius': '10px' }, // IE issues: 'about:blank' fails on HTTPS and javascript:false is s-l-o-w // (hat tip to Jorge H. N. de Vasconcelos) /*jshint scripturl:true */ iframeSrc: /^https/i.test(window.location.href || '') ? 'javascript:false' : 'about:blank', // force usage of iframe in non-IE browsers (handy for blocking applets) forceIframe: false, // z-index for the blocking overlay baseZ: 1000, // set these to true to have the message automatically centered centerX: true, // <-- only effects element blocking (page block controlled via css above) centerY: true, // allow body element to be stetched in ie6; this makes blocking look better // on "short" pages. disable if you wish to prevent changes to the body height allowBodyStretch: true, // enable if you want key and mouse events to be disabled for content that is blocked bindEvents: true, // be default blockUI will suppress tab navigation from leaving blocking content // (if bindEvents is true) constrainTabKey: true, // fadeIn time in millis; set to 0 to disable fadeIn on block fadeIn: 200, // fadeOut time in millis; set to 0 to disable fadeOut on unblock fadeOut: 400, // time in millis to wait before auto-unblocking; set to 0 to disable auto-unblock timeout: 0, // disable if you don't want to show the overlay showOverlay: true, // if true, focus will be placed in the first available input field when // page blocking focusInput: true, // elements that can receive focus focusableElements: ':input:enabled:visible', // suppresses the use of overlay styles on FF/Linux (due to performance issues with opacity) // no longer needed in 2012 // applyPlatformOpacityRules: true, // callback method invoked when fadeIn has completed and blocking message is visible onBlock: null, // callback method invoked when unblocking has completed; the callback is // passed the element that has been unblocked (which is the window object for page // blocks) and the options that were passed to the unblock call: // onUnblock(element, options) onUnblock: null, // callback method invoked when the overlay area is clicked. // setting this will turn the cursor to a pointer, otherwise cursor defined in overlayCss will be used. onOverlayClick: null, // don't ask; if you really must know: http://groups.google.com/group/jquery-en/browse_thread/thread/36640a8730503595/2f6a79a77a78e493#2f6a79a77a78e493 quirksmodeOffsetHack: 4, // class name of the message block blockMsgClass: 'blockMsg', // if it is already blocked, then ignore it (don't unblock and reblock) ignoreIfBlocked: false }; // private data and functions follow... var pageBlock = null; var pageBlockEls = []; function install(el, opts) { var css, themedCSS; var full = (el == window); var msg = (opts && opts.message !== undefined ? opts.message : undefined); opts = $.extend({}, $.blockUI.defaults, opts || {}); if (opts.ignoreIfBlocked && $(el).data('blockUI.isBlocked')) return; opts.overlayCSS = $.extend({}, $.blockUI.defaults.overlayCSS, opts.overlayCSS || {}); css = $.extend({}, $.blockUI.defaults.css, opts.css || {}); if (opts.onOverlayClick) opts.overlayCSS.cursor = 'pointer'; themedCSS = $.extend({}, $.blockUI.defaults.themedCSS, opts.themedCSS || {}); msg = msg === undefined ? opts.message : msg; // remove the current block (if there is one) if (full && pageBlock) remove(window, {fadeOut:0}); // if an existing element is being used as the blocking content then we capture // its current place in the DOM (and current display style) so we can restore // it when we unblock if (msg && typeof msg != 'string' && (msg.parentNode || msg.jquery)) { var node = msg.jquery ? msg[0] : msg; var data = {}; $(el).data('blockUI.history', data); data.el = node; data.parent = node.parentNode; data.display = node.style.display; data.position = node.style.position; if (data.parent) data.parent.removeChild(node); } $(el).data('blockUI.onUnblock', opts.onUnblock); var z = opts.baseZ; // blockUI uses 3 layers for blocking, for simplicity they are all used on every platform; // layer1 is the iframe layer which is used to suppress bleed through of underlying content // layer2 is the overlay layer which has opacity and a wait cursor (by default) // layer3 is the message content that is displayed while blocking var lyr1, lyr2, lyr3, s; if (msie || opts.forceIframe) lyr1 = $(''); else lyr1 = $(''); if (opts.theme) lyr2 = $(''); else lyr2 = $(''); if (opts.theme && full) { s = ''; } else if (opts.theme) { s = ''; } else if (full) { s = ''; } else { s = ''; } lyr3 = $(s); // if we have a message, style it if (msg) { if (opts.theme) { lyr3.css(themedCSS); lyr3.addClass('ui-widget-content'); } else lyr3.css(css); } // style the overlay if (!opts.theme /*&& (!opts.applyPlatformOpacityRules)*/) lyr2.css(opts.overlayCSS); lyr2.css('position', full ? 'fixed' : 'absolute'); // make iframe layer transparent in IE if (msie || opts.forceIframe) lyr1.css('opacity',0.0); //$([lyr1[0],lyr2[0],lyr3[0]]).appendTo(full ? 'body' : el); var layers = [lyr1,lyr2,lyr3], $par = full ? $('body') : $(el); $.each(layers, function() { this.appendTo($par); }); if (opts.theme && opts.draggable && $.fn.draggable) { lyr3.draggable({ handle: '.ui-dialog-titlebar', cancel: 'li' }); } // ie7 must use absolute positioning in quirks mode and to account for activex issues (when scrolling) var expr = setExpr && ( "CSS1Compat" !== document.compatMode || $('object,embed', full ? null : el).length > 0); if (ie6 || expr) { // give body 100% height if (full && opts.allowBodyStretch && "CSS1Compat" === document.compatMode) $('html,body').css('height','100%'); // fix ie6 issue when blocked element has a border width if ((ie6 || "CSS1Compat" !== document.compatMode) && !full) { var t = sz(el,'borderTopWidth'), l = sz(el,'borderLeftWidth'); var fixT = t ? '(0 - '+t+')' : 0; var fixL = l ? '(0 - '+l+')' : 0; } // simulate fixed position $.each(layers, function(i,o) { var s = o[0].style; s.position = 'absolute'; if (i < 2) { if (full) s.setExpression('height','Math.max(document.body.scrollHeight, document.body.offsetHeight) - ("CSS1Compat" === document.compatMode?0:'+opts.quirksmodeOffsetHack+') + "px"'); else s.setExpression('height','this.parentNode.offsetHeight + "px"'); if (full) s.setExpression('width','"CSS1Compat" === document.compatMode && document.documentElement.clientWidth || document.body.clientWidth + "px"'); else s.setExpression('width','this.parentNode.offsetWidth + "px"'); if (fixL) s.setExpression('left', fixL); if (fixT) s.setExpression('top', fixT); } else if (opts.centerY) { if (full) s.setExpression('top','(document.documentElement.clientHeight || document.body.clientHeight) / 2 - (this.offsetHeight / 2) + (blah = document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop) + "px"'); s.marginTop = 0; } else if (!opts.centerY && full) { var top = (opts.css && opts.css.top) ? parseInt(opts.css.top, 10) : 0; var expression = '((document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop) + '+top+') + "px"'; s.setExpression('top',expression); } }); } // show the message if (msg) { if (opts.theme) lyr3.find('.ui-widget-content').append(msg); else lyr3.append(msg); if (msg.jquery || msg.nodeType) $(msg).show(); } if ((msie || opts.forceIframe) && opts.showOverlay) lyr1.show(); // opacity is zero if (opts.fadeIn) { var cb = opts.onBlock ? opts.onBlock : noOp; var cb1 = (opts.showOverlay && !msg) ? cb : noOp; var cb2 = msg ? cb : noOp; if (opts.showOverlay) lyr2._fadeIn(opts.fadeIn, cb1); if (msg) lyr3._fadeIn(opts.fadeIn, cb2); } else { if (opts.showOverlay) lyr2.show(); if (msg) lyr3.show(); if (opts.onBlock) opts.onBlock.bind(lyr3)(); } // bind key and mouse events bind(1, el, opts); if (full) { pageBlock = lyr3[0]; pageBlockEls = $(opts.focusableElements,pageBlock); if (opts.focusInput) setTimeout(focus, 20); } else center(lyr3[0], opts.centerX, opts.centerY); if (opts.timeout) { // auto-unblock var to = setTimeout(function() { if (full) $.unblockUI(opts); else $(el).unblock(opts); }, opts.timeout); $(el).data('blockUI.timeout', to); } } // remove the block function remove(el, opts) { var count; var full = (el == window); var $el = $(el); var data = $el.data('blockUI.history'); var to = $el.data('blockUI.timeout'); if (to) { clearTimeout(to); $el.removeData('blockUI.timeout'); } opts = $.extend({}, $.blockUI.defaults, opts || {}); bind(0, el, opts); // unbind events if (opts.onUnblock === null) { opts.onUnblock = $el.data('blockUI.onUnblock'); $el.removeData('blockUI.onUnblock'); } var els; if (full) // crazy selector to handle odd field errors in ie6/7 els = $('body').children().filter('.blockUI').add('body > .blockUI'); else els = $el.find('>.blockUI'); // fix cursor issue if ( opts.cursorReset ) { if ( els.length > 1 ) els[1].style.cursor = opts.cursorReset; if ( els.length > 2 ) els[2].style.cursor = opts.cursorReset; } if (full) pageBlock = pageBlockEls = null; if (opts.fadeOut) { count = els.length; els.stop().fadeOut(opts.fadeOut, function() { if ( --count === 0) reset(els,data,opts,el); }); } else reset(els, data, opts, el); } // move blocking element back into the DOM where it started function reset(els,data,opts,el) { var $el = $(el); if ( $el.data('blockUI.isBlocked') ) return; els.each(function(i,o) { // remove via DOM calls so we don't lose event handlers if (this.parentNode) this.parentNode.removeChild(this); }); if (data && data.el) { data.el.style.display = data.display; data.el.style.position = data.position; data.el.style.cursor = 'default'; // #59 if (data.parent) data.parent.appendChild(data.el); $el.removeData('blockUI.history'); } if ($el.data('blockUI.static')) { $el.css('position', 'static'); // #22 } if (typeof opts.onUnblock == 'function') opts.onUnblock(el,opts); // fix issue in Safari 6 where block artifacts remain until reflow var body = $(document.body), w = body.width(), cssW = body[0].style.width; body.width(w-1).width(w); body[0].style.width = cssW; } // bind/unbind the handler function bind(b, el, opts) { var full = el == window, $el = $(el); // don't bother unbinding if there is nothing to unbind if (!b && (full && !pageBlock || !full && !$el.data('blockUI.isBlocked'))) return; $el.data('blockUI.isBlocked', b); // don't bind events when overlay is not in use or if bindEvents is false if (!full || !opts.bindEvents || (b && !opts.showOverlay)) return; // bind anchors and inputs for mouse and key events var events = 'mousedown mouseup keydown keypress keyup touchstart touchend touchmove'; if (b) $(document).on(events, opts, handler); else $(document).off(events, handler); // former impl... // var $e = $('a,:input'); // b ? $e.bind(events, opts, handler) : $e.unbind(events, handler); } // event handler to suppress keyboard/mouse events when blocking function handler(e) { // allow tab navigation (conditionally) if (e.type === 'keydown' && e.keyCode && e.keyCode == 9) { if (pageBlock && e.data.constrainTabKey) { var els = pageBlockEls; var fwd = !e.shiftKey && e.target === els[els.length-1]; var back = e.shiftKey && e.target === els[0]; if (fwd || back) { setTimeout(function(){focus(back);},10); return false; } } } var opts = e.data; var target = $(e.target); if (target.hasClass('blockOverlay') && opts.onOverlayClick) opts.onOverlayClick(e); // allow events within the message content if (target.parents('div.' + opts.blockMsgClass).length > 0) return true; // allow events for content that is not being blocked return target.parents().children().filter('div.blockUI').length === 0; } function focus(back) { if (!pageBlockEls) return; var e = pageBlockEls[back===true ? pageBlockEls.length-1 : 0]; if (e) e.focus(); } function center(el, x, y) { var p = el.parentNode, s = el.style; var l = ((p.offsetWidth - el.offsetWidth)/2) - sz(p,'borderLeftWidth'); var t = ((p.offsetHeight - el.offsetHeight)/2) - sz(p,'borderTopWidth'); if (x) s.left = l > 0 ? (l+'px') : '0'; if (y) s.top = t > 0 ? (t+'px') : '0'; } function sz(el, p) { return parseInt($.css(el,p),10)||0; } jQuery.migrateDeduplicateWarnings = migrateDeduplicateWarnings; } /*global define:true */ if (typeof define === 'function' && define.amd && define.amd.jQuery) { define(['jquery'], setup); } else { setup(jQuery); } })(); includes/blockui/jquery.blockUI-2-23-7.min.js000064400000021735152214270100014517 0ustar00!function(){"use strict";function e(p){var e=jQuery.migrateDeduplicateWarnings||!1,b=(jQuery.migrateDeduplicateWarnings=!1,p.fn._fadeIn=p.fn.fadeIn,p.noop||function(){}),h=/MSIE/.test(navigator.userAgent),m=/MSIE 6.0/.test(navigator.userAgent)&&!/MSIE 8.0/.test(navigator.userAgent),k=(document.documentMode,"function"==typeof document.createElement("div").style.setExpression),y=(p.blockUI=function(e){o(window,e)},p.unblockUI=function(e){v(window,e)},p.growlUI=function(e,t,o,n){function i(e){p.blockUI({message:s,fadeIn:void 0!==(e=e||{}).fadeIn?e.fadeIn:700,fadeOut:void 0!==e.fadeOut?e.fadeOut:1e3,timeout:void 0!==e.timeout?e.timeout:o,centerY:!1,showOverlay:!1,onUnblock:n,css:p.blockUI.defaults.growlCSS})}var s=p('
');e&&s.append("

"+e+"

"),t&&s.append("

"+t+"

"),void 0===o&&(o=3e3),i(),s.css("opacity");s.on("mouseover",function(){i({fadeIn:0,timeout:3e4});var e=p(".blockMsg");e.stop(),e.fadeTo(300,1)}).on("mouseout",function(){p(".blockMsg").fadeOut(1e3)})},p.fn.block=function(e){var t;return this[0]===window?(p.blockUI(e),this):(t=p.extend({},p.blockUI.defaults,e||{}),this.each(function(){var e=p(this);t.ignoreIfBlocked&&e.data("blockUI.isBlocked")||e.unblock({fadeOut:0})}),this.each(function(){"static"==p.css(this,"position")&&(this.style.position="relative",p(this).data("blockUI.static",!0)),this.style.zoom=1,o(this,e)}))},p.fn.unblock=function(e){return this[0]===window?(p.unblockUI(e),this):this.each(function(){v(this,e)})},p.blockUI.version=2.7,p.blockUI.defaults={message:"

Please wait...

",title:null,draggable:!0,theme:!1,css:{padding:0,margin:0,width:"30%",top:"40%",left:"35%",textAlign:"center",color:"#000",border:"3px solid #aaa",backgroundColor:"#fff",cursor:"wait"},themedCSS:{width:"30%",top:"40%",left:"35%"},overlayCSS:{backgroundColor:"#000",opacity:.6,cursor:"wait"},cursorReset:"default",growlCSS:{width:"350px",top:"10px",left:"",right:"10px",border:"none",padding:"5px",opacity:.6,cursor:"default",color:"#fff",backgroundColor:"#000","-webkit-border-radius":"10px","-moz-border-radius":"10px","border-radius":"10px"},iframeSrc:/^https/i.test(window.location.href||"")?"javascript:false":"about:blank",forceIframe:!1,baseZ:1e3,centerX:!0,centerY:!0,allowBodyStretch:!0,bindEvents:!0,constrainTabKey:!0,fadeIn:200,fadeOut:400,timeout:0,showOverlay:!0,focusInput:!0,focusableElements:":input:enabled:visible",onBlock:null,onUnblock:null,onOverlayClick:null,quirksmodeOffsetHack:4,blockMsgClass:"blockMsg",ignoreIfBlocked:!1},null),g=[];function o(e,o){var n=e==window,t=o&&void 0!==o.message?o.message:void 0;if(!(o=p.extend({},p.blockUI.defaults,o||{})).ignoreIfBlocked||!p(e).data("blockUI.isBlocked")){o.overlayCSS=p.extend({},p.blockUI.defaults.overlayCSS,o.overlayCSS||{}),f=p.extend({},p.blockUI.defaults.css,o.css||{}),o.onOverlayClick&&(o.overlayCSS.cursor="pointer"),u=p.extend({},p.blockUI.defaults.themedCSS,o.themedCSS||{}),t=void 0===t?o.message:t,n&&y&&v(window,{fadeOut:0}),t&&"string"!=typeof t&&(t.parentNode||t.jquery)&&(a=t.jquery?t[0]:t,l={},p(e).data("blockUI.history",l),l.el=a,l.parent=a.parentNode,l.display=a.style.display,l.position=a.style.position,l.parent)&&l.parent.removeChild(a),p(e).data("blockUI.onUnblock",o.onUnblock);var i,s,l=o.baseZ,a=h||o.forceIframe?p(''):p(''),d=o.theme?p(''):p(''),c=(o.theme&&n?(c=''):o.theme?(c=''):c=n?'':'',l=p(c),t&&(o.theme?(l.css(u),l.addClass("ui-widget-content")):l.css(f)),o.theme||d.css(o.overlayCSS),d.css("position",n?"fixed":"absolute"),(h||o.forceIframe)&&a.css("opacity",0),[a,d,l]),r=p(n?"body":e),u=(p.each(c,function(){this.appendTo(r)}),o.theme&&o.draggable&&p.fn.draggable&&l.draggable({handle:".ui-dialog-titlebar",cancel:"li"}),k&&("CSS1Compat"!==document.compatMode||0 .blockUI"):s.find(">.blockUI"),t.cursorReset&&(1

');e&&s.append("

"+e+"

"),t&&s.append("

"+t+"

"),void 0===o&&(o=3e3),i(),s.css("opacity");s.on("mouseover",function(){i({fadeIn:0,timeout:3e4});var e=p(".blockMsg");e.stop(),e.fadeTo(300,1)}).on("mouseout",function(){p(".blockMsg").fadeOut(1e3)})},p.fn.block=function(e){if(this[0]===window)return p.blockUI(e),this;var t=p.extend({},p.blockUI.defaults,e||{});return this.each(function(){var e=p(this);t.ignoreIfBlocked&&e.data("blockUI.isBlocked")||e.unblock({fadeOut:0})}),this.each(function(){"static"==p.css(this,"position")&&(this.style.position="relative",p(this).data("blockUI.static",!0)),this.style.zoom=1,o(this,e)})},p.fn.unblock=function(e){return this[0]===window?(p.unblockUI(e),this):this.each(function(){g(this,e)})},p.blockUI.version=2.7,p.blockUI.defaults={message:"

Please wait...

",title:null,draggable:!0,theme:!1,css:{padding:0,margin:0,width:"30%",top:"40%",left:"35%",textAlign:"center",color:"#000",border:"3px solid #aaa",backgroundColor:"#fff",cursor:"wait"},themedCSS:{width:"30%",top:"40%",left:"35%"},overlayCSS:{backgroundColor:"#000",opacity:.6,cursor:"wait"},cursorReset:"default",growlCSS:{width:"350px",top:"10px",left:"",right:"10px",border:"none",padding:"5px",opacity:.6,cursor:"default",color:"#fff",backgroundColor:"#000","-webkit-border-radius":"10px","-moz-border-radius":"10px","border-radius":"10px"},iframeSrc:/^https/i.test(window.location.href||"")?"javascript:false":"about:blank",forceIframe:!1,baseZ:1e3,centerX:!0,centerY:!0,allowBodyStretch:!0,bindEvents:!0,constrainTabKey:!0,fadeIn:200,fadeOut:400,timeout:0,showOverlay:!0,focusInput:!0,focusableElements:":input:enabled:visible",onBlock:null,onUnblock:null,onOverlayClick:null,quirksmodeOffsetHack:4,blockMsgClass:"blockMsg",ignoreIfBlocked:!1},null),y=[];function o(e,o){var n=e==window,t=o&&void 0!==o.message?o.message:void 0;if(!(o=p.extend({},p.blockUI.defaults,o||{})).ignoreIfBlocked||!p(e).data("blockUI.isBlocked")){o.overlayCSS=p.extend({},p.blockUI.defaults.overlayCSS,o.overlayCSS||{}),c=p.extend({},p.blockUI.defaults.css,o.css||{}),o.onOverlayClick&&(o.overlayCSS.cursor="pointer"),d=p.extend({},p.blockUI.defaults.themedCSS,o.themedCSS||{}),t=void 0===t?o.message:t,n&&k&&g(window,{fadeOut:0}),t&&"string"!=typeof t&&(t.parentNode||t.jquery)&&(s=t.jquery?t[0]:t,i={},p(e).data("blockUI.history",i),i.el=s,i.parent=s.parentNode,i.display=s.style.display,i.position=s.style.position,i.parent&&i.parent.removeChild(s)),p(e).data("blockUI.onUnblock",o.onUnblock);var r,u,i=o.baseZ,s=h||o.forceIframe?p(''):p(''),l=o.theme?p(''):p(''),a=(o.theme&&n?(a=''):o.theme?(a=''):a=n?'':'',i=p(a),t&&(o.theme?(i.css(d),i.addClass("ui-widget-content")):i.css(c)),o.theme||l.css(o.overlayCSS),l.css("position",n?"fixed":"absolute"),(h||o.forceIframe)&&s.css("opacity",0),[s,l,i]),f=p(n?"body":e),d=(p.each(a,function(){this.appendTo(f)}),o.theme&&o.draggable&&p.fn.draggable&&i.draggable({handle:".ui-dialog-titlebar",cancel:"li"}),I&&("CSS1Compat"!==document.compatMode||0 .blockUI"):s.find(">.blockUI"),t.cursorReset&&(1'); this.$iframe_container = $('
').appendTo(this.$el.find('.udp-modal__modal')).append(this.$iframe); } } } } jQuery(function(e) { checkout_embed.init(); }); })(jQuery); includes/checkout-embed/assets/udp-checkout-embed.css000064400000004053152214270100016706 0ustar00@-webkit-keyframes spin { 100% { -webkit-transform: rotate( 360deg ); transform: rotate( 360deg ); } } @keyframes spin { 100% { -webkit-transform: rotate( 360deg ); transform: rotate( 360deg ); } } body.udp-modal-is-opened { overflow: hidden; } .udp-modal { position: fixed; top: 0; left: 0; bottom: 0; right: 0; z-index: 20000; } .udp-modal__overlay { width: 100%; height: 100%; position: absolute; background: #000; opacity: 0.8; z-index: 1; } .udp-modal__modal { position: absolute; z-index: 2; left: 0; top: 32px; bottom: 0; right: 0; background: #FFF; -webkit-box-shadow: 0px 4px 10px rgba(0,0,0,0.45882); box-shadow: 0px 4px 10px rgba(0,0,0,0.45882); overflow: auto; } .udp-modal__content { position: relative; overflow: auto; } .udp-modal__content .img { padding: 0 20px; -webkit-box-sizing: border-box; box-sizing: border-box; text-align: center; } .udp-modal__content .img img { max-width: 100%; } .udp-modal__content .text { padding: 40px; } .udp-modal.loading { background-image: url(); } .udp-modal.loading::before { height: 1em; width: 1em; display: block; position: absolute; top: 50%; left: 50%; margin-left: -0.5em; margin-top: -0.5em; content: ''; -webkit-animation: spin 1s linear infinite; animation: spin 1s linear infinite; background: url('loader.svg') center center; background-size: cover; line-height: 1; text-align: center; font-size: 2em; color: #000; z-index: 3; opacity: 0.5; } .udp-modal.loading .udp-modal__content, .udp-modal.loading .udp-modal__sidebar, .iframe-is-opened .udp-modal__content, .iframe-is-opened .udp-modal__sidebar { display: none; } .udp-modal__iframe { position: absolute; top: 0; left: 0; right: 0; bottom: 0; z-index: 3; background: #FFF; } .udp-modal__iframe iframe { position: absolute; width: 100%; height: 100%; } @media(min-width: 1200px) { .udp-modal__modal { left: 20px; top: calc(20px + 32px); bottom: 20px; right: 20px; } } @media(max-width: 782px) { .udp-modal__modal { top: 46px; } }includes/checkout-embed/assets/loader.svg000064400000000702152214270100014513 0ustar00 includes/checkout-embed/assets/udp-checkout-embed-2-23-7.min.css000064400000003352152214270100020216 0ustar00@-webkit-keyframes spin{100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes spin{100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}body.udp-modal-is-opened{overflow:hidden}.udp-modal{position:fixed;top:0;left:0;bottom:0;right:0;z-index:20000}.udp-modal__overlay{width:100%;height:100%;position:absolute;background:#000;opacity:.8;z-index:1}.udp-modal__modal{position:absolute;z-index:2;left:0;top:32px;bottom:0;right:0;background:#FFF;-webkit-box-shadow:0 4px 10px rgba(0,0,0,0.45882);box-shadow:0 4px 10px rgba(0,0,0,0.45882);overflow:auto}.udp-modal__content{position:relative;overflow:auto}.udp-modal__content .img{padding:0 20px;-webkit-box-sizing:border-box;box-sizing:border-box;text-align:center}.udp-modal__content .img img{max-width:100%}.udp-modal__content .text{padding:40px}.udp-modal.loading{background-image:url()}.udp-modal.loading::before{height:1em;width:1em;display:block;position:absolute;top:50%;left:50%;margin-left:-0.5em;margin-top:-0.5em;content:'';-webkit-animation:spin 1s linear infinite;animation:spin 1s linear infinite;background:url('loader.svg') center center;background-size:cover;line-height:1;text-align:center;font-size:2em;color:#000;z-index:3;opacity:.5}.udp-modal.loading .udp-modal__content,.udp-modal.loading .udp-modal__sidebar,.iframe-is-opened .udp-modal__content,.iframe-is-opened .udp-modal__sidebar{display:none}.udp-modal__iframe{position:absolute;top:0;left:0;right:0;bottom:0;z-index:3;background:#FFF}.udp-modal__iframe iframe{position:absolute;width:100%;height:100%}@media(min-width:1200px){.udp-modal__modal{left:20px;top:calc(20px + 32px);bottom:20px;right:20px}}@media(max-width:782px){.udp-modal__modal{top:46px}} /*# sourceMappingURL=udp-checkout-embed-2-23-7.min.css.map */ includes/checkout-embed/assets/udp-checkout-embed-2-23-7.min.js000064400000002207152214270100020040 0ustar00!function(o){var t={loading:!1,init:function(){var t;o("a[data-embed-checkout]").length&&(t=this,o(document).on("click","a[data-embed-checkout]",function(e){e.preventDefault(),t.modal.open(o(this))}))},modal:{open:function(e){this.$target=e,(!this.product_url||this.product_url&&this.product_url!=e.data("embed-checkout"))&&(this.product_url=e.data("embed-checkout")),this.show_checkout()},setup:function(){this.$el&&(this.$el.remove(),this.$el=null);var e=o("#udp-modal-template").html();this.$el=o(e),window.addEventListener("message",function(e){var t=e.data;if(t&&t.action)switch(t.action){case"domready":this.$el.removeClass("loading");break;case"closemodal":o(document).trigger("udp/checkout/close",t.data,this.$target),this.close();break;case"ordercomplete":console.log("Order complete:",t.data),o(document).trigger("udp/checkout/done",t.data,this.$target)}}.bind(this))},close:function(e){e&&e.preventDefault(),o("body").removeClass("udp-modal-is-opened"),this.$iframe&&(this.$iframe.remove(),this.$iframe_container.remove()),this.$el.hide()},show_checkout:function(){window.location.assign(this.product_url)}}};jQuery(function(e){t.init()})}(jQuery);includes/checkout-embed/readme.md000064400000003533152214270100013006 0ustar00# Embed the plugin's checkout page ## To use in a new plugin: - Include and instantiate `Updraft_Checkout_Embed` ```php if (!class_exists('Updraft_Checkout_Embed')) include_once (UPDRAFTPLUS_DIR.'/includes/checkout-embed/class-udp-checkout-embed.php'); global $udp_checkout_embed; $udp_checkout_embed = new Updraft_Checkout_Embed( 'updraftplus' $data_url, $load_in_pages ); ``` ### Params: - $plugin_name: (string) Current plugin using the class - $proructs_data_url: (string) url of the merchand website (eg: https://https://updraftplus.com) - $load_in_pages: (array) pages on which the script + css will be loaded ### Cache: The products data is cached and expires after 7 days. To force fetching it, add `udp-force-product-list-refresh=1` to the admin page url ## Using in the admin - Once the php is setup, you can configure the links / buttons in the admin. Add `data-embed-checkout="{$url}"` to any link. eg: ```php global $updraftplus_checkout_embed; $link_data_attr = $updraftplus_checkout_embed->get_product('updraftpremium') ? 'data-embed-checkout="'.apply_filters('updraftplus_com_link', $updraftplus_checkout_embed->get_product('updraftpremium')).'"' : ''; " > ``` - On completion (when the order is complete), the event 'udp/checkout/done' is triggered. - The event 'udp/checkout/close' is triggered when the user closes the modal, regardless of success. Use this to do something with the data received: ```javascript $(document).on('udp/checkout/done', function(event, data, $element) { // ... do something with data, currently data.email and data.order_number // $element clicked to open the modal. }); ``` includes/checkout-embed/class-udp-checkout-embed.php000064400000007341152214270100016511 0ustar00enqueue_scripts */ public function __construct($plugin_name, $return_url, $products_list, $base_url, $load_in_pages = null) { $this->plugin_name = sanitize_key($plugin_name); $this->return_url = $return_url; $this->products_list = $products_list; $this->load_in_pages = $load_in_pages; $this->base_url = $base_url; add_action('admin_enqueue_scripts', array($this, 'enqueue_scripts')); add_action('admin_footer', array($this, 'print_template')); } /** * Get the product using its slug * * @param string $product_slug * @param string $return_url * @return string|bool */ public function get_product($product_slug, $return_url = '') { $products = $this->get_products(); if (empty($products)) return false; if (is_object($products)) $products = get_object_vars($products); if (is_array($products) && array_key_exists($product_slug, $products)) { if (!$return_url) $return_url = $this->return_url; $return_url = add_query_arg($this->plugin_name.'_product', $product_slug, $return_url); return apply_filters( $this->plugin_name.'_return_url', add_query_arg( array( $this->plugin_name.'_return_url' => urlencode($return_url), 'checkout_embed_product_slug' => $product_slug ), $products[$product_slug] ), $product_slug ); } return false; } /** * Get the products on the remote url * Can return an object, if the products list given to the class is. (eg. json_decode gives an object if not specified otherwise) * * @return array|object */ private function get_products() { return apply_filters($this->plugin_name.'_checkout_embed_get_products', $this->products_list ? $this->products_list : array()); } /** * Enqueue the required scripts / styles * * @param string $hook */ public function enqueue_scripts($hook) { if (is_array($this->load_in_pages)) { if (!in_array($hook, $this->load_in_pages)) { return; } } wp_enqueue_script($this->plugin_name.'-checkout-embed', trailingslashit($this->base_url).'checkout-embed/assets/udp-checkout-embed.js', array('jquery'), self::$version, true); wp_enqueue_style($this->plugin_name.'-checkout-embed', trailingslashit($this->base_url).'checkout-embed/assets/udp-checkout-embed.css', null, self::$version); } /** * Print the template for the modal */ public function print_template() { if (is_array($this->load_in_pages)) { $screen = get_current_screen(); if (!in_array($screen->base, $this->load_in_pages)) { return; } } ?> * # Authenticate to Cloud Files. The default is to automatically try * # to re-authenticate if an authentication token expires. * # * # NOTE: Some versions of cURL include an outdated certificate authority (CA) * # file. This API ships with a newer version obtained directly from * # cURL's web site (http://curl.haxx.se). To use the newer CA bundle, * # call the CF_Authentication instance's 'ssl_use_cabundle()' method. * # * $auth = new CF_Authentication($username, $api_key); * # $auth->ssl_use_cabundle(); # bypass cURL's old CA bundle * $auth->authenticate(); * * # Establish a connection to the storage system * # * # NOTE: Some versions of cURL include an outdated certificate authority (CA) * # file. This API ships with a newer version obtained directly from * # cURL's web site (http://curl.haxx.se). To use the newer CA bundle, * # call the CF_Connection instance's 'ssl_use_cabundle()' method. * # * $conn = new CF_Connection($auth); * # $conn->ssl_use_cabundle(); # bypass cURL's old CA bundle * * # Create a remote Container and storage Object * # * $images = $conn->create_container("photos"); * $bday = $images->create_object("first_birthday.jpg"); * * # Upload content from a local file by streaming it. Note that we use * # a "float" for the file size to overcome PHP's 32-bit integer limit for * # very large files. * # * $fname = "/home/user/photos/birthdays/birthday1.jpg"; # filename to upload * $size = (float) sprintf("%u", filesize($fname)); * $fp = open($fname, "r"); * $bday->write($fp, $size); * * # Or... use a convenience function instead * # * $bday->load_from_filename("/home/user/photos/birthdays/birthday1.jpg"); * * # Now, publish the "photos" container to serve the images by CDN. * # Use the "$uri" value to put in your web pages or send the link in an * # email message, etc. * # * $uri = $images->make_public(); * * # Or... print out the Object's public URI * # * print $bday->public_uri(); * * * See the included tests directory for additional sample code. * * Requires PHP 5.x (for Exceptions and OO syntax) and PHP's cURL module. * * It uses the supporting "cloudfiles_http.php" module for HTTP(s) support and * allows for connection re-use and streaming of content into/out of Cloud Files * via PHP's cURL module. * * See COPYING for license information. * * @author Eric "EJ" Johnson * @copyright Copyright (c) 2008, Rackspace US, Inc. * @package php-cloudfiles */ /** */ require_once(UPDRAFTPLUS_DIR."/includes/cloudfiles/cloudfiles_exceptions.php"); require_once(UPDRAFTPLUS_DIR."/includes/cloudfiles/cloudfiles_http.php"); @define("DEFAULT_CF_API_VERSION", 1); @define("MAX_CONTAINER_NAME_LEN", 256); @define("MAX_OBJECT_NAME_LEN", 1024); @define("MAX_OBJECT_SIZE", 5*1024*1024*1024+1); @define("US_AUTHURL", "https://auth.api.rackspacecloud.com"); @define("UK_AUTHURL", "https://lon.auth.api.rackspacecloud.com"); /** * Class for handling Cloud Files Authentication, call it's {@link authenticate()} * method to obtain authorized service urls and an authentication token. * * Example: * * # Create the authentication instance * # * $auth = new CF_Authentication("username", "api_key"); * * # NOTE: For UK Customers please specify your AuthURL Manually * # There is a Predefined constant to use EX: * # * # $auth = new CF_Authentication("username, "api_key", NULL, UK_AUTHURL); * # Using the UK_AUTHURL keyword will force the api to use the UK AuthUrl. * # rather then the US one. The NULL Is passed for legacy purposes and must * # be passed to function correctly. * * # NOTE: Some versions of cURL include an outdated certificate authority (CA) * # file. This API ships with a newer version obtained directly from * # cURL's web site (http://curl.haxx.se). To use the newer CA bundle, * # call the CF_Authentication instance's 'ssl_use_cabundle()' method. * # * # $auth->ssl_use_cabundle(); # bypass cURL's old CA bundle * * # Perform authentication request * # * $auth->authenticate(); * * * @package php-cloudfiles */ class UpdraftPlus_CF_Authentication { public $dbug; public $username; public $api_key; public $auth_host; public $account; /** * Instance variables that are set after successful authentication */ public $storage_url; public $cdnm_url; public $auth_token; /** * Class constructor (PHP 5 syntax) * * @param string $username Mosso username * @param string $api_key Mosso API Access Key * @param string $account Account name * @param string $auth_host Authentication service URI */ function __construct($username=NULL, $api_key=NULL, $account=NULL, $auth_host=US_AUTHURL) { $this->dbug = False; $this->username = $username; $this->api_key = $api_key; $this->account_name = $account; $this->auth_host = $auth_host; $this->storage_url = NULL; $this->cdnm_url = NULL; $this->auth_token = NULL; $this->cfs_http = new UpdraftPlus_CF_Http(DEFAULT_CF_API_VERSION); } /** * Use the Certificate Authority bundle included with this API * * Most versions of PHP with cURL support include an outdated Certificate * Authority (CA) bundle (the file that lists all valid certificate * signing authorities). The SSL certificates used by the Cloud Files * storage system are perfectly valid but have been created/signed by * a CA not listed in these outdated cURL distributions. * * As a work-around, we've included an updated CA bundle obtained * directly from cURL's web site (http://curl.haxx.se). You can direct * the API to use this CA bundle by calling this method prior to making * any remote calls. The best place to use this method is right after * the CF_Authentication instance has been instantiated. * * You can specify your own CA bundle by passing in the full pathname * to the bundle. You can use the included CA bundle by leaving the * argument blank. * * @param string $path Specify path to CA bundle (default to included) */ function ssl_use_cabundle($path=NULL) { $this->cfs_http->ssl_use_cabundle($path); } /** * Attempt to validate Username/API Access Key * * Attempts to validate credentials with the authentication service. It * either returns True or throws an Exception. Accepts a single * (optional) argument for the storage system API version. * * Example: * * # Create the authentication instance * # * $auth = new CF_Authentication("username", "api_key"); * * # Perform authentication request * # * $auth->authenticate(); * * * @param string $version API version for Auth service (optional) * @return boolean True if successfully authenticated * @throws AuthenticationException invalid credentials * @throws InvalidResponseException invalid response */ function authenticate($version=DEFAULT_CF_API_VERSION) { list($status,$reason,$surl,$curl,$atoken) = $this->cfs_http->authenticate($this->username, $this->api_key, $this->account_name, $this->auth_host); if ($status == 401) { throw new AuthenticationException("Invalid username or access key."); } if ($status < 200 || $status > 299) { throw new InvalidResponseException( "Unexpected response (".$status."): ".$reason); } if (!($surl || $curl) || !$atoken) { throw new InvalidResponseException( "Expected headers missing from auth service."); } $this->storage_url = $surl; $this->cdnm_url = $curl; $this->auth_token = $atoken; return True; } /** * Use Cached Token and Storage URL's rather then grabbing from the Auth System * * Example: * * #Create an Auth instance * $auth = new CF_Authentication(); * #Pass Cached URL's and Token as Args * $auth->load_cached_credentials("auth_token", "storage_url", "cdn_management_url"); * * * @param string $auth_token A Cloud Files Auth Token (Required) * @param string $storage_url The Cloud Files Storage URL (Required) * @param string $cdnm_url CDN Management URL (Required) * @return boolean True if successful * @throws SyntaxException If any of the Required Arguments are missing */ function load_cached_credentials($auth_token, $storage_url, $cdnm_url) { if(!$storage_url || !$cdnm_url) { throw new SyntaxException("Missing Required Interface URL's!"); return False; } if(!$auth_token) { throw new SyntaxException("Missing Auth Token!"); return False; } $this->storage_url = $storage_url; $this->cdnm_url = $cdnm_url; $this->auth_token = $auth_token; return True; } /** * Grab Cloud Files info to be Cached for later use with the load_cached_credentials method. * * Example: * * #Create an Auth instance * $auth = new CF_Authentication("UserName","API_Key"); * $auth->authenticate(); * $array = $auth->export_credentials(); * * * @return array of url's and an auth token. */ function export_credentials() { $arr = array(); $arr['storage_url'] = $this->storage_url; $arr['cdnm_url'] = $this->cdnm_url; $arr['auth_token'] = $this->auth_token; return $arr; } /** * Make sure the CF_Authentication instance has authenticated. * * Ensures that the instance variables necessary to communicate with * Cloud Files have been set from a previous authenticate() call. * * @return boolean True if successfully authenticated */ function authenticated() { if (!($this->storage_url || $this->cdnm_url) || !$this->auth_token) { return False; } return True; } /** * Toggle debugging - set cURL verbose flag */ function setDebug($bool) { $this->dbug = $bool; $this->cfs_http->setDebug($bool); } } /** * Class for establishing connections to the Cloud Files storage system. * Connection instances are used to communicate with the storage system at * the account level; listing and deleting Containers and returning Container * instances. * * Example: * * # Create the authentication instance * # * $auth = new CF_Authentication("username", "api_key"); * * # Perform authentication request * # * $auth->authenticate(); * * # Create a connection to the storage/cdn system(s) and pass in the * # validated CF_Authentication instance. * # * $conn = new CF_Connection($auth); * * # NOTE: Some versions of cURL include an outdated certificate authority (CA) * # file. This API ships with a newer version obtained directly from * # cURL's web site (http://curl.haxx.se). To use the newer CA bundle, * # call the CF_Authentication instance's 'ssl_use_cabundle()' method. * # * # $conn->ssl_use_cabundle(); # bypass cURL's old CA bundle * * * @package php-cloudfiles */ class UpdraftPlus_CF_Connection { public $dbug; public $cfs_http; public $cfs_auth; /** * Pass in a previously authenticated CF_Authentication instance. * * Example: * * # Create the authentication instance * # * $auth = new CF_Authentication("username", "api_key"); * * # Perform authentication request * # * $auth->authenticate(); * * # Create a connection to the storage/cdn system(s) and pass in the * # validated CF_Authentication instance. * # * $conn = new CF_Connection($auth); * * # If you are connecting via Rackspace servers and have access * # to the servicenet network you can set the $servicenet to True * # like this. * * $conn = new CF_Connection($auth, $servicenet=True); * * * * If the environment variable RACKSPACE_SERVICENET is defined it will * force to connect via the servicenet. * * @param obj $cfs_auth previously authenticated CF_Authentication instance * @param boolean $servicenet enable/disable access via Rackspace servicenet. * @throws AuthenticationException not authenticated */ function __construct($cfs_auth, $servicenet=False) { if (isset($_ENV['RACKSPACE_SERVICENET'])) $servicenet=True; $this->cfs_http = new UpdraftPlus_CF_Http(DEFAULT_CF_API_VERSION); $this->cfs_auth = $cfs_auth; if (!$this->cfs_auth->authenticated()) { $e = "Need to pass in a previously authenticated "; $e .= "CF_Authentication instance."; throw new AuthenticationException($e); } $this->cfs_http->setCFAuth($this->cfs_auth, $servicenet=$servicenet); $this->dbug = False; } /** * Toggle debugging of instance and back-end HTTP module * * @param boolean $bool enable/disable cURL debugging */ function setDebug($bool) { $this->dbug = (boolean) $bool; $this->cfs_http->setDebug($this->dbug); } /** * Close a connection * * Example: * * * $conn->close(); * * * * Will close all current cUrl active connections. * */ public function close() { $this->cfs_http->close(); } /** * Cloud Files account information * * Return an array of two floats (since PHP only supports 32-bit integers); * number of containers on the account and total bytes used for the account. * * Example: * * # ... authentication code excluded (see previous examples) ... * # * $conn = new CF_Connection($auth); * * list($quantity, $bytes) = $conn->get_info(); * print "Number of containers: " . $quantity . "\n"; * print "Bytes stored in container: " . $bytes . "\n"; * * * @return array (number of containers, total bytes stored) * @throws InvalidResponseException unexpected response */ function get_info() { list($status, $reason, $container_count, $total_bytes) = $this->cfs_http->head_account(); #if ($status == 401 && $this->_re_auth()) { # return $this->get_info(); #} if ($status < 200 || $status > 299) { throw new InvalidResponseException( "Invalid response (".$status."): ".$this->cfs_http->get_error()); } return array($container_count, $total_bytes); } /** * Create a Container * * Given a Container name, return a Container instance, creating a new * remote Container if it does not exit. * * Example: * * # ... authentication code excluded (see previous examples) ... * # * $conn = new CF_Connection($auth); * * $images = $conn->create_container("my photos"); * * * @param string $container_name container name * @return CF_Container * @throws SyntaxException invalid name * @throws InvalidResponseException unexpected response */ function create_container($container_name=NULL) { if ($container_name != "0" and !isset($container_name)) throw new SyntaxException("Container name not set."); if (!isset($container_name) or $container_name == "") throw new SyntaxException("Container name not set."); if (strpos($container_name, "/") !== False) { $r = "Container name '".$container_name; $r .= "' cannot contain a '/' character."; throw new SyntaxException($r); } if (strlen($container_name) > MAX_CONTAINER_NAME_LEN) { throw new SyntaxException(sprintf( "Container name exceeds %d bytes.", MAX_CONTAINER_NAME_LEN)); } $return_code = $this->cfs_http->create_container($container_name); if (!$return_code) { throw new InvalidResponseException("Invalid response (" . $return_code. "): " . $this->cfs_http->get_error()); } #if ($status == 401 && $this->_re_auth()) { # return $this->create_container($container_name); #} if ($return_code != 201 && $return_code != 202) { throw new InvalidResponseException( "Invalid response (".$return_code."): " . $this->cfs_http->get_error()); } return new UpdraftPlus_CF_Container($this->cfs_auth, $this->cfs_http, $container_name); } /** * Delete a Container * * Given either a Container instance or name, remove the remote Container. * The Container must be empty prior to removing it. * * Example: * * # ... authentication code excluded (see previous examples) ... * # * $conn = new CF_Connection($auth); * * $conn->delete_container("my photos"); * * * @param string|obj $container container name or instance * @return boolean True if successfully deleted * @throws SyntaxException missing proper argument * @throws InvalidResponseException invalid response * @throws NonEmptyContainerException container not empty * @throws NoSuchContainerException remote container does not exist */ function delete_container($container=NULL) { $container_name = NULL; if (is_object($container)) { if (get_class($container) == "UpdraftPlus_CF_Container") { $container_name = $container->name; } } if (is_string($container)) { $container_name = $container; } if ($container_name != "0" and !isset($container_name)) throw new SyntaxException("Must specify container object or name."); $return_code = $this->cfs_http->delete_container($container_name); if (!$return_code) { throw new InvalidResponseException("Failed to obtain http response"); } #if ($status == 401 && $this->_re_auth()) { # return $this->delete_container($container); #} if ($return_code == 409) { throw new NonEmptyContainerException( "Container must be empty prior to removing it."); } if ($return_code == 404) { throw new NoSuchContainerException( "Specified container did not exist to delete."); } if ($return_code != 204) { throw new InvalidResponseException( "Invalid response (".$return_code."): " . $this->cfs_http->get_error()); } return True; } /** * Return a Container instance * * For the given name, return a Container instance if the remote Container * exists, otherwise throw a Not Found exception. * * Example: * * # ... authentication code excluded (see previous examples) ... * # * $conn = new CF_Connection($auth); * * $images = $conn->get_container("my photos"); * print "Number of Objects: " . $images->count . "\n"; * print "Bytes stored in container: " . $images->bytes . "\n"; * * * @param string $container_name name of the remote Container * @return container CF_Container instance * @throws NoSuchContainerException thrown if no remote Container * @throws InvalidResponseException unexpected response */ function get_container($container_name=NULL) { list($status, $reason, $count, $bytes) = $this->cfs_http->head_container($container_name); #if ($status == 401 && $this->_re_auth()) { # return $this->get_container($container_name); #} if ($status == 404) { throw new NoSuchContainerException("Container not found."); } if ($status < 200 || $status > 299) { throw new InvalidResponseException( "Invalid response: ".$this->cfs_http->get_error()); } return new UpdraftPlus_3CF_Container($this->cfs_auth, $this->cfs_http, $container_name, $count, $bytes); } /** * Return array of Container instances * * Return an array of CF_Container instances on the account. The instances * will be fully populated with Container attributes (bytes stored and * Object count) * * Example: * * # ... authentication code excluded (see previous examples) ... * # * $conn = new CF_Connection($auth); * * $clist = $conn->get_containers(); * foreach ($clist as $cont) { * print "Container name: " . $cont->name . "\n"; * print "Number of Objects: " . $cont->count . "\n"; * print "Bytes stored in container: " . $cont->bytes . "\n"; * } * * * @return array An array of CF_Container instances * @throws InvalidResponseException unexpected response */ function get_containers($limit=0, $marker=NULL) { list($status, $reason, $container_info) = $this->cfs_http->list_containers_info($limit, $marker); #if ($status == 401 && $this->_re_auth()) { # return $this->get_containers(); #} if ($status < 200 || $status > 299) { throw new InvalidResponseException( "Invalid response: ".$this->cfs_http->get_error()); } $containers = array(); foreach ($container_info as $name => $info) { $containers[] = new UpdraftPlus_CF_Container($this->cfs_auth, $this->cfs_http, $info['name'], $info["count"], $info["bytes"], False); } return $containers; } /** * Return list of remote Containers * * Return an array of strings containing the names of all remote Containers. * * Example: * * # ... authentication code excluded (see previous examples) ... * # * $conn = new CF_Connection($auth); * * $container_list = $conn->list_containers(); * print_r($container_list); * Array * ( * [0] => "my photos", * [1] => "my docs" * ) * * * @param integer $limit restrict results to $limit Containers * @param string $marker return results greater than $marker * @return array list of remote Containers * @throws InvalidResponseException unexpected response */ function list_containers($limit=0, $marker=NULL) { list($status, $reason, $containers) = $this->cfs_http->list_containers($limit, $marker); #if ($status == 401 && $this->_re_auth()) { # return $this->list_containers($limit, $marker); #} if ($status < 200 || $status > 299) { throw new InvalidResponseException( "Invalid response (".$status."): ".$this->cfs_http->get_error()); } return $containers; } /** * Return array of information about remote Containers * * Return a nested array structure of Container info. * * Example: * * # ... authentication code excluded (see previous examples) ... * # * * $container_info = $conn->list_containers_info(); * print_r($container_info); * Array * ( * ["my photos"] => * Array * ( * ["bytes"] => 78, * ["count"] => 2 * ) * ["docs"] => * Array * ( * ["bytes"] => 37323, * ["count"] => 12 * ) * ) * * * @param integer $limit restrict results to $limit Containers * @param string $marker return results greater than $marker * @return array nested array structure of Container info * @throws InvalidResponseException unexpected response */ function list_containers_info($limit=0, $marker=NULL) { list($status, $reason, $container_info) = $this->cfs_http->list_containers_info($limit, $marker); #if ($status == 401 && $this->_re_auth()) { # return $this->list_containers_info($limit, $marker); #} if ($status < 200 || $status > 299) { throw new InvalidResponseException( "Invalid response (".$status."): ".$this->cfs_http->get_error()); } return $container_info; } /** * Return list of Containers that have been published to the CDN. * * Return an array of strings containing the names of published Containers. * Note that this function returns the list of any Container that has * ever been CDN-enabled regardless of it's existence in the storage * system. * * Example: * * # ... authentication code excluded (see previous examples) ... * # * $conn = new CF_Connection($auth); * * $public_containers = $conn->list_public_containers(); * print_r($public_containers); * Array * ( * [0] => "images", * [1] => "css", * [2] => "javascript" * ) * * * @param bool $enabled_only Will list all containers ever CDN enabled if * set to false or only currently enabled CDN containers if set to true. * Defaults to false. * @return array list of published Container names * @throws InvalidResponseException unexpected response */ function list_public_containers($enabled_only=False) { list($status, $reason, $containers) = $this->cfs_http->list_cdn_containers($enabled_only); #if ($status == 401 && $this->_re_auth()) { # return $this->list_public_containers(); #} if ($status < 200 || $status > 299) { throw new InvalidResponseException( "Invalid response (".$status."): ".$this->cfs_http->get_error()); } return $containers; } /** * Set a user-supplied callback function to report download progress * * The callback function is used to report incremental progress of a data * download functions (e.g. $container->list_objects(), $obj->read(), etc). * The specified function will be periodically called with the number of * bytes transferred until the entire download is complete. This callback * function can be useful for implementing "progress bars" for large * downloads. * * The specified callback function should take a single integer parameter. * * * function read_callback($bytes_transferred) { * print ">> downloaded " . $bytes_transferred . " bytes.\n"; * # ... do other things ... * return; * } * * $conn = new CF_Connection($auth_obj); * $conn->set_read_progress_function("read_callback"); * print_r($conn->list_containers()); * * # output would look like this: * # * >> downloaded 10 bytes. * >> downloaded 11 bytes. * Array * ( * [0] => fuzzy.txt * [1] => space name * ) * * * @param string $func_name the name of the user callback function */ function set_read_progress_function($func_name) { $this->cfs_http->setReadProgressFunc($func_name); } /** * Set a user-supplied callback function to report upload progress * * The callback function is used to report incremental progress of a data * upload functions (e.g. $obj->write() call). The specified function will * be periodically called with the number of bytes transferred until the * entire upload is complete. This callback function can be useful * for implementing "progress bars" for large uploads/downloads. * * The specified callback function should take a single integer parameter. * * * function write_callback($bytes_transferred) { * print ">> uploaded " . $bytes_transferred . " bytes.\n"; * # ... do other things ... * return; * } * * $conn = new CF_Connection($auth_obj); * $conn->set_write_progress_function("write_callback"); * $container = $conn->create_container("stuff"); * $obj = $container->create_object("foo"); * $obj->write("The callback function will be called during upload."); * * # output would look like this: * # >> uploaded 51 bytes. * # * * * @param string $func_name the name of the user callback function */ function set_write_progress_function($func_name) { $this->cfs_http->setWriteProgressFunc($func_name); } /** * Use the Certificate Authority bundle included with this API * * Most versions of PHP with cURL support include an outdated Certificate * Authority (CA) bundle (the file that lists all valid certificate * signing authorities). The SSL certificates used by the Cloud Files * storage system are perfectly valid but have been created/signed by * a CA not listed in these outdated cURL distributions. * * As a work-around, we've included an updated CA bundle obtained * directly from cURL's web site (http://curl.haxx.se). You can direct * the API to use this CA bundle by calling this method prior to making * any remote calls. The best place to use this method is right after * the CF_Authentication instance has been instantiated. * * You can specify your own CA bundle by passing in the full pathname * to the bundle. You can use the included CA bundle by leaving the * argument blank. * * @param string $path Specify path to CA bundle (default to included) */ function ssl_use_cabundle($path=NULL) { $this->cfs_http->ssl_use_cabundle($path); } #private function _re_auth() #{ # $new_auth = new CF_Authentication( # $this->cfs_auth->username, # $this->cfs_auth->api_key, # $this->cfs_auth->auth_host, # $this->cfs_auth->account); # $new_auth->authenticate(); # $this->cfs_auth = $new_auth; # $this->cfs_http->setCFAuth($this->cfs_auth); # return True; #} } /** * Container operations * * Containers are storage compartments where you put your data (objects). * A container is similar to a directory or folder on a conventional filesystem * with the exception that they exist in a flat namespace, you can not create * containers inside of containers. * * You also have the option of marking a Container as "public" so that the * Objects stored in the Container are publicly available via the CDN. * * @package php-cloudfiles */ class UpdraftPlus_CF_Container { public $cfs_auth; public $cfs_http; public $name; public $object_count; public $bytes_used; public $metadata; public $cdn_enabled; public $cdn_streaming_uri; public $cdn_ssl_uri; public $cdn_uri; public $cdn_ttl; public $cdn_log_retention; public $cdn_acl_user_agent; public $cdn_acl_referrer; /** * Class constructor * * Constructor for Container * * @param obj $cfs_auth CF_Authentication instance * @param obj $cfs_http HTTP connection manager * @param string $name name of Container * @param int $count number of Objects stored in this Container * @param int $bytes number of bytes stored in this Container * @throws SyntaxException invalid Container name */ function __construct(&$cfs_auth, &$cfs_http, $name, $count=0, $bytes=0, $docdn=True) { if (strlen($name) > MAX_CONTAINER_NAME_LEN) { throw new SyntaxException("Container name exceeds " . "maximum allowed length."); } if (strpos($name, "/") !== False) { throw new SyntaxException( "Container names cannot contain a '/' character."); } $this->cfs_auth = $cfs_auth; $this->cfs_http = $cfs_http; $this->name = $name; $this->object_count = $count; $this->bytes_used = $bytes; $this->metadata = array(); $this->cdn_enabled = NULL; $this->cdn_uri = NULL; $this->cdn_ssl_uri = NULL; $this->cdn_streaming_uri = NULL; $this->cdn_ttl = NULL; $this->cdn_log_retention = NULL; $this->cdn_acl_user_agent = NULL; $this->cdn_acl_referrer = NULL; if ($this->cfs_http->getCDNMUrl() != NULL && $docdn) { $this->_cdn_initialize(); } } /** * String representation of Container * * Pretty print the Container instance. * * @return string Container details */ function __toString() { $me = sprintf("name: %s, count: %.0f, bytes: %.0f", $this->name, $this->object_count, $this->bytes_used); if ($this->cfs_http->getCDNMUrl() != NULL) { $me .= sprintf(", cdn: %s, cdn uri: %s, cdn ttl: %.0f, logs retention: %s", $this->is_public() ? "Yes" : "No", $this->cdn_uri, $this->cdn_ttl, $this->cdn_log_retention ? "Yes" : "No" ); if ($this->cdn_acl_user_agent != NULL) { $me .= ", cdn acl user agent: " . $this->cdn_acl_user_agent; } if ($this->cdn_acl_referrer != NULL) { $me .= ", cdn acl referrer: " . $this->cdn_acl_referrer; } } return $me; } /** * Enable Container content to be served via CDN or modify CDN attributes * * Either enable this Container's content to be served via CDN or * adjust its CDN attributes. This Container will always return the * same CDN-enabled URI each time it is toggled public/private/public. * * Example: * * # ... authentication code excluded (see previous examples) ... * # * $conn = new CF_Connection($auth); * * $public_container = $conn->create_container("public"); * * # CDN-enable the container and set it's TTL for a month * # * $public_container->make_public(86400/2); # 12 hours (86400 seconds/day) * * * @param int $ttl the time in seconds content will be cached in the CDN * @returns string the CDN enabled Container's URI * @throws CDNNotEnabledException CDN functionality not returned during auth * @throws AuthenticationException if auth token is not valid/expired * @throws InvalidResponseException unexpected response */ function make_public($ttl=86400) { if ($this->cfs_http->getCDNMUrl() == NULL) { throw new CDNNotEnabledException( "Authentication response did not indicate CDN availability"); } if ($this->cdn_uri != NULL) { # previously published, assume we're setting new attributes list($status, $reason, $cdn_uri, $cdn_ssl_uri) = $this->cfs_http->update_cdn_container($this->name,$ttl, $this->cdn_log_retention, $this->cdn_acl_user_agent, $this->cdn_acl_referrer); #if ($status == 401 && $this->_re_auth()) { # return $this->make_public($ttl); #} if ($status == 404) { # this instance _thinks_ the container was published, but the # cdn management system thinks otherwise - try again with a PUT list($status, $reason, $cdn_uri, $cdn_ssl_uri) = $this->cfs_http->add_cdn_container($this->name,$ttl); } } else { # publish it for first time list($status, $reason, $cdn_uri, $cdn_ssl_uri) = $this->cfs_http->add_cdn_container($this->name,$ttl); } #if ($status == 401 && $this->_re_auth()) { # return $this->make_public($ttl); #} if (!in_array($status, array(201,202))) { throw new InvalidResponseException( "Invalid response (".$status."): ".$this->cfs_http->get_error()); } $this->cdn_enabled = True; $this->cdn_ttl = $ttl; $this->cdn_ssl_uri = $cdn_ssl_uri; $this->cdn_uri = $cdn_uri; $this->cdn_log_retention = False; $this->cdn_acl_user_agent = ""; $this->cdn_acl_referrer = ""; return $this->cdn_uri; } /** * Purge Containers objects from CDN Cache. * Example: * * # ... authentication code excluded (see previous examples) ... * # * $conn = new CF_Connection($auth); * $container = $conn->get_container("cdn_enabled"); * $container->purge_from_cdn("user@domain.com"); * # or * $container->purge_from_cdn(); * # or * $container->purge_from_cdn("user1@domain.com,user2@domain.com"); * @returns boolean True if successful * @throws CDNNotEnabledException if CDN Is not enabled on this connection * @throws InvalidResponseException if the response expected is not returned */ function purge_from_cdn($email=null) { if (!$this->cfs_http->getCDNMUrl()) { throw new CDNNotEnabledException( "Authentication response did not indicate CDN availability"); } $status = $this->cfs_http->purge_from_cdn($this->name, $email); if ($status < 199 or $status > 299) { throw new InvalidResponseException( "Invalid response (".$status."): ".$this->cfs_http->get_error()); } return True; } /** * Enable ACL restriction by User Agent for this container. * * Example: * * # ... authentication code excluded (see previous examples) ... * # * $conn = new CF_Connection($auth); * * $public_container = $conn->get_container("public"); * * # Enable ACL by Referrer * $public_container->acl_referrer("Mozilla"); * * * @returns boolean True if successful * @throws CDNNotEnabledException CDN functionality not returned during auth * @throws AuthenticationException if auth token is not valid/expired * @throws InvalidResponseException unexpected response */ function acl_user_agent($cdn_acl_user_agent="") { if ($this->cfs_http->getCDNMUrl() == NULL) { throw new CDNNotEnabledException( "Authentication response did not indicate CDN availability"); } list($status,$reason) = $this->cfs_http->update_cdn_container($this->name, $this->cdn_ttl, $this->cdn_log_retention, $cdn_acl_user_agent, $this->cdn_acl_referrer ); if (!in_array($status, array(202,404))) { throw new InvalidResponseException( "Invalid response (".$status."): ".$this->cfs_http->get_error()); } $this->cdn_acl_user_agent = $cdn_acl_user_agent; return True; } /** * Enable ACL restriction by referer for this container. * * Example: * * # ... authentication code excluded (see previous examples) ... * # * $conn = new CF_Connection($auth); * * $public_container = $conn->get_container("public"); * * # Enable Referrer * $public_container->acl_referrer("http://www.example.com/gallery.php"); * * * @returns boolean True if successful * @throws CDNNotEnabledException CDN functionality not returned during auth * @throws AuthenticationException if auth token is not valid/expired * @throws InvalidResponseException unexpected response */ function acl_referrer($cdn_acl_referrer="") { if ($this->cfs_http->getCDNMUrl() == NULL) { throw new CDNNotEnabledException( "Authentication response did not indicate CDN availability"); } list($status,$reason) = $this->cfs_http->update_cdn_container($this->name, $this->cdn_ttl, $this->cdn_log_retention, $this->cdn_acl_user_agent, $cdn_acl_referrer ); if (!in_array($status, array(202,404))) { throw new InvalidResponseException( "Invalid response (".$status."): ".$this->cfs_http->get_error()); } $this->cdn_acl_referrer = $cdn_acl_referrer; return True; } /** * Enable log retention for this CDN container. * * Enable CDN log retention on the container. If enabled logs will * be periodically (at unpredictable intervals) compressed and * uploaded to a ".CDN_ACCESS_LOGS" container in the form of * "container_name.YYYYMMDDHH-XXXX.gz". Requires CDN be enabled on * the account. * * Example: * * # ... authentication code excluded (see previous examples) ... * # * $conn = new CF_Connection($auth); * * $public_container = $conn->get_container("public"); * * # Enable logs retention. * $public_container->log_retention(True); * * * @returns boolean True if successful * @throws CDNNotEnabledException CDN functionality not returned during auth * @throws AuthenticationException if auth token is not valid/expired * @throws InvalidResponseException unexpected response */ function log_retention($cdn_log_retention=False) { if ($this->cfs_http->getCDNMUrl() == NULL) { throw new CDNNotEnabledException( "Authentication response did not indicate CDN availability"); } list($status,$reason) = $this->cfs_http->update_cdn_container($this->name, $this->cdn_ttl, $cdn_log_retention, $this->cdn_acl_user_agent, $this->cdn_acl_referrer ); if (!in_array($status, array(202,404))) { throw new InvalidResponseException( "Invalid response (".$status."): ".$this->cfs_http->get_error()); } $this->cdn_log_retention = $cdn_log_retention; return True; } /** * Disable the CDN sharing for this container * * Use this method to disallow distribution into the CDN of this Container's * content. * * NOTE: Any content already cached in the CDN will continue to be served * from its cache until the TTL expiration transpires. The default * TTL is typically one day, so "privatizing" the Container will take * up to 24 hours before the content is purged from the CDN cache. * * Example: * * # ... authentication code excluded (see previous examples) ... * # * $conn = new CF_Connection($auth); * * $public_container = $conn->get_container("public"); * * # Disable CDN accessibility * # ... still cached up to a month based on previous example * # * $public_container->make_private(); * * * @returns boolean True if successful * @throws CDNNotEnabledException CDN functionality not returned during auth * @throws AuthenticationException if auth token is not valid/expired * @throws InvalidResponseException unexpected response */ function make_private() { if ($this->cfs_http->getCDNMUrl() == NULL) { throw new CDNNotEnabledException( "Authentication response did not indicate CDN availability"); } list($status,$reason) = $this->cfs_http->remove_cdn_container($this->name); #if ($status == 401 && $this->_re_auth()) { # return $this->make_private(); #} if (!in_array($status, array(202,404))) { throw new InvalidResponseException( "Invalid response (".$status."): ".$this->cfs_http->get_error()); } $this->cdn_enabled = False; $this->cdn_ttl = NULL; $this->cdn_uri = NULL; $this->cdn_ssl_uri = NULL; $this->cdn_streaming_uri - NULL; $this->cdn_log_retention = NULL; $this->cdn_acl_user_agent = NULL; $this->cdn_acl_referrer = NULL; return True; } /** * Check if this Container is being publicly served via CDN * * Use this method to determine if the Container's content is currently * available through the CDN. * * Example: * * # ... authentication code excluded (see previous examples) ... * # * $conn = new CF_Connection($auth); * * $public_container = $conn->get_container("public"); * * # Display CDN accessibility * # * $public_container->is_public() ? print "Yes" : print "No"; * * * @returns boolean True if enabled, False otherwise */ function is_public() { return $this->cdn_enabled == True ? True : False; } /** * Create a new remote storage Object * * Return a new Object instance. If the remote storage Object exists, * the instance's attributes are populated. * * Example: * * # ... authentication code excluded (see previous examples) ... * # * $conn = new CF_Connection($auth); * * $public_container = $conn->get_container("public"); * * # This creates a local instance of a storage object but only creates * # it in the storage system when the object's write() method is called. * # * $pic = $public_container->create_object("baby.jpg"); * * * @param string $obj_name name of storage Object * @return obj CF_Object instance */ function create_object($obj_name=NULL) { return new UpdraftPlus_CF_Object($this, $obj_name); } /** * Return an Object instance for the remote storage Object * * Given a name, return a Object instance representing the * remote storage object. * * Example: * * # ... authentication code excluded (see previous examples) ... * # * $conn = new CF_Connection($auth); * * $public_container = $conn->get_container("public"); * * # This call only fetches header information and not the content of * # the storage object. Use the Object's read() or stream() methods * # to obtain the object's data. * # * $pic = $public_container->get_object("baby.jpg"); * * * @param string $obj_name name of storage Object * @return obj CF_Object instance */ function get_object($obj_name=NULL) { return new UpdraftPlus_CF_Object($this, $obj_name, True); } /** * Return a list of Objects * * Return an array of strings listing the Object names in this Container. * * Example: * * # ... authentication code excluded (see previous examples) ... * # * $images = $conn->get_container("my photos"); * * # Grab the list of all storage objects * # * $all_objects = $images->list_objects(); * * # Grab subsets of all storage objects * # * $first_ten = $images->list_objects(10); * * # Note the use of the previous result's last object name being * # used as the 'marker' parameter to fetch the next 10 objects * # * $next_ten = $images->list_objects(10, $first_ten[count($first_ten)-1]); * * # Grab images starting with "birthday_party" and default limit/marker * # to match all photos with that prefix * # * $prefixed = $images->list_objects(0, NULL, "birthday"); * * # Assuming you have created the appropriate directory marker Objects, * # you can traverse your pseudo-hierarchical containers * # with the "path" argument. * # * $animals = $images->list_objects(0,NULL,NULL,"pictures/animals"); * $dogs = $images->list_objects(0,NULL,NULL,"pictures/animals/dogs"); * * * @param int $limit optional only return $limit names * @param int $marker optional subset of names starting at $marker * @param string $prefix optional Objects whose names begin with $prefix * @param string $path optional only return results under "pathname" * @return array array of strings * @throws InvalidResponseException unexpected response */ function list_objects($limit=0, $marker=NULL, $prefix=NULL, $path=NULL) { list($status, $reason, $obj_list) = $this->cfs_http->list_objects($this->name, $limit, $marker, $prefix, $path); #if ($status == 401 && $this->_re_auth()) { # return $this->list_objects($limit, $marker, $prefix, $path); #} if ($status < 200 || $status > 299) { throw new InvalidResponseException( "Invalid response (".$status."): ".$this->cfs_http->get_error()); } return $obj_list; } /** * Return an array of Objects * * Return an array of Object instances in this Container. * * Example: * * # ... authentication code excluded (see previous examples) ... * # * $images = $conn->get_container("my photos"); * * # Grab the list of all storage objects * # * $all_objects = $images->get_objects(); * * # Grab subsets of all storage objects * # * $first_ten = $images->get_objects(10); * * # Note the use of the previous result's last object name being * # used as the 'marker' parameter to fetch the next 10 objects * # * $next_ten = $images->list_objects(10, $first_ten[count($first_ten)-1]); * * # Grab images starting with "birthday_party" and default limit/marker * # to match all photos with that prefix * # * $prefixed = $images->get_objects(0, NULL, "birthday"); * * # Assuming you have created the appropriate directory marker Objects, * # you can traverse your pseudo-hierarchical containers * # with the "path" argument. * # * $animals = $images->get_objects(0,NULL,NULL,"pictures/animals"); * $dogs = $images->get_objects(0,NULL,NULL,"pictures/animals/dogs"); * * * @param int $limit optional only return $limit names * @param int $marker optional subset of names starting at $marker * @param string $prefix optional Objects whose names begin with $prefix * @param string $path optional only return results under "pathname" * @return array array of strings * @throws InvalidResponseException unexpected response */ function get_objects($limit=0, $marker=NULL, $prefix=NULL, $path=NULL, $delimiter=NULL) { list($status, $reason, $obj_array) = $this->cfs_http->get_objects($this->name, $limit, $marker, $prefix, $path, $delimiter); #if ($status == 401 && $this->_re_auth()) { # return $this->get_objects($limit, $marker, $prefix, $path); #} if ($status < 200 || $status > 299) { throw new InvalidResponseException( "Invalid response (".$status."): ".$this->cfs_http->get_error()); } $objects = array(); foreach ($obj_array as $obj) { if(!isset($obj['subdir'])) { $tmp = new UpdraftPlus_CF_Object($this, $obj["name"], False, False); $tmp->content_type = $obj["content_type"]; $tmp->content_length = (float) $obj["bytes"]; $tmp->set_etag($obj["hash"]); $tmp->last_modified = $obj["last_modified"]; $objects[] = $tmp; } } return $objects; } /** * Copy a remote storage Object to a target Container * * Given an Object instance or name and a target Container instance or name, copy copies the remote Object * and all associated metadata. * * Example: * * # ... authentication code excluded (see previous examples) ... * # * $conn = new CF_Connection($auth); * * $images = $conn->get_container("my photos"); * * # Copy specific object * # * $images->copy_object_to("disco_dancing.jpg","container_target"); * * * @param obj $obj name or instance of Object to copy * @param obj $container_target name or instance of target Container * @param string $dest_obj_name name of target object (optional - uses source name if omitted) * @param array $metadata metadata array for new object (optional) * @param array $headers header fields array for the new object (optional) * @return boolean true if successfully copied * @throws SyntaxException invalid Object/Container name * @throws NoSuchObjectException remote Object does not exist * @throws InvalidResponseException unexpected response */ function copy_object_to($obj,$container_target,$dest_obj_name=NULL,$metadata=NULL,$headers=NULL) { $obj_name = NULL; if (is_object($obj)) { if (get_class($obj) == "UpdraftPlus_CF_Object") { $obj_name = $obj->name; } } if (is_string($obj)) { $obj_name = $obj; } if (!$obj_name) { throw new SyntaxException("Object name not set."); } if ($dest_obj_name === NULL) { $dest_obj_name = $obj_name; } $container_name_target = NULL; if (is_object($container_target)) { if (get_class($container_target) == "UpdraftPlus_CF_Container") { $container_name_target = $container_target->name; } } if (is_string($container_target)) { $container_name_target = $container_target; } if (!$container_name_target) { throw new SyntaxException("Container name target not set."); } $status = $this->cfs_http->copy_object($obj_name,$dest_obj_name,$this->name,$container_name_target,$metadata,$headers); if ($status == 404) { $m = "Specified object '".$this->name."/".$obj_name; $m.= "' did not exist as source to copy from or '".$container_name_target."' did not exist as target to copy to."; throw new NoSuchObjectException($m); } if ($status < 200 || $status > 299) { throw new InvalidResponseException( "Invalid response (".$status."): ".$this->cfs_http->get_error()); } return true; } /** * Copy a remote storage Object from a source Container * * Given an Object instance or name and a source Container instance or name, copy copies the remote Object * and all associated metadata. * * Example: * * # ... authentication code excluded (see previous examples) ... * # * $conn = new CF_Connection($auth); * * $images = $conn->get_container("my photos"); * * # Copy specific object * # * $images->copy_object_from("disco_dancing.jpg","container_source"); * * * @param obj $obj name or instance of Object to copy * @param obj $container_source name or instance of source Container * @param string $dest_obj_name name of target object (optional - uses source name if omitted) * @param array $metadata metadata array for new object (optional) * @param array $headers header fields array for the new object (optional) * @return boolean true if successfully copied * @throws SyntaxException invalid Object/Container name * @throws NoSuchObjectException remote Object does not exist * @throws InvalidResponseException unexpected response */ function copy_object_from($obj,$container_source,$dest_obj_name=NULL,$metadata=NULL,$headers=NULL) { $obj_name = NULL; if (is_object($obj)) { if (get_class($obj) == "UpdraftPlus_CF_Object") { $obj_name = $obj->name; } } if (is_string($obj)) { $obj_name = $obj; } if (!$obj_name) { throw new SyntaxException("Object name not set."); } if ($dest_obj_name === NULL) { $dest_obj_name = $obj_name; } $container_name_source = NULL; if (is_object($container_source)) { if (get_class($container_source) == "UpdraftPlus_CF_Container") { $container_name_source = $container_source->name; } } if (is_string($container_source)) { $container_name_source = $container_source; } if (!$container_name_source) { throw new SyntaxException("Container name source not set."); } $status = $this->cfs_http->copy_object($obj_name,$dest_obj_name,$container_name_source,$this->name,$metadata,$headers); if ($status == 404) { $m = "Specified object '".$container_name_source."/".$obj_name; $m.= "' did not exist as source to copy from or '".$this->name."/".$obj_name."' did not exist as target to copy to."; throw new NoSuchObjectException($m); } if ($status < 200 || $status > 299) { throw new InvalidResponseException( "Invalid response (".$status."): ".$this->cfs_http->get_error()); } return true; } /** * Move a remote storage Object to a target Container * * Given an Object instance or name and a target Container instance or name, move copies the remote Object * and all associated metadata and deletes the source Object afterwards * * Example: * * # ... authentication code excluded (see previous examples) ... * # * $conn = new CF_Connection($auth); * * $images = $conn->get_container("my photos"); * * # Move specific object * # * $images->move_object_to("disco_dancing.jpg","container_target"); * * * @param obj $obj name or instance of Object to move * @param obj $container_target name or instance of target Container * @param string $dest_obj_name name of target object (optional - uses source name if omitted) * @param array $metadata metadata array for new object (optional) * @param array $headers header fields array for the new object (optional) * @return boolean true if successfully moved * @throws SyntaxException invalid Object/Container name * @throws NoSuchObjectException remote Object does not exist * @throws InvalidResponseException unexpected response */ function move_object_to($obj,$container_target,$dest_obj_name=NULL,$metadata=NULL,$headers=NULL) { $retVal = false; if(self::copy_object_to($obj,$container_target,$dest_obj_name,$metadata,$headers)) { $retVal = self::delete_object($obj,$this->name); } return $retVal; } /** * Move a remote storage Object from a source Container * * Given an Object instance or name and a source Container instance or name, move copies the remote Object * and all associated metadata and deletes the source Object afterwards * * Example: * * # ... authentication code excluded (see previous examples) ... * # * $conn = new CF_Connection($auth); * * $images = $conn->get_container("my photos"); * * # Move specific object * # * $images->move_object_from("disco_dancing.jpg","container_target"); * * * @param obj $obj name or instance of Object to move * @param obj $container_source name or instance of target Container * @param string $dest_obj_name name of target object (optional - uses source name if omitted) * @param array $metadata metadata array for new object (optional) * @param array $headers header fields array for the new object (optional) * @return boolean true if successfully moved * @throws SyntaxException invalid Object/Container name * @throws NoSuchObjectException remote Object does not exist * @throws InvalidResponseException unexpected response */ function move_object_from($obj,$container_source,$dest_obj_name=NULL,$metadata=NULL,$headers=NULL) { $retVal = false; if(self::copy_object_from($obj,$container_source,$dest_obj_name,$metadata,$headers)) { $retVal = self::delete_object($obj,$container_source); } return $retVal; } /** * Delete a remote storage Object * * Given an Object instance or name, permanently remove the remote Object * and all associated metadata. * * Example: * * # ... authentication code excluded (see previous examples) ... * # * $conn = new CF_Connection($auth); * * $images = $conn->get_container("my photos"); * * # Delete specific object * # * $images->delete_object("disco_dancing.jpg"); * * * @param obj $obj name or instance of Object to delete * @param obj $container name or instance of Container in which the object resides (optional) * @return boolean True if successfully removed * @throws SyntaxException invalid Object name * @throws NoSuchObjectException remote Object does not exist * @throws InvalidResponseException unexpected response */ function delete_object($obj,$container=NULL) { $obj_name = NULL; if (is_object($obj)) { if (get_class($obj) == "UpdraftPlus_CF_Object") { $obj_name = $obj->name; } } if (is_string($obj)) { $obj_name = $obj; } if (!$obj_name) { throw new SyntaxException("Object name not set."); } $container_name = NULL; if($container === NULL) { $container_name = $this->name; } else { if (is_object($container)) { if (get_class($container) == "UpdraftPlus_CF_Container") { $container_name = $container->name; } } if (is_string($container)) { $container_name = $container; } if (!$container_name) { throw new SyntaxException("Container name source not set."); } } $status = $this->cfs_http->delete_object($container_name, $obj_name); #if ($status == 401 && $this->_re_auth()) { # return $this->delete_object($obj); #} if ($status == 404) { $m = "Specified object '".$container_name."/".$obj_name; $m.= "' did not exist to delete."; throw new NoSuchObjectException($m); } if ($status != 204) { throw new InvalidResponseException( "Invalid response (".$status."): ".$this->cfs_http->get_error()); } return True; } /** * Helper function to create "path" elements for a given Object name * * Given an Object whose name contains '/' path separators, this function * will create the "directory marker" Objects of one byte with the * Content-Type of "application/directory". * * It assumes the last element of the full path is the "real" Object * and does NOT create a remote storage Object for that last element. */ function create_paths($path_name) { if ($path_name[0] == '/') { $path_name = mb_substr($path_name, 0, 1); } $elements = explode('/', $path_name, -1); $build_path = ""; foreach ($elements as $idx => $val) { if (!$build_path) { $build_path = $val; } else { $build_path .= "/" . $val; } $obj = new UpdraftPlus_CF_Object($this, $build_path); $obj->content_type = "application/directory"; $obj->write(".", 1); } } /** * Internal method to grab CDN/Container info if appropriate to do so * * @throws InvalidResponseException unexpected response */ private function _cdn_initialize() { list($status, $reason, $cdn_enabled, $cdn_ssl_uri, $cdn_streaming_uri, $cdn_uri, $cdn_ttl, $cdn_log_retention, $cdn_acl_user_agent, $cdn_acl_referrer) = $this->cfs_http->head_cdn_container($this->name); #if ($status == 401 && $this->_re_auth()) { # return $this->_cdn_initialize(); #} if (!in_array($status, array(204,404))) { throw new InvalidResponseException( "Invalid response (".$status."): ".$this->cfs_http->get_error()); } $this->cdn_enabled = $cdn_enabled; $this->cdn_streaming_uri = $cdn_streaming_uri; $this->cdn_ssl_uri = $cdn_ssl_uri; $this->cdn_uri = $cdn_uri; $this->cdn_ttl = $cdn_ttl; $this->cdn_log_retention = $cdn_log_retention; $this->cdn_acl_user_agent = $cdn_acl_user_agent; $this->cdn_acl_referrer = $cdn_acl_referrer; } #private function _re_auth() #{ # $new_auth = new CF_Authentication( # $this->cfs_auth->username, # $this->cfs_auth->api_key, # $this->cfs_auth->auth_host, # $this->cfs_auth->account); # $new_auth->authenticate(); # $this->cfs_auth = $new_auth; # $this->cfs_http->setCFAuth($this->cfs_auth); # return True; #} } /** * Object operations * * An Object is analogous to a file on a conventional filesystem. You can * read data from, or write data to your Objects. You can also associate * arbitrary metadata with them. * * @package php-cloudfiles */ class UpdraftPlus_CF_Object { public $container; public $name; public $last_modified; public $content_type; public $content_length; public $metadata; public $headers; public $manifest; private $etag; /** * Class constructor * * @param obj $container CF_Container instance * @param string $name name of Object * @param boolean $force_exists if set, throw an error if Object doesn't exist */ function __construct(&$container, $name, $force_exists=False, $dohead=True) { if ($name[0] == "/") { $r = "Object name '".$name; $r .= "' cannot contain begin with a '/' character."; throw new SyntaxException($r); } if (strlen($name) > MAX_OBJECT_NAME_LEN) { throw new SyntaxException("Object name exceeds " . "maximum allowed length."); } $this->container = $container; $this->name = $name; $this->etag = NULL; $this->_etag_override = False; $this->last_modified = NULL; $this->content_type = NULL; $this->content_length = 0; $this->metadata = array(); $this->headers = array(); $this->manifest = NULL; if ($dohead) { if (!$this->_initialize() && $force_exists) { throw new NoSuchObjectException("No such object '".$name."'"); } } } /** * String representation of Object * * Pretty print the Object's location and name * * @return string Object information */ function __toString() { return $this->container->name . "/" . $this->name; } /** * Internal check to get the proper mimetype. * * This function would go over the available PHP methods to get * the MIME type. * * By default it will try to use the PHP fileinfo library which is * available from PHP 5.3 or as an PECL extension * (http://pecl.php.net/package/Fileinfo). * * It will get the magic file by default from the system wide file * which is usually available in /usr/share/magic on Unix or try * to use the file specified in the source directory of the API * (share directory). * * if fileinfo is not available it will try to use the internal * mime_content_type function. * * @param string $handle name of file or buffer to guess the type from * @return boolean True if successful * @throws BadContentTypeException */ function _guess_content_type($handle) { if ($this->content_type) return; if (function_exists("finfo_open")) { $local_magic = dirname(__FILE__) . "/share/magic"; $finfo = @finfo_open(FILEINFO_MIME, $local_magic); if (!$finfo) $finfo = @finfo_open(FILEINFO_MIME); if ($finfo) { if (is_file((string)$handle)) $ct = @finfo_file($finfo, $handle); else $ct = @finfo_buffer($finfo, $handle); /* PHP 5.3 fileinfo display extra information like charset so we remove everything after the ; since we are not into that stuff */ if ($ct) { $extra_content_type_info = strpos($ct, "; "); if ($extra_content_type_info) $ct = substr($ct, 0, $extra_content_type_info); } if ($ct && $ct != 'application/octet-stream') $this->content_type = $ct; @finfo_close($finfo); } } if (!$this->content_type && (string)is_file($handle) && function_exists("mime_content_type")) { $this->content_type = @mime_content_type($handle); } if (!$this->content_type) { throw new BadContentTypeException("Required Content-Type not set"); } return True; } /** * String representation of the Object's public URI * * A string representing the Object's public URI assuming that it's * parent Container is CDN-enabled. * * Example: * * # ... authentication/connection/container code excluded * # ... see previous examples * * # Print out the Object's CDN URI (if it has one) in an HTML img-tag * # * print "\n"; * * * @return string Object's public URI or NULL */ function public_uri() { if ($this->container->cdn_enabled) { return $this->container->cdn_uri . "/" . $this->name; } return NULL; } /** * String representation of the Object's public SSL URI * * A string representing the Object's public SSL URI assuming that it's * parent Container is CDN-enabled. * * Example: * * # ... authentication/connection/container code excluded * # ... see previous examples * * # Print out the Object's CDN SSL URI (if it has one) in an HTML img-tag * # * print "\n"; * * * @return string Object's public SSL URI or NULL */ function public_ssl_uri() { if ($this->container->cdn_enabled) { return $this->container->cdn_ssl_uri . "/" . $this->name; } return NULL; } /** * String representation of the Object's public Streaming URI * * A string representing the Object's public Streaming URI assuming that it's * parent Container is CDN-enabled. * * Example: * * # ... authentication/connection/container code excluded * # ... see previous examples * * # Print out the Object's CDN Streaming URI (if it has one) in an HTML img-tag * # * print "\n"; * * * @return string Object's public Streaming URI or NULL */ function public_streaming_uri() { if ($this->container->cdn_enabled) { return $this->container->cdn_streaming_uri . "/" . $this->name; } return NULL; } /** * Read the remote Object's data * * Returns the Object's data. This is useful for smaller Objects such * as images or office documents. Object's with larger content should use * the stream() method below. * * Pass in $hdrs array to set specific custom HTTP headers such as * If-Match, If-None-Match, If-Modified-Since, Range, etc. * * Example: * * # ... authentication/connection/container code excluded * # ... see previous examples * * $my_docs = $conn->get_container("documents"); * $doc = $my_docs->get_object("README"); * $data = $doc->read(); # read image content into a string variable * print $data; * * # Or see stream() below for a different example. * # * * * @param array $hdrs user-defined headers (Range, If-Match, etc.) * @return string Object's data * @throws InvalidResponseException unexpected response */ function read($hdrs=array()) { list($status, $reason, $data) = $this->container->cfs_http->get_object_to_string($this, $hdrs); #if ($status == 401 && $this->_re_auth()) { # return $this->read($hdrs); #} if (($status < 200) || ($status > 299 && $status != 412 && $status != 304)) { throw new InvalidResponseException("Invalid response (".$status."): " . $this->container->cfs_http->get_error()); } return $data; } /** * Streaming read of Object's data * * Given an open PHP resource (see PHP's fopen() method), fetch the Object's * data and write it to the open resource handle. This is useful for * streaming an Object's content to the browser (videos, images) or for * fetching content to a local file. * * Pass in $hdrs array to set specific custom HTTP headers such as * If-Match, If-None-Match, If-Modified-Since, Range, etc. * * Example: * * # ... authentication/connection/container code excluded * # ... see previous examples * * # Assuming this is a web script to display the README to the * # user's browser: * # * get_container("documents"); * $doc = $my_docs->get_object("README"); * * // Hand it back to user's browser with appropriate content-type * // * header("Content-Type: " . $doc->content_type); * $output = fopen("php://output", "w"); * $doc->stream($output); # stream object content to PHP's output buffer * fclose($output); * ?> * * # See read() above for a more simple example. * # * * * @param resource $fp open resource for writing data to * @param array $hdrs user-defined headers (Range, If-Match, etc.) * @return string Object's data * @throws InvalidResponseException unexpected response */ function stream(&$fp, $hdrs=array()) { list($status, $reason) = $this->container->cfs_http->get_object_to_stream($this,$fp,$hdrs); #if ($status == 401 && $this->_re_auth()) { # return $this->stream($fp, $hdrs); #} if (($status < 200) || ($status > 299 && $status != 412 && $status != 304)) { throw new InvalidResponseException("Invalid response (".$status."): " .$reason); } return True; } /** * Store new Object metadata * * Write's an Object's metadata to the remote Object. This will overwrite * an prior Object metadata. * * Example: * * # ... authentication/connection/container code excluded * # ... see previous examples * * $my_docs = $conn->get_container("documents"); * $doc = $my_docs->get_object("README"); * * # Define new metadata for the object * # * $doc->metadata = array( * "Author" => "EJ", * "Subject" => "How to use the PHP tests", * "Version" => "1.2.2" * ); * * # Define additional headers for the object * # * $doc->headers = array( * "Content-Disposition" => "attachment", * ); * * # Push the new metadata up to the storage system * # * $doc->sync_metadata(); * * * @return boolean True if successful, False otherwise * @throws InvalidResponseException unexpected response */ function sync_metadata() { if (!empty($this->metadata) || !empty($this->headers) || $this->manifest) { $status = $this->container->cfs_http->update_object($this); #if ($status == 401 && $this->_re_auth()) { # return $this->sync_metadata(); #} if ($status != 202) { throw new InvalidResponseException("Invalid response (" .$status."): ".$this->container->cfs_http->get_error()); } return True; } return False; } /** * Store new Object manifest * * Write's an Object's manifest to the remote Object. This will overwrite * an prior Object manifest. * * Example: * * # ... authentication/connection/container code excluded * # ... see previous examples * * $my_docs = $conn->get_container("documents"); * $doc = $my_docs->get_object("README"); * * # Define new manifest for the object * # * $doc->manifest = "container/prefix"; * * # Push the new manifest up to the storage system * # * $doc->sync_manifest(); * * * @return boolean True if successful, False otherwise * @throws InvalidResponseException unexpected response */ function sync_manifest() { return $this->sync_metadata(); } /** * Upload Object's data to Cloud Files * * Write data to the remote Object. The $data argument can either be a * PHP resource open for reading (see PHP's fopen() method) or an in-memory * variable. If passing in a PHP resource, you must also include the $bytes * parameter. * * Example: * * # ... authentication/connection/container code excluded * # ... see previous examples * * $my_docs = $conn->get_container("documents"); * $doc = $my_docs->get_object("README"); * * # Upload placeholder text in my README * # * $doc->write("This is just placeholder text for now..."); * * * @param string|resource $data string or open resource * @param float $bytes amount of data to upload (required for resources) * @param boolean $verify generate, send, and compare MD5 checksums * @return boolean True when data uploaded successfully * @throws SyntaxException missing required parameters * @throws BadContentTypeException if no Content-Type was/could be set * @throws MisMatchedChecksumException $verify is set and checksums unequal * @throws InvalidResponseException unexpected response */ function write($data=NULL, $bytes=0, $verify=True) { if (!$data && !is_string($data)) { throw new SyntaxException("Missing data source."); } if ($bytes > MAX_OBJECT_SIZE) { throw new SyntaxException("Bytes exceeds maximum object size."); } if ($verify) { if (!$this->_etag_override) { $this->etag = $this->compute_md5sum($data); } } else { $this->etag = NULL; } $close_fh = False; if (!is_resource($data)) { # A hack to treat string data as a file handle. php://memory feels # like a better option, but it seems to break on Windows so use # a temporary file instead. # $fp = fopen("php://temp", "wb+"); #$fp = fopen("php://memory", "wb+"); fwrite($fp, $data, strlen($data)); rewind($fp); $close_fh = True; $this->content_length = (float) strlen($data); if ($this->content_length > MAX_OBJECT_SIZE) { throw new SyntaxException("Data exceeds maximum object size"); } $ct_data = substr($data, 0, 64); } else { // The original Rackspace library used rewind() instead of ftell/fseek here - which meant fseek(0), which was sometimes wrong $fpos = ftell($data); $this->content_length = $bytes; $fp = $data; $ct_data = fread($data, 64); fseek($data, $fpos); } $this->_guess_content_type($ct_data); list($status, $reason, $etag) = $this->container->cfs_http->put_object($this, $fp); #if ($status == 401 && $this->_re_auth()) { # return $this->write($data, $bytes, $verify); #} if ($status == 412) { if ($close_fh) { fclose($fp); } throw new SyntaxException("Missing Content-Type header"); } if ($status == 422) { if ($close_fh) { fclose($fp); } throw new MisMatchedChecksumException( "Supplied and computed checksums do not match."); } if ($status != 201) { if ($close_fh) { fclose($fp); } throw new InvalidResponseException("Invalid response (".$status."): " . $this->container->cfs_http->get_error()); } if (!$verify) { $this->etag = $etag; } if ($close_fh) { fclose($fp); } return True; } /** * Upload Object data from local filename * * This is a convenience function to upload the data from a local file. A * True value for $verify will cause the method to compute the Object's MD5 * checksum prior to uploading. * * Example: * * # ... authentication/connection/container code excluded * # ... see previous examples * * $my_docs = $conn->get_container("documents"); * $doc = $my_docs->get_object("README"); * * # Upload my local README's content * # * $doc->load_from_filename("/home/ej/cloudfiles/readme"); * * * @param string $filename full path to local file * @param boolean $verify enable local/remote MD5 checksum validation * @return boolean True if data uploaded successfully * @throws SyntaxException missing required parameters * @throws BadContentTypeException if no Content-Type was/could be set * @throws MisMatchedChecksumException $verify is set and checksums unequal * @throws InvalidResponseException unexpected response * @throws IOException error opening file */ function load_from_filename($filename, $verify=True) { $fp = @fopen($filename, "r"); if (!$fp) { throw new IOException("Could not open file for reading: ".$filename); } clearstatcache(); $size = (float) sprintf("%u", filesize($filename)); if ($size > MAX_OBJECT_SIZE) { throw new SyntaxException("File size exceeds maximum object size."); } $this->_guess_content_type($filename); $this->write($fp, $size, $verify); fclose($fp); return True; } /** * Save Object's data to local filename * * Given a local filename, the Object's data will be written to the newly * created file. * * Example: * * # ... authentication/connection/container code excluded * # ... see previous examples * * # Whoops! I deleted my local README, let me download/save it * # * $my_docs = $conn->get_container("documents"); * $doc = $my_docs->get_object("README"); * * $doc->save_to_filename("/home/ej/cloudfiles/readme.restored"); * * * @param string $filename name of local file to write data to * @return boolean True if successful * @throws IOException error opening file * @throws InvalidResponseException unexpected response */ function save_to_filename($filename) { $fp = @fopen($filename, "wb"); if (!$fp) { throw new IOException("Could not open file for writing: ".$filename); } $result = $this->stream($fp); fclose($fp); return $result; } /** * Purge this Object from CDN Cache. * Example: * * # ... authentication code excluded (see previous examples) ... * # * $conn = new CF_Connection($auth); * $container = $conn->get_container("cdn_enabled"); * $obj = $container->get_object("object"); * $obj->purge_from_cdn("user@domain.com"); * # or * $obj->purge_from_cdn(); * # or * $obj->purge_from_cdn("user1@domain.com,user2@domain.com"); * * @returns boolean True if successful * @throws CDNNotEnabledException if CDN Is not enabled on this connection * @throws InvalidResponseException if the response expected is not returned */ function purge_from_cdn($email=null) { if (!$this->container->cfs_http->getCDNMUrl()) { throw new CDNNotEnabledException( "Authentication response did not indicate CDN availability"); } $status = $this->container->cfs_http->purge_from_cdn($this->container->name . "/" . $this->name, $email); if ($status < 199 or $status > 299) { throw new InvalidResponseException( "Invalid response (".$status."): ".$this->container->cfs_http->get_error()); } return True; } /** * Set Object's MD5 checksum * * Manually set the Object's ETag. Including the ETag is mandatory for * Cloud Files to perform end-to-end verification. Omitting the ETag forces * the user to handle any data integrity checks. * * @param string $etag MD5 checksum hexadecimal string */ function set_etag($etag) { $this->etag = $etag; $this->_etag_override = True; } /** * Object's MD5 checksum * * Accessor method for reading Object's private ETag attribute. * * @return string MD5 checksum hexadecimal string */ function getETag() { return $this->etag; } /** * Compute the MD5 checksum * * Calculate the MD5 checksum on either a PHP resource or data. The argument * may either be a local filename, open resource for reading, or a string. * * WARNING: if you are uploading a big file over a stream * it could get very slow to compute the md5 you probably want to * set the $verify parameter to False in the write() method and * compute yourself the md5 before if you have it. * * @param filename|obj|string $data filename, open resource, or string * @return string MD5 checksum hexadecimal string */ function compute_md5sum(&$data) { if (function_exists("hash_init") && is_resource($data)) { $ctx = hash_init('md5'); $fpos = ftell($data); while (!feof($data)) { $buffer = fgets($data, 65536); hash_update($ctx, $buffer); } $md5 = hash_final($ctx, false); fseek($data, $fpos); } elseif ((string)is_file($data)) { $md5 = md5_file($data); } else { $md5 = md5($data); } return $md5; } /** * PRIVATE: fetch information about the remote Object if it exists */ private function _initialize() { list($status, $reason, $etag, $last_modified, $content_type, $content_length, $metadata, $manifest, $headers) = $this->container->cfs_http->head_object($this); #if ($status == 401 && $this->_re_auth()) { # return $this->_initialize(); #} if ($status == 404) { return False; } if ($status < 200 || $status > 299) { throw new InvalidResponseException("Invalid response (".$status."): " . $this->container->cfs_http->get_error()); } $this->etag = $etag; $this->last_modified = $last_modified; $this->content_type = $content_type; $this->content_length = $content_length; $this->metadata = $metadata; $this->headers = $headers; $this->manifest = $manifest; return True; } /** * Generate a Temp Url for a object * Example: * * # ... authentication code excluded (see previous examples) ... * $conn = new CF_Connection($auth); * $container = $conn->get_container("foo"); * $obj = $container->get_object("foo"); * $tempurl = $obj->get_temp_url("shared_secret", "expire_time_in_seconds", "{HTTP_METHOD}"); (note: replace {HTTP_METHOD} with the request method: GET, POST, PUT, DELETE, etc. * * @returns The temp url */ public function get_temp_url($key, $expires, $method) { $expires += time(); $url = $this->container->cfs_http->getStorageUrl() . '/' . $this->container->name . '/' . $this->name; return $url . '?temp_url_sig=' . hash_hmac('sha1', strtoupper($method) . "\n" . $expires . "\n" . parse_url($url, PHP_URL_PATH), $key) . '&temp_url_expires=' . $expires; } /** * Generate hidden input for form post. * @returns array Returns an associative array with form post input. */ public function get_form_post_input($key, $expires, $redirect, $max_file_size=5368709120, $max_file_count=1) { $expires += time(); $url = $this->container->cfs_http->getStorageUrl() . '/' . $this->container->name . '/' . $this->name; $form_post = array('action' => $url, 'redirect' => $redirect, 'max_file_size' => $max_file_size, 'expires' => $expires, 'file' => $this->name); $form_post['signature'] = hash_hmac('sha1', parse_url($url, PHP_URL_PATH) . "\n" . $redirect . "\n" . $max_file_size . "\n" . $max_file_count . "\n" . $expires, $key ); return $form_post; } #private function _re_auth() #{ # $new_auth = new CF_Authentication( # $this->cfs_auth->username, # $this->cfs_auth->api_key, # $this->cfs_auth->auth_host, # $this->cfs_auth->account); # $new_auth->authenticate(); # $this->container->cfs_auth = $new_auth; # $this->container->cfs_http->setCFAuth($this->cfs_auth); # return True; #} } /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * c-hanging-comment-ender-p: nil * End: */ ?> includes/cloudfiles/cloudfiles_exceptions.php000064400000003515152214270100015604 0ustar00 * @copyright Copyright (c) 2008, Rackspace US, Inc. * @package php-cloudfiles-exceptions */ /** * Custom Exceptions for the CloudFiles API * @package php-cloudfiles-exceptions */ if (!class_exists('SyntaxException')) { class SyntaxException extends Exception { } } if (!class_exists('AuthenticationException')) { class AuthenticationException extends Exception { } } if (!class_exists('InvalidResponseException')) { class InvalidResponseException extends Exception { } } if (!class_exists('NonEmptyContainerException')) { class NonEmptyContainerException extends Exception { } } if (!class_exists('NoSuchObjectException')) { class NoSuchObjectException extends Exception { } } if (!class_exists('NoSuchContainerException')) { class NoSuchContainerException extends Exception { } } if (!class_exists('NoSuchAccountException')) { class NoSuchAccountException extends Exception { } } if (!class_exists('MisMatchedChecksumException')) { class MisMatchedChecksumException extends Exception { } } if (!class_exists('IOException')) { class IOException extends Exception { } } if (!class_exists('CDNNotEnabledException')) { class CDNNotEnabledException extends Exception { } } if (!class_exists('BadContentTypeException')) { class BadContentTypeException extends Exception { } } if (!class_exists('InvalidUTF8Exception')) { class InvalidUTF8Exception extends Exception { } } if (!class_exists('ConnectionNotOpenException')) { class ConnectionNotOpenException extends Exception { } } /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * c-hanging-comment-ender-p: nil * End: */ ?> includes/cloudfiles/cloudfiles_http.php000064400000155332152214270100014407 0ustar00 * @copyright Copyright (c) 2008, Rackspace US, Inc. * @package php-cloudfiles-http */ /** */ require_once("cloudfiles_exceptions.php"); @define("PHP_CF_VERSION", "1.7.11"); @define("USER_AGENT", sprintf("PHP-CloudFiles/%s", PHP_CF_VERSION)); @define("MAX_HEADER_NAME_LEN", 128); @define("MAX_HEADER_VALUE_LEN", 256); @define("ACCOUNT_CONTAINER_COUNT", "X-Account-Container-Count"); @define("ACCOUNT_BYTES_USED", "X-Account-Bytes-Used"); @define("ACCOUNT_KEY", "X-Account-Meta-Key"); @define("ACCOUNT_METADATA_HEADER_PREFIX", "X-Account-Meta-"); @define("CONTAINER_OBJ_COUNT", "X-Container-Object-Count"); @define("CONTAINER_BYTES_USED", "X-Container-Bytes-Used"); @define("CONTAINER_METADATA_HEADER_PREFIX", "X-Container-Meta-"); @define("DELETE_AFTER", "X-Delete-After"); @define("DELETE_AT", "X-Delete-At"); @define("MANIFEST_HEADER", "X-Object-Manifest"); @define("METADATA_HEADER_PREFIX", "X-Object-Meta-"); @define("CONTENT_HEADER_PREFIX", "Content-"); @define("ACCESS_CONTROL_HEADER_PREFIX", "Access-Control-"); @define("ORIGIN_HEADER", "Origin"); @define("CDN_URI", "X-CDN-URI"); @define("CDN_SSL_URI", "X-CDN-SSL-URI"); @define("CDN_STREAMING_URI", "X-CDN-Streaming-URI"); @define("CDN_ENABLED", "X-CDN-Enabled"); @define("CDN_LOG_RETENTION", "X-Log-Retention"); @define("CDN_ACL_USER_AGENT", "X-User-Agent-ACL"); @define("CDN_ACL_REFERRER", "X-Referrer-ACL"); @define("CDN_TTL", "X-TTL"); @define("CDNM_URL", "X-CDN-Management-Url"); @define("STORAGE_URL", "X-Storage-Url"); @define("AUTH_TOKEN", "X-Auth-Token"); @define("AUTH_USER_HEADER", "X-Auth-User"); @define("AUTH_KEY_HEADER", "X-Auth-Key"); @define("AUTH_USER_HEADER_LEGACY", "X-Storage-User"); @define("AUTH_KEY_HEADER_LEGACY", "X-Storage-Pass"); @define("AUTH_TOKEN_LEGACY", "X-Storage-Token"); @define("CDN_EMAIL", "X-Purge-Email"); @define("DESTINATION", "Destination"); @define("ETAG_HEADER", "ETag"); @define("LAST_MODIFIED_HEADER", "Last-Modified"); @define("CONTENT_TYPE_HEADER", "Content-Type"); @define("CONTENT_LENGTH_HEADER", "Content-Length"); @define("USER_AGENT_HEADER", "User-Agent"); /** * HTTP/cURL wrapper for Cloud Files * * This class should not be used directly. It's only purpose is to abstract * out the HTTP communication from the main API. * * @package php-cloudfiles-http */ class UpdraftPlus_CF_Http { private $error_str; private $dbug; private $cabundle_path; private $api_version; # Authentication instance variables # private $storage_url; private $cdnm_url; private $auth_token; # Request/response variables # private $response_status; private $response_reason; private $connections; # Variables used for content/header callbacks # private $_user_read_progress_callback_func; private $_user_write_progress_callback_func; private $_write_callback_type; private $_text_list; private $_account_metadata; private $_account_container_count; private $_account_bytes_used; private $_account_key; private $_container_metadata; private $_container_object_count; private $_container_bytes_used; private $_obj_delete_after; private $_obj_delete_at; private $_obj_etag; private $_obj_last_modified; private $_obj_content_type; private $_obj_content_length; private $_obj_metadata; private $_obj_headers; private $_obj_manifest; private $_obj_write_resource; private $_obj_write_string; private $_cdn_enabled; private $_cdn_ssl_uri; private $_cdn_streaming_uri; private $_cdn_uri; private $_cdn_ttl; private $_cdn_log_retention; private $_cdn_acl_user_agent; private $_cdn_acl_referrer; function __construct($api_version) { $this->dbug = False; $this->cabundle_path = NULL; $this->api_version = $api_version; $this->error_str = NULL; $this->storage_url = NULL; $this->cdnm_url = NULL; $this->auth_token = NULL; $this->response_status = NULL; $this->response_reason = NULL; # Curl connections array - since there is no way to "re-set" the # connection parameters for a cURL handle, we keep an array of # the unique use-cases and funnel all of those same type # requests through the appropriate curl connection. # $this->connections = array( "GET_CALL" => NULL, # GET objects/containers/lists "PUT_OBJ" => NULL, # PUT object "HEAD" => NULL, # HEAD requests "PUT_CONT" => NULL, # PUT container "DEL_POST" => NULL, # DELETE containers/objects, POST objects "COPY" => null, # COPY objects ); $this->_user_read_progress_callback_func = NULL; $this->_user_write_progress_callback_func = NULL; $this->_write_callback_type = NULL; $this->_text_list = array(); $this->_return_list = NULL; $this->_account_metadata = array(); $this->_account_key = NULL; $this->_account_container_count = 0; $this->_account_bytes_used = 0; $this->_container_metadata = array(); $this->_container_object_count = 0; $this->_container_bytes_used = 0; $this->_obj_delete_after = NULL; $this->_obj_delete_at = NULL; $this->_obj_write_resource = NULL; $this->_obj_write_string = ""; $this->_obj_etag = NULL; $this->_obj_last_modified = NULL; $this->_obj_content_type = NULL; $this->_obj_content_length = NULL; $this->_obj_metadata = array(); $this->_obj_manifest = NULL; $this->_obj_headers = NULL; $this->_cdn_enabled = NULL; $this->_cdn_ssl_uri = NULL; $this->_cdn_streaming_uri = NULL; $this->_cdn_uri = NULL; $this->_cdn_ttl = NULL; $this->_cdn_log_retention = NULL; $this->_cdn_acl_user_agent = NULL; $this->_cdn_acl_referrer = NULL; # The OS list with a PHP without an updated CA File for CURL to # connect to SSL Websites. It is the first 3 letters of the PHP_OS # variable. $OS_CAFILE_NONUPDATED=array( "win","dar" ); // We don't want this happening automatically - since the UpdraftPlus default is to use our own certificate already // if (in_array((strtolower (substr(PHP_OS, 0,3))), $OS_CAFILE_NONUPDATED)) // $this->ssl_use_cabundle(); } function ssl_use_cabundle($path=NULL) { if ($path) { $this->cabundle_path = $path; } else { $this->cabundle_path = UPDRAFTPLUS_DIR.'/includes/cacert.pem'; } if (!file_exists($this->cabundle_path)) { throw new IOException("Could not use CA bundle: " . $this->cabundle_path); } return; } # Uses separate cURL connection to authenticate # function authenticate($user, $pass, $acct=NULL, $host=NULL) { $path = array(); if (isset($acct)){ $headers = array( sprintf("%s: %s", AUTH_USER_HEADER_LEGACY, $user), sprintf("%s: %s", AUTH_KEY_HEADER_LEGACY, $pass), ); $path[] = $host; $path[] = rawurlencode(sprintf("v%d",$this->api_version)); $path[] = rawurlencode($acct); } else { $headers = array( sprintf("%s: %s", AUTH_USER_HEADER, $user), sprintf("%s: %s", AUTH_KEY_HEADER, $pass), ); $path[] = $host; } $path[] = "v1.0"; $url = implode("/", $path); $curl_ch = curl_init(); if (!is_null($this->cabundle_path)) { curl_setopt($curl_ch, CURLOPT_CAINFO, $this->cabundle_path); } if (defined('UPDRAFTPLUS_SSL_DISABLEVERIFY')) { curl_setopt($curl_ch, CURLOPT_SSL_VERIFYPEER, UPDRAFTPLUS_SSL_DISABLEVERIFY); } elseif (UpdraftPlus_Options::get_updraft_option('updraft_ssl_disableverify')) { curl_setopt($curl_ch, CURLOPT_SSL_VERIFYPEER, false); } else { curl_setopt($curl_ch, CURLOPT_SSL_VERIFYPEER, true); } curl_setopt($curl_ch, CURLOPT_VERBOSE, $this->dbug); curl_setopt($curl_ch, CURLOPT_FOLLOWLOCATION, 1); curl_setopt($curl_ch, CURLOPT_MAXREDIRS, 4); curl_setopt($curl_ch, CURLOPT_HEADER, 0); curl_setopt($curl_ch, CURLOPT_HTTPHEADER, $headers); curl_setopt($curl_ch, CURLOPT_USERAGENT, USER_AGENT); curl_setopt($curl_ch, CURLOPT_RETURNTRANSFER, TRUE); curl_setopt($curl_ch, CURLOPT_HEADERFUNCTION,array(&$this,'_auth_hdr_cb')); curl_setopt($curl_ch, CURLOPT_CONNECTTIMEOUT, 10); curl_setopt($curl_ch, CURLOPT_URL, $url); curl_exec($curl_ch); curl_close($curl_ch); return array($this->response_status, $this->response_reason, $this->storage_url, $this->cdnm_url, $this->auth_token); } # (CDN) GET /v1/Account # function list_cdn_containers($enabled_only) { $conn_type = "GET_CALL"; $url_path = $this->_make_path("CDN"); $this->_write_callback_type = "TEXT_LIST"; if ($enabled_only) { $return_code = $this->_send_request($conn_type, $url_path . '/?enabled_only=true'); } else { $return_code = $this->_send_request($conn_type, $url_path); } if (!$return_code) { $this->error_str .= ": Failed to obtain valid HTTP response."; return array(0,$this->error_str,array()); } if ($return_code == 401) { return array($return_code,"Unauthorized",array()); } if ($return_code == 404) { return array($return_code,"Account not found.",array()); } if ($return_code == 204) { return array($return_code,"Account has no CDN enabled Containers.", array()); } if ($return_code == 200) { $this->create_array(); return array($return_code,$this->response_reason,$this->_text_list); } $this->error_str = "Unexpected HTTP response: ".$this->response_reason; return array($return_code,$this->error_str,array()); } # (CDN) DELETE /v1/Account/Container or /v1/Account/Container/Object # function purge_from_cdn($path, $email=null) { if(!$path) throw new SyntaxException("Path not set"); $url_path = $this->_make_path("CDN", NULL, $path); if($email) { $hdrs = array(CDN_EMAIL => $email); $return_code = $this->_send_request("DEL_POST",$url_path,$hdrs,"DELETE"); } else $return_code = $this->_send_request("DEL_POST",$url_path,null,"DELETE"); return $return_code; } # (CDN) POST /v1/Account/Container function update_cdn_container($container_name, $ttl=86400, $cdn_log_retention=False, $cdn_acl_user_agent="", $cdn_acl_referrer) { if ($container_name == "") throw new SyntaxException("Container name not set."); if ($container_name != "0" and !isset($container_name)) throw new SyntaxException("Container name not set."); $url_path = $this->_make_path("CDN", $container_name); $hdrs = array( CDN_ENABLED => "True", CDN_TTL => $ttl, CDN_LOG_RETENTION => $cdn_log_retention ? "True" : "False", CDN_ACL_USER_AGENT => $cdn_acl_user_agent, CDN_ACL_REFERRER => $cdn_acl_referrer, ); $return_code = $this->_send_request("DEL_POST",$url_path,$hdrs,"POST"); if ($return_code == 401) { $this->error_str = "Unauthorized"; return array($return_code, $this->error_str, NULL); } if ($return_code == 404) { $this->error_str = "Container not found."; return array($return_code, $this->error_str, NULL); } if ($return_code != 202) { $this->error_str="Unexpected HTTP response: ".$this->response_reason; return array($return_code, $this->error_str, NULL); } return array($return_code, "Accepted", $this->_cdn_uri, $this->_cdn_ssl_uri); } # (CDN) PUT /v1/Account/Container # function add_cdn_container($container_name, $ttl=86400) { if ($container_name == "") throw new SyntaxException("Container name not set."); if ($container_name != "0" and !isset($container_name)) throw new SyntaxException("Container name not set."); $url_path = $this->_make_path("CDN", $container_name); $hdrs = array( CDN_ENABLED => "True", CDN_TTL => $ttl, ); $return_code = $this->_send_request("PUT_CONT", $url_path, $hdrs); if ($return_code == 401) { $this->error_str = "Unauthorized"; return array($return_code,$this->response_reason,False); } if (!in_array($return_code, array(201,202))) { $this->error_str="Unexpected HTTP response: ".$this->response_reason; return array($return_code,$this->response_reason,False); } return array($return_code,$this->response_reason,$this->_cdn_uri, $this->_cdn_ssl_uri); } # (CDN) POST /v1/Account/Container # function remove_cdn_container($container_name) { if ($container_name == "") throw new SyntaxException("Container name not set."); if ($container_name != "0" and !isset($container_name)) throw new SyntaxException("Container name not set."); $url_path = $this->_make_path("CDN", $container_name); $hdrs = array(CDN_ENABLED => "False"); $return_code = $this->_send_request("DEL_POST",$url_path,$hdrs,"POST"); if ($return_code == 401) { $this->error_str = "Unauthorized"; return array($return_code, $this->error_str); } if ($return_code == 404) { $this->error_str = "Container not found."; return array($return_code, $this->error_str); } if ($return_code != 202) { $this->error_str="Unexpected HTTP response: ".$this->response_reason; return array($return_code, $this->error_str); } return array($return_code, "Accepted"); } # (CDN) HEAD /v1/Account # function head_cdn_container($container_name) { if ($container_name == "") throw new SyntaxException("Container name not set."); if ($container_name != "0" and !isset($container_name)) throw new SyntaxException("Container name not set."); $conn_type = "HEAD"; $url_path = $this->_make_path("CDN", $container_name); $return_code = $this->_send_request($conn_type, $url_path, NULL, "GET", True); if (!$return_code) { $this->error_str .= ": Failed to obtain valid HTTP response."; return array(0,$this->error_str,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL); } if ($return_code == 401) { return array($return_code,"Unauthorized",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL); } if ($return_code == 404) { return array($return_code,"Account not found.",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL); } if ($return_code == 204) { return array($return_code,$this->response_reason, $this->_cdn_enabled, $this->_cdn_ssl_uri, $this->_cdn_streaming_uri, $this->_cdn_uri, $this->_cdn_ttl, $this->_cdn_log_retention, $this->_cdn_acl_user_agent, $this->_cdn_acl_referrer ); } return array($return_code,$this->response_reason, NULL,NULL,NULL,NULL, $this->_cdn_log_retention, $this->_cdn_acl_user_agent, $this->_cdn_acl_referrer, NULL ); } # GET /v1/Account # function list_containers($limit=0, $marker=NULL) { $conn_type = "GET_CALL"; $url_path = $this->_make_path(); $limit = intval($limit); $params = array(); if ($limit > 0) { $params[] = "limit=$limit"; } if ($marker) { $params[] = "marker=".rawurlencode($marker); } if (!empty($params)) { $url_path .= "?" . implode("&", $params); } $this->_write_callback_type = "TEXT_LIST"; $return_code = $this->_send_request($conn_type, $url_path); if (!$return_code) { $this->error_str .= ": Failed to obtain valid HTTP response."; return array(0,$this->error_str,array()); } if ($return_code == 204) { return array($return_code, "Account has no containers.", array()); } if ($return_code == 404) { $this->error_str = "Invalid account name for authentication token."; return array($return_code,$this->error_str,array()); } if ($return_code == 200) { $this->create_array(); return array($return_code, $this->response_reason, $this->_text_list); } $this->error_str = "Unexpected HTTP response: ".$this->response_reason; return array($return_code,$this->error_str,array()); } # GET /v1/Account?format=json # function list_containers_info($limit=0, $marker=NULL) { $conn_type = "GET_CALL"; $url_path = $this->_make_path() . "?format=json"; $limit = intval($limit); $params = array(); if ($limit > 0) { $params[] = "limit=$limit"; } if ($marker) { $params[] = "marker=".rawurlencode($marker); } if (!empty($params)) { $url_path .= "&" . implode("&", $params); } $this->_write_callback_type = "OBJECT_STRING"; $return_code = $this->_send_request($conn_type, $url_path); if (!$return_code) { $this->error_str .= ": Failed to obtain valid HTTP response."; return array(0,$this->error_str,array()); } if ($return_code == 204) { return array($return_code, "Account has no containers.", array()); } if ($return_code == 404) { $this->error_str = "Invalid account name for authentication token."; return array($return_code,$this->error_str,array()); } if ($return_code == 200) { $json_body = json_decode($this->_obj_write_string, True); return array($return_code, $this->response_reason, $json_body); } $this->error_str = "Unexpected HTTP response: ".$this->response_reason; return array($return_code,$this->error_str,array()); } # HEAD /v1/Account # function head_account() { $conn_type = "HEAD"; $url_path = $this->_make_path(); $return_code = $this->_send_request($conn_type,$url_path); if (!$return_code) { $this->error_str .= ": Failed to obtain valid HTTP response."; return array(0,$this->error_str,0,0, NULL, array()); } if ($return_code == 404) { return array($return_code,"Account not found.",0,0, NULL, array()); } if ($return_code == 204) { return array($return_code,$this->response_reason, $this->_account_container_count, $this->_account_bytes_used, $this->_account_key, $this->account_metadata); } return array($return_code,$this->response_reason,0,0, NULL, array()); } # PUT /v1/Account/Container # function create_container($container_name) { if ($container_name == "") throw new SyntaxException("Container name not set."); if ($container_name != "0" and !isset($container_name)) throw new SyntaxException("Container name not set."); $url_path = $this->_make_path("STORAGE", $container_name); $return_code = $this->_send_request("PUT_CONT",$url_path); if (!$return_code) { $this->error_str .= ": Failed to obtain valid HTTP response."; return False; } return $return_code; } # DELETE /v1/Account/Container # function delete_container($container_name) { if ($container_name == "") throw new SyntaxException("Container name not set."); if ($container_name != "0" and !isset($container_name)) throw new SyntaxException("Container name not set."); $url_path = $this->_make_path("STORAGE", $container_name); $return_code = $this->_send_request("DEL_POST",$url_path,array(),"DELETE"); switch ($return_code) { case 204: break; case 0: $this->error_str .= ": Failed to obtain valid HTTP response.";; break; case 409: $this->error_str = "Container must be empty prior to removing it."; break; case 404: $this->error_str = "Specified container did not exist to delete."; break; default: $this->error_str = "Unexpected HTTP return code: $return_code."; } return $return_code; } # GET /v1/Account/Container # function list_objects($cname,$limit=0,$marker=NULL,$prefix=NULL,$path=NULL) { if (!$cname) { $this->error_str = "Container name not set."; return array(0, $this->error_str, array()); } $url_path = $this->_make_path("STORAGE", $cname); $limit = intval($limit); $params = array(); if ($limit > 0) { $params[] = "limit=$limit"; } if ($marker) { $params[] = "marker=".rawurlencode($marker); } if ($prefix) { $params[] = "prefix=".rawurlencode($prefix); } if ($path) { $params[] = "path=".rawurlencode($path); } if (!empty($params)) { $url_path .= "?" . implode("&", $params); } $conn_type = "GET_CALL"; $this->_write_callback_type = "TEXT_LIST"; $return_code = $this->_send_request($conn_type,$url_path); if (!$return_code) { $this->error_str .= ": Failed to obtain valid HTTP response."; return array(0,$this->error_str,array()); } if ($return_code == 204) { $this->error_str = "Container has no Objects."; return array($return_code,$this->error_str,array()); } if ($return_code == 404) { $this->error_str = "Container has no Objects."; return array($return_code,$this->error_str,array()); } if ($return_code == 200) { $this->create_array(); return array($return_code,$this->response_reason, $this->_text_list); } $this->error_str = "Unexpected HTTP response code: $return_code"; return array(0,$this->error_str,array()); } # GET /v1/Account/Container?format=json # function get_objects($cname,$limit=0,$marker=NULL,$prefix=NULL,$path=NULL,$delimiter=NULL) { if (strlen($cname) == 0) { $this->error_str = "Container name not set."; return array(0, $this->error_str, array()); } $url_path = $this->_make_path("STORAGE", $cname); $limit = intval($limit); $params = array(); $params[] = "format=json"; if ($limit > 0) { $params[] = "limit=$limit"; } if ($marker) { $params[] = "marker=".rawurlencode($marker); } if ($prefix) { $params[] = "prefix=".rawurlencode($prefix); } if ($path) { $params[] = "path=".rawurlencode($path); } if ($delimiter) { $params[] = "delimiter=".rawurlencode($delimiter); } if (!empty($params)) { $url_path .= "?" . implode("&", $params); } $conn_type = "GET_CALL"; $this->_write_callback_type = "OBJECT_STRING"; $return_code = $this->_send_request($conn_type,$url_path); if (!$return_code) { $this->error_str .= ": Failed to obtain valid HTTP response."; return array(0,$this->error_str,array()); } if ($return_code == 204) { $this->error_str = "Container has no Objects."; return array($return_code,$this->error_str,array()); } if ($return_code == 404) { $this->error_str = "Container has no Objects."; return array($return_code,$this->error_str,array()); } if ($return_code == 200) { $json_body = json_decode($this->_obj_write_string, True); return array($return_code,$this->response_reason, $json_body); } $this->error_str = "Unexpected HTTP response code: $return_code"; return array(0,$this->error_str,array()); } # HEAD /v1/Account/Container # function head_container($container_name) { if ($container_name == "") { $this->error_str = "Container name not set."; return False; } if ($container_name != "0" and !isset($container_name)) { $this->error_str = "Container name not set."; return False; } $conn_type = "HEAD"; $url_path = $this->_make_path("STORAGE", $container_name); $return_code = $this->_send_request($conn_type,$url_path); if (!$return_code) { $this->error_str .= ": Failed to obtain valid HTTP response."; return array(0,$this->error_str,0,0, array()); } if ($return_code == 404) { return array($return_code,"Container not found.",0,0, array()); } if ($return_code == 204 || $return_code == 200) { return array($return_code,$this->response_reason, $this->_container_object_count, $this->_container_bytes_used, $this->_container_metadata); } return array($return_code,$this->response_reason,0,0, array()); } # GET /v1/Account/Container/Object # function get_object_to_string(&$obj, $hdrs=array()) { if (!is_object($obj) || get_class($obj) != "UpdraftPlus_CF_Object") { throw new SyntaxException( "Method argument is not a valid CF_Object."); } $conn_type = "GET_CALL"; $url_path = $this->_make_path("STORAGE", $obj->container->name,$obj->name); $this->_write_callback_type = "OBJECT_STRING"; $return_code = $this->_send_request($conn_type,$url_path,$hdrs); if (!$return_code) { $this->error_str .= ": Failed to obtain valid HTTP response."; return array($return_code0,$this->error_str,NULL); } if ($return_code == 404) { $this->error_str = "Object not found."; return array($return_code0,$this->error_str,NULL); } if (($return_code < 200) || ($return_code > 299 && $return_code != 412 && $return_code != 304)) { $this->error_str = "Unexpected HTTP return code: $return_code"; return array($return_code,$this->error_str,NULL); } return array($return_code,$this->response_reason, $this->_obj_write_string); } # GET /v1/Account/Container/Object # function get_object_to_stream(&$obj, &$resource=NULL, $hdrs=array()) { if (!is_object($obj) || get_class($obj) != "UpdraftPlus_CF_Object") { throw new SyntaxException( "Method argument is not a valid CF_Object."); } if (!is_resource($resource)) { throw new SyntaxException( "Resource argument not a valid PHP resource."); } $conn_type = "GET_CALL"; $url_path = $this->_make_path("STORAGE", $obj->container->name,$obj->name); $this->_obj_write_resource = $resource; $this->_write_callback_type = "OBJECT_STREAM"; $return_code = $this->_send_request($conn_type,$url_path,$hdrs); if (!$return_code) { $this->error_str .= ": Failed to obtain valid HTTP response."; return array($return_code,$this->error_str); } if ($return_code == 404) { $this->error_str = "Object not found."; return array($return_code,$this->error_str); } if (($return_code < 200) || ($return_code > 299 && $return_code != 412 && $return_code != 304)) { $this->error_str = "Unexpected HTTP return code: $return_code"; return array($return_code,$this->error_str); } return array($return_code,$this->response_reason); } # PUT /v1/Account/Container/Object # function put_object(&$obj, &$fp) { if (!is_object($obj) || get_class($obj) != "UpdraftPlus_CF_Object") { throw new SyntaxException( "Method argument is not a valid CF_Object."); } if (!is_resource($fp)) { throw new SyntaxException( "File pointer argument is not a valid resource."); } $conn_type = "PUT_OBJ"; $url_path = $this->_make_path("STORAGE", $obj->container->name,$obj->name); $hdrs = $this->_headers($obj); $etag = $obj->getETag(); if (isset($etag)) { $hdrs[] = "ETag: " . $etag; } if (!$obj->content_type) { $hdrs[] = "Content-Type: application/octet-stream"; } else { $hdrs[] = "Content-Type: " . $obj->content_type; } $this->_init($conn_type); curl_setopt($this->connections[$conn_type], CURLOPT_INFILE, $fp); if (!$obj->content_length) { # We don''t know the Content-Length, so assumed "chunked" PUT # curl_setopt($this->connections[$conn_type], CURLOPT_UPLOAD, True); $hdrs[] = 'Transfer-Encoding: chunked'; } else { # We know the Content-Length, so use regular transfer # curl_setopt($this->connections[$conn_type], CURLOPT_INFILESIZE, $obj->content_length); } $return_code = $this->_send_request($conn_type,$url_path,$hdrs); if (!$return_code) { $this->error_str .= ": Failed to obtain valid HTTP response."; return array(0,$this->error_str,NULL); } if ($return_code == 412) { $this->error_str = "Missing Content-Type header"; return array($return_code,$this->error_str,NULL); } if ($return_code == 422) { $this->error_str = "Derived and computed checksums do not match."; return array($return_code,$this->error_str,NULL); } if ($return_code != 201) { $this->error_str = "Unexpected HTTP return code: $return_code"; return array($return_code,$this->error_str,NULL); } return array($return_code,$this->response_reason,$this->_obj_etag); } function post_account(&$conn) { if (!is_object($conn) || get_class($conn) != "UpdraftPlus_CF_Connection") { throw new SyntaxException( "Method argument is not a valid CF_Connection object."); } if (!is_array($conn->metadata)) { throw new SyntaxException("Metadata array is empty"); } $return_code = $this->_send_request("DEL_POST", $this->_make_path("STORAGE"), $conn->metadata, "POST"); switch ($return_code) { case 202: case 201: break; case 0: $this->error_str .= ": Failed to obtain valid HTTP response."; $return_code = 0; break; case 404: $this->error_str = "Account, Container, or Object not found."; break; default: $this->error_str = "Unexpected HTTP return code: $return_code"; break; } return $return_code; } function post_container(&$cont) { if (!is_object($cont) || get_class($cont) != "UpdraftPlus_CF_Container") { throw new SyntaxException( "Method argument is not a valid CF_Container object."); } if (!is_array($cont->metadata)) { throw new SyntaxException("Metadata array is empty"); } $return_code = $this->_send_request("DEL_POST", $this->_make_path("STORAGE", $cont->name), $cont->metadata, "POST"); switch ($return_code) { case 201: case 202: break; case 0: $this->error_str .= ": Failed to obtain valid HTTP response."; $return_code = 0; break; case 404: $this->error_str = "Account, Container, or Object not found."; break; default: $this->error_str = "Unexpected HTTP return code: $return_code"; break; } return $return_code; } # POST /v1/Account/Container/Object # function update_object(&$obj) { if (!is_object($obj) || get_class($obj) != "UpdraftPlus_CF_Object") { throw new SyntaxException( "Method argument is not a valid CF_Object."); } # TODO: The is_array check isn't in sync with the error message if (!$obj->manifest && !(is_array($obj->metadata) || is_array($obj->headers))) { $this->error_str = "Metadata and headers arrays are empty."; return 0; } $url_path = $this->_make_path("STORAGE", $obj->container->name,$obj->name); $hdrs = $this->_headers($obj); $return_code = $this->_send_request("DEL_POST",$url_path,$hdrs,"POST"); switch ($return_code) { case 202: break; case 0: $this->error_str .= ": Failed to obtain valid HTTP response."; $return_code = 0; break; case 404: $this->error_str = "Account, Container, or Object not found."; break; default: $this->error_str = "Unexpected HTTP return code: $return_code"; break; } return $return_code; } # HEAD /v1/Account/Container/Object # function head_object(&$obj) { if (!is_object($obj) || get_class($obj) != "UpdraftPlus_CF_Object") { throw new SyntaxException( "Method argument is not a valid CF_Object."); } $conn_type = "HEAD"; $url_path = $this->_make_path("STORAGE", $obj->container->name,$obj->name); $return_code = $this->_send_request($conn_type,$url_path); if (!$return_code) { $this->error_str .= ": Failed to obtain valid HTTP response."; return array(0, $this->error_str." ".$this->response_reason, NULL, NULL, NULL, NULL, array(), NULL, NULL, NULL, array()); } if ($return_code == 404) { return array($return_code, $this->response_reason, NULL, NULL, NULL, NULL, array(), NULL, NULL, NULL, array()); } if ($return_code == 204 || $return_code == 200) { return array($return_code,$this->response_reason, $this->_obj_etag, $this->_obj_last_modified, $this->_obj_content_type, $this->_obj_content_length, $this->_obj_metadata, $this->_obj_manifest, $this->_obj_delete_at, $this->_obj_delete_after, $this->_obj_headers); } $this->error_str = "Unexpected HTTP return code: $return_code"; return array($return_code, $this->error_str." ".$this->response_reason, NULL, NULL, NULL, NULL, array(), NULL, NULL, NULL, array()); } # COPY /v1/Account/Container/Object # function copy_object($src_obj_name, $dest_obj_name, $container_name_source, $container_name_target, $metadata=NULL, $headers=NULL) { if (!$src_obj_name) { $this->error_str = "Object name not set."; return 0; } if ($container_name_source == "") { $this->error_str = "Container name source not set."; return 0; } if ($container_name_source != "0" and !isset($container_name_source)) { $this->error_str = "Container name source not set."; return 0; } if ($container_name_target == "") { $this->error_str = "Container name target not set."; return 0; } if ($container_name_target != "0" and !isset($container_name_target)) { $this->error_str = "Container name target not set."; return 0; } $conn_type = "COPY"; $url_path = $this->_make_path("STORAGE", $container_name_source, rawurlencode($src_obj_name)); $destination = rawurlencode($container_name_target."/".$dest_obj_name); $hdrs = self::_process_headers($metadata, $headers); $hdrs[DESTINATION] = $destination; $return_code = $this->_send_request($conn_type,$url_path,$hdrs,"COPY"); switch ($return_code) { case 201: break; case 0: $this->error_str .= ": Failed to obtain valid HTTP response."; $return_code = 0; break; case 404: $this->error_str = "Specified container/object did not exist."; break; default: $this->error_str = "Unexpected HTTP return code: $return_code."; } return $return_code; } # DELETE /v1/Account/Container/Object # function delete_object($container_name, $object_name) { if ($container_name == "") { $this->error_str = "Container name not set."; return 0; } if ($container_name != "0" and !isset($container_name)) { $this->error_str = "Container name not set."; return 0; } if (!$object_name) { $this->error_str = "Object name not set."; return 0; } $url_path = $this->_make_path("STORAGE", $container_name,$object_name); $return_code = $this->_send_request("DEL_POST",$url_path,NULL,"DELETE"); switch ($return_code) { case 204: break; case 0: $this->error_str .= ": Failed to obtain valid HTTP response."; $return_code = 0; break; case 404: $this->error_str = "Specified container did not exist to delete."; break; default: $this->error_str = "Unexpected HTTP return code: $return_code."; } return $return_code; } function get_error() { return $this->error_str; } function setDebug($bool) { $this->dbug = $bool; foreach ($this->connections as $k => $v) { if (!is_null($v)) { curl_setopt($this->connections[$k], CURLOPT_VERBOSE, $this->dbug); } } } function getCDNMUrl() { return $this->cdnm_url; } function getStorageUrl() { return $this->storage_url; } function getAuthToken() { return $this->auth_token; } function setCFAuth($cfs_auth, $servicenet=False) { if ($servicenet) { $this->storage_url = "https://snet-" . substr($cfs_auth->storage_url, 8); } else { $this->storage_url = $cfs_auth->storage_url; } $this->auth_token = $cfs_auth->auth_token; $this->cdnm_url = $cfs_auth->cdnm_url; } function setReadProgressFunc($func_name) { $this->_user_read_progress_callback_func = $func_name; } function setWriteProgressFunc($func_name) { $this->_user_write_progress_callback_func = $func_name; } private function _header_cb($ch, $header) { $header_len = strlen($header); if (preg_match("/^(HTTP\/1\.[01]) (\d{3}) (.*)/", $header, $matches)) { $this->response_status = $matches[2]; $this->response_reason = $matches[3]; return $header_len; } if (strpos($header, ":") === False) return $header_len; list($name, $value) = explode(":", $header, 2); $value = trim($value); switch (strtolower($name)) { case strtolower(CDN_ENABLED): $this->_cdn_enabled = strtolower($value) == "true"; break; case strtolower(CDN_URI): $this->_cdn_uri = $value; break; case strtolower(CDN_SSL_URI): $this->_cdn_ssl_uri = $value; break; case strtolower(CDN_STREAMING_URI): $this->_cdn_streaming_uri = $value; break; case strtolower(CDN_TTL): $this->_cdn_ttl = $value; break; case strtolower(MANIFEST_HEADER): $this->_obj_manifest = $value; break; case strtolower(CDN_LOG_RETENTION): $this->_cdn_log_retention = strtolower($value) == "true"; break; case strtolower(CDN_ACL_USER_AGENT): $this->_cdn_acl_user_agent = $value; break; case strtolower(CDN_ACL_REFERRER): $this->_cdn_acl_referrer = $value; break; case strtolower(ACCOUNT_CONTAINER_COUNT): $this->_account_container_count = (float)$value+0; break; case strtolower(ACCOUNT_BYTES_USED): $this->_account_bytes_used = (float)$value+0; break; case strtolower(CONTAINER_OBJ_COUNT): $this->_container_object_count = (float)$value+0; break; case strtolower(CONTAINER_BYTES_USED): $this->_container_bytes_used = (float)$value+0; break; case strtolower(ETAG_HEADER): $this->_obj_etag = $value; break; case strtolower(LAST_MODIFIED_HEADER): $this->_obj_last_modified = $value; break; case strtolower(CONTENT_TYPE_HEADER): $this->_obj_content_type = $value; break; case strtolower(CONTENT_LENGTH_HEADER): $this->_obj_content_length = (float)$value+0; break; case strtolower(ORIGIN_HEADER): $this->_obj_headers[ORIGIN_HEADER] = $value; break; case strtolower(ACCOUNT_KEY): $this->_account_key = $value; break; default: if (strncasecmp($name, METADATA_HEADER_PREFIX, strlen(METADATA_HEADER_PREFIX)) == 0) { $name = substr($name, strlen(METADATA_HEADER_PREFIX)); $this->_obj_metadata[$name] = $value; } elseif ((strncasecmp($name, CONTENT_HEADER_PREFIX, strlen(CONTENT_HEADER_PREFIX)) == 0) || (strncasecmp($name, ACCESS_CONTROL_HEADER_PREFIX, strlen(ACCESS_CONTROL_HEADER_PREFIX)) == 0)) { $this->_obj_headers[$name] = $value; } elseif (strncasecmp($name, ACCOUNT_METADATA_HEADER_PREFIX, strlen(ACCOUNT_METADATA_HEADER_PREFIX)) == 0) { $this->_account_metadata[$name] = $value; } elseif (strncasecmp($name, CONTAINER_METADATA_HEADER_PREFIX, strlen(CONTAINER_METADATA_HEADER_PREFIX)) == 0) { $this->_container_metadata[$name] = $value; } } return $header_len; } private function _read_cb($ch, $fd, $length) { $data = fread($fd, $length); $len = strlen($data); if (isset($this->_user_write_progress_callback_func)) { call_user_func($this->_user_write_progress_callback_func, $len); } return $data; } private function _write_cb($ch, $data) { $dlen = strlen($data); switch ($this->_write_callback_type) { case "TEXT_LIST": $this->_return_list = $this->_return_list . $data; //= explode("\n",$data); # keep tab,space //his->_text_list[] = rtrim($data,"\n\r\x0B"); # keep tab,space break; case "OBJECT_STREAM": fwrite($this->_obj_write_resource, $data, $dlen); break; case "OBJECT_STRING": $this->_obj_write_string .= $data; break; } if (isset($this->_user_read_progress_callback_func)) { call_user_func($this->_user_read_progress_callback_func, $dlen); } return $dlen; } private function _auth_hdr_cb($ch, $header) { preg_match("/^HTTP\/1\.[01] (\d{3}) (.*)/", $header, $matches); if (isset($matches[1])) { $this->response_status = $matches[1]; } if (isset($matches[2])) { $this->response_reason = $matches[2]; } if (stripos($header, STORAGE_URL) === 0) { $this->storage_url = trim(substr($header, strlen(STORAGE_URL)+1)); } if (stripos($header, CDNM_URL) === 0) { $this->cdnm_url = trim(substr($header, strlen(CDNM_URL)+1)); } if (stripos($header, AUTH_TOKEN) === 0) { $this->auth_token = trim(substr($header, strlen(AUTH_TOKEN)+1)); } if (stripos($header, AUTH_TOKEN_LEGACY) === 0) { $this->auth_token = trim(substr($header,strlen(AUTH_TOKEN_LEGACY)+1)); } return strlen($header); } private function _make_headers($hdrs=NULL) { $new_headers = array(); $has_stoken = False; $has_uagent = False; if (is_array($hdrs)) { foreach ($hdrs as $h => $v) { if (is_int($h)) { list($h, $v) = explode(":", $v, 2); } if (strncasecmp($h, AUTH_TOKEN, strlen(AUTH_TOKEN)) === 0) { $has_stoken = True; } if (strncasecmp($h, USER_AGENT_HEADER, strlen(USER_AGENT_HEADER)) === 0) { $has_uagent = True; } $new_headers[] = $h . ": " . trim($v); } } if (!$has_stoken) { $new_headers[] = AUTH_TOKEN . ": " . $this->auth_token; } if (!$has_uagent) { $new_headers[] = USER_AGENT_HEADER . ": " . USER_AGENT; } return $new_headers; } private function _init($conn_type, $force_new=False) { if (!array_key_exists($conn_type, $this->connections)) { $this->error_str = "Invalid CURL_XXX connection type"; return False; } if (is_null($this->connections[$conn_type]) || $force_new) { $ch = curl_init(); } else { return; } if ($this->dbug) { curl_setopt($ch, CURLOPT_VERBOSE, 1); } if (!is_null($this->cabundle_path)) { curl_setopt($ch, CURLOPT_CAINFO, $this->cabundle_path); } if (UpdraftPlus_Options::get_updraft_option('updraft_ssl_disableverify')) { curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); } else { curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true); } curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10); curl_setopt($ch, CURLOPT_MAXREDIRS, 4); curl_setopt($ch, CURLOPT_HEADER, 0); curl_setopt($ch, CURLOPT_HEADERFUNCTION, array(&$this, '_header_cb')); if ($conn_type == "GET_CALL") { curl_setopt($ch, CURLOPT_WRITEFUNCTION, array(&$this, '_write_cb')); } if ($conn_type == "PUT_OBJ") { curl_setopt($ch, CURLOPT_PUT, 1); curl_setopt($ch, CURLOPT_READFUNCTION, array(&$this, '_read_cb')); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); } if ($conn_type == "HEAD") { curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "HEAD"); curl_setopt($ch, CURLOPT_NOBODY, 1); } if ($conn_type == "PUT_CONT") { curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PUT"); curl_setopt($ch, CURLOPT_INFILESIZE, 0); curl_setopt($ch, CURLOPT_NOBODY, 1); } if ($conn_type == "DEL_POST") { curl_setopt($ch, CURLOPT_NOBODY, 1); } if ($conn_type == "COPY") { curl_setopt($ch, CURLOPT_NOBODY, 1); } $this->connections[$conn_type] = $ch; return; } private function _reset_callback_vars() { $this->_text_list = array(); $this->_return_list = NULL; $this->_account_metadata = array(); $this->_account_key = NULL; $this->_account_container_count = 0; $this->_account_bytes_used = 0; $this->_container_metadata = array(); $this->_container_object_count = 0; $this->_container_bytes_used = 0; $this->_obj_delete_at = NULL; $this->_obj_delete_after = NULL; $this->_obj_etag = NULL; $this->_obj_last_modified = NULL; $this->_obj_content_type = NULL; $this->_obj_content_length = NULL; $this->_obj_metadata = array(); $this->_obj_manifest = NULL; $this->_obj_headers = NULL; $this->_obj_write_string = ""; $this->_cdn_streaming_uri = NULL; $this->_cdn_enabled = NULL; $this->_cdn_ssl_uri = NULL; $this->_cdn_uri = NULL; $this->_cdn_ttl = NULL; $this->response_status = 0; $this->response_reason = ""; } private function _make_path($t="STORAGE",$c=NULL,$o=NULL) { $path = array(); switch ($t) { case "STORAGE": $path[] = $this->storage_url; break; case "CDN": $path[] = $this->cdnm_url; break; } if ($c != "") { $path[] = rawurlencode($c); } if ($o) { # mimic Python''s urllib.quote() feature of a "safe" '/' character # $path[] = str_replace("%2F","/",rawurlencode($o)); } return implode("/",$path); } private function _headers(&$obj) { $hdrs = self::_process_headers($obj->metadata, $obj->headers); if ($obj->manifest) $hdrs[MANIFEST_HEADER] = $obj->manifest; return $hdrs; } private function _process_headers($metadata=null, $headers=null) { $rules = array( array( 'prefix' => METADATA_HEADER_PREFIX, ), array( 'prefix' => '', 'filter' => array( # key order is important, first match decides CONTENT_TYPE_HEADER => false, CONTENT_LENGTH_HEADER => false, CONTENT_HEADER_PREFIX => true, ACCESS_CONTROL_HEADER_PREFIX => true, ORIGIN_HEADER => true, ), ), ); $hdrs = array(); $argc = func_num_args(); $argv = func_get_args(); for ($argi = 0; $argi < $argc; $argi++) { if(!is_array($argv[$argi])) continue; $rule = $rules[$argi]; foreach ($argv[$argi] as $k => $v) { $k = trim($k); $v = trim($v); if (strpos($k, ":") !== False) throw new SyntaxException( "Header names cannot contain a ':' character."); if (array_key_exists('filter', $rule)) { $result = null; foreach ($rule['filter'] as $p => $f) { if (strncasecmp($k, $p, strlen($p)) == 0) { $result = $f; break; } } if (!$result) throw new SyntaxException(sprintf( "Header name %s is not allowed", $k)); } $k = $rule['prefix'] . $k; if (strlen($k) > MAX_HEADER_NAME_LEN || strlen($v) > MAX_HEADER_VALUE_LEN) throw new SyntaxException(sprintf( "Header %s exceeds maximum length: %d/%d", $k, strlen($k), strlen($v))); $hdrs[$k] = $v; } } return $hdrs; } private function _send_request($conn_type, $url_path, $hdrs=NULL, $method="GET", $force_new=False) { $this->_init($conn_type, $force_new); $this->_reset_callback_vars(); $headers = $this->_make_headers($hdrs); if (gettype($this->connections[$conn_type]) == "unknown type") throw new ConnectionNotOpenException ( "Connection is not open." ); switch ($method) { case "COPY": curl_setopt($this->connections[$conn_type], CURLOPT_CUSTOMREQUEST, "COPY"); break; case "DELETE": curl_setopt($this->connections[$conn_type], CURLOPT_CUSTOMREQUEST, "DELETE"); break; case "POST": curl_setopt($this->connections[$conn_type], CURLOPT_CUSTOMREQUEST, "POST"); default: break; } curl_setopt($this->connections[$conn_type], CURLOPT_HTTPHEADER, $headers); curl_setopt($this->connections[$conn_type], CURLOPT_URL, $url_path); if (!curl_exec($this->connections[$conn_type]) && curl_errno($this->connections[$conn_type]) !== 0) { $this->error_str = "(curl error: " . curl_errno($this->connections[$conn_type]) . ") "; $this->error_str .= curl_error($this->connections[$conn_type]); return False; } return curl_getinfo($this->connections[$conn_type], CURLINFO_HTTP_CODE); } function close() { foreach ($this->connections as $cnx) { if (isset($cnx)) { curl_close($cnx); $this->connections[$cnx] = NULL; } } } private function create_array() { $this->_text_list = explode("\n",rtrim($this->_return_list,"\n\x0B")); return True; } } /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */ /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * c-hanging-comment-ender-p: nil * End: */ ?> includes/handlebars/LICENSE000064400000002047152214270100011457 0ustar00Copyright (C) 2011-2019 by Yehuda Katz Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. includes/handlebars/handlebars.runtime.min.js000064400000050330152214270100015355 0ustar00/**! @license handlebars v4.7.7 Copyright (C) 2011-2019 by Yehuda Katz Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ !function(a,b){"object"==typeof exports&&"object"==typeof module?module.exports=b():"function"==typeof define&&define.amd?define([],b):"object"==typeof exports?exports.Handlebars=b():a.Handlebars=b()}(this,function(){return function(a){function b(d){if(c[d])return c[d].exports;var e=c[d]={exports:{},id:d,loaded:!1};return a[d].call(e.exports,e,e.exports,b),e.loaded=!0,e.exports}var c={};return b.m=a,b.c=c,b.p="",b(0)}([function(a,b,c){"use strict";function d(){var a=new h.HandlebarsEnvironment;return n.extend(a,h),a.SafeString=j["default"],a.Exception=l["default"],a.Utils=n,a.escapeExpression=n.escapeExpression,a.VM=p,a.template=function(b){return p.template(b,a)},a}var e=c(1)["default"],f=c(2)["default"];b.__esModule=!0;var g=c(3),h=e(g),i=c(36),j=f(i),k=c(5),l=f(k),m=c(4),n=e(m),o=c(37),p=e(o),q=c(43),r=f(q),s=d();s.create=d,r["default"](s),s["default"]=s,b["default"]=s,a.exports=b["default"]},function(a,b){"use strict";b["default"]=function(a){if(a&&a.__esModule)return a;var b={};if(null!=a)for(var c in a)Object.prototype.hasOwnProperty.call(a,c)&&(b[c]=a[c]);return b["default"]=a,b},b.__esModule=!0},function(a,b){"use strict";b["default"]=function(a){return a&&a.__esModule?a:{"default":a}},b.__esModule=!0},function(a,b,c){"use strict";function d(a,b,c){this.helpers=a||{},this.partials=b||{},this.decorators=c||{},i.registerDefaultHelpers(this),j.registerDefaultDecorators(this)}var e=c(2)["default"];b.__esModule=!0,b.HandlebarsEnvironment=d;var f=c(4),g=c(5),h=e(g),i=c(9),j=c(29),k=c(31),l=e(k),m=c(32),n="4.7.7";b.VERSION=n;var o=8;b.COMPILER_REVISION=o;var p=7;b.LAST_COMPATIBLE_COMPILER_REVISION=p;var q={1:"<= 1.0.rc.2",2:"== 1.0.0-rc.3",3:"== 1.0.0-rc.4",4:"== 1.x.x",5:"== 2.0.0-alpha.x",6:">= 2.0.0-beta.1",7:">= 4.0.0 <4.3.0",8:">= 4.3.0"};b.REVISION_CHANGES=q;var r="[object Object]";d.prototype={constructor:d,logger:l["default"],log:l["default"].log,registerHelper:function(a,b){if(f.toString.call(a)===r){if(b)throw new h["default"]("Arg not supported with multiple helpers");f.extend(this.helpers,a)}else this.helpers[a]=b},unregisterHelper:function(a){delete this.helpers[a]},registerPartial:function(a,b){if(f.toString.call(a)===r)f.extend(this.partials,a);else{if("undefined"==typeof b)throw new h["default"]('Attempting to register a partial called "'+a+'" as undefined');this.partials[a]=b}},unregisterPartial:function(a){delete this.partials[a]},registerDecorator:function(a,b){if(f.toString.call(a)===r){if(b)throw new h["default"]("Arg not supported with multiple decorators");f.extend(this.decorators,a)}else this.decorators[a]=b},unregisterDecorator:function(a){delete this.decorators[a]},resetLoggedPropertyAccesses:function(){m.resetLoggedProperties()}};var s=l["default"].log;b.log=s,b.createFrame=f.createFrame,b.logger=l["default"]},function(a,b){"use strict";function c(a){return k[a]}function d(a){for(var b=1;b":">",'"':""","'":"'","`":"`","=":"="},l=/[&<>"'`=]/g,m=/[&<>"'`=]/,n=Object.prototype.toString;b.toString=n;var o=function(a){return"function"==typeof a};o(/x/)&&(b.isFunction=o=function(a){return"function"==typeof a&&"[object Function]"===n.call(a)}),b.isFunction=o;var p=Array.isArray||function(a){return!(!a||"object"!=typeof a)&&"[object Array]"===n.call(a)};b.isArray=p},function(a,b,c){"use strict";function d(a,b){var c=b&&b.loc,g=void 0,h=void 0,i=void 0,j=void 0;c&&(g=c.start.line,h=c.end.line,i=c.start.column,j=c.end.column,a+=" - "+g+":"+i);for(var k=Error.prototype.constructor.call(this,a),l=0;l0?(c.ids&&(c.ids=[c.name]),a.helpers.each(b,c)):e(this);if(c.data&&c.ids){var g=d.createFrame(c.data);g.contextPath=d.appendContextPath(c.data.contextPath,c.name),c={data:g}}return f(b,c)})},a.exports=b["default"]},function(a,b,c){(function(d){"use strict";var e=c(12)["default"],f=c(2)["default"];b.__esModule=!0;var g=c(4),h=c(5),i=f(h);b["default"]=function(a){a.registerHelper("each",function(a,b){function c(b,c,d){l&&(l.key=b,l.index=c,l.first=0===c,l.last=!!d,m&&(l.contextPath=m+b)),k+=f(a[b],{data:l,blockParams:g.blockParams([a[b],b],[m+b,null])})}if(!b)throw new i["default"]("Must pass iterator to #each");var f=b.fn,h=b.inverse,j=0,k="",l=void 0,m=void 0;if(b.data&&b.ids&&(m=g.appendContextPath(b.data.contextPath,b.ids[0])+"."),g.isFunction(a)&&(a=a.call(this)),b.data&&(l=g.createFrame(b.data)),a&&"object"==typeof a)if(g.isArray(a))for(var n=a.length;j=0?b:parseInt(a,10)}return a},log:function(a){if(a=e.lookupLevel(a),"undefined"!=typeof console&&e.lookupLevel(e.level)<=a){var b=e.methodMap[a];console[b]||(b="log");for(var c=arguments.length,d=Array(c>1?c-1:0),f=1;f=v.LAST_COMPATIBLE_COMPILER_REVISION&&b<=v.COMPILER_REVISION)){if(b= 2.0.0-beta.1",7:">= 4.0.0 <4.3.0",8:">= 4.3.0"};b.REVISION_CHANGES=q;var r="[object Object]";d.prototype={constructor:d,logger:l["default"],log:l["default"].log,registerHelper:function(a,b){if(f.toString.call(a)===r){if(b)throw new h["default"]("Arg not supported with multiple helpers");f.extend(this.helpers,a)}else this.helpers[a]=b},unregisterHelper:function(a){delete this.helpers[a]},registerPartial:function(a,b){if(f.toString.call(a)===r)f.extend(this.partials,a);else{if("undefined"==typeof b)throw new h["default"]('Attempting to register a partial called "'+a+'" as undefined');this.partials[a]=b}},unregisterPartial:function(a){delete this.partials[a]},registerDecorator:function(a,b){if(f.toString.call(a)===r){if(b)throw new h["default"]("Arg not supported with multiple decorators");f.extend(this.decorators,a)}else this.decorators[a]=b},unregisterDecorator:function(a){delete this.decorators[a]},resetLoggedPropertyAccesses:function(){m.resetLoggedProperties()}};var s=l["default"].log;b.log=s,b.createFrame=f.createFrame,b.logger=l["default"]},function(a,b){"use strict";function c(a){return k[a]}function d(a){for(var b=1;b":">",'"':""","'":"'","`":"`","=":"="},l=/[&<>"'`=]/g,m=/[&<>"'`=]/,n=Object.prototype.toString;b.toString=n;var o=function(a){return"function"==typeof a};o(/x/)&&(b.isFunction=o=function(a){return"function"==typeof a&&"[object Function]"===n.call(a)}),b.isFunction=o;var p=Array.isArray||function(a){return!(!a||"object"!=typeof a)&&"[object Array]"===n.call(a)};b.isArray=p},function(a,b,c){"use strict";function d(a,b){var c=b&&b.loc,g=void 0,h=void 0,i=void 0,j=void 0;c&&(g=c.start.line,h=c.end.line,i=c.start.column,j=c.end.column,a+=" - "+g+":"+i);for(var k=Error.prototype.constructor.call(this,a),l=0;l0?(c.ids&&(c.ids=[c.name]),a.helpers.each(b,c)):e(this);if(c.data&&c.ids){var g=d.createFrame(c.data);g.contextPath=d.appendContextPath(c.data.contextPath,c.name),c={data:g}}return f(b,c)})},a.exports=b["default"]},function(a,b,c){(function(d){"use strict";var e=c(13)["default"],f=c(1)["default"];b.__esModule=!0;var g=c(5),h=c(6),i=f(h);b["default"]=function(a){a.registerHelper("each",function(a,b){function c(b,c,d){l&&(l.key=b,l.index=c,l.first=0===c,l.last=!!d,m&&(l.contextPath=m+b)),k+=f(a[b],{data:l,blockParams:g.blockParams([a[b],b],[m+b,null])})}if(!b)throw new i["default"]("Must pass iterator to #each");var f=b.fn,h=b.inverse,j=0,k="",l=void 0,m=void 0;if(b.data&&b.ids&&(m=g.appendContextPath(b.data.contextPath,b.ids[0])+"."),g.isFunction(a)&&(a=a.call(this)),b.data&&(l=g.createFrame(b.data)),a&&"object"==typeof a)if(g.isArray(a))for(var n=a.length;j=0?b:parseInt(a,10)}return a},log:function(a){if(a=e.lookupLevel(a),"undefined"!=typeof console&&e.lookupLevel(e.level)<=a){var b=e.methodMap[a];console[b]||(b="log");for(var c=arguments.length,d=Array(c>1?c-1:0),f=1;f=v.LAST_COMPATIBLE_COMPILER_REVISION&&b<=v.COMPILER_REVISION)){if(b2&&v.push("'"+this.terminals_[s]+"'");x=this.lexer.showPosition?"Parse error on line "+(i+1)+":\n"+this.lexer.showPosition()+"\nExpecting "+v.join(", ")+", got '"+(this.terminals_[n]||n)+"'":"Parse error on line "+(i+1)+": Unexpected "+(1==n?"end of input":"'"+(this.terminals_[n]||n)+"'"),this.parseError(x,{text:this.lexer.match,token:this.terminals_[n]||n,line:this.lexer.yylineno,loc:l,expected:v})}}if(q[0]instanceof Array&&q.length>1)throw new Error("Parse Error: multiple actions possible at state: "+p+", token: "+n);switch(q[0]){case 1:d.push(n),e.push(this.lexer.yytext),f.push(this.lexer.yylloc),d.push(q[1]),n=null,o?(n=o,o=null):(j=this.lexer.yyleng,h=this.lexer.yytext,i=this.lexer.yylineno,l=this.lexer.yylloc,k>0&&k--);break;case 2:if(t=this.productions_[q[1]][1],w.$=e[e.length-t],w._$={first_line:f[f.length-(t||1)].first_line,last_line:f[f.length-1].last_line,first_column:f[f.length-(t||1)].first_column,last_column:f[f.length-1].last_column},m&&(w._$.range=[f[f.length-(t||1)].range[0],f[f.length-1].range[1]]),r=this.performAction.call(w,h,j,i,this.yy,q[1],e,f),"undefined"!=typeof r)return r;t&&(d=d.slice(0,-1*t*2),e=e.slice(0,-1*t),f=f.slice(0,-1*t)),d.push(this.productions_[q[1]][0]),e.push(w.$),f.push(w._$),u=g[d[d.length-2]][d[d.length-1]],d.push(u);break;case 3:return!0}}return!0}},c=function(){var a={EOF:1,parseError:function(a,b){if(!this.yy.parser)throw new Error(a);this.yy.parser.parseError(a,b)},setInput:function(a){return this._input=a,this._more=this._less=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},input:function(){var a=this._input[0];this.yytext+=a,this.yyleng++,this.offset++,this.match+=a,this.matched+=a;var b=a.match(/(?:\r\n?|\n).*/g);return b?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),a},unput:function(a){var b=a.length,c=a.split(/(?:\r\n?|\n)/g);this._input=a+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-b-1),this.offset-=b;var d=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),c.length-1&&(this.yylineno-=c.length-1);var e=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:c?(c.length===d.length?this.yylloc.first_column:0)+d[d.length-c.length].length-c[0].length:this.yylloc.first_column-b},this.options.ranges&&(this.yylloc.range=[e[0],e[0]+this.yyleng-b]),this},more:function(){return this._more=!0,this},less:function(a){this.unput(this.match.slice(a))},pastInput:function(){var a=this.matched.substr(0,this.matched.length-this.match.length);return(a.length>20?"...":"")+a.substr(-20).replace(/\n/g,"")},upcomingInput:function(){var a=this.match;return a.length<20&&(a+=this._input.substr(0,20-a.length)),(a.substr(0,20)+(a.length>20?"...":"")).replace(/\n/g,"")},showPosition:function(){var a=this.pastInput(),b=new Array(a.length+1).join("-");return a+this.upcomingInput()+"\n"+b+"^"},next:function(){if(this.done)return this.EOF;this._input||(this.done=!0);var a,b,c,d,e;this._more||(this.yytext="",this.match="");for(var f=this._currentRules(),g=0;gb[0].length)||(b=c,d=g,this.options.flex));g++);return b?(e=b[0].match(/(?:\r\n?|\n).*/g),e&&(this.yylineno+=e.length),this.yylloc={first_line:this.yylloc.last_line,last_line:this.yylineno+1,first_column:this.yylloc.last_column,last_column:e?e[e.length-1].length-e[e.length-1].match(/\r?\n?/)[0].length:this.yylloc.last_column+b[0].length},this.yytext+=b[0],this.match+=b[0],this.matches=b,this.yyleng=this.yytext.length,this.options.ranges&&(this.yylloc.range=[this.offset,this.offset+=this.yyleng]),this._more=!1,this._input=this._input.slice(b[0].length),this.matched+=b[0],a=this.performAction.call(this,this.yy,this,f[d],this.conditionStack[this.conditionStack.length-1]),this.done&&this._input&&(this.done=!1),a?a:void 0):""===this._input?this.EOF:this.parseError("Lexical error on line "+(this.yylineno+1)+". Unrecognized text.\n"+this.showPosition(),{text:"",token:null,line:this.yylineno})},lex:function(){var a=this.next();return"undefined"!=typeof a?a:this.lex()},begin:function(a){this.conditionStack.push(a)},popState:function(){return this.conditionStack.pop()},_currentRules:function(){return this.conditions[this.conditionStack[this.conditionStack.length-1]].rules},topState:function(){return this.conditionStack[this.conditionStack.length-2]},pushState:function(a){this.begin(a)}};return a.options={},a.performAction=function(a,b,c,d){function e(a,c){return b.yytext=b.yytext.substring(a,b.yyleng-c+a)}switch(c){case 0:if("\\\\"===b.yytext.slice(-2)?(e(0,1),this.begin("mu")):"\\"===b.yytext.slice(-1)?(e(0,1),this.begin("emu")):this.begin("mu"),b.yytext)return 15;break;case 1:return 15;case 2:return this.popState(),15;case 3:return this.begin("raw"),15;case 4:return this.popState(),"raw"===this.conditionStack[this.conditionStack.length-1]?15:(e(5,9),"END_RAW_BLOCK");case 5:return 15;case 6:return this.popState(),14;case 7:return 65;case 8:return 68;case 9:return 19;case 10:return this.popState(),this.begin("raw"),23;case 11:return 55;case 12:return 60;case 13:return 29;case 14:return 47;case 15:return this.popState(),44;case 16:return this.popState(),44;case 17:return 34;case 18:return 39;case 19:return 51;case 20:return 48;case 21:this.unput(b.yytext),this.popState(),this.begin("com");break;case 22:return this.popState(),14;case 23:return 48;case 24:return 73;case 25:return 72;case 26:return 72;case 27:return 87;case 28:break;case 29:return this.popState(),54;case 30:return this.popState(),33;case 31:return b.yytext=e(1,2).replace(/\\"/g,'"'),80;case 32:return b.yytext=e(1,2).replace(/\\'/g,"'"),80;case 33:return 85;case 34:return 82;case 35:return 82;case 36:return 83;case 37:return 84;case 38:return 81;case 39:return 75;case 40:return 77;case 41:return 72;case 42:return b.yytext=b.yytext.replace(/\\([\\\]])/g,"$1"),72;case 43:return"INVALID";case 44:return 5}},a.rules=[/^(?:[^\x00]*?(?=(\{\{)))/,/^(?:[^\x00]+)/,/^(?:[^\x00]{2,}?(?=(\{\{|\\\{\{|\\\\\{\{|$)))/,/^(?:\{\{\{\{(?=[^\/]))/,/^(?:\{\{\{\{\/[^\s!"#%-,\.\/;->@\[-\^`\{-~]+(?=[=}\s\/.])\}\}\}\})/,/^(?:[^\x00]+?(?=(\{\{\{\{)))/,/^(?:[\s\S]*?--(~)?\}\})/,/^(?:\()/,/^(?:\))/,/^(?:\{\{\{\{)/,/^(?:\}\}\}\})/,/^(?:\{\{(~)?>)/,/^(?:\{\{(~)?#>)/,/^(?:\{\{(~)?#\*?)/,/^(?:\{\{(~)?\/)/,/^(?:\{\{(~)?\^\s*(~)?\}\})/,/^(?:\{\{(~)?\s*else\s*(~)?\}\})/,/^(?:\{\{(~)?\^)/,/^(?:\{\{(~)?\s*else\b)/,/^(?:\{\{(~)?\{)/,/^(?:\{\{(~)?&)/,/^(?:\{\{(~)?!--)/,/^(?:\{\{(~)?![\s\S]*?\}\})/,/^(?:\{\{(~)?\*?)/,/^(?:=)/,/^(?:\.\.)/,/^(?:\.(?=([=~}\s\/.)|])))/,/^(?:[\/.])/,/^(?:\s+)/,/^(?:\}(~)?\}\})/,/^(?:(~)?\}\})/,/^(?:"(\\["]|[^"])*")/,/^(?:'(\\[']|[^'])*')/,/^(?:@)/,/^(?:true(?=([~}\s)])))/,/^(?:false(?=([~}\s)])))/,/^(?:undefined(?=([~}\s)])))/,/^(?:null(?=([~}\s)])))/,/^(?:-?[0-9]+(?:\.[0-9]+)?(?=([~}\s)])))/,/^(?:as\s+\|)/,/^(?:\|)/,/^(?:([^\s!"#%-,\.\/;->@\[-\^`\{-~]+(?=([=~}\s\/.)|]))))/,/^(?:\[(\\\]|[^\]])*\])/,/^(?:.)/,/^(?:$)/],a.conditions={mu:{rules:[7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44],inclusive:!1},emu:{rules:[2],inclusive:!1},com:{rules:[6],inclusive:!1},raw:{rules:[3,4,5],inclusive:!1},INITIAL:{rules:[0,1,44],inclusive:!0}},a}();return b.lexer=c,a.prototype=b,b.Parser=a,new a}();b["default"]=c,a.exports=b["default"]},function(a,b,c){"use strict";function d(){var a=arguments.length<=0||void 0===arguments[0]?{}:arguments[0];this.options=a}function e(a,b,c){void 0===b&&(b=a.length);var d=a[b-1],e=a[b-2];return d?"ContentStatement"===d.type?(e||!c?/\r?\n\s*?$/:/(^|\r?\n)\s*?$/).test(d.original):void 0:c}function f(a,b,c){void 0===b&&(b=-1);var d=a[b+1],e=a[b+2];return d?"ContentStatement"===d.type?(e||!c?/^\s*?\r?\n/:/^\s*?(\r?\n|$)/).test(d.original):void 0:c}function g(a,b,c){var d=a[null==b?0:b+1];if(d&&"ContentStatement"===d.type&&(c||!d.rightStripped)){var e=d.value;d.value=d.value.replace(c?/^\s+/:/^[ \t]*\r?\n?/,""),d.rightStripped=d.value!==e}}function h(a,b,c){var d=a[null==b?a.length-1:b-1];if(d&&"ContentStatement"===d.type&&(c||!d.leftStripped)){var e=d.value;return d.value=d.value.replace(c?/\s+$/:/[ \t]+$/,""),d.leftStripped=d.value!==e,d.leftStripped}}var i=c(1)["default"];b.__esModule=!0;var j=c(49),k=i(j);d.prototype=new k["default"],d.prototype.Program=function(a){var b=!this.options.ignoreStandalone,c=!this.isRootSeen;this.isRootSeen=!0;for(var d=a.body,i=0,j=d.length;i0)throw new q["default"]("Invalid path: "+d,{loc:c});".."===i&&f++}}return{type:"PathExpression",data:a,depth:f,parts:e,original:d,loc:c}}function j(a,b,c,d,e,f){var g=d.charAt(3)||d.charAt(2),h="{"!==g&&"&"!==g,i=/\*/.test(d);return{type:i?"Decorator":"MustacheStatement",path:a,params:b,hash:c,escaped:h,strip:e,loc:this.locInfo(f)}}function k(a,b,c,e){d(a,c),e=this.locInfo(e);var f={type:"Program",body:b,strip:{},loc:e};return{type:"BlockStatement",path:a.path,params:a.params,hash:a.hash,program:f,openStrip:{},inverseStrip:{},closeStrip:{},loc:e}}function l(a,b,c,e,f,g){e&&e.path&&d(a,e);var h=/\*/.test(a.open);b.blockParams=a.blockParams;var i=void 0,j=void 0;if(c){if(h)throw new q["default"]("Unexpected inverse block on decorator",c);c.chain&&(c.program.body[0].closeStrip=e.strip),j=c.strip,i=c.program}return f&&(f=i,i=b,b=f),{type:h?"DecoratorBlock":"BlockStatement",path:a.path,params:a.params,hash:a.hash,program:b,inverse:i,openStrip:a.strip,inverseStrip:j,closeStrip:e&&e.strip,loc:this.locInfo(g)}}function m(a,b){if(!b&&a.length){var c=a[0].loc,d=a[a.length-1].loc;c&&d&&(b={source:c.source,start:{line:c.start.line,column:c.start.column},end:{line:d.end.line,column:d.end.column}})}return{type:"Program",body:a,strip:{},loc:b}}function n(a,b,c,e){return d(a,c),{type:"PartialBlockStatement",name:a.path,params:a.params,hash:a.hash,program:b,openStrip:a.strip,closeStrip:c&&c.strip,loc:this.locInfo(e)}}var o=c(1)["default"];b.__esModule=!0,b.SourceLocation=e,b.id=f,b.stripFlags=g,b.stripComment=h,b.preparePath=i,b.prepareMustache=j,b.prepareRawBlock=k,b.prepareBlock=l,b.prepareProgram=m,b.preparePartialBlock=n;var p=c(6),q=o(p)},function(a,b,c){"use strict";function d(){}function e(a,b,c){if(null==a||"string"!=typeof a&&"Program"!==a.type)throw new l["default"]("You must pass a string or Handlebars AST to Handlebars.precompile. You passed "+a);b=b||{},"data"in b||(b.data=!0),b.compat&&(b.useDepths=!0);var d=c.parse(a,b),e=(new c.Compiler).compile(d,b);return(new c.JavaScriptCompiler).compile(e,b)}function f(a,b,c){function d(){var d=c.parse(a,b),e=(new c.Compiler).compile(d,b),f=(new c.JavaScriptCompiler).compile(e,b,void 0,!0);return c.template(f)}function e(a,b){return f||(f=d()),f.call(this,a,b)}if(void 0===b&&(b={}),null==a||"string"!=typeof a&&"Program"!==a.type)throw new l["default"]("You must pass a string or Handlebars AST to Handlebars.compile. You passed "+a);b=m.extend({},b),"data"in b||(b.data=!0),b.compat&&(b.useDepths=!0);var f=void 0;return e._setup=function(a){return f||(f=d()),f._setup(a)},e._child=function(a,b,c,e){return f||(f=d()),f._child(a,b,c,e)},e}function g(a,b){if(a===b)return!0;if(m.isArray(a)&&m.isArray(b)&&a.length===b.length){for(var c=0;c1)throw new l["default"]("Unsupported number of partial arguments: "+c.length,a);c.length||(this.options.explicitPartialContext?this.opcode("pushLiteral","undefined"):c.push({type:"PathExpression",parts:[],depth:0}));var d=a.name.original,e="SubExpression"===a.name.type;e&&this.accept(a.name),this.setupFullMustacheParams(a,b,void 0,!0);var f=a.indent||"";this.options.preventIndent&&f&&(this.opcode("appendContent",f),f=""),this.opcode("invokePartial",e,d,f),this.opcode("append")},PartialBlockStatement:function(a){this.PartialStatement(a)},MustacheStatement:function(a){this.SubExpression(a),a.escaped&&!this.options.noEscape?this.opcode("appendEscaped"):this.opcode("append")},Decorator:function(a){this.DecoratorBlock(a)},ContentStatement:function(a){a.value&&this.opcode("appendContent",a.value)},CommentStatement:function(){},SubExpression:function(a){h(a);var b=this.classifySexpr(a);"simple"===b?this.simpleSexpr(a):"helper"===b?this.helperSexpr(a):this.ambiguousSexpr(a)},ambiguousSexpr:function(a,b,c){var d=a.path,e=d.parts[0],f=null!=b||null!=c;this.opcode("getContext",d.depth),this.opcode("pushProgram",b),this.opcode("pushProgram",c),d.strict=!0,this.accept(d),this.opcode("invokeAmbiguous",e,f)},simpleSexpr:function(a){var b=a.path;b.strict=!0,this.accept(b),this.opcode("resolvePossibleLambda")},helperSexpr:function(a,b,c){var d=this.setupFullMustacheParams(a,b,c),e=a.path,f=e.parts[0];if(this.options.knownHelpers[f])this.opcode("invokeKnownHelper",d.length,f);else{if(this.options.knownHelpersOnly)throw new l["default"]("You specified knownHelpersOnly, but used the unknown helper "+f,a);e.strict=!0,e.falsy=!0,this.accept(e),this.opcode("invokeHelper",d.length,e.original,o["default"].helpers.simpleId(e))}},PathExpression:function(a){this.addDepth(a.depth),this.opcode("getContext",a.depth);var b=a.parts[0],c=o["default"].helpers.scopedId(a),d=!a.depth&&!c&&this.blockParamIndex(b);d?this.opcode("lookupBlockParam",d,a.parts):b?a.data?(this.options.data=!0,this.opcode("lookupData",a.depth,a.parts,a.strict)):this.opcode("lookupOnContext",a.parts,a.falsy,a.strict,c):this.opcode("pushContext")},StringLiteral:function(a){this.opcode("pushString",a.value)},NumberLiteral:function(a){this.opcode("pushLiteral",a.value)},BooleanLiteral:function(a){this.opcode("pushLiteral",a.value)},UndefinedLiteral:function(){this.opcode("pushLiteral","undefined")},NullLiteral:function(){this.opcode("pushLiteral","null")},Hash:function(a){var b=a.pairs,c=0,d=b.length;for(this.opcode("pushHash");c=0)return[b,e]}}}},function(a,b,c){"use strict";function d(a){this.value=a}function e(){}function f(a,b,c,d){var e=b.popStack(),f=0,g=c.length;for(a&&g--;f0&&(c+=", "+d.join(", "));var e=0;g(this.aliases).forEach(function(a){var d=b.aliases[a];d.children&&d.referenceCount>1&&(c+=", alias"+ ++e+"="+a,d.children[0]="alias"+e)}),this.lookupPropertyFunctionIsUsed&&(c+=", "+this.lookupPropertyFunctionVarDeclaration());var f=["container","depth0","helpers","partials","data"];(this.useBlockParams||this.useDepths)&&f.push("blockParams"),this.useDepths&&f.push("depths");var h=this.mergeSource(c);return a?(f.push(h),Function.apply(this,f)):this.source.wrap(["function(",f.join(","),") {\n ",h,"}"])},mergeSource:function(a){var b=this.environment.isSimple,c=!this.forceBuffer,d=void 0,e=void 0,f=void 0,g=void 0;return this.source.each(function(a){a.appendToBuffer?(f?a.prepend(" + "):f=a,g=a):(f&&(e?f.prepend("buffer += "):d=!0,g.add(";"),f=g=void 0),e=!0,b||(c=!1))}),c?f?(f.prepend("return "),g.add(";")):e||this.source.push('return "";'):(a+=", buffer = "+(d?"":this.initializeBuffer()),f?(f.prepend("return buffer + "),g.add(";")):this.source.push("return buffer;")),a&&this.source.prepend("var "+a.substring(2)+(d?"":";\n")),this.source.merge()},lookupPropertyFunctionVarDeclaration:function(){return"\n lookupProperty = container.lookupProperty || function(parent, propertyName) {\n if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {\n return parent[propertyName];\n }\n return undefined\n }\n ".trim()},blockValue:function(a){var b=this.aliasable("container.hooks.blockHelperMissing"),c=[this.contextName(0)];this.setupHelperArgs(a,0,c);var d=this.popStack();c.splice(1,0,d),this.push(this.source.functionCall(b,"call",c))},ambiguousBlockValue:function(){var a=this.aliasable("container.hooks.blockHelperMissing"),b=[this.contextName(0)];this.setupHelperArgs("",0,b,!0),this.flushInline();var c=this.topStack();b.splice(1,0,c),this.pushSource(["if (!",this.lastHelper,") { ",c," = ",this.source.functionCall(a,"call",b),"}"])},appendContent:function(a){this.pendingContent?a=this.pendingContent+a:this.pendingLocation=this.source.currentLocation,this.pendingContent=a},append:function(){if(this.isInline())this.replaceStack(function(a){return[" != null ? ",a,' : ""']}),this.pushSource(this.appendToBuffer(this.popStack()));else{var a=this.popStack();this.pushSource(["if (",a," != null) { ",this.appendToBuffer(a,void 0,!0)," }"]),this.environment.isSimple&&this.pushSource(["else { ",this.appendToBuffer("''",void 0,!0)," }"])}},appendEscaped:function(){this.pushSource(this.appendToBuffer([this.aliasable("container.escapeExpression"),"(",this.popStack(),")"]))},getContext:function(a){this.lastContext=a},pushContext:function(){this.pushStackLiteral(this.contextName(this.lastContext))},lookupOnContext:function(a,b,c,d){var e=0;d||!this.options.compat||this.lastContext?this.pushContext():this.push(this.depthedLookup(a[e++])),this.resolvePath("context",a,e,b,c)},lookupBlockParam:function(a,b){this.useBlockParams=!0,this.push(["blockParams[",a[0],"][",a[1],"]"]),this.resolvePath("context",b,1)},lookupData:function(a,b,c){a?this.pushStackLiteral("container.data(data, "+a+")"):this.pushStackLiteral("data"),this.resolvePath("data",b,0,!0,c)},resolvePath:function(a,b,c,d,e){var g=this;if(this.options.strict||this.options.assumeObjects)return void this.push(f(this.options.strict&&e,this,b,a));for(var h=b.length;cthis.stackVars.length&&this.stackVars.push("stack"+this.stackSlot),this.topStackName()},topStackName:function(){return"stack"+this.stackSlot},flushInline:function(){var a=this.inlineStack;this.inlineStack=[];for(var b=0,c=a.length;b= 2.0.0-beta.1', 7: '>= 4.0.0 <4.3.0', 8: '>= 4.3.0' }; exports.REVISION_CHANGES = REVISION_CHANGES; var objectType = '[object Object]'; function HandlebarsEnvironment(helpers, partials, decorators) { this.helpers = helpers || {}; this.partials = partials || {}; this.decorators = decorators || {}; _helpers.registerDefaultHelpers(this); _decorators.registerDefaultDecorators(this); } HandlebarsEnvironment.prototype = { constructor: HandlebarsEnvironment, logger: _logger2['default'], log: _logger2['default'].log, registerHelper: function registerHelper(name, fn) { if (_utils.toString.call(name) === objectType) { if (fn) { throw new _exception2['default']('Arg not supported with multiple helpers'); } _utils.extend(this.helpers, name); } else { this.helpers[name] = fn; } }, unregisterHelper: function unregisterHelper(name) { delete this.helpers[name]; }, registerPartial: function registerPartial(name, partial) { if (_utils.toString.call(name) === objectType) { _utils.extend(this.partials, name); } else { if (typeof partial === 'undefined') { throw new _exception2['default']('Attempting to register a partial called "' + name + '" as undefined'); } this.partials[name] = partial; } }, unregisterPartial: function unregisterPartial(name) { delete this.partials[name]; }, registerDecorator: function registerDecorator(name, fn) { if (_utils.toString.call(name) === objectType) { if (fn) { throw new _exception2['default']('Arg not supported with multiple decorators'); } _utils.extend(this.decorators, name); } else { this.decorators[name] = fn; } }, unregisterDecorator: function unregisterDecorator(name) { delete this.decorators[name]; }, /** * Reset the memory of illegal property accesses that have already been logged. * @deprecated should only be used in handlebars test-cases */ resetLoggedPropertyAccesses: function resetLoggedPropertyAccesses() { _internalProtoAccess.resetLoggedProperties(); } }; var log = _logger2['default'].log; exports.log = log; exports.createFrame = _utils.createFrame; exports.logger = _logger2['default']; /***/ }), /* 4 */ /***/ (function(module, exports) { 'use strict'; exports.__esModule = true; exports.extend = extend; exports.indexOf = indexOf; exports.escapeExpression = escapeExpression; exports.isEmpty = isEmpty; exports.createFrame = createFrame; exports.blockParams = blockParams; exports.appendContextPath = appendContextPath; var escape = { '&': '&', '<': '<', '>': '>', '"': '"', "'": ''', '`': '`', '=': '=' }; var badChars = /[&<>"'`=]/g, possible = /[&<>"'`=]/; function escapeChar(chr) { return escape[chr]; } function extend(obj /* , ...source */) { for (var i = 1; i < arguments.length; i++) { for (var key in arguments[i]) { if (Object.prototype.hasOwnProperty.call(arguments[i], key)) { obj[key] = arguments[i][key]; } } } return obj; } var toString = Object.prototype.toString; exports.toString = toString; // Sourced from lodash // https://github.com/bestiejs/lodash/blob/master/LICENSE.txt /* eslint-disable func-style */ var isFunction = function isFunction(value) { return typeof value === 'function'; }; // fallback for older versions of Chrome and Safari /* istanbul ignore next */ if (isFunction(/x/)) { exports.isFunction = isFunction = function (value) { return typeof value === 'function' && toString.call(value) === '[object Function]'; }; } exports.isFunction = isFunction; /* eslint-enable func-style */ /* istanbul ignore next */ var isArray = Array.isArray || function (value) { return value && typeof value === 'object' ? toString.call(value) === '[object Array]' : false; }; exports.isArray = isArray; // Older IE versions do not directly support indexOf so we must implement our own, sadly. function indexOf(array, value) { for (var i = 0, len = array.length; i < len; i++) { if (array[i] === value) { return i; } } return -1; } function escapeExpression(string) { if (typeof string !== 'string') { // don't escape SafeStrings, since they're already safe if (string && string.toHTML) { return string.toHTML(); } else if (string == null) { return ''; } else if (!string) { return string + ''; } // Force a string conversion as this will be done by the append regardless and // the regex test will do this transparently behind the scenes, causing issues if // an object's to string has escaped characters in it. string = '' + string; } if (!possible.test(string)) { return string; } return string.replace(badChars, escapeChar); } function isEmpty(value) { if (!value && value !== 0) { return true; } else if (isArray(value) && value.length === 0) { return true; } else { return false; } } function createFrame(object) { var frame = extend({}, object); frame._parent = object; return frame; } function blockParams(params, ids) { params.path = ids; return params; } function appendContextPath(contextPath, id) { return (contextPath ? contextPath + '.' : '') + id; } /***/ }), /* 5 */ /***/ (function(module, exports, __webpack_require__) { 'use strict'; var _Object$defineProperty = __webpack_require__(6)['default']; exports.__esModule = true; var errorProps = ['description', 'fileName', 'lineNumber', 'endLineNumber', 'message', 'name', 'number', 'stack']; function Exception(message, node) { var loc = node && node.loc, line = undefined, endLineNumber = undefined, column = undefined, endColumn = undefined; if (loc) { line = loc.start.line; endLineNumber = loc.end.line; column = loc.start.column; endColumn = loc.end.column; message += ' - ' + line + ':' + column; } var tmp = Error.prototype.constructor.call(this, message); // Unfortunately errors are not enumerable in Chrome (at least), so `for prop in tmp` doesn't work. for (var idx = 0; idx < errorProps.length; idx++) { this[errorProps[idx]] = tmp[errorProps[idx]]; } /* istanbul ignore else */ if (Error.captureStackTrace) { Error.captureStackTrace(this, Exception); } try { if (loc) { this.lineNumber = line; this.endLineNumber = endLineNumber; // Work around issue under safari where we can't directly set the column value /* istanbul ignore next */ if (_Object$defineProperty) { Object.defineProperty(this, 'column', { value: column, enumerable: true }); Object.defineProperty(this, 'endColumn', { value: endColumn, enumerable: true }); } else { this.column = column; this.endColumn = endColumn; } } } catch (nop) { /* Ignore if the browser is very particular */ } } Exception.prototype = new Error(); exports['default'] = Exception; module.exports = exports['default']; /***/ }), /* 6 */ /***/ (function(module, exports, __webpack_require__) { module.exports = { "default": __webpack_require__(7), __esModule: true }; /***/ }), /* 7 */ /***/ (function(module, exports, __webpack_require__) { var $ = __webpack_require__(8); module.exports = function defineProperty(it, key, desc){ return $.setDesc(it, key, desc); }; /***/ }), /* 8 */ /***/ (function(module, exports) { var $Object = Object; module.exports = { create: $Object.create, getProto: $Object.getPrototypeOf, isEnum: {}.propertyIsEnumerable, getDesc: $Object.getOwnPropertyDescriptor, setDesc: $Object.defineProperty, setDescs: $Object.defineProperties, getKeys: $Object.keys, getNames: $Object.getOwnPropertyNames, getSymbols: $Object.getOwnPropertySymbols, each: [].forEach }; /***/ }), /* 9 */ /***/ (function(module, exports, __webpack_require__) { 'use strict'; var _interopRequireDefault = __webpack_require__(2)['default']; exports.__esModule = true; exports.registerDefaultHelpers = registerDefaultHelpers; exports.moveHelperToHooks = moveHelperToHooks; var _helpersBlockHelperMissing = __webpack_require__(10); var _helpersBlockHelperMissing2 = _interopRequireDefault(_helpersBlockHelperMissing); var _helpersEach = __webpack_require__(11); var _helpersEach2 = _interopRequireDefault(_helpersEach); var _helpersHelperMissing = __webpack_require__(24); var _helpersHelperMissing2 = _interopRequireDefault(_helpersHelperMissing); var _helpersIf = __webpack_require__(25); var _helpersIf2 = _interopRequireDefault(_helpersIf); var _helpersLog = __webpack_require__(26); var _helpersLog2 = _interopRequireDefault(_helpersLog); var _helpersLookup = __webpack_require__(27); var _helpersLookup2 = _interopRequireDefault(_helpersLookup); var _helpersWith = __webpack_require__(28); var _helpersWith2 = _interopRequireDefault(_helpersWith); function registerDefaultHelpers(instance) { _helpersBlockHelperMissing2['default'](instance); _helpersEach2['default'](instance); _helpersHelperMissing2['default'](instance); _helpersIf2['default'](instance); _helpersLog2['default'](instance); _helpersLookup2['default'](instance); _helpersWith2['default'](instance); } function moveHelperToHooks(instance, helperName, keepHelper) { if (instance.helpers[helperName]) { instance.hooks[helperName] = instance.helpers[helperName]; if (!keepHelper) { delete instance.helpers[helperName]; } } } /***/ }), /* 10 */ /***/ (function(module, exports, __webpack_require__) { 'use strict'; exports.__esModule = true; var _utils = __webpack_require__(4); exports['default'] = function (instance) { instance.registerHelper('blockHelperMissing', function (context, options) { var inverse = options.inverse, fn = options.fn; if (context === true) { return fn(this); } else if (context === false || context == null) { return inverse(this); } else if (_utils.isArray(context)) { if (context.length > 0) { if (options.ids) { options.ids = [options.name]; } return instance.helpers.each(context, options); } else { return inverse(this); } } else { if (options.data && options.ids) { var data = _utils.createFrame(options.data); data.contextPath = _utils.appendContextPath(options.data.contextPath, options.name); options = { data: data }; } return fn(context, options); } }); }; module.exports = exports['default']; /***/ }), /* 11 */ /***/ (function(module, exports, __webpack_require__) { /* WEBPACK VAR INJECTION */(function(global) {'use strict'; var _Object$keys = __webpack_require__(12)['default']; var _interopRequireDefault = __webpack_require__(2)['default']; exports.__esModule = true; var _utils = __webpack_require__(4); var _exception = __webpack_require__(5); var _exception2 = _interopRequireDefault(_exception); exports['default'] = function (instance) { instance.registerHelper('each', function (context, options) { if (!options) { throw new _exception2['default']('Must pass iterator to #each'); } var fn = options.fn, inverse = options.inverse, i = 0, ret = '', data = undefined, contextPath = undefined; if (options.data && options.ids) { contextPath = _utils.appendContextPath(options.data.contextPath, options.ids[0]) + '.'; } if (_utils.isFunction(context)) { context = context.call(this); } if (options.data) { data = _utils.createFrame(options.data); } function execIteration(field, index, last) { if (data) { data.key = field; data.index = index; data.first = index === 0; data.last = !!last; if (contextPath) { data.contextPath = contextPath + field; } } ret = ret + fn(context[field], { data: data, blockParams: _utils.blockParams([context[field], field], [contextPath + field, null]) }); } if (context && typeof context === 'object') { if (_utils.isArray(context)) { for (var j = context.length; i < j; i++) { if (i in context) { execIteration(i, i, i === context.length - 1); } } } else if (global.Symbol && context[global.Symbol.iterator]) { var newContext = []; var iterator = context[global.Symbol.iterator](); for (var it = iterator.next(); !it.done; it = iterator.next()) { newContext.push(it.value); } context = newContext; for (var j = context.length; i < j; i++) { execIteration(i, i, i === context.length - 1); } } else { (function () { var priorKey = undefined; _Object$keys(context).forEach(function (key) { // We're running the iterations one step out of sync so we can detect // the last iteration without have to scan the object twice and create // an itermediate keys array. if (priorKey !== undefined) { execIteration(priorKey, i - 1); } priorKey = key; i++; }); if (priorKey !== undefined) { execIteration(priorKey, i - 1, true); } })(); } } if (i === 0) { ret = inverse(this); } return ret; }); }; module.exports = exports['default']; /* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }()))) /***/ }), /* 12 */ /***/ (function(module, exports, __webpack_require__) { module.exports = { "default": __webpack_require__(13), __esModule: true }; /***/ }), /* 13 */ /***/ (function(module, exports, __webpack_require__) { __webpack_require__(14); module.exports = __webpack_require__(20).Object.keys; /***/ }), /* 14 */ /***/ (function(module, exports, __webpack_require__) { // 19.1.2.14 Object.keys(O) var toObject = __webpack_require__(15); __webpack_require__(17)('keys', function($keys){ return function keys(it){ return $keys(toObject(it)); }; }); /***/ }), /* 15 */ /***/ (function(module, exports, __webpack_require__) { // 7.1.13 ToObject(argument) var defined = __webpack_require__(16); module.exports = function(it){ return Object(defined(it)); }; /***/ }), /* 16 */ /***/ (function(module, exports) { // 7.2.1 RequireObjectCoercible(argument) module.exports = function(it){ if(it == undefined)throw TypeError("Can't call method on " + it); return it; }; /***/ }), /* 17 */ /***/ (function(module, exports, __webpack_require__) { // most Object methods by ES6 should accept primitives var $export = __webpack_require__(18) , core = __webpack_require__(20) , fails = __webpack_require__(23); module.exports = function(KEY, exec){ var fn = (core.Object || {})[KEY] || Object[KEY] , exp = {}; exp[KEY] = exec(fn); $export($export.S + $export.F * fails(function(){ fn(1); }), 'Object', exp); }; /***/ }), /* 18 */ /***/ (function(module, exports, __webpack_require__) { var global = __webpack_require__(19) , core = __webpack_require__(20) , ctx = __webpack_require__(21) , PROTOTYPE = 'prototype'; var $export = function(type, name, source){ var IS_FORCED = type & $export.F , IS_GLOBAL = type & $export.G , IS_STATIC = type & $export.S , IS_PROTO = type & $export.P , IS_BIND = type & $export.B , IS_WRAP = type & $export.W , exports = IS_GLOBAL ? core : core[name] || (core[name] = {}) , target = IS_GLOBAL ? global : IS_STATIC ? global[name] : (global[name] || {})[PROTOTYPE] , key, own, out; if(IS_GLOBAL)source = name; for(key in source){ // contains in native own = !IS_FORCED && target && key in target; if(own && key in exports)continue; // export native or passed out = own ? target[key] : source[key]; // prevent global pollution for namespaces exports[key] = IS_GLOBAL && typeof target[key] != 'function' ? source[key] // bind timers to global for call from export context : IS_BIND && own ? ctx(out, global) // wrap global constructors for prevent change them in library : IS_WRAP && target[key] == out ? (function(C){ var F = function(param){ return this instanceof C ? new C(param) : C(param); }; F[PROTOTYPE] = C[PROTOTYPE]; return F; // make static versions for prototype methods })(out) : IS_PROTO && typeof out == 'function' ? ctx(Function.call, out) : out; if(IS_PROTO)(exports[PROTOTYPE] || (exports[PROTOTYPE] = {}))[key] = out; } }; // type bitmap $export.F = 1; // forced $export.G = 2; // global $export.S = 4; // static $export.P = 8; // proto $export.B = 16; // bind $export.W = 32; // wrap module.exports = $export; /***/ }), /* 19 */ /***/ (function(module, exports) { // https://github.com/zloirock/core-js/issues/86#issuecomment-115759028 var global = module.exports = typeof window != 'undefined' && window.Math == Math ? window : typeof self != 'undefined' && self.Math == Math ? self : Function('return this')(); if(typeof __g == 'number')__g = global; // eslint-disable-line no-undef /***/ }), /* 20 */ /***/ (function(module, exports) { var core = module.exports = {version: '1.2.6'}; if(typeof __e == 'number')__e = core; // eslint-disable-line no-undef /***/ }), /* 21 */ /***/ (function(module, exports, __webpack_require__) { // optional / simple context binding var aFunction = __webpack_require__(22); module.exports = function(fn, that, length){ aFunction(fn); if(that === undefined)return fn; switch(length){ case 1: return function(a){ return fn.call(that, a); }; case 2: return function(a, b){ return fn.call(that, a, b); }; case 3: return function(a, b, c){ return fn.call(that, a, b, c); }; } return function(/* ...args */){ return fn.apply(that, arguments); }; }; /***/ }), /* 22 */ /***/ (function(module, exports) { module.exports = function(it){ if(typeof it != 'function')throw TypeError(it + ' is not a function!'); return it; }; /***/ }), /* 23 */ /***/ (function(module, exports) { module.exports = function(exec){ try { return !!exec(); } catch(e){ return true; } }; /***/ }), /* 24 */ /***/ (function(module, exports, __webpack_require__) { 'use strict'; var _interopRequireDefault = __webpack_require__(2)['default']; exports.__esModule = true; var _exception = __webpack_require__(5); var _exception2 = _interopRequireDefault(_exception); exports['default'] = function (instance) { instance.registerHelper('helperMissing', function () /* [args, ]options */{ if (arguments.length === 1) { // A missing field in a {{foo}} construct. return undefined; } else { // Someone is actually trying to call something, blow up. throw new _exception2['default']('Missing helper: "' + arguments[arguments.length - 1].name + '"'); } }); }; module.exports = exports['default']; /***/ }), /* 25 */ /***/ (function(module, exports, __webpack_require__) { 'use strict'; var _interopRequireDefault = __webpack_require__(2)['default']; exports.__esModule = true; var _utils = __webpack_require__(4); var _exception = __webpack_require__(5); var _exception2 = _interopRequireDefault(_exception); exports['default'] = function (instance) { instance.registerHelper('if', function (conditional, options) { if (arguments.length != 2) { throw new _exception2['default']('#if requires exactly one argument'); } if (_utils.isFunction(conditional)) { conditional = conditional.call(this); } // Default behavior is to render the positive path if the value is truthy and not empty. // The `includeZero` option may be set to treat the condtional as purely not empty based on the // behavior of isEmpty. Effectively this determines if 0 is handled by the positive path or negative. if (!options.hash.includeZero && !conditional || _utils.isEmpty(conditional)) { return options.inverse(this); } else { return options.fn(this); } }); instance.registerHelper('unless', function (conditional, options) { if (arguments.length != 2) { throw new _exception2['default']('#unless requires exactly one argument'); } return instance.helpers['if'].call(this, conditional, { fn: options.inverse, inverse: options.fn, hash: options.hash }); }); }; module.exports = exports['default']; /***/ }), /* 26 */ /***/ (function(module, exports) { 'use strict'; exports.__esModule = true; exports['default'] = function (instance) { instance.registerHelper('log', function () /* message, options */{ var args = [undefined], options = arguments[arguments.length - 1]; for (var i = 0; i < arguments.length - 1; i++) { args.push(arguments[i]); } var level = 1; if (options.hash.level != null) { level = options.hash.level; } else if (options.data && options.data.level != null) { level = options.data.level; } args[0] = level; instance.log.apply(instance, args); }); }; module.exports = exports['default']; /***/ }), /* 27 */ /***/ (function(module, exports) { 'use strict'; exports.__esModule = true; exports['default'] = function (instance) { instance.registerHelper('lookup', function (obj, field, options) { if (!obj) { // Note for 5.0: Change to "obj == null" in 5.0 return obj; } return options.lookupProperty(obj, field); }); }; module.exports = exports['default']; /***/ }), /* 28 */ /***/ (function(module, exports, __webpack_require__) { 'use strict'; var _interopRequireDefault = __webpack_require__(2)['default']; exports.__esModule = true; var _utils = __webpack_require__(4); var _exception = __webpack_require__(5); var _exception2 = _interopRequireDefault(_exception); exports['default'] = function (instance) { instance.registerHelper('with', function (context, options) { if (arguments.length != 2) { throw new _exception2['default']('#with requires exactly one argument'); } if (_utils.isFunction(context)) { context = context.call(this); } var fn = options.fn; if (!_utils.isEmpty(context)) { var data = options.data; if (options.data && options.ids) { data = _utils.createFrame(options.data); data.contextPath = _utils.appendContextPath(options.data.contextPath, options.ids[0]); } return fn(context, { data: data, blockParams: _utils.blockParams([context], [data && data.contextPath]) }); } else { return options.inverse(this); } }); }; module.exports = exports['default']; /***/ }), /* 29 */ /***/ (function(module, exports, __webpack_require__) { 'use strict'; var _interopRequireDefault = __webpack_require__(2)['default']; exports.__esModule = true; exports.registerDefaultDecorators = registerDefaultDecorators; var _decoratorsInline = __webpack_require__(30); var _decoratorsInline2 = _interopRequireDefault(_decoratorsInline); function registerDefaultDecorators(instance) { _decoratorsInline2['default'](instance); } /***/ }), /* 30 */ /***/ (function(module, exports, __webpack_require__) { 'use strict'; exports.__esModule = true; var _utils = __webpack_require__(4); exports['default'] = function (instance) { instance.registerDecorator('inline', function (fn, props, container, options) { var ret = fn; if (!props.partials) { props.partials = {}; ret = function (context, options) { // Create a new partials stack frame prior to exec. var original = container.partials; container.partials = _utils.extend({}, original, props.partials); var ret = fn(context, options); container.partials = original; return ret; }; } props.partials[options.args[0]] = options.fn; return ret; }); }; module.exports = exports['default']; /***/ }), /* 31 */ /***/ (function(module, exports, __webpack_require__) { 'use strict'; exports.__esModule = true; var _utils = __webpack_require__(4); var logger = { methodMap: ['debug', 'info', 'warn', 'error'], level: 'info', // Maps a given level value to the `methodMap` indexes above. lookupLevel: function lookupLevel(level) { if (typeof level === 'string') { var levelMap = _utils.indexOf(logger.methodMap, level.toLowerCase()); if (levelMap >= 0) { level = levelMap; } else { level = parseInt(level, 10); } } return level; }, // Can be overridden in the host environment log: function log(level) { level = logger.lookupLevel(level); if (typeof console !== 'undefined' && logger.lookupLevel(logger.level) <= level) { var method = logger.methodMap[level]; // eslint-disable-next-line no-console if (!console[method]) { method = 'log'; } for (var _len = arguments.length, message = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { message[_key - 1] = arguments[_key]; } console[method].apply(console, message); // eslint-disable-line no-console } } }; exports['default'] = logger; module.exports = exports['default']; /***/ }), /* 32 */ /***/ (function(module, exports, __webpack_require__) { 'use strict'; var _Object$create = __webpack_require__(33)['default']; var _Object$keys = __webpack_require__(12)['default']; var _interopRequireWildcard = __webpack_require__(1)['default']; exports.__esModule = true; exports.createProtoAccessControl = createProtoAccessControl; exports.resultIsAllowed = resultIsAllowed; exports.resetLoggedProperties = resetLoggedProperties; var _createNewLookupObject = __webpack_require__(35); var _logger = __webpack_require__(31); var logger = _interopRequireWildcard(_logger); var loggedProperties = _Object$create(null); function createProtoAccessControl(runtimeOptions) { var defaultMethodWhiteList = _Object$create(null); defaultMethodWhiteList['constructor'] = false; defaultMethodWhiteList['__defineGetter__'] = false; defaultMethodWhiteList['__defineSetter__'] = false; defaultMethodWhiteList['__lookupGetter__'] = false; var defaultPropertyWhiteList = _Object$create(null); // eslint-disable-next-line no-proto defaultPropertyWhiteList['__proto__'] = false; return { properties: { whitelist: _createNewLookupObject.createNewLookupObject(defaultPropertyWhiteList, runtimeOptions.allowedProtoProperties), defaultValue: runtimeOptions.allowProtoPropertiesByDefault }, methods: { whitelist: _createNewLookupObject.createNewLookupObject(defaultMethodWhiteList, runtimeOptions.allowedProtoMethods), defaultValue: runtimeOptions.allowProtoMethodsByDefault } }; } function resultIsAllowed(result, protoAccessControl, propertyName) { if (typeof result === 'function') { return checkWhiteList(protoAccessControl.methods, propertyName); } else { return checkWhiteList(protoAccessControl.properties, propertyName); } } function checkWhiteList(protoAccessControlForType, propertyName) { if (protoAccessControlForType.whitelist[propertyName] !== undefined) { return protoAccessControlForType.whitelist[propertyName] === true; } if (protoAccessControlForType.defaultValue !== undefined) { return protoAccessControlForType.defaultValue; } logUnexpecedPropertyAccessOnce(propertyName); return false; } function logUnexpecedPropertyAccessOnce(propertyName) { if (loggedProperties[propertyName] !== true) { loggedProperties[propertyName] = true; logger.log('error', 'Handlebars: Access has been denied to resolve the property "' + propertyName + '" because it is not an "own property" of its parent.\n' + 'You can add a runtime option to disable the check or this warning:\n' + 'See https://handlebarsjs.com/api-reference/runtime-options.html#options-to-control-prototype-access for details'); } } function resetLoggedProperties() { _Object$keys(loggedProperties).forEach(function (propertyName) { delete loggedProperties[propertyName]; }); } /***/ }), /* 33 */ /***/ (function(module, exports, __webpack_require__) { module.exports = { "default": __webpack_require__(34), __esModule: true }; /***/ }), /* 34 */ /***/ (function(module, exports, __webpack_require__) { var $ = __webpack_require__(8); module.exports = function create(P, D){ return $.create(P, D); }; /***/ }), /* 35 */ /***/ (function(module, exports, __webpack_require__) { 'use strict'; var _Object$create = __webpack_require__(33)['default']; exports.__esModule = true; exports.createNewLookupObject = createNewLookupObject; var _utils = __webpack_require__(4); /** * Create a new object with "null"-prototype to avoid truthy results on prototype properties. * The resulting object can be used with "object[property]" to check if a property exists * @param {...object} sources a varargs parameter of source objects that will be merged * @returns {object} */ function createNewLookupObject() { for (var _len = arguments.length, sources = Array(_len), _key = 0; _key < _len; _key++) { sources[_key] = arguments[_key]; } return _utils.extend.apply(undefined, [_Object$create(null)].concat(sources)); } /***/ }), /* 36 */ /***/ (function(module, exports) { // Build out our basic SafeString type 'use strict'; exports.__esModule = true; function SafeString(string) { this.string = string; } SafeString.prototype.toString = SafeString.prototype.toHTML = function () { return '' + this.string; }; exports['default'] = SafeString; module.exports = exports['default']; /***/ }), /* 37 */ /***/ (function(module, exports, __webpack_require__) { 'use strict'; var _Object$seal = __webpack_require__(38)['default']; var _Object$keys = __webpack_require__(12)['default']; var _interopRequireWildcard = __webpack_require__(1)['default']; var _interopRequireDefault = __webpack_require__(2)['default']; exports.__esModule = true; exports.checkRevision = checkRevision; exports.template = template; exports.wrapProgram = wrapProgram; exports.resolvePartial = resolvePartial; exports.invokePartial = invokePartial; exports.noop = noop; var _utils = __webpack_require__(4); var Utils = _interopRequireWildcard(_utils); var _exception = __webpack_require__(5); var _exception2 = _interopRequireDefault(_exception); var _base = __webpack_require__(3); var _helpers = __webpack_require__(9); var _internalWrapHelper = __webpack_require__(42); var _internalProtoAccess = __webpack_require__(32); function checkRevision(compilerInfo) { var compilerRevision = compilerInfo && compilerInfo[0] || 1, currentRevision = _base.COMPILER_REVISION; if (compilerRevision >= _base.LAST_COMPATIBLE_COMPILER_REVISION && compilerRevision <= _base.COMPILER_REVISION) { return; } if (compilerRevision < _base.LAST_COMPATIBLE_COMPILER_REVISION) { var runtimeVersions = _base.REVISION_CHANGES[currentRevision], compilerVersions = _base.REVISION_CHANGES[compilerRevision]; throw new _exception2['default']('Template was precompiled with an older version of Handlebars than the current runtime. ' + 'Please update your precompiler to a newer version (' + runtimeVersions + ') or downgrade your runtime to an older version (' + compilerVersions + ').'); } else { // Use the embedded version info since the runtime doesn't know about this revision yet throw new _exception2['default']('Template was precompiled with a newer version of Handlebars than the current runtime. ' + 'Please update your runtime to a newer version (' + compilerInfo[1] + ').'); } } function template(templateSpec, env) { /* istanbul ignore next */ if (!env) { throw new _exception2['default']('No environment passed to template'); } if (!templateSpec || !templateSpec.main) { throw new _exception2['default']('Unknown template object: ' + typeof templateSpec); } templateSpec.main.decorator = templateSpec.main_d; // Note: Using env.VM references rather than local var references throughout this section to allow // for external users to override these as pseudo-supported APIs. env.VM.checkRevision(templateSpec.compiler); // backwards compatibility for precompiled templates with compiler-version 7 (<4.3.0) var templateWasPrecompiledWithCompilerV7 = templateSpec.compiler && templateSpec.compiler[0] === 7; function invokePartialWrapper(partial, context, options) { if (options.hash) { context = Utils.extend({}, context, options.hash); if (options.ids) { options.ids[0] = true; } } partial = env.VM.resolvePartial.call(this, partial, context, options); var extendedOptions = Utils.extend({}, options, { hooks: this.hooks, protoAccessControl: this.protoAccessControl }); var result = env.VM.invokePartial.call(this, partial, context, extendedOptions); if (result == null && env.compile) { options.partials[options.name] = env.compile(partial, templateSpec.compilerOptions, env); result = options.partials[options.name](context, extendedOptions); } if (result != null) { if (options.indent) { var lines = result.split('\n'); for (var i = 0, l = lines.length; i < l; i++) { if (!lines[i] && i + 1 === l) { break; } lines[i] = options.indent + lines[i]; } result = lines.join('\n'); } return result; } else { throw new _exception2['default']('The partial ' + options.name + ' could not be compiled when running in runtime-only mode'); } } // Just add water var container = { strict: function strict(obj, name, loc) { if (!obj || !(name in obj)) { throw new _exception2['default']('"' + name + '" not defined in ' + obj, { loc: loc }); } return container.lookupProperty(obj, name); }, lookupProperty: function lookupProperty(parent, propertyName) { var result = parent[propertyName]; if (result == null) { return result; } if (Object.prototype.hasOwnProperty.call(parent, propertyName)) { return result; } if (_internalProtoAccess.resultIsAllowed(result, container.protoAccessControl, propertyName)) { return result; } return undefined; }, lookup: function lookup(depths, name) { var len = depths.length; for (var i = 0; i < len; i++) { var result = depths[i] && container.lookupProperty(depths[i], name); if (result != null) { return depths[i][name]; } } }, lambda: function lambda(current, context) { return typeof current === 'function' ? current.call(context) : current; }, escapeExpression: Utils.escapeExpression, invokePartial: invokePartialWrapper, fn: function fn(i) { var ret = templateSpec[i]; ret.decorator = templateSpec[i + '_d']; return ret; }, programs: [], program: function program(i, data, declaredBlockParams, blockParams, depths) { var programWrapper = this.programs[i], fn = this.fn(i); if (data || depths || blockParams || declaredBlockParams) { programWrapper = wrapProgram(this, i, fn, data, declaredBlockParams, blockParams, depths); } else if (!programWrapper) { programWrapper = this.programs[i] = wrapProgram(this, i, fn); } return programWrapper; }, data: function data(value, depth) { while (value && depth--) { value = value._parent; } return value; }, mergeIfNeeded: function mergeIfNeeded(param, common) { var obj = param || common; if (param && common && param !== common) { obj = Utils.extend({}, common, param); } return obj; }, // An empty object to use as replacement for null-contexts nullContext: _Object$seal({}), noop: env.VM.noop, compilerInfo: templateSpec.compiler }; function ret(context) { var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1]; var data = options.data; ret._setup(options); if (!options.partial && templateSpec.useData) { data = initData(context, data); } var depths = undefined, blockParams = templateSpec.useBlockParams ? [] : undefined; if (templateSpec.useDepths) { if (options.depths) { depths = context != options.depths[0] ? [context].concat(options.depths) : options.depths; } else { depths = [context]; } } function main(context /*, options*/) { return '' + templateSpec.main(container, context, container.helpers, container.partials, data, blockParams, depths); } main = executeDecorators(templateSpec.main, main, container, options.depths || [], data, blockParams); return main(context, options); } ret.isTop = true; ret._setup = function (options) { if (!options.partial) { var mergedHelpers = Utils.extend({}, env.helpers, options.helpers); wrapHelpersToPassLookupProperty(mergedHelpers, container); container.helpers = mergedHelpers; if (templateSpec.usePartial) { // Use mergeIfNeeded here to prevent compiling global partials multiple times container.partials = container.mergeIfNeeded(options.partials, env.partials); } if (templateSpec.usePartial || templateSpec.useDecorators) { container.decorators = Utils.extend({}, env.decorators, options.decorators); } container.hooks = {}; container.protoAccessControl = _internalProtoAccess.createProtoAccessControl(options); var keepHelperInHelpers = options.allowCallsToHelperMissing || templateWasPrecompiledWithCompilerV7; _helpers.moveHelperToHooks(container, 'helperMissing', keepHelperInHelpers); _helpers.moveHelperToHooks(container, 'blockHelperMissing', keepHelperInHelpers); } else { container.protoAccessControl = options.protoAccessControl; // internal option container.helpers = options.helpers; container.partials = options.partials; container.decorators = options.decorators; container.hooks = options.hooks; } }; ret._child = function (i, data, blockParams, depths) { if (templateSpec.useBlockParams && !blockParams) { throw new _exception2['default']('must pass block params'); } if (templateSpec.useDepths && !depths) { throw new _exception2['default']('must pass parent depths'); } return wrapProgram(container, i, templateSpec[i], data, 0, blockParams, depths); }; return ret; } function wrapProgram(container, i, fn, data, declaredBlockParams, blockParams, depths) { function prog(context) { var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1]; var currentDepths = depths; if (depths && context != depths[0] && !(context === container.nullContext && depths[0] === null)) { currentDepths = [context].concat(depths); } return fn(container, context, container.helpers, container.partials, options.data || data, blockParams && [options.blockParams].concat(blockParams), currentDepths); } prog = executeDecorators(fn, prog, container, depths, data, blockParams); prog.program = i; prog.depth = depths ? depths.length : 0; prog.blockParams = declaredBlockParams || 0; return prog; } /** * This is currently part of the official API, therefore implementation details should not be changed. */ function resolvePartial(partial, context, options) { if (!partial) { if (options.name === '@partial-block') { partial = options.data['partial-block']; } else { partial = options.partials[options.name]; } } else if (!partial.call && !options.name) { // This is a dynamic partial that returned a string options.name = partial; partial = options.partials[partial]; } return partial; } function invokePartial(partial, context, options) { // Use the current closure context to save the partial-block if this partial var currentPartialBlock = options.data && options.data['partial-block']; options.partial = true; if (options.ids) { options.data.contextPath = options.ids[0] || options.data.contextPath; } var partialBlock = undefined; if (options.fn && options.fn !== noop) { (function () { options.data = _base.createFrame(options.data); // Wrapper function to get access to currentPartialBlock from the closure var fn = options.fn; partialBlock = options.data['partial-block'] = function partialBlockWrapper(context) { var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1]; // Restore the partial-block from the closure for the execution of the block // i.e. the part inside the block of the partial call. options.data = _base.createFrame(options.data); options.data['partial-block'] = currentPartialBlock; return fn(context, options); }; if (fn.partials) { options.partials = Utils.extend({}, options.partials, fn.partials); } })(); } if (partial === undefined && partialBlock) { partial = partialBlock; } if (partial === undefined) { throw new _exception2['default']('The partial ' + options.name + ' could not be found'); } else if (partial instanceof Function) { return partial(context, options); } } function noop() { return ''; } function initData(context, data) { if (!data || !('root' in data)) { data = data ? _base.createFrame(data) : {}; data.root = context; } return data; } function executeDecorators(fn, prog, container, depths, data, blockParams) { if (fn.decorator) { var props = {}; prog = fn.decorator(prog, props, container, depths && depths[0], data, blockParams, depths); Utils.extend(prog, props); } return prog; } function wrapHelpersToPassLookupProperty(mergedHelpers, container) { _Object$keys(mergedHelpers).forEach(function (helperName) { var helper = mergedHelpers[helperName]; mergedHelpers[helperName] = passLookupPropertyOption(helper, container); }); } function passLookupPropertyOption(helper, container) { var lookupProperty = container.lookupProperty; return _internalWrapHelper.wrapHelper(helper, function (options) { return Utils.extend({ lookupProperty: lookupProperty }, options); }); } /***/ }), /* 38 */ /***/ (function(module, exports, __webpack_require__) { module.exports = { "default": __webpack_require__(39), __esModule: true }; /***/ }), /* 39 */ /***/ (function(module, exports, __webpack_require__) { __webpack_require__(40); module.exports = __webpack_require__(20).Object.seal; /***/ }), /* 40 */ /***/ (function(module, exports, __webpack_require__) { // 19.1.2.17 Object.seal(O) var isObject = __webpack_require__(41); __webpack_require__(17)('seal', function($seal){ return function seal(it){ return $seal && isObject(it) ? $seal(it) : it; }; }); /***/ }), /* 41 */ /***/ (function(module, exports) { module.exports = function(it){ return typeof it === 'object' ? it !== null : typeof it === 'function'; }; /***/ }), /* 42 */ /***/ (function(module, exports) { 'use strict'; exports.__esModule = true; exports.wrapHelper = wrapHelper; function wrapHelper(helper, transformOptionsFn) { if (typeof helper !== 'function') { // This should not happen, but apparently it does in https://github.com/wycats/handlebars.js/issues/1639 // We try to make the wrapper least-invasive by not wrapping it, if the helper is not a function. return helper; } var wrapper = function wrapper() /* dynamic arguments */{ var options = arguments[arguments.length - 1]; arguments[arguments.length - 1] = transformOptionsFn(options); return helper.apply(this, arguments); }; return wrapper; } /***/ }), /* 43 */ /***/ (function(module, exports) { /* WEBPACK VAR INJECTION */(function(global) {'use strict'; exports.__esModule = true; exports['default'] = function (Handlebars) { /* istanbul ignore next */ var root = typeof global !== 'undefined' ? global : window, $Handlebars = root.Handlebars; /* istanbul ignore next */ Handlebars.noConflict = function () { if (root.Handlebars === Handlebars) { root.Handlebars = $Handlebars; } return Handlebars; }; }; module.exports = exports['default']; /* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }()))) /***/ }) /******/ ]) }); ;includes/handlebars/handlebars.js000064400000536152152214270100013124 0ustar00/**! @license handlebars v4.7.7 Copyright (C) 2011-2019 by Yehuda Katz Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ (function webpackUniversalModuleDefinition(root, factory) { if(typeof exports === 'object' && typeof module === 'object') module.exports = factory(); else if(typeof define === 'function' && define.amd) define([], factory); else if(typeof exports === 'object') exports["Handlebars"] = factory(); else root["Handlebars"] = factory(); })(this, function() { return /******/ (function(modules) { // webpackBootstrap /******/ // The module cache /******/ var installedModules = {}; /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ // Check if module is in cache /******/ if(installedModules[moduleId]) /******/ return installedModules[moduleId].exports; /******/ // Create a new module (and put it into the cache) /******/ var module = installedModules[moduleId] = { /******/ exports: {}, /******/ id: moduleId, /******/ loaded: false /******/ }; /******/ // Execute the module function /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); /******/ // Flag the module as loaded /******/ module.loaded = true; /******/ // Return the exports of the module /******/ return module.exports; /******/ } /******/ // expose the modules object (__webpack_modules__) /******/ __webpack_require__.m = modules; /******/ // expose the module cache /******/ __webpack_require__.c = installedModules; /******/ // __webpack_public_path__ /******/ __webpack_require__.p = ""; /******/ // Load entry module and return exports /******/ return __webpack_require__(0); /******/ }) /************************************************************************/ /******/ ([ /* 0 */ /***/ (function(module, exports, __webpack_require__) { 'use strict'; var _interopRequireDefault = __webpack_require__(1)['default']; exports.__esModule = true; var _handlebarsRuntime = __webpack_require__(2); var _handlebarsRuntime2 = _interopRequireDefault(_handlebarsRuntime); // Compiler imports var _handlebarsCompilerAst = __webpack_require__(45); var _handlebarsCompilerAst2 = _interopRequireDefault(_handlebarsCompilerAst); var _handlebarsCompilerBase = __webpack_require__(46); var _handlebarsCompilerCompiler = __webpack_require__(51); var _handlebarsCompilerJavascriptCompiler = __webpack_require__(52); var _handlebarsCompilerJavascriptCompiler2 = _interopRequireDefault(_handlebarsCompilerJavascriptCompiler); var _handlebarsCompilerVisitor = __webpack_require__(49); var _handlebarsCompilerVisitor2 = _interopRequireDefault(_handlebarsCompilerVisitor); var _handlebarsNoConflict = __webpack_require__(44); var _handlebarsNoConflict2 = _interopRequireDefault(_handlebarsNoConflict); var _create = _handlebarsRuntime2['default'].create; function create() { var hb = _create(); hb.compile = function (input, options) { return _handlebarsCompilerCompiler.compile(input, options, hb); }; hb.precompile = function (input, options) { return _handlebarsCompilerCompiler.precompile(input, options, hb); }; hb.AST = _handlebarsCompilerAst2['default']; hb.Compiler = _handlebarsCompilerCompiler.Compiler; hb.JavaScriptCompiler = _handlebarsCompilerJavascriptCompiler2['default']; hb.Parser = _handlebarsCompilerBase.parser; hb.parse = _handlebarsCompilerBase.parse; hb.parseWithoutProcessing = _handlebarsCompilerBase.parseWithoutProcessing; return hb; } var inst = create(); inst.create = create; _handlebarsNoConflict2['default'](inst); inst.Visitor = _handlebarsCompilerVisitor2['default']; inst['default'] = inst; exports['default'] = inst; module.exports = exports['default']; /***/ }), /* 1 */ /***/ (function(module, exports) { "use strict"; exports["default"] = function (obj) { return obj && obj.__esModule ? obj : { "default": obj }; }; exports.__esModule = true; /***/ }), /* 2 */ /***/ (function(module, exports, __webpack_require__) { 'use strict'; var _interopRequireWildcard = __webpack_require__(3)['default']; var _interopRequireDefault = __webpack_require__(1)['default']; exports.__esModule = true; var _handlebarsBase = __webpack_require__(4); var base = _interopRequireWildcard(_handlebarsBase); // Each of these augment the Handlebars object. No need to setup here. // (This is done to easily share code between commonjs and browse envs) var _handlebarsSafeString = __webpack_require__(37); var _handlebarsSafeString2 = _interopRequireDefault(_handlebarsSafeString); var _handlebarsException = __webpack_require__(6); var _handlebarsException2 = _interopRequireDefault(_handlebarsException); var _handlebarsUtils = __webpack_require__(5); var Utils = _interopRequireWildcard(_handlebarsUtils); var _handlebarsRuntime = __webpack_require__(38); var runtime = _interopRequireWildcard(_handlebarsRuntime); var _handlebarsNoConflict = __webpack_require__(44); var _handlebarsNoConflict2 = _interopRequireDefault(_handlebarsNoConflict); // For compatibility and usage outside of module systems, make the Handlebars object a namespace function create() { var hb = new base.HandlebarsEnvironment(); Utils.extend(hb, base); hb.SafeString = _handlebarsSafeString2['default']; hb.Exception = _handlebarsException2['default']; hb.Utils = Utils; hb.escapeExpression = Utils.escapeExpression; hb.VM = runtime; hb.template = function (spec) { return runtime.template(spec, hb); }; return hb; } var inst = create(); inst.create = create; _handlebarsNoConflict2['default'](inst); inst['default'] = inst; exports['default'] = inst; module.exports = exports['default']; /***/ }), /* 3 */ /***/ (function(module, exports) { "use strict"; exports["default"] = function (obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj["default"] = obj; return newObj; } }; exports.__esModule = true; /***/ }), /* 4 */ /***/ (function(module, exports, __webpack_require__) { 'use strict'; var _interopRequireDefault = __webpack_require__(1)['default']; exports.__esModule = true; exports.HandlebarsEnvironment = HandlebarsEnvironment; var _utils = __webpack_require__(5); var _exception = __webpack_require__(6); var _exception2 = _interopRequireDefault(_exception); var _helpers = __webpack_require__(10); var _decorators = __webpack_require__(30); var _logger = __webpack_require__(32); var _logger2 = _interopRequireDefault(_logger); var _internalProtoAccess = __webpack_require__(33); var VERSION = '4.7.7'; exports.VERSION = VERSION; var COMPILER_REVISION = 8; exports.COMPILER_REVISION = COMPILER_REVISION; var LAST_COMPATIBLE_COMPILER_REVISION = 7; exports.LAST_COMPATIBLE_COMPILER_REVISION = LAST_COMPATIBLE_COMPILER_REVISION; var REVISION_CHANGES = { 1: '<= 1.0.rc.2', // 1.0.rc.2 is actually rev2 but doesn't report it 2: '== 1.0.0-rc.3', 3: '== 1.0.0-rc.4', 4: '== 1.x.x', 5: '== 2.0.0-alpha.x', 6: '>= 2.0.0-beta.1', 7: '>= 4.0.0 <4.3.0', 8: '>= 4.3.0' }; exports.REVISION_CHANGES = REVISION_CHANGES; var objectType = '[object Object]'; function HandlebarsEnvironment(helpers, partials, decorators) { this.helpers = helpers || {}; this.partials = partials || {}; this.decorators = decorators || {}; _helpers.registerDefaultHelpers(this); _decorators.registerDefaultDecorators(this); } HandlebarsEnvironment.prototype = { constructor: HandlebarsEnvironment, logger: _logger2['default'], log: _logger2['default'].log, registerHelper: function registerHelper(name, fn) { if (_utils.toString.call(name) === objectType) { if (fn) { throw new _exception2['default']('Arg not supported with multiple helpers'); } _utils.extend(this.helpers, name); } else { this.helpers[name] = fn; } }, unregisterHelper: function unregisterHelper(name) { delete this.helpers[name]; }, registerPartial: function registerPartial(name, partial) { if (_utils.toString.call(name) === objectType) { _utils.extend(this.partials, name); } else { if (typeof partial === 'undefined') { throw new _exception2['default']('Attempting to register a partial called "' + name + '" as undefined'); } this.partials[name] = partial; } }, unregisterPartial: function unregisterPartial(name) { delete this.partials[name]; }, registerDecorator: function registerDecorator(name, fn) { if (_utils.toString.call(name) === objectType) { if (fn) { throw new _exception2['default']('Arg not supported with multiple decorators'); } _utils.extend(this.decorators, name); } else { this.decorators[name] = fn; } }, unregisterDecorator: function unregisterDecorator(name) { delete this.decorators[name]; }, /** * Reset the memory of illegal property accesses that have already been logged. * @deprecated should only be used in handlebars test-cases */ resetLoggedPropertyAccesses: function resetLoggedPropertyAccesses() { _internalProtoAccess.resetLoggedProperties(); } }; var log = _logger2['default'].log; exports.log = log; exports.createFrame = _utils.createFrame; exports.logger = _logger2['default']; /***/ }), /* 5 */ /***/ (function(module, exports) { 'use strict'; exports.__esModule = true; exports.extend = extend; exports.indexOf = indexOf; exports.escapeExpression = escapeExpression; exports.isEmpty = isEmpty; exports.createFrame = createFrame; exports.blockParams = blockParams; exports.appendContextPath = appendContextPath; var escape = { '&': '&', '<': '<', '>': '>', '"': '"', "'": ''', '`': '`', '=': '=' }; var badChars = /[&<>"'`=]/g, possible = /[&<>"'`=]/; function escapeChar(chr) { return escape[chr]; } function extend(obj /* , ...source */) { for (var i = 1; i < arguments.length; i++) { for (var key in arguments[i]) { if (Object.prototype.hasOwnProperty.call(arguments[i], key)) { obj[key] = arguments[i][key]; } } } return obj; } var toString = Object.prototype.toString; exports.toString = toString; // Sourced from lodash // https://github.com/bestiejs/lodash/blob/master/LICENSE.txt /* eslint-disable func-style */ var isFunction = function isFunction(value) { return typeof value === 'function'; }; // fallback for older versions of Chrome and Safari /* istanbul ignore next */ if (isFunction(/x/)) { exports.isFunction = isFunction = function (value) { return typeof value === 'function' && toString.call(value) === '[object Function]'; }; } exports.isFunction = isFunction; /* eslint-enable func-style */ /* istanbul ignore next */ var isArray = Array.isArray || function (value) { return value && typeof value === 'object' ? toString.call(value) === '[object Array]' : false; }; exports.isArray = isArray; // Older IE versions do not directly support indexOf so we must implement our own, sadly. function indexOf(array, value) { for (var i = 0, len = array.length; i < len; i++) { if (array[i] === value) { return i; } } return -1; } function escapeExpression(string) { if (typeof string !== 'string') { // don't escape SafeStrings, since they're already safe if (string && string.toHTML) { return string.toHTML(); } else if (string == null) { return ''; } else if (!string) { return string + ''; } // Force a string conversion as this will be done by the append regardless and // the regex test will do this transparently behind the scenes, causing issues if // an object's to string has escaped characters in it. string = '' + string; } if (!possible.test(string)) { return string; } return string.replace(badChars, escapeChar); } function isEmpty(value) { if (!value && value !== 0) { return true; } else if (isArray(value) && value.length === 0) { return true; } else { return false; } } function createFrame(object) { var frame = extend({}, object); frame._parent = object; return frame; } function blockParams(params, ids) { params.path = ids; return params; } function appendContextPath(contextPath, id) { return (contextPath ? contextPath + '.' : '') + id; } /***/ }), /* 6 */ /***/ (function(module, exports, __webpack_require__) { 'use strict'; var _Object$defineProperty = __webpack_require__(7)['default']; exports.__esModule = true; var errorProps = ['description', 'fileName', 'lineNumber', 'endLineNumber', 'message', 'name', 'number', 'stack']; function Exception(message, node) { var loc = node && node.loc, line = undefined, endLineNumber = undefined, column = undefined, endColumn = undefined; if (loc) { line = loc.start.line; endLineNumber = loc.end.line; column = loc.start.column; endColumn = loc.end.column; message += ' - ' + line + ':' + column; } var tmp = Error.prototype.constructor.call(this, message); // Unfortunately errors are not enumerable in Chrome (at least), so `for prop in tmp` doesn't work. for (var idx = 0; idx < errorProps.length; idx++) { this[errorProps[idx]] = tmp[errorProps[idx]]; } /* istanbul ignore else */ if (Error.captureStackTrace) { Error.captureStackTrace(this, Exception); } try { if (loc) { this.lineNumber = line; this.endLineNumber = endLineNumber; // Work around issue under safari where we can't directly set the column value /* istanbul ignore next */ if (_Object$defineProperty) { Object.defineProperty(this, 'column', { value: column, enumerable: true }); Object.defineProperty(this, 'endColumn', { value: endColumn, enumerable: true }); } else { this.column = column; this.endColumn = endColumn; } } } catch (nop) { /* Ignore if the browser is very particular */ } } Exception.prototype = new Error(); exports['default'] = Exception; module.exports = exports['default']; /***/ }), /* 7 */ /***/ (function(module, exports, __webpack_require__) { module.exports = { "default": __webpack_require__(8), __esModule: true }; /***/ }), /* 8 */ /***/ (function(module, exports, __webpack_require__) { var $ = __webpack_require__(9); module.exports = function defineProperty(it, key, desc){ return $.setDesc(it, key, desc); }; /***/ }), /* 9 */ /***/ (function(module, exports) { var $Object = Object; module.exports = { create: $Object.create, getProto: $Object.getPrototypeOf, isEnum: {}.propertyIsEnumerable, getDesc: $Object.getOwnPropertyDescriptor, setDesc: $Object.defineProperty, setDescs: $Object.defineProperties, getKeys: $Object.keys, getNames: $Object.getOwnPropertyNames, getSymbols: $Object.getOwnPropertySymbols, each: [].forEach }; /***/ }), /* 10 */ /***/ (function(module, exports, __webpack_require__) { 'use strict'; var _interopRequireDefault = __webpack_require__(1)['default']; exports.__esModule = true; exports.registerDefaultHelpers = registerDefaultHelpers; exports.moveHelperToHooks = moveHelperToHooks; var _helpersBlockHelperMissing = __webpack_require__(11); var _helpersBlockHelperMissing2 = _interopRequireDefault(_helpersBlockHelperMissing); var _helpersEach = __webpack_require__(12); var _helpersEach2 = _interopRequireDefault(_helpersEach); var _helpersHelperMissing = __webpack_require__(25); var _helpersHelperMissing2 = _interopRequireDefault(_helpersHelperMissing); var _helpersIf = __webpack_require__(26); var _helpersIf2 = _interopRequireDefault(_helpersIf); var _helpersLog = __webpack_require__(27); var _helpersLog2 = _interopRequireDefault(_helpersLog); var _helpersLookup = __webpack_require__(28); var _helpersLookup2 = _interopRequireDefault(_helpersLookup); var _helpersWith = __webpack_require__(29); var _helpersWith2 = _interopRequireDefault(_helpersWith); function registerDefaultHelpers(instance) { _helpersBlockHelperMissing2['default'](instance); _helpersEach2['default'](instance); _helpersHelperMissing2['default'](instance); _helpersIf2['default'](instance); _helpersLog2['default'](instance); _helpersLookup2['default'](instance); _helpersWith2['default'](instance); } function moveHelperToHooks(instance, helperName, keepHelper) { if (instance.helpers[helperName]) { instance.hooks[helperName] = instance.helpers[helperName]; if (!keepHelper) { delete instance.helpers[helperName]; } } } /***/ }), /* 11 */ /***/ (function(module, exports, __webpack_require__) { 'use strict'; exports.__esModule = true; var _utils = __webpack_require__(5); exports['default'] = function (instance) { instance.registerHelper('blockHelperMissing', function (context, options) { var inverse = options.inverse, fn = options.fn; if (context === true) { return fn(this); } else if (context === false || context == null) { return inverse(this); } else if (_utils.isArray(context)) { if (context.length > 0) { if (options.ids) { options.ids = [options.name]; } return instance.helpers.each(context, options); } else { return inverse(this); } } else { if (options.data && options.ids) { var data = _utils.createFrame(options.data); data.contextPath = _utils.appendContextPath(options.data.contextPath, options.name); options = { data: data }; } return fn(context, options); } }); }; module.exports = exports['default']; /***/ }), /* 12 */ /***/ (function(module, exports, __webpack_require__) { /* WEBPACK VAR INJECTION */(function(global) {'use strict'; var _Object$keys = __webpack_require__(13)['default']; var _interopRequireDefault = __webpack_require__(1)['default']; exports.__esModule = true; var _utils = __webpack_require__(5); var _exception = __webpack_require__(6); var _exception2 = _interopRequireDefault(_exception); exports['default'] = function (instance) { instance.registerHelper('each', function (context, options) { if (!options) { throw new _exception2['default']('Must pass iterator to #each'); } var fn = options.fn, inverse = options.inverse, i = 0, ret = '', data = undefined, contextPath = undefined; if (options.data && options.ids) { contextPath = _utils.appendContextPath(options.data.contextPath, options.ids[0]) + '.'; } if (_utils.isFunction(context)) { context = context.call(this); } if (options.data) { data = _utils.createFrame(options.data); } function execIteration(field, index, last) { if (data) { data.key = field; data.index = index; data.first = index === 0; data.last = !!last; if (contextPath) { data.contextPath = contextPath + field; } } ret = ret + fn(context[field], { data: data, blockParams: _utils.blockParams([context[field], field], [contextPath + field, null]) }); } if (context && typeof context === 'object') { if (_utils.isArray(context)) { for (var j = context.length; i < j; i++) { if (i in context) { execIteration(i, i, i === context.length - 1); } } } else if (global.Symbol && context[global.Symbol.iterator]) { var newContext = []; var iterator = context[global.Symbol.iterator](); for (var it = iterator.next(); !it.done; it = iterator.next()) { newContext.push(it.value); } context = newContext; for (var j = context.length; i < j; i++) { execIteration(i, i, i === context.length - 1); } } else { (function () { var priorKey = undefined; _Object$keys(context).forEach(function (key) { // We're running the iterations one step out of sync so we can detect // the last iteration without have to scan the object twice and create // an itermediate keys array. if (priorKey !== undefined) { execIteration(priorKey, i - 1); } priorKey = key; i++; }); if (priorKey !== undefined) { execIteration(priorKey, i - 1, true); } })(); } } if (i === 0) { ret = inverse(this); } return ret; }); }; module.exports = exports['default']; /* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }()))) /***/ }), /* 13 */ /***/ (function(module, exports, __webpack_require__) { module.exports = { "default": __webpack_require__(14), __esModule: true }; /***/ }), /* 14 */ /***/ (function(module, exports, __webpack_require__) { __webpack_require__(15); module.exports = __webpack_require__(21).Object.keys; /***/ }), /* 15 */ /***/ (function(module, exports, __webpack_require__) { // 19.1.2.14 Object.keys(O) var toObject = __webpack_require__(16); __webpack_require__(18)('keys', function($keys){ return function keys(it){ return $keys(toObject(it)); }; }); /***/ }), /* 16 */ /***/ (function(module, exports, __webpack_require__) { // 7.1.13 ToObject(argument) var defined = __webpack_require__(17); module.exports = function(it){ return Object(defined(it)); }; /***/ }), /* 17 */ /***/ (function(module, exports) { // 7.2.1 RequireObjectCoercible(argument) module.exports = function(it){ if(it == undefined)throw TypeError("Can't call method on " + it); return it; }; /***/ }), /* 18 */ /***/ (function(module, exports, __webpack_require__) { // most Object methods by ES6 should accept primitives var $export = __webpack_require__(19) , core = __webpack_require__(21) , fails = __webpack_require__(24); module.exports = function(KEY, exec){ var fn = (core.Object || {})[KEY] || Object[KEY] , exp = {}; exp[KEY] = exec(fn); $export($export.S + $export.F * fails(function(){ fn(1); }), 'Object', exp); }; /***/ }), /* 19 */ /***/ (function(module, exports, __webpack_require__) { var global = __webpack_require__(20) , core = __webpack_require__(21) , ctx = __webpack_require__(22) , PROTOTYPE = 'prototype'; var $export = function(type, name, source){ var IS_FORCED = type & $export.F , IS_GLOBAL = type & $export.G , IS_STATIC = type & $export.S , IS_PROTO = type & $export.P , IS_BIND = type & $export.B , IS_WRAP = type & $export.W , exports = IS_GLOBAL ? core : core[name] || (core[name] = {}) , target = IS_GLOBAL ? global : IS_STATIC ? global[name] : (global[name] || {})[PROTOTYPE] , key, own, out; if(IS_GLOBAL)source = name; for(key in source){ // contains in native own = !IS_FORCED && target && key in target; if(own && key in exports)continue; // export native or passed out = own ? target[key] : source[key]; // prevent global pollution for namespaces exports[key] = IS_GLOBAL && typeof target[key] != 'function' ? source[key] // bind timers to global for call from export context : IS_BIND && own ? ctx(out, global) // wrap global constructors for prevent change them in library : IS_WRAP && target[key] == out ? (function(C){ var F = function(param){ return this instanceof C ? new C(param) : C(param); }; F[PROTOTYPE] = C[PROTOTYPE]; return F; // make static versions for prototype methods })(out) : IS_PROTO && typeof out == 'function' ? ctx(Function.call, out) : out; if(IS_PROTO)(exports[PROTOTYPE] || (exports[PROTOTYPE] = {}))[key] = out; } }; // type bitmap $export.F = 1; // forced $export.G = 2; // global $export.S = 4; // static $export.P = 8; // proto $export.B = 16; // bind $export.W = 32; // wrap module.exports = $export; /***/ }), /* 20 */ /***/ (function(module, exports) { // https://github.com/zloirock/core-js/issues/86#issuecomment-115759028 var global = module.exports = typeof window != 'undefined' && window.Math == Math ? window : typeof self != 'undefined' && self.Math == Math ? self : Function('return this')(); if(typeof __g == 'number')__g = global; // eslint-disable-line no-undef /***/ }), /* 21 */ /***/ (function(module, exports) { var core = module.exports = {version: '1.2.6'}; if(typeof __e == 'number')__e = core; // eslint-disable-line no-undef /***/ }), /* 22 */ /***/ (function(module, exports, __webpack_require__) { // optional / simple context binding var aFunction = __webpack_require__(23); module.exports = function(fn, that, length){ aFunction(fn); if(that === undefined)return fn; switch(length){ case 1: return function(a){ return fn.call(that, a); }; case 2: return function(a, b){ return fn.call(that, a, b); }; case 3: return function(a, b, c){ return fn.call(that, a, b, c); }; } return function(/* ...args */){ return fn.apply(that, arguments); }; }; /***/ }), /* 23 */ /***/ (function(module, exports) { module.exports = function(it){ if(typeof it != 'function')throw TypeError(it + ' is not a function!'); return it; }; /***/ }), /* 24 */ /***/ (function(module, exports) { module.exports = function(exec){ try { return !!exec(); } catch(e){ return true; } }; /***/ }), /* 25 */ /***/ (function(module, exports, __webpack_require__) { 'use strict'; var _interopRequireDefault = __webpack_require__(1)['default']; exports.__esModule = true; var _exception = __webpack_require__(6); var _exception2 = _interopRequireDefault(_exception); exports['default'] = function (instance) { instance.registerHelper('helperMissing', function () /* [args, ]options */{ if (arguments.length === 1) { // A missing field in a {{foo}} construct. return undefined; } else { // Someone is actually trying to call something, blow up. throw new _exception2['default']('Missing helper: "' + arguments[arguments.length - 1].name + '"'); } }); }; module.exports = exports['default']; /***/ }), /* 26 */ /***/ (function(module, exports, __webpack_require__) { 'use strict'; var _interopRequireDefault = __webpack_require__(1)['default']; exports.__esModule = true; var _utils = __webpack_require__(5); var _exception = __webpack_require__(6); var _exception2 = _interopRequireDefault(_exception); exports['default'] = function (instance) { instance.registerHelper('if', function (conditional, options) { if (arguments.length != 2) { throw new _exception2['default']('#if requires exactly one argument'); } if (_utils.isFunction(conditional)) { conditional = conditional.call(this); } // Default behavior is to render the positive path if the value is truthy and not empty. // The `includeZero` option may be set to treat the condtional as purely not empty based on the // behavior of isEmpty. Effectively this determines if 0 is handled by the positive path or negative. if (!options.hash.includeZero && !conditional || _utils.isEmpty(conditional)) { return options.inverse(this); } else { return options.fn(this); } }); instance.registerHelper('unless', function (conditional, options) { if (arguments.length != 2) { throw new _exception2['default']('#unless requires exactly one argument'); } return instance.helpers['if'].call(this, conditional, { fn: options.inverse, inverse: options.fn, hash: options.hash }); }); }; module.exports = exports['default']; /***/ }), /* 27 */ /***/ (function(module, exports) { 'use strict'; exports.__esModule = true; exports['default'] = function (instance) { instance.registerHelper('log', function () /* message, options */{ var args = [undefined], options = arguments[arguments.length - 1]; for (var i = 0; i < arguments.length - 1; i++) { args.push(arguments[i]); } var level = 1; if (options.hash.level != null) { level = options.hash.level; } else if (options.data && options.data.level != null) { level = options.data.level; } args[0] = level; instance.log.apply(instance, args); }); }; module.exports = exports['default']; /***/ }), /* 28 */ /***/ (function(module, exports) { 'use strict'; exports.__esModule = true; exports['default'] = function (instance) { instance.registerHelper('lookup', function (obj, field, options) { if (!obj) { // Note for 5.0: Change to "obj == null" in 5.0 return obj; } return options.lookupProperty(obj, field); }); }; module.exports = exports['default']; /***/ }), /* 29 */ /***/ (function(module, exports, __webpack_require__) { 'use strict'; var _interopRequireDefault = __webpack_require__(1)['default']; exports.__esModule = true; var _utils = __webpack_require__(5); var _exception = __webpack_require__(6); var _exception2 = _interopRequireDefault(_exception); exports['default'] = function (instance) { instance.registerHelper('with', function (context, options) { if (arguments.length != 2) { throw new _exception2['default']('#with requires exactly one argument'); } if (_utils.isFunction(context)) { context = context.call(this); } var fn = options.fn; if (!_utils.isEmpty(context)) { var data = options.data; if (options.data && options.ids) { data = _utils.createFrame(options.data); data.contextPath = _utils.appendContextPath(options.data.contextPath, options.ids[0]); } return fn(context, { data: data, blockParams: _utils.blockParams([context], [data && data.contextPath]) }); } else { return options.inverse(this); } }); }; module.exports = exports['default']; /***/ }), /* 30 */ /***/ (function(module, exports, __webpack_require__) { 'use strict'; var _interopRequireDefault = __webpack_require__(1)['default']; exports.__esModule = true; exports.registerDefaultDecorators = registerDefaultDecorators; var _decoratorsInline = __webpack_require__(31); var _decoratorsInline2 = _interopRequireDefault(_decoratorsInline); function registerDefaultDecorators(instance) { _decoratorsInline2['default'](instance); } /***/ }), /* 31 */ /***/ (function(module, exports, __webpack_require__) { 'use strict'; exports.__esModule = true; var _utils = __webpack_require__(5); exports['default'] = function (instance) { instance.registerDecorator('inline', function (fn, props, container, options) { var ret = fn; if (!props.partials) { props.partials = {}; ret = function (context, options) { // Create a new partials stack frame prior to exec. var original = container.partials; container.partials = _utils.extend({}, original, props.partials); var ret = fn(context, options); container.partials = original; return ret; }; } props.partials[options.args[0]] = options.fn; return ret; }); }; module.exports = exports['default']; /***/ }), /* 32 */ /***/ (function(module, exports, __webpack_require__) { 'use strict'; exports.__esModule = true; var _utils = __webpack_require__(5); var logger = { methodMap: ['debug', 'info', 'warn', 'error'], level: 'info', // Maps a given level value to the `methodMap` indexes above. lookupLevel: function lookupLevel(level) { if (typeof level === 'string') { var levelMap = _utils.indexOf(logger.methodMap, level.toLowerCase()); if (levelMap >= 0) { level = levelMap; } else { level = parseInt(level, 10); } } return level; }, // Can be overridden in the host environment log: function log(level) { level = logger.lookupLevel(level); if (typeof console !== 'undefined' && logger.lookupLevel(logger.level) <= level) { var method = logger.methodMap[level]; // eslint-disable-next-line no-console if (!console[method]) { method = 'log'; } for (var _len = arguments.length, message = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { message[_key - 1] = arguments[_key]; } console[method].apply(console, message); // eslint-disable-line no-console } } }; exports['default'] = logger; module.exports = exports['default']; /***/ }), /* 33 */ /***/ (function(module, exports, __webpack_require__) { 'use strict'; var _Object$create = __webpack_require__(34)['default']; var _Object$keys = __webpack_require__(13)['default']; var _interopRequireWildcard = __webpack_require__(3)['default']; exports.__esModule = true; exports.createProtoAccessControl = createProtoAccessControl; exports.resultIsAllowed = resultIsAllowed; exports.resetLoggedProperties = resetLoggedProperties; var _createNewLookupObject = __webpack_require__(36); var _logger = __webpack_require__(32); var logger = _interopRequireWildcard(_logger); var loggedProperties = _Object$create(null); function createProtoAccessControl(runtimeOptions) { var defaultMethodWhiteList = _Object$create(null); defaultMethodWhiteList['constructor'] = false; defaultMethodWhiteList['__defineGetter__'] = false; defaultMethodWhiteList['__defineSetter__'] = false; defaultMethodWhiteList['__lookupGetter__'] = false; var defaultPropertyWhiteList = _Object$create(null); // eslint-disable-next-line no-proto defaultPropertyWhiteList['__proto__'] = false; return { properties: { whitelist: _createNewLookupObject.createNewLookupObject(defaultPropertyWhiteList, runtimeOptions.allowedProtoProperties), defaultValue: runtimeOptions.allowProtoPropertiesByDefault }, methods: { whitelist: _createNewLookupObject.createNewLookupObject(defaultMethodWhiteList, runtimeOptions.allowedProtoMethods), defaultValue: runtimeOptions.allowProtoMethodsByDefault } }; } function resultIsAllowed(result, protoAccessControl, propertyName) { if (typeof result === 'function') { return checkWhiteList(protoAccessControl.methods, propertyName); } else { return checkWhiteList(protoAccessControl.properties, propertyName); } } function checkWhiteList(protoAccessControlForType, propertyName) { if (protoAccessControlForType.whitelist[propertyName] !== undefined) { return protoAccessControlForType.whitelist[propertyName] === true; } if (protoAccessControlForType.defaultValue !== undefined) { return protoAccessControlForType.defaultValue; } logUnexpecedPropertyAccessOnce(propertyName); return false; } function logUnexpecedPropertyAccessOnce(propertyName) { if (loggedProperties[propertyName] !== true) { loggedProperties[propertyName] = true; logger.log('error', 'Handlebars: Access has been denied to resolve the property "' + propertyName + '" because it is not an "own property" of its parent.\n' + 'You can add a runtime option to disable the check or this warning:\n' + 'See https://handlebarsjs.com/api-reference/runtime-options.html#options-to-control-prototype-access for details'); } } function resetLoggedProperties() { _Object$keys(loggedProperties).forEach(function (propertyName) { delete loggedProperties[propertyName]; }); } /***/ }), /* 34 */ /***/ (function(module, exports, __webpack_require__) { module.exports = { "default": __webpack_require__(35), __esModule: true }; /***/ }), /* 35 */ /***/ (function(module, exports, __webpack_require__) { var $ = __webpack_require__(9); module.exports = function create(P, D){ return $.create(P, D); }; /***/ }), /* 36 */ /***/ (function(module, exports, __webpack_require__) { 'use strict'; var _Object$create = __webpack_require__(34)['default']; exports.__esModule = true; exports.createNewLookupObject = createNewLookupObject; var _utils = __webpack_require__(5); /** * Create a new object with "null"-prototype to avoid truthy results on prototype properties. * The resulting object can be used with "object[property]" to check if a property exists * @param {...object} sources a varargs parameter of source objects that will be merged * @returns {object} */ function createNewLookupObject() { for (var _len = arguments.length, sources = Array(_len), _key = 0; _key < _len; _key++) { sources[_key] = arguments[_key]; } return _utils.extend.apply(undefined, [_Object$create(null)].concat(sources)); } /***/ }), /* 37 */ /***/ (function(module, exports) { // Build out our basic SafeString type 'use strict'; exports.__esModule = true; function SafeString(string) { this.string = string; } SafeString.prototype.toString = SafeString.prototype.toHTML = function () { return '' + this.string; }; exports['default'] = SafeString; module.exports = exports['default']; /***/ }), /* 38 */ /***/ (function(module, exports, __webpack_require__) { 'use strict'; var _Object$seal = __webpack_require__(39)['default']; var _Object$keys = __webpack_require__(13)['default']; var _interopRequireWildcard = __webpack_require__(3)['default']; var _interopRequireDefault = __webpack_require__(1)['default']; exports.__esModule = true; exports.checkRevision = checkRevision; exports.template = template; exports.wrapProgram = wrapProgram; exports.resolvePartial = resolvePartial; exports.invokePartial = invokePartial; exports.noop = noop; var _utils = __webpack_require__(5); var Utils = _interopRequireWildcard(_utils); var _exception = __webpack_require__(6); var _exception2 = _interopRequireDefault(_exception); var _base = __webpack_require__(4); var _helpers = __webpack_require__(10); var _internalWrapHelper = __webpack_require__(43); var _internalProtoAccess = __webpack_require__(33); function checkRevision(compilerInfo) { var compilerRevision = compilerInfo && compilerInfo[0] || 1, currentRevision = _base.COMPILER_REVISION; if (compilerRevision >= _base.LAST_COMPATIBLE_COMPILER_REVISION && compilerRevision <= _base.COMPILER_REVISION) { return; } if (compilerRevision < _base.LAST_COMPATIBLE_COMPILER_REVISION) { var runtimeVersions = _base.REVISION_CHANGES[currentRevision], compilerVersions = _base.REVISION_CHANGES[compilerRevision]; throw new _exception2['default']('Template was precompiled with an older version of Handlebars than the current runtime. ' + 'Please update your precompiler to a newer version (' + runtimeVersions + ') or downgrade your runtime to an older version (' + compilerVersions + ').'); } else { // Use the embedded version info since the runtime doesn't know about this revision yet throw new _exception2['default']('Template was precompiled with a newer version of Handlebars than the current runtime. ' + 'Please update your runtime to a newer version (' + compilerInfo[1] + ').'); } } function template(templateSpec, env) { /* istanbul ignore next */ if (!env) { throw new _exception2['default']('No environment passed to template'); } if (!templateSpec || !templateSpec.main) { throw new _exception2['default']('Unknown template object: ' + typeof templateSpec); } templateSpec.main.decorator = templateSpec.main_d; // Note: Using env.VM references rather than local var references throughout this section to allow // for external users to override these as pseudo-supported APIs. env.VM.checkRevision(templateSpec.compiler); // backwards compatibility for precompiled templates with compiler-version 7 (<4.3.0) var templateWasPrecompiledWithCompilerV7 = templateSpec.compiler && templateSpec.compiler[0] === 7; function invokePartialWrapper(partial, context, options) { if (options.hash) { context = Utils.extend({}, context, options.hash); if (options.ids) { options.ids[0] = true; } } partial = env.VM.resolvePartial.call(this, partial, context, options); var extendedOptions = Utils.extend({}, options, { hooks: this.hooks, protoAccessControl: this.protoAccessControl }); var result = env.VM.invokePartial.call(this, partial, context, extendedOptions); if (result == null && env.compile) { options.partials[options.name] = env.compile(partial, templateSpec.compilerOptions, env); result = options.partials[options.name](context, extendedOptions); } if (result != null) { if (options.indent) { var lines = result.split('\n'); for (var i = 0, l = lines.length; i < l; i++) { if (!lines[i] && i + 1 === l) { break; } lines[i] = options.indent + lines[i]; } result = lines.join('\n'); } return result; } else { throw new _exception2['default']('The partial ' + options.name + ' could not be compiled when running in runtime-only mode'); } } // Just add water var container = { strict: function strict(obj, name, loc) { if (!obj || !(name in obj)) { throw new _exception2['default']('"' + name + '" not defined in ' + obj, { loc: loc }); } return container.lookupProperty(obj, name); }, lookupProperty: function lookupProperty(parent, propertyName) { var result = parent[propertyName]; if (result == null) { return result; } if (Object.prototype.hasOwnProperty.call(parent, propertyName)) { return result; } if (_internalProtoAccess.resultIsAllowed(result, container.protoAccessControl, propertyName)) { return result; } return undefined; }, lookup: function lookup(depths, name) { var len = depths.length; for (var i = 0; i < len; i++) { var result = depths[i] && container.lookupProperty(depths[i], name); if (result != null) { return depths[i][name]; } } }, lambda: function lambda(current, context) { return typeof current === 'function' ? current.call(context) : current; }, escapeExpression: Utils.escapeExpression, invokePartial: invokePartialWrapper, fn: function fn(i) { var ret = templateSpec[i]; ret.decorator = templateSpec[i + '_d']; return ret; }, programs: [], program: function program(i, data, declaredBlockParams, blockParams, depths) { var programWrapper = this.programs[i], fn = this.fn(i); if (data || depths || blockParams || declaredBlockParams) { programWrapper = wrapProgram(this, i, fn, data, declaredBlockParams, blockParams, depths); } else if (!programWrapper) { programWrapper = this.programs[i] = wrapProgram(this, i, fn); } return programWrapper; }, data: function data(value, depth) { while (value && depth--) { value = value._parent; } return value; }, mergeIfNeeded: function mergeIfNeeded(param, common) { var obj = param || common; if (param && common && param !== common) { obj = Utils.extend({}, common, param); } return obj; }, // An empty object to use as replacement for null-contexts nullContext: _Object$seal({}), noop: env.VM.noop, compilerInfo: templateSpec.compiler }; function ret(context) { var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1]; var data = options.data; ret._setup(options); if (!options.partial && templateSpec.useData) { data = initData(context, data); } var depths = undefined, blockParams = templateSpec.useBlockParams ? [] : undefined; if (templateSpec.useDepths) { if (options.depths) { depths = context != options.depths[0] ? [context].concat(options.depths) : options.depths; } else { depths = [context]; } } function main(context /*, options*/) { return '' + templateSpec.main(container, context, container.helpers, container.partials, data, blockParams, depths); } main = executeDecorators(templateSpec.main, main, container, options.depths || [], data, blockParams); return main(context, options); } ret.isTop = true; ret._setup = function (options) { if (!options.partial) { var mergedHelpers = Utils.extend({}, env.helpers, options.helpers); wrapHelpersToPassLookupProperty(mergedHelpers, container); container.helpers = mergedHelpers; if (templateSpec.usePartial) { // Use mergeIfNeeded here to prevent compiling global partials multiple times container.partials = container.mergeIfNeeded(options.partials, env.partials); } if (templateSpec.usePartial || templateSpec.useDecorators) { container.decorators = Utils.extend({}, env.decorators, options.decorators); } container.hooks = {}; container.protoAccessControl = _internalProtoAccess.createProtoAccessControl(options); var keepHelperInHelpers = options.allowCallsToHelperMissing || templateWasPrecompiledWithCompilerV7; _helpers.moveHelperToHooks(container, 'helperMissing', keepHelperInHelpers); _helpers.moveHelperToHooks(container, 'blockHelperMissing', keepHelperInHelpers); } else { container.protoAccessControl = options.protoAccessControl; // internal option container.helpers = options.helpers; container.partials = options.partials; container.decorators = options.decorators; container.hooks = options.hooks; } }; ret._child = function (i, data, blockParams, depths) { if (templateSpec.useBlockParams && !blockParams) { throw new _exception2['default']('must pass block params'); } if (templateSpec.useDepths && !depths) { throw new _exception2['default']('must pass parent depths'); } return wrapProgram(container, i, templateSpec[i], data, 0, blockParams, depths); }; return ret; } function wrapProgram(container, i, fn, data, declaredBlockParams, blockParams, depths) { function prog(context) { var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1]; var currentDepths = depths; if (depths && context != depths[0] && !(context === container.nullContext && depths[0] === null)) { currentDepths = [context].concat(depths); } return fn(container, context, container.helpers, container.partials, options.data || data, blockParams && [options.blockParams].concat(blockParams), currentDepths); } prog = executeDecorators(fn, prog, container, depths, data, blockParams); prog.program = i; prog.depth = depths ? depths.length : 0; prog.blockParams = declaredBlockParams || 0; return prog; } /** * This is currently part of the official API, therefore implementation details should not be changed. */ function resolvePartial(partial, context, options) { if (!partial) { if (options.name === '@partial-block') { partial = options.data['partial-block']; } else { partial = options.partials[options.name]; } } else if (!partial.call && !options.name) { // This is a dynamic partial that returned a string options.name = partial; partial = options.partials[partial]; } return partial; } function invokePartial(partial, context, options) { // Use the current closure context to save the partial-block if this partial var currentPartialBlock = options.data && options.data['partial-block']; options.partial = true; if (options.ids) { options.data.contextPath = options.ids[0] || options.data.contextPath; } var partialBlock = undefined; if (options.fn && options.fn !== noop) { (function () { options.data = _base.createFrame(options.data); // Wrapper function to get access to currentPartialBlock from the closure var fn = options.fn; partialBlock = options.data['partial-block'] = function partialBlockWrapper(context) { var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1]; // Restore the partial-block from the closure for the execution of the block // i.e. the part inside the block of the partial call. options.data = _base.createFrame(options.data); options.data['partial-block'] = currentPartialBlock; return fn(context, options); }; if (fn.partials) { options.partials = Utils.extend({}, options.partials, fn.partials); } })(); } if (partial === undefined && partialBlock) { partial = partialBlock; } if (partial === undefined) { throw new _exception2['default']('The partial ' + options.name + ' could not be found'); } else if (partial instanceof Function) { return partial(context, options); } } function noop() { return ''; } function initData(context, data) { if (!data || !('root' in data)) { data = data ? _base.createFrame(data) : {}; data.root = context; } return data; } function executeDecorators(fn, prog, container, depths, data, blockParams) { if (fn.decorator) { var props = {}; prog = fn.decorator(prog, props, container, depths && depths[0], data, blockParams, depths); Utils.extend(prog, props); } return prog; } function wrapHelpersToPassLookupProperty(mergedHelpers, container) { _Object$keys(mergedHelpers).forEach(function (helperName) { var helper = mergedHelpers[helperName]; mergedHelpers[helperName] = passLookupPropertyOption(helper, container); }); } function passLookupPropertyOption(helper, container) { var lookupProperty = container.lookupProperty; return _internalWrapHelper.wrapHelper(helper, function (options) { return Utils.extend({ lookupProperty: lookupProperty }, options); }); } /***/ }), /* 39 */ /***/ (function(module, exports, __webpack_require__) { module.exports = { "default": __webpack_require__(40), __esModule: true }; /***/ }), /* 40 */ /***/ (function(module, exports, __webpack_require__) { __webpack_require__(41); module.exports = __webpack_require__(21).Object.seal; /***/ }), /* 41 */ /***/ (function(module, exports, __webpack_require__) { // 19.1.2.17 Object.seal(O) var isObject = __webpack_require__(42); __webpack_require__(18)('seal', function($seal){ return function seal(it){ return $seal && isObject(it) ? $seal(it) : it; }; }); /***/ }), /* 42 */ /***/ (function(module, exports) { module.exports = function(it){ return typeof it === 'object' ? it !== null : typeof it === 'function'; }; /***/ }), /* 43 */ /***/ (function(module, exports) { 'use strict'; exports.__esModule = true; exports.wrapHelper = wrapHelper; function wrapHelper(helper, transformOptionsFn) { if (typeof helper !== 'function') { // This should not happen, but apparently it does in https://github.com/wycats/handlebars.js/issues/1639 // We try to make the wrapper least-invasive by not wrapping it, if the helper is not a function. return helper; } var wrapper = function wrapper() /* dynamic arguments */{ var options = arguments[arguments.length - 1]; arguments[arguments.length - 1] = transformOptionsFn(options); return helper.apply(this, arguments); }; return wrapper; } /***/ }), /* 44 */ /***/ (function(module, exports) { /* WEBPACK VAR INJECTION */(function(global) {'use strict'; exports.__esModule = true; exports['default'] = function (Handlebars) { /* istanbul ignore next */ var root = typeof global !== 'undefined' ? global : window, $Handlebars = root.Handlebars; /* istanbul ignore next */ Handlebars.noConflict = function () { if (root.Handlebars === Handlebars) { root.Handlebars = $Handlebars; } return Handlebars; }; }; module.exports = exports['default']; /* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }()))) /***/ }), /* 45 */ /***/ (function(module, exports) { 'use strict'; exports.__esModule = true; var AST = { // Public API used to evaluate derived attributes regarding AST nodes helpers: { // a mustache is definitely a helper if: // * it is an eligible helper, and // * it has at least one parameter or hash segment helperExpression: function helperExpression(node) { return node.type === 'SubExpression' || (node.type === 'MustacheStatement' || node.type === 'BlockStatement') && !!(node.params && node.params.length || node.hash); }, scopedId: function scopedId(path) { return (/^\.|this\b/.test(path.original) ); }, // an ID is simple if it only has one part, and that part is not // `..` or `this`. simpleId: function simpleId(path) { return path.parts.length === 1 && !AST.helpers.scopedId(path) && !path.depth; } } }; // Must be exported as an object rather than the root of the module as the jison lexer // must modify the object to operate properly. exports['default'] = AST; module.exports = exports['default']; /***/ }), /* 46 */ /***/ (function(module, exports, __webpack_require__) { 'use strict'; var _interopRequireDefault = __webpack_require__(1)['default']; var _interopRequireWildcard = __webpack_require__(3)['default']; exports.__esModule = true; exports.parseWithoutProcessing = parseWithoutProcessing; exports.parse = parse; var _parser = __webpack_require__(47); var _parser2 = _interopRequireDefault(_parser); var _whitespaceControl = __webpack_require__(48); var _whitespaceControl2 = _interopRequireDefault(_whitespaceControl); var _helpers = __webpack_require__(50); var Helpers = _interopRequireWildcard(_helpers); var _utils = __webpack_require__(5); exports.parser = _parser2['default']; var yy = {}; _utils.extend(yy, Helpers); function parseWithoutProcessing(input, options) { // Just return if an already-compiled AST was passed in. if (input.type === 'Program') { return input; } _parser2['default'].yy = yy; // Altering the shared object here, but this is ok as parser is a sync operation yy.locInfo = function (locInfo) { return new yy.SourceLocation(options && options.srcName, locInfo); }; var ast = _parser2['default'].parse(input); return ast; } function parse(input, options) { var ast = parseWithoutProcessing(input, options); var strip = new _whitespaceControl2['default'](options); return strip.accept(ast); } /***/ }), /* 47 */ /***/ (function(module, exports) { // File ignored in coverage tests via setting in .istanbul.yml /* Jison generated parser */ "use strict"; exports.__esModule = true; var handlebars = (function () { var parser = { trace: function trace() {}, yy: {}, symbols_: { "error": 2, "root": 3, "program": 4, "EOF": 5, "program_repetition0": 6, "statement": 7, "mustache": 8, "block": 9, "rawBlock": 10, "partial": 11, "partialBlock": 12, "content": 13, "COMMENT": 14, "CONTENT": 15, "openRawBlock": 16, "rawBlock_repetition0": 17, "END_RAW_BLOCK": 18, "OPEN_RAW_BLOCK": 19, "helperName": 20, "openRawBlock_repetition0": 21, "openRawBlock_option0": 22, "CLOSE_RAW_BLOCK": 23, "openBlock": 24, "block_option0": 25, "closeBlock": 26, "openInverse": 27, "block_option1": 28, "OPEN_BLOCK": 29, "openBlock_repetition0": 30, "openBlock_option0": 31, "openBlock_option1": 32, "CLOSE": 33, "OPEN_INVERSE": 34, "openInverse_repetition0": 35, "openInverse_option0": 36, "openInverse_option1": 37, "openInverseChain": 38, "OPEN_INVERSE_CHAIN": 39, "openInverseChain_repetition0": 40, "openInverseChain_option0": 41, "openInverseChain_option1": 42, "inverseAndProgram": 43, "INVERSE": 44, "inverseChain": 45, "inverseChain_option0": 46, "OPEN_ENDBLOCK": 47, "OPEN": 48, "mustache_repetition0": 49, "mustache_option0": 50, "OPEN_UNESCAPED": 51, "mustache_repetition1": 52, "mustache_option1": 53, "CLOSE_UNESCAPED": 54, "OPEN_PARTIAL": 55, "partialName": 56, "partial_repetition0": 57, "partial_option0": 58, "openPartialBlock": 59, "OPEN_PARTIAL_BLOCK": 60, "openPartialBlock_repetition0": 61, "openPartialBlock_option0": 62, "param": 63, "sexpr": 64, "OPEN_SEXPR": 65, "sexpr_repetition0": 66, "sexpr_option0": 67, "CLOSE_SEXPR": 68, "hash": 69, "hash_repetition_plus0": 70, "hashSegment": 71, "ID": 72, "EQUALS": 73, "blockParams": 74, "OPEN_BLOCK_PARAMS": 75, "blockParams_repetition_plus0": 76, "CLOSE_BLOCK_PARAMS": 77, "path": 78, "dataName": 79, "STRING": 80, "NUMBER": 81, "BOOLEAN": 82, "UNDEFINED": 83, "NULL": 84, "DATA": 85, "pathSegments": 86, "SEP": 87, "$accept": 0, "$end": 1 }, terminals_: { 2: "error", 5: "EOF", 14: "COMMENT", 15: "CONTENT", 18: "END_RAW_BLOCK", 19: "OPEN_RAW_BLOCK", 23: "CLOSE_RAW_BLOCK", 29: "OPEN_BLOCK", 33: "CLOSE", 34: "OPEN_INVERSE", 39: "OPEN_INVERSE_CHAIN", 44: "INVERSE", 47: "OPEN_ENDBLOCK", 48: "OPEN", 51: "OPEN_UNESCAPED", 54: "CLOSE_UNESCAPED", 55: "OPEN_PARTIAL", 60: "OPEN_PARTIAL_BLOCK", 65: "OPEN_SEXPR", 68: "CLOSE_SEXPR", 72: "ID", 73: "EQUALS", 75: "OPEN_BLOCK_PARAMS", 77: "CLOSE_BLOCK_PARAMS", 80: "STRING", 81: "NUMBER", 82: "BOOLEAN", 83: "UNDEFINED", 84: "NULL", 85: "DATA", 87: "SEP" }, productions_: [0, [3, 2], [4, 1], [7, 1], [7, 1], [7, 1], [7, 1], [7, 1], [7, 1], [7, 1], [13, 1], [10, 3], [16, 5], [9, 4], [9, 4], [24, 6], [27, 6], [38, 6], [43, 2], [45, 3], [45, 1], [26, 3], [8, 5], [8, 5], [11, 5], [12, 3], [59, 5], [63, 1], [63, 1], [64, 5], [69, 1], [71, 3], [74, 3], [20, 1], [20, 1], [20, 1], [20, 1], [20, 1], [20, 1], [20, 1], [56, 1], [56, 1], [79, 2], [78, 1], [86, 3], [86, 1], [6, 0], [6, 2], [17, 0], [17, 2], [21, 0], [21, 2], [22, 0], [22, 1], [25, 0], [25, 1], [28, 0], [28, 1], [30, 0], [30, 2], [31, 0], [31, 1], [32, 0], [32, 1], [35, 0], [35, 2], [36, 0], [36, 1], [37, 0], [37, 1], [40, 0], [40, 2], [41, 0], [41, 1], [42, 0], [42, 1], [46, 0], [46, 1], [49, 0], [49, 2], [50, 0], [50, 1], [52, 0], [52, 2], [53, 0], [53, 1], [57, 0], [57, 2], [58, 0], [58, 1], [61, 0], [61, 2], [62, 0], [62, 1], [66, 0], [66, 2], [67, 0], [67, 1], [70, 1], [70, 2], [76, 1], [76, 2]], performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate, $$, _$) { var $0 = $$.length - 1; switch (yystate) { case 1: return $$[$0 - 1]; break; case 2: this.$ = yy.prepareProgram($$[$0]); break; case 3: this.$ = $$[$0]; break; case 4: this.$ = $$[$0]; break; case 5: this.$ = $$[$0]; break; case 6: this.$ = $$[$0]; break; case 7: this.$ = $$[$0]; break; case 8: this.$ = $$[$0]; break; case 9: this.$ = { type: 'CommentStatement', value: yy.stripComment($$[$0]), strip: yy.stripFlags($$[$0], $$[$0]), loc: yy.locInfo(this._$) }; break; case 10: this.$ = { type: 'ContentStatement', original: $$[$0], value: $$[$0], loc: yy.locInfo(this._$) }; break; case 11: this.$ = yy.prepareRawBlock($$[$0 - 2], $$[$0 - 1], $$[$0], this._$); break; case 12: this.$ = { path: $$[$0 - 3], params: $$[$0 - 2], hash: $$[$0 - 1] }; break; case 13: this.$ = yy.prepareBlock($$[$0 - 3], $$[$0 - 2], $$[$0 - 1], $$[$0], false, this._$); break; case 14: this.$ = yy.prepareBlock($$[$0 - 3], $$[$0 - 2], $$[$0 - 1], $$[$0], true, this._$); break; case 15: this.$ = { open: $$[$0 - 5], path: $$[$0 - 4], params: $$[$0 - 3], hash: $$[$0 - 2], blockParams: $$[$0 - 1], strip: yy.stripFlags($$[$0 - 5], $$[$0]) }; break; case 16: this.$ = { path: $$[$0 - 4], params: $$[$0 - 3], hash: $$[$0 - 2], blockParams: $$[$0 - 1], strip: yy.stripFlags($$[$0 - 5], $$[$0]) }; break; case 17: this.$ = { path: $$[$0 - 4], params: $$[$0 - 3], hash: $$[$0 - 2], blockParams: $$[$0 - 1], strip: yy.stripFlags($$[$0 - 5], $$[$0]) }; break; case 18: this.$ = { strip: yy.stripFlags($$[$0 - 1], $$[$0 - 1]), program: $$[$0] }; break; case 19: var inverse = yy.prepareBlock($$[$0 - 2], $$[$0 - 1], $$[$0], $$[$0], false, this._$), program = yy.prepareProgram([inverse], $$[$0 - 1].loc); program.chained = true; this.$ = { strip: $$[$0 - 2].strip, program: program, chain: true }; break; case 20: this.$ = $$[$0]; break; case 21: this.$ = { path: $$[$0 - 1], strip: yy.stripFlags($$[$0 - 2], $$[$0]) }; break; case 22: this.$ = yy.prepareMustache($$[$0 - 3], $$[$0 - 2], $$[$0 - 1], $$[$0 - 4], yy.stripFlags($$[$0 - 4], $$[$0]), this._$); break; case 23: this.$ = yy.prepareMustache($$[$0 - 3], $$[$0 - 2], $$[$0 - 1], $$[$0 - 4], yy.stripFlags($$[$0 - 4], $$[$0]), this._$); break; case 24: this.$ = { type: 'PartialStatement', name: $$[$0 - 3], params: $$[$0 - 2], hash: $$[$0 - 1], indent: '', strip: yy.stripFlags($$[$0 - 4], $$[$0]), loc: yy.locInfo(this._$) }; break; case 25: this.$ = yy.preparePartialBlock($$[$0 - 2], $$[$0 - 1], $$[$0], this._$); break; case 26: this.$ = { path: $$[$0 - 3], params: $$[$0 - 2], hash: $$[$0 - 1], strip: yy.stripFlags($$[$0 - 4], $$[$0]) }; break; case 27: this.$ = $$[$0]; break; case 28: this.$ = $$[$0]; break; case 29: this.$ = { type: 'SubExpression', path: $$[$0 - 3], params: $$[$0 - 2], hash: $$[$0 - 1], loc: yy.locInfo(this._$) }; break; case 30: this.$ = { type: 'Hash', pairs: $$[$0], loc: yy.locInfo(this._$) }; break; case 31: this.$ = { type: 'HashPair', key: yy.id($$[$0 - 2]), value: $$[$0], loc: yy.locInfo(this._$) }; break; case 32: this.$ = yy.id($$[$0 - 1]); break; case 33: this.$ = $$[$0]; break; case 34: this.$ = $$[$0]; break; case 35: this.$ = { type: 'StringLiteral', value: $$[$0], original: $$[$0], loc: yy.locInfo(this._$) }; break; case 36: this.$ = { type: 'NumberLiteral', value: Number($$[$0]), original: Number($$[$0]), loc: yy.locInfo(this._$) }; break; case 37: this.$ = { type: 'BooleanLiteral', value: $$[$0] === 'true', original: $$[$0] === 'true', loc: yy.locInfo(this._$) }; break; case 38: this.$ = { type: 'UndefinedLiteral', original: undefined, value: undefined, loc: yy.locInfo(this._$) }; break; case 39: this.$ = { type: 'NullLiteral', original: null, value: null, loc: yy.locInfo(this._$) }; break; case 40: this.$ = $$[$0]; break; case 41: this.$ = $$[$0]; break; case 42: this.$ = yy.preparePath(true, $$[$0], this._$); break; case 43: this.$ = yy.preparePath(false, $$[$0], this._$); break; case 44: $$[$0 - 2].push({ part: yy.id($$[$0]), original: $$[$0], separator: $$[$0 - 1] });this.$ = $$[$0 - 2]; break; case 45: this.$ = [{ part: yy.id($$[$0]), original: $$[$0] }]; break; case 46: this.$ = []; break; case 47: $$[$0 - 1].push($$[$0]); break; case 48: this.$ = []; break; case 49: $$[$0 - 1].push($$[$0]); break; case 50: this.$ = []; break; case 51: $$[$0 - 1].push($$[$0]); break; case 58: this.$ = []; break; case 59: $$[$0 - 1].push($$[$0]); break; case 64: this.$ = []; break; case 65: $$[$0 - 1].push($$[$0]); break; case 70: this.$ = []; break; case 71: $$[$0 - 1].push($$[$0]); break; case 78: this.$ = []; break; case 79: $$[$0 - 1].push($$[$0]); break; case 82: this.$ = []; break; case 83: $$[$0 - 1].push($$[$0]); break; case 86: this.$ = []; break; case 87: $$[$0 - 1].push($$[$0]); break; case 90: this.$ = []; break; case 91: $$[$0 - 1].push($$[$0]); break; case 94: this.$ = []; break; case 95: $$[$0 - 1].push($$[$0]); break; case 98: this.$ = [$$[$0]]; break; case 99: $$[$0 - 1].push($$[$0]); break; case 100: this.$ = [$$[$0]]; break; case 101: $$[$0 - 1].push($$[$0]); break; } }, table: [{ 3: 1, 4: 2, 5: [2, 46], 6: 3, 14: [2, 46], 15: [2, 46], 19: [2, 46], 29: [2, 46], 34: [2, 46], 48: [2, 46], 51: [2, 46], 55: [2, 46], 60: [2, 46] }, { 1: [3] }, { 5: [1, 4] }, { 5: [2, 2], 7: 5, 8: 6, 9: 7, 10: 8, 11: 9, 12: 10, 13: 11, 14: [1, 12], 15: [1, 20], 16: 17, 19: [1, 23], 24: 15, 27: 16, 29: [1, 21], 34: [1, 22], 39: [2, 2], 44: [2, 2], 47: [2, 2], 48: [1, 13], 51: [1, 14], 55: [1, 18], 59: 19, 60: [1, 24] }, { 1: [2, 1] }, { 5: [2, 47], 14: [2, 47], 15: [2, 47], 19: [2, 47], 29: [2, 47], 34: [2, 47], 39: [2, 47], 44: [2, 47], 47: [2, 47], 48: [2, 47], 51: [2, 47], 55: [2, 47], 60: [2, 47] }, { 5: [2, 3], 14: [2, 3], 15: [2, 3], 19: [2, 3], 29: [2, 3], 34: [2, 3], 39: [2, 3], 44: [2, 3], 47: [2, 3], 48: [2, 3], 51: [2, 3], 55: [2, 3], 60: [2, 3] }, { 5: [2, 4], 14: [2, 4], 15: [2, 4], 19: [2, 4], 29: [2, 4], 34: [2, 4], 39: [2, 4], 44: [2, 4], 47: [2, 4], 48: [2, 4], 51: [2, 4], 55: [2, 4], 60: [2, 4] }, { 5: [2, 5], 14: [2, 5], 15: [2, 5], 19: [2, 5], 29: [2, 5], 34: [2, 5], 39: [2, 5], 44: [2, 5], 47: [2, 5], 48: [2, 5], 51: [2, 5], 55: [2, 5], 60: [2, 5] }, { 5: [2, 6], 14: [2, 6], 15: [2, 6], 19: [2, 6], 29: [2, 6], 34: [2, 6], 39: [2, 6], 44: [2, 6], 47: [2, 6], 48: [2, 6], 51: [2, 6], 55: [2, 6], 60: [2, 6] }, { 5: [2, 7], 14: [2, 7], 15: [2, 7], 19: [2, 7], 29: [2, 7], 34: [2, 7], 39: [2, 7], 44: [2, 7], 47: [2, 7], 48: [2, 7], 51: [2, 7], 55: [2, 7], 60: [2, 7] }, { 5: [2, 8], 14: [2, 8], 15: [2, 8], 19: [2, 8], 29: [2, 8], 34: [2, 8], 39: [2, 8], 44: [2, 8], 47: [2, 8], 48: [2, 8], 51: [2, 8], 55: [2, 8], 60: [2, 8] }, { 5: [2, 9], 14: [2, 9], 15: [2, 9], 19: [2, 9], 29: [2, 9], 34: [2, 9], 39: [2, 9], 44: [2, 9], 47: [2, 9], 48: [2, 9], 51: [2, 9], 55: [2, 9], 60: [2, 9] }, { 20: 25, 72: [1, 35], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 20: 36, 72: [1, 35], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 4: 37, 6: 3, 14: [2, 46], 15: [2, 46], 19: [2, 46], 29: [2, 46], 34: [2, 46], 39: [2, 46], 44: [2, 46], 47: [2, 46], 48: [2, 46], 51: [2, 46], 55: [2, 46], 60: [2, 46] }, { 4: 38, 6: 3, 14: [2, 46], 15: [2, 46], 19: [2, 46], 29: [2, 46], 34: [2, 46], 44: [2, 46], 47: [2, 46], 48: [2, 46], 51: [2, 46], 55: [2, 46], 60: [2, 46] }, { 15: [2, 48], 17: 39, 18: [2, 48] }, { 20: 41, 56: 40, 64: 42, 65: [1, 43], 72: [1, 35], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 4: 44, 6: 3, 14: [2, 46], 15: [2, 46], 19: [2, 46], 29: [2, 46], 34: [2, 46], 47: [2, 46], 48: [2, 46], 51: [2, 46], 55: [2, 46], 60: [2, 46] }, { 5: [2, 10], 14: [2, 10], 15: [2, 10], 18: [2, 10], 19: [2, 10], 29: [2, 10], 34: [2, 10], 39: [2, 10], 44: [2, 10], 47: [2, 10], 48: [2, 10], 51: [2, 10], 55: [2, 10], 60: [2, 10] }, { 20: 45, 72: [1, 35], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 20: 46, 72: [1, 35], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 20: 47, 72: [1, 35], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 20: 41, 56: 48, 64: 42, 65: [1, 43], 72: [1, 35], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 33: [2, 78], 49: 49, 65: [2, 78], 72: [2, 78], 80: [2, 78], 81: [2, 78], 82: [2, 78], 83: [2, 78], 84: [2, 78], 85: [2, 78] }, { 23: [2, 33], 33: [2, 33], 54: [2, 33], 65: [2, 33], 68: [2, 33], 72: [2, 33], 75: [2, 33], 80: [2, 33], 81: [2, 33], 82: [2, 33], 83: [2, 33], 84: [2, 33], 85: [2, 33] }, { 23: [2, 34], 33: [2, 34], 54: [2, 34], 65: [2, 34], 68: [2, 34], 72: [2, 34], 75: [2, 34], 80: [2, 34], 81: [2, 34], 82: [2, 34], 83: [2, 34], 84: [2, 34], 85: [2, 34] }, { 23: [2, 35], 33: [2, 35], 54: [2, 35], 65: [2, 35], 68: [2, 35], 72: [2, 35], 75: [2, 35], 80: [2, 35], 81: [2, 35], 82: [2, 35], 83: [2, 35], 84: [2, 35], 85: [2, 35] }, { 23: [2, 36], 33: [2, 36], 54: [2, 36], 65: [2, 36], 68: [2, 36], 72: [2, 36], 75: [2, 36], 80: [2, 36], 81: [2, 36], 82: [2, 36], 83: [2, 36], 84: [2, 36], 85: [2, 36] }, { 23: [2, 37], 33: [2, 37], 54: [2, 37], 65: [2, 37], 68: [2, 37], 72: [2, 37], 75: [2, 37], 80: [2, 37], 81: [2, 37], 82: [2, 37], 83: [2, 37], 84: [2, 37], 85: [2, 37] }, { 23: [2, 38], 33: [2, 38], 54: [2, 38], 65: [2, 38], 68: [2, 38], 72: [2, 38], 75: [2, 38], 80: [2, 38], 81: [2, 38], 82: [2, 38], 83: [2, 38], 84: [2, 38], 85: [2, 38] }, { 23: [2, 39], 33: [2, 39], 54: [2, 39], 65: [2, 39], 68: [2, 39], 72: [2, 39], 75: [2, 39], 80: [2, 39], 81: [2, 39], 82: [2, 39], 83: [2, 39], 84: [2, 39], 85: [2, 39] }, { 23: [2, 43], 33: [2, 43], 54: [2, 43], 65: [2, 43], 68: [2, 43], 72: [2, 43], 75: [2, 43], 80: [2, 43], 81: [2, 43], 82: [2, 43], 83: [2, 43], 84: [2, 43], 85: [2, 43], 87: [1, 50] }, { 72: [1, 35], 86: 51 }, { 23: [2, 45], 33: [2, 45], 54: [2, 45], 65: [2, 45], 68: [2, 45], 72: [2, 45], 75: [2, 45], 80: [2, 45], 81: [2, 45], 82: [2, 45], 83: [2, 45], 84: [2, 45], 85: [2, 45], 87: [2, 45] }, { 52: 52, 54: [2, 82], 65: [2, 82], 72: [2, 82], 80: [2, 82], 81: [2, 82], 82: [2, 82], 83: [2, 82], 84: [2, 82], 85: [2, 82] }, { 25: 53, 38: 55, 39: [1, 57], 43: 56, 44: [1, 58], 45: 54, 47: [2, 54] }, { 28: 59, 43: 60, 44: [1, 58], 47: [2, 56] }, { 13: 62, 15: [1, 20], 18: [1, 61] }, { 33: [2, 86], 57: 63, 65: [2, 86], 72: [2, 86], 80: [2, 86], 81: [2, 86], 82: [2, 86], 83: [2, 86], 84: [2, 86], 85: [2, 86] }, { 33: [2, 40], 65: [2, 40], 72: [2, 40], 80: [2, 40], 81: [2, 40], 82: [2, 40], 83: [2, 40], 84: [2, 40], 85: [2, 40] }, { 33: [2, 41], 65: [2, 41], 72: [2, 41], 80: [2, 41], 81: [2, 41], 82: [2, 41], 83: [2, 41], 84: [2, 41], 85: [2, 41] }, { 20: 64, 72: [1, 35], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 26: 65, 47: [1, 66] }, { 30: 67, 33: [2, 58], 65: [2, 58], 72: [2, 58], 75: [2, 58], 80: [2, 58], 81: [2, 58], 82: [2, 58], 83: [2, 58], 84: [2, 58], 85: [2, 58] }, { 33: [2, 64], 35: 68, 65: [2, 64], 72: [2, 64], 75: [2, 64], 80: [2, 64], 81: [2, 64], 82: [2, 64], 83: [2, 64], 84: [2, 64], 85: [2, 64] }, { 21: 69, 23: [2, 50], 65: [2, 50], 72: [2, 50], 80: [2, 50], 81: [2, 50], 82: [2, 50], 83: [2, 50], 84: [2, 50], 85: [2, 50] }, { 33: [2, 90], 61: 70, 65: [2, 90], 72: [2, 90], 80: [2, 90], 81: [2, 90], 82: [2, 90], 83: [2, 90], 84: [2, 90], 85: [2, 90] }, { 20: 74, 33: [2, 80], 50: 71, 63: 72, 64: 75, 65: [1, 43], 69: 73, 70: 76, 71: 77, 72: [1, 78], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 72: [1, 79] }, { 23: [2, 42], 33: [2, 42], 54: [2, 42], 65: [2, 42], 68: [2, 42], 72: [2, 42], 75: [2, 42], 80: [2, 42], 81: [2, 42], 82: [2, 42], 83: [2, 42], 84: [2, 42], 85: [2, 42], 87: [1, 50] }, { 20: 74, 53: 80, 54: [2, 84], 63: 81, 64: 75, 65: [1, 43], 69: 82, 70: 76, 71: 77, 72: [1, 78], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 26: 83, 47: [1, 66] }, { 47: [2, 55] }, { 4: 84, 6: 3, 14: [2, 46], 15: [2, 46], 19: [2, 46], 29: [2, 46], 34: [2, 46], 39: [2, 46], 44: [2, 46], 47: [2, 46], 48: [2, 46], 51: [2, 46], 55: [2, 46], 60: [2, 46] }, { 47: [2, 20] }, { 20: 85, 72: [1, 35], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 4: 86, 6: 3, 14: [2, 46], 15: [2, 46], 19: [2, 46], 29: [2, 46], 34: [2, 46], 47: [2, 46], 48: [2, 46], 51: [2, 46], 55: [2, 46], 60: [2, 46] }, { 26: 87, 47: [1, 66] }, { 47: [2, 57] }, { 5: [2, 11], 14: [2, 11], 15: [2, 11], 19: [2, 11], 29: [2, 11], 34: [2, 11], 39: [2, 11], 44: [2, 11], 47: [2, 11], 48: [2, 11], 51: [2, 11], 55: [2, 11], 60: [2, 11] }, { 15: [2, 49], 18: [2, 49] }, { 20: 74, 33: [2, 88], 58: 88, 63: 89, 64: 75, 65: [1, 43], 69: 90, 70: 76, 71: 77, 72: [1, 78], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 65: [2, 94], 66: 91, 68: [2, 94], 72: [2, 94], 80: [2, 94], 81: [2, 94], 82: [2, 94], 83: [2, 94], 84: [2, 94], 85: [2, 94] }, { 5: [2, 25], 14: [2, 25], 15: [2, 25], 19: [2, 25], 29: [2, 25], 34: [2, 25], 39: [2, 25], 44: [2, 25], 47: [2, 25], 48: [2, 25], 51: [2, 25], 55: [2, 25], 60: [2, 25] }, { 20: 92, 72: [1, 35], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 20: 74, 31: 93, 33: [2, 60], 63: 94, 64: 75, 65: [1, 43], 69: 95, 70: 76, 71: 77, 72: [1, 78], 75: [2, 60], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 20: 74, 33: [2, 66], 36: 96, 63: 97, 64: 75, 65: [1, 43], 69: 98, 70: 76, 71: 77, 72: [1, 78], 75: [2, 66], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 20: 74, 22: 99, 23: [2, 52], 63: 100, 64: 75, 65: [1, 43], 69: 101, 70: 76, 71: 77, 72: [1, 78], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 20: 74, 33: [2, 92], 62: 102, 63: 103, 64: 75, 65: [1, 43], 69: 104, 70: 76, 71: 77, 72: [1, 78], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 33: [1, 105] }, { 33: [2, 79], 65: [2, 79], 72: [2, 79], 80: [2, 79], 81: [2, 79], 82: [2, 79], 83: [2, 79], 84: [2, 79], 85: [2, 79] }, { 33: [2, 81] }, { 23: [2, 27], 33: [2, 27], 54: [2, 27], 65: [2, 27], 68: [2, 27], 72: [2, 27], 75: [2, 27], 80: [2, 27], 81: [2, 27], 82: [2, 27], 83: [2, 27], 84: [2, 27], 85: [2, 27] }, { 23: [2, 28], 33: [2, 28], 54: [2, 28], 65: [2, 28], 68: [2, 28], 72: [2, 28], 75: [2, 28], 80: [2, 28], 81: [2, 28], 82: [2, 28], 83: [2, 28], 84: [2, 28], 85: [2, 28] }, { 23: [2, 30], 33: [2, 30], 54: [2, 30], 68: [2, 30], 71: 106, 72: [1, 107], 75: [2, 30] }, { 23: [2, 98], 33: [2, 98], 54: [2, 98], 68: [2, 98], 72: [2, 98], 75: [2, 98] }, { 23: [2, 45], 33: [2, 45], 54: [2, 45], 65: [2, 45], 68: [2, 45], 72: [2, 45], 73: [1, 108], 75: [2, 45], 80: [2, 45], 81: [2, 45], 82: [2, 45], 83: [2, 45], 84: [2, 45], 85: [2, 45], 87: [2, 45] }, { 23: [2, 44], 33: [2, 44], 54: [2, 44], 65: [2, 44], 68: [2, 44], 72: [2, 44], 75: [2, 44], 80: [2, 44], 81: [2, 44], 82: [2, 44], 83: [2, 44], 84: [2, 44], 85: [2, 44], 87: [2, 44] }, { 54: [1, 109] }, { 54: [2, 83], 65: [2, 83], 72: [2, 83], 80: [2, 83], 81: [2, 83], 82: [2, 83], 83: [2, 83], 84: [2, 83], 85: [2, 83] }, { 54: [2, 85] }, { 5: [2, 13], 14: [2, 13], 15: [2, 13], 19: [2, 13], 29: [2, 13], 34: [2, 13], 39: [2, 13], 44: [2, 13], 47: [2, 13], 48: [2, 13], 51: [2, 13], 55: [2, 13], 60: [2, 13] }, { 38: 55, 39: [1, 57], 43: 56, 44: [1, 58], 45: 111, 46: 110, 47: [2, 76] }, { 33: [2, 70], 40: 112, 65: [2, 70], 72: [2, 70], 75: [2, 70], 80: [2, 70], 81: [2, 70], 82: [2, 70], 83: [2, 70], 84: [2, 70], 85: [2, 70] }, { 47: [2, 18] }, { 5: [2, 14], 14: [2, 14], 15: [2, 14], 19: [2, 14], 29: [2, 14], 34: [2, 14], 39: [2, 14], 44: [2, 14], 47: [2, 14], 48: [2, 14], 51: [2, 14], 55: [2, 14], 60: [2, 14] }, { 33: [1, 113] }, { 33: [2, 87], 65: [2, 87], 72: [2, 87], 80: [2, 87], 81: [2, 87], 82: [2, 87], 83: [2, 87], 84: [2, 87], 85: [2, 87] }, { 33: [2, 89] }, { 20: 74, 63: 115, 64: 75, 65: [1, 43], 67: 114, 68: [2, 96], 69: 116, 70: 76, 71: 77, 72: [1, 78], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 33: [1, 117] }, { 32: 118, 33: [2, 62], 74: 119, 75: [1, 120] }, { 33: [2, 59], 65: [2, 59], 72: [2, 59], 75: [2, 59], 80: [2, 59], 81: [2, 59], 82: [2, 59], 83: [2, 59], 84: [2, 59], 85: [2, 59] }, { 33: [2, 61], 75: [2, 61] }, { 33: [2, 68], 37: 121, 74: 122, 75: [1, 120] }, { 33: [2, 65], 65: [2, 65], 72: [2, 65], 75: [2, 65], 80: [2, 65], 81: [2, 65], 82: [2, 65], 83: [2, 65], 84: [2, 65], 85: [2, 65] }, { 33: [2, 67], 75: [2, 67] }, { 23: [1, 123] }, { 23: [2, 51], 65: [2, 51], 72: [2, 51], 80: [2, 51], 81: [2, 51], 82: [2, 51], 83: [2, 51], 84: [2, 51], 85: [2, 51] }, { 23: [2, 53] }, { 33: [1, 124] }, { 33: [2, 91], 65: [2, 91], 72: [2, 91], 80: [2, 91], 81: [2, 91], 82: [2, 91], 83: [2, 91], 84: [2, 91], 85: [2, 91] }, { 33: [2, 93] }, { 5: [2, 22], 14: [2, 22], 15: [2, 22], 19: [2, 22], 29: [2, 22], 34: [2, 22], 39: [2, 22], 44: [2, 22], 47: [2, 22], 48: [2, 22], 51: [2, 22], 55: [2, 22], 60: [2, 22] }, { 23: [2, 99], 33: [2, 99], 54: [2, 99], 68: [2, 99], 72: [2, 99], 75: [2, 99] }, { 73: [1, 108] }, { 20: 74, 63: 125, 64: 75, 65: [1, 43], 72: [1, 35], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 5: [2, 23], 14: [2, 23], 15: [2, 23], 19: [2, 23], 29: [2, 23], 34: [2, 23], 39: [2, 23], 44: [2, 23], 47: [2, 23], 48: [2, 23], 51: [2, 23], 55: [2, 23], 60: [2, 23] }, { 47: [2, 19] }, { 47: [2, 77] }, { 20: 74, 33: [2, 72], 41: 126, 63: 127, 64: 75, 65: [1, 43], 69: 128, 70: 76, 71: 77, 72: [1, 78], 75: [2, 72], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 5: [2, 24], 14: [2, 24], 15: [2, 24], 19: [2, 24], 29: [2, 24], 34: [2, 24], 39: [2, 24], 44: [2, 24], 47: [2, 24], 48: [2, 24], 51: [2, 24], 55: [2, 24], 60: [2, 24] }, { 68: [1, 129] }, { 65: [2, 95], 68: [2, 95], 72: [2, 95], 80: [2, 95], 81: [2, 95], 82: [2, 95], 83: [2, 95], 84: [2, 95], 85: [2, 95] }, { 68: [2, 97] }, { 5: [2, 21], 14: [2, 21], 15: [2, 21], 19: [2, 21], 29: [2, 21], 34: [2, 21], 39: [2, 21], 44: [2, 21], 47: [2, 21], 48: [2, 21], 51: [2, 21], 55: [2, 21], 60: [2, 21] }, { 33: [1, 130] }, { 33: [2, 63] }, { 72: [1, 132], 76: 131 }, { 33: [1, 133] }, { 33: [2, 69] }, { 15: [2, 12], 18: [2, 12] }, { 14: [2, 26], 15: [2, 26], 19: [2, 26], 29: [2, 26], 34: [2, 26], 47: [2, 26], 48: [2, 26], 51: [2, 26], 55: [2, 26], 60: [2, 26] }, { 23: [2, 31], 33: [2, 31], 54: [2, 31], 68: [2, 31], 72: [2, 31], 75: [2, 31] }, { 33: [2, 74], 42: 134, 74: 135, 75: [1, 120] }, { 33: [2, 71], 65: [2, 71], 72: [2, 71], 75: [2, 71], 80: [2, 71], 81: [2, 71], 82: [2, 71], 83: [2, 71], 84: [2, 71], 85: [2, 71] }, { 33: [2, 73], 75: [2, 73] }, { 23: [2, 29], 33: [2, 29], 54: [2, 29], 65: [2, 29], 68: [2, 29], 72: [2, 29], 75: [2, 29], 80: [2, 29], 81: [2, 29], 82: [2, 29], 83: [2, 29], 84: [2, 29], 85: [2, 29] }, { 14: [2, 15], 15: [2, 15], 19: [2, 15], 29: [2, 15], 34: [2, 15], 39: [2, 15], 44: [2, 15], 47: [2, 15], 48: [2, 15], 51: [2, 15], 55: [2, 15], 60: [2, 15] }, { 72: [1, 137], 77: [1, 136] }, { 72: [2, 100], 77: [2, 100] }, { 14: [2, 16], 15: [2, 16], 19: [2, 16], 29: [2, 16], 34: [2, 16], 44: [2, 16], 47: [2, 16], 48: [2, 16], 51: [2, 16], 55: [2, 16], 60: [2, 16] }, { 33: [1, 138] }, { 33: [2, 75] }, { 33: [2, 32] }, { 72: [2, 101], 77: [2, 101] }, { 14: [2, 17], 15: [2, 17], 19: [2, 17], 29: [2, 17], 34: [2, 17], 39: [2, 17], 44: [2, 17], 47: [2, 17], 48: [2, 17], 51: [2, 17], 55: [2, 17], 60: [2, 17] }], defaultActions: { 4: [2, 1], 54: [2, 55], 56: [2, 20], 60: [2, 57], 73: [2, 81], 82: [2, 85], 86: [2, 18], 90: [2, 89], 101: [2, 53], 104: [2, 93], 110: [2, 19], 111: [2, 77], 116: [2, 97], 119: [2, 63], 122: [2, 69], 135: [2, 75], 136: [2, 32] }, parseError: function parseError(str, hash) { throw new Error(str); }, parse: function parse(input) { var self = this, stack = [0], vstack = [null], lstack = [], table = this.table, yytext = "", yylineno = 0, yyleng = 0, recovering = 0, TERROR = 2, EOF = 1; this.lexer.setInput(input); this.lexer.yy = this.yy; this.yy.lexer = this.lexer; this.yy.parser = this; if (typeof this.lexer.yylloc == "undefined") this.lexer.yylloc = {}; var yyloc = this.lexer.yylloc; lstack.push(yyloc); var ranges = this.lexer.options && this.lexer.options.ranges; if (typeof this.yy.parseError === "function") this.parseError = this.yy.parseError; function popStack(n) { stack.length = stack.length - 2 * n; vstack.length = vstack.length - n; lstack.length = lstack.length - n; } function lex() { var token; token = self.lexer.lex() || 1; if (typeof token !== "number") { token = self.symbols_[token] || token; } return token; } var symbol, preErrorSymbol, state, action, a, r, yyval = {}, p, len, newState, expected; while (true) { state = stack[stack.length - 1]; if (this.defaultActions[state]) { action = this.defaultActions[state]; } else { if (symbol === null || typeof symbol == "undefined") { symbol = lex(); } action = table[state] && table[state][symbol]; } if (typeof action === "undefined" || !action.length || !action[0]) { var errStr = ""; if (!recovering) { expected = []; for (p in table[state]) if (this.terminals_[p] && p > 2) { expected.push("'" + this.terminals_[p] + "'"); } if (this.lexer.showPosition) { errStr = "Parse error on line " + (yylineno + 1) + ":\n" + this.lexer.showPosition() + "\nExpecting " + expected.join(", ") + ", got '" + (this.terminals_[symbol] || symbol) + "'"; } else { errStr = "Parse error on line " + (yylineno + 1) + ": Unexpected " + (symbol == 1 ? "end of input" : "'" + (this.terminals_[symbol] || symbol) + "'"); } this.parseError(errStr, { text: this.lexer.match, token: this.terminals_[symbol] || symbol, line: this.lexer.yylineno, loc: yyloc, expected: expected }); } } if (action[0] instanceof Array && action.length > 1) { throw new Error("Parse Error: multiple actions possible at state: " + state + ", token: " + symbol); } switch (action[0]) { case 1: stack.push(symbol); vstack.push(this.lexer.yytext); lstack.push(this.lexer.yylloc); stack.push(action[1]); symbol = null; if (!preErrorSymbol) { yyleng = this.lexer.yyleng; yytext = this.lexer.yytext; yylineno = this.lexer.yylineno; yyloc = this.lexer.yylloc; if (recovering > 0) recovering--; } else { symbol = preErrorSymbol; preErrorSymbol = null; } break; case 2: len = this.productions_[action[1]][1]; yyval.$ = vstack[vstack.length - len]; yyval._$ = { first_line: lstack[lstack.length - (len || 1)].first_line, last_line: lstack[lstack.length - 1].last_line, first_column: lstack[lstack.length - (len || 1)].first_column, last_column: lstack[lstack.length - 1].last_column }; if (ranges) { yyval._$.range = [lstack[lstack.length - (len || 1)].range[0], lstack[lstack.length - 1].range[1]]; } r = this.performAction.call(yyval, yytext, yyleng, yylineno, this.yy, action[1], vstack, lstack); if (typeof r !== "undefined") { return r; } if (len) { stack = stack.slice(0, -1 * len * 2); vstack = vstack.slice(0, -1 * len); lstack = lstack.slice(0, -1 * len); } stack.push(this.productions_[action[1]][0]); vstack.push(yyval.$); lstack.push(yyval._$); newState = table[stack[stack.length - 2]][stack[stack.length - 1]]; stack.push(newState); break; case 3: return true; } } return true; } }; /* Jison generated lexer */ var lexer = (function () { var lexer = { EOF: 1, parseError: function parseError(str, hash) { if (this.yy.parser) { this.yy.parser.parseError(str, hash); } else { throw new Error(str); } }, setInput: function setInput(input) { this._input = input; this._more = this._less = this.done = false; this.yylineno = this.yyleng = 0; this.yytext = this.matched = this.match = ''; this.conditionStack = ['INITIAL']; this.yylloc = { first_line: 1, first_column: 0, last_line: 1, last_column: 0 }; if (this.options.ranges) this.yylloc.range = [0, 0]; this.offset = 0; return this; }, input: function input() { var ch = this._input[0]; this.yytext += ch; this.yyleng++; this.offset++; this.match += ch; this.matched += ch; var lines = ch.match(/(?:\r\n?|\n).*/g); if (lines) { this.yylineno++; this.yylloc.last_line++; } else { this.yylloc.last_column++; } if (this.options.ranges) this.yylloc.range[1]++; this._input = this._input.slice(1); return ch; }, unput: function unput(ch) { var len = ch.length; var lines = ch.split(/(?:\r\n?|\n)/g); this._input = ch + this._input; this.yytext = this.yytext.substr(0, this.yytext.length - len - 1); //this.yyleng -= len; this.offset -= len; var oldLines = this.match.split(/(?:\r\n?|\n)/g); this.match = this.match.substr(0, this.match.length - 1); this.matched = this.matched.substr(0, this.matched.length - 1); if (lines.length - 1) this.yylineno -= lines.length - 1; var r = this.yylloc.range; this.yylloc = { first_line: this.yylloc.first_line, last_line: this.yylineno + 1, first_column: this.yylloc.first_column, last_column: lines ? (lines.length === oldLines.length ? this.yylloc.first_column : 0) + oldLines[oldLines.length - lines.length].length - lines[0].length : this.yylloc.first_column - len }; if (this.options.ranges) { this.yylloc.range = [r[0], r[0] + this.yyleng - len]; } return this; }, more: function more() { this._more = true; return this; }, less: function less(n) { this.unput(this.match.slice(n)); }, pastInput: function pastInput() { var past = this.matched.substr(0, this.matched.length - this.match.length); return (past.length > 20 ? '...' : '') + past.substr(-20).replace(/\n/g, ""); }, upcomingInput: function upcomingInput() { var next = this.match; if (next.length < 20) { next += this._input.substr(0, 20 - next.length); } return (next.substr(0, 20) + (next.length > 20 ? '...' : '')).replace(/\n/g, ""); }, showPosition: function showPosition() { var pre = this.pastInput(); var c = new Array(pre.length + 1).join("-"); return pre + this.upcomingInput() + "\n" + c + "^"; }, next: function next() { if (this.done) { return this.EOF; } if (!this._input) this.done = true; var token, match, tempMatch, index, col, lines; if (!this._more) { this.yytext = ''; this.match = ''; } var rules = this._currentRules(); for (var i = 0; i < rules.length; i++) { tempMatch = this._input.match(this.rules[rules[i]]); if (tempMatch && (!match || tempMatch[0].length > match[0].length)) { match = tempMatch; index = i; if (!this.options.flex) break; } } if (match) { lines = match[0].match(/(?:\r\n?|\n).*/g); if (lines) this.yylineno += lines.length; this.yylloc = { first_line: this.yylloc.last_line, last_line: this.yylineno + 1, first_column: this.yylloc.last_column, last_column: lines ? lines[lines.length - 1].length - lines[lines.length - 1].match(/\r?\n?/)[0].length : this.yylloc.last_column + match[0].length }; this.yytext += match[0]; this.match += match[0]; this.matches = match; this.yyleng = this.yytext.length; if (this.options.ranges) { this.yylloc.range = [this.offset, this.offset += this.yyleng]; } this._more = false; this._input = this._input.slice(match[0].length); this.matched += match[0]; token = this.performAction.call(this, this.yy, this, rules[index], this.conditionStack[this.conditionStack.length - 1]); if (this.done && this._input) this.done = false; if (token) return token;else return; } if (this._input === "") { return this.EOF; } else { return this.parseError('Lexical error on line ' + (this.yylineno + 1) + '. Unrecognized text.\n' + this.showPosition(), { text: "", token: null, line: this.yylineno }); } }, lex: function lex() { var r = this.next(); if (typeof r !== 'undefined') { return r; } else { return this.lex(); } }, begin: function begin(condition) { this.conditionStack.push(condition); }, popState: function popState() { return this.conditionStack.pop(); }, _currentRules: function _currentRules() { return this.conditions[this.conditionStack[this.conditionStack.length - 1]].rules; }, topState: function topState() { return this.conditionStack[this.conditionStack.length - 2]; }, pushState: function begin(condition) { this.begin(condition); } }; lexer.options = {}; lexer.performAction = function anonymous(yy, yy_, $avoiding_name_collisions, YY_START) { function strip(start, end) { return yy_.yytext = yy_.yytext.substring(start, yy_.yyleng - end + start); } var YYSTATE = YY_START; switch ($avoiding_name_collisions) { case 0: if (yy_.yytext.slice(-2) === "\\\\") { strip(0, 1); this.begin("mu"); } else if (yy_.yytext.slice(-1) === "\\") { strip(0, 1); this.begin("emu"); } else { this.begin("mu"); } if (yy_.yytext) return 15; break; case 1: return 15; break; case 2: this.popState(); return 15; break; case 3: this.begin('raw');return 15; break; case 4: this.popState(); // Should be using `this.topState()` below, but it currently // returns the second top instead of the first top. Opened an // issue about it at https://github.com/zaach/jison/issues/291 if (this.conditionStack[this.conditionStack.length - 1] === 'raw') { return 15; } else { strip(5, 9); return 'END_RAW_BLOCK'; } break; case 5: return 15; break; case 6: this.popState(); return 14; break; case 7: return 65; break; case 8: return 68; break; case 9: return 19; break; case 10: this.popState(); this.begin('raw'); return 23; break; case 11: return 55; break; case 12: return 60; break; case 13: return 29; break; case 14: return 47; break; case 15: this.popState();return 44; break; case 16: this.popState();return 44; break; case 17: return 34; break; case 18: return 39; break; case 19: return 51; break; case 20: return 48; break; case 21: this.unput(yy_.yytext); this.popState(); this.begin('com'); break; case 22: this.popState(); return 14; break; case 23: return 48; break; case 24: return 73; break; case 25: return 72; break; case 26: return 72; break; case 27: return 87; break; case 28: // ignore whitespace break; case 29: this.popState();return 54; break; case 30: this.popState();return 33; break; case 31: yy_.yytext = strip(1, 2).replace(/\\"/g, '"');return 80; break; case 32: yy_.yytext = strip(1, 2).replace(/\\'/g, "'");return 80; break; case 33: return 85; break; case 34: return 82; break; case 35: return 82; break; case 36: return 83; break; case 37: return 84; break; case 38: return 81; break; case 39: return 75; break; case 40: return 77; break; case 41: return 72; break; case 42: yy_.yytext = yy_.yytext.replace(/\\([\\\]])/g, '$1');return 72; break; case 43: return 'INVALID'; break; case 44: return 5; break; } }; lexer.rules = [/^(?:[^\x00]*?(?=(\{\{)))/, /^(?:[^\x00]+)/, /^(?:[^\x00]{2,}?(?=(\{\{|\\\{\{|\\\\\{\{|$)))/, /^(?:\{\{\{\{(?=[^\/]))/, /^(?:\{\{\{\{\/[^\s!"#%-,\.\/;->@\[-\^`\{-~]+(?=[=}\s\/.])\}\}\}\})/, /^(?:[^\x00]+?(?=(\{\{\{\{)))/, /^(?:[\s\S]*?--(~)?\}\})/, /^(?:\()/, /^(?:\))/, /^(?:\{\{\{\{)/, /^(?:\}\}\}\})/, /^(?:\{\{(~)?>)/, /^(?:\{\{(~)?#>)/, /^(?:\{\{(~)?#\*?)/, /^(?:\{\{(~)?\/)/, /^(?:\{\{(~)?\^\s*(~)?\}\})/, /^(?:\{\{(~)?\s*else\s*(~)?\}\})/, /^(?:\{\{(~)?\^)/, /^(?:\{\{(~)?\s*else\b)/, /^(?:\{\{(~)?\{)/, /^(?:\{\{(~)?&)/, /^(?:\{\{(~)?!--)/, /^(?:\{\{(~)?![\s\S]*?\}\})/, /^(?:\{\{(~)?\*?)/, /^(?:=)/, /^(?:\.\.)/, /^(?:\.(?=([=~}\s\/.)|])))/, /^(?:[\/.])/, /^(?:\s+)/, /^(?:\}(~)?\}\})/, /^(?:(~)?\}\})/, /^(?:"(\\["]|[^"])*")/, /^(?:'(\\[']|[^'])*')/, /^(?:@)/, /^(?:true(?=([~}\s)])))/, /^(?:false(?=([~}\s)])))/, /^(?:undefined(?=([~}\s)])))/, /^(?:null(?=([~}\s)])))/, /^(?:-?[0-9]+(?:\.[0-9]+)?(?=([~}\s)])))/, /^(?:as\s+\|)/, /^(?:\|)/, /^(?:([^\s!"#%-,\.\/;->@\[-\^`\{-~]+(?=([=~}\s\/.)|]))))/, /^(?:\[(\\\]|[^\]])*\])/, /^(?:.)/, /^(?:$)/]; lexer.conditions = { "mu": { "rules": [7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44], "inclusive": false }, "emu": { "rules": [2], "inclusive": false }, "com": { "rules": [6], "inclusive": false }, "raw": { "rules": [3, 4, 5], "inclusive": false }, "INITIAL": { "rules": [0, 1, 44], "inclusive": true } }; return lexer; })(); parser.lexer = lexer; function Parser() { this.yy = {}; }Parser.prototype = parser;parser.Parser = Parser; return new Parser(); })();exports["default"] = handlebars; module.exports = exports["default"]; /***/ }), /* 48 */ /***/ (function(module, exports, __webpack_require__) { 'use strict'; var _interopRequireDefault = __webpack_require__(1)['default']; exports.__esModule = true; var _visitor = __webpack_require__(49); var _visitor2 = _interopRequireDefault(_visitor); function WhitespaceControl() { var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0]; this.options = options; } WhitespaceControl.prototype = new _visitor2['default'](); WhitespaceControl.prototype.Program = function (program) { var doStandalone = !this.options.ignoreStandalone; var isRoot = !this.isRootSeen; this.isRootSeen = true; var body = program.body; for (var i = 0, l = body.length; i < l; i++) { var current = body[i], strip = this.accept(current); if (!strip) { continue; } var _isPrevWhitespace = isPrevWhitespace(body, i, isRoot), _isNextWhitespace = isNextWhitespace(body, i, isRoot), openStandalone = strip.openStandalone && _isPrevWhitespace, closeStandalone = strip.closeStandalone && _isNextWhitespace, inlineStandalone = strip.inlineStandalone && _isPrevWhitespace && _isNextWhitespace; if (strip.close) { omitRight(body, i, true); } if (strip.open) { omitLeft(body, i, true); } if (doStandalone && inlineStandalone) { omitRight(body, i); if (omitLeft(body, i)) { // If we are on a standalone node, save the indent info for partials if (current.type === 'PartialStatement') { // Pull out the whitespace from the final line current.indent = /([ \t]+$)/.exec(body[i - 1].original)[1]; } } } if (doStandalone && openStandalone) { omitRight((current.program || current.inverse).body); // Strip out the previous content node if it's whitespace only omitLeft(body, i); } if (doStandalone && closeStandalone) { // Always strip the next node omitRight(body, i); omitLeft((current.inverse || current.program).body); } } return program; }; WhitespaceControl.prototype.BlockStatement = WhitespaceControl.prototype.DecoratorBlock = WhitespaceControl.prototype.PartialBlockStatement = function (block) { this.accept(block.program); this.accept(block.inverse); // Find the inverse program that is involed with whitespace stripping. var program = block.program || block.inverse, inverse = block.program && block.inverse, firstInverse = inverse, lastInverse = inverse; if (inverse && inverse.chained) { firstInverse = inverse.body[0].program; // Walk the inverse chain to find the last inverse that is actually in the chain. while (lastInverse.chained) { lastInverse = lastInverse.body[lastInverse.body.length - 1].program; } } var strip = { open: block.openStrip.open, close: block.closeStrip.close, // Determine the standalone candiacy. Basically flag our content as being possibly standalone // so our parent can determine if we actually are standalone openStandalone: isNextWhitespace(program.body), closeStandalone: isPrevWhitespace((firstInverse || program).body) }; if (block.openStrip.close) { omitRight(program.body, null, true); } if (inverse) { var inverseStrip = block.inverseStrip; if (inverseStrip.open) { omitLeft(program.body, null, true); } if (inverseStrip.close) { omitRight(firstInverse.body, null, true); } if (block.closeStrip.open) { omitLeft(lastInverse.body, null, true); } // Find standalone else statments if (!this.options.ignoreStandalone && isPrevWhitespace(program.body) && isNextWhitespace(firstInverse.body)) { omitLeft(program.body); omitRight(firstInverse.body); } } else if (block.closeStrip.open) { omitLeft(program.body, null, true); } return strip; }; WhitespaceControl.prototype.Decorator = WhitespaceControl.prototype.MustacheStatement = function (mustache) { return mustache.strip; }; WhitespaceControl.prototype.PartialStatement = WhitespaceControl.prototype.CommentStatement = function (node) { /* istanbul ignore next */ var strip = node.strip || {}; return { inlineStandalone: true, open: strip.open, close: strip.close }; }; function isPrevWhitespace(body, i, isRoot) { if (i === undefined) { i = body.length; } // Nodes that end with newlines are considered whitespace (but are special // cased for strip operations) var prev = body[i - 1], sibling = body[i - 2]; if (!prev) { return isRoot; } if (prev.type === 'ContentStatement') { return (sibling || !isRoot ? /\r?\n\s*?$/ : /(^|\r?\n)\s*?$/).test(prev.original); } } function isNextWhitespace(body, i, isRoot) { if (i === undefined) { i = -1; } var next = body[i + 1], sibling = body[i + 2]; if (!next) { return isRoot; } if (next.type === 'ContentStatement') { return (sibling || !isRoot ? /^\s*?\r?\n/ : /^\s*?(\r?\n|$)/).test(next.original); } } // Marks the node to the right of the position as omitted. // I.e. {{foo}}' ' will mark the ' ' node as omitted. // // If i is undefined, then the first child will be marked as such. // // If mulitple is truthy then all whitespace will be stripped out until non-whitespace // content is met. function omitRight(body, i, multiple) { var current = body[i == null ? 0 : i + 1]; if (!current || current.type !== 'ContentStatement' || !multiple && current.rightStripped) { return; } var original = current.value; current.value = current.value.replace(multiple ? /^\s+/ : /^[ \t]*\r?\n?/, ''); current.rightStripped = current.value !== original; } // Marks the node to the left of the position as omitted. // I.e. ' '{{foo}} will mark the ' ' node as omitted. // // If i is undefined then the last child will be marked as such. // // If mulitple is truthy then all whitespace will be stripped out until non-whitespace // content is met. function omitLeft(body, i, multiple) { var current = body[i == null ? body.length - 1 : i - 1]; if (!current || current.type !== 'ContentStatement' || !multiple && current.leftStripped) { return; } // We omit the last node if it's whitespace only and not preceded by a non-content node. var original = current.value; current.value = current.value.replace(multiple ? /\s+$/ : /[ \t]+$/, ''); current.leftStripped = current.value !== original; return current.leftStripped; } exports['default'] = WhitespaceControl; module.exports = exports['default']; /***/ }), /* 49 */ /***/ (function(module, exports, __webpack_require__) { 'use strict'; var _interopRequireDefault = __webpack_require__(1)['default']; exports.__esModule = true; var _exception = __webpack_require__(6); var _exception2 = _interopRequireDefault(_exception); function Visitor() { this.parents = []; } Visitor.prototype = { constructor: Visitor, mutating: false, // Visits a given value. If mutating, will replace the value if necessary. acceptKey: function acceptKey(node, name) { var value = this.accept(node[name]); if (this.mutating) { // Hacky sanity check: This may have a few false positives for type for the helper // methods but will generally do the right thing without a lot of overhead. if (value && !Visitor.prototype[value.type]) { throw new _exception2['default']('Unexpected node type "' + value.type + '" found when accepting ' + name + ' on ' + node.type); } node[name] = value; } }, // Performs an accept operation with added sanity check to ensure // required keys are not removed. acceptRequired: function acceptRequired(node, name) { this.acceptKey(node, name); if (!node[name]) { throw new _exception2['default'](node.type + ' requires ' + name); } }, // Traverses a given array. If mutating, empty respnses will be removed // for child elements. acceptArray: function acceptArray(array) { for (var i = 0, l = array.length; i < l; i++) { this.acceptKey(array, i); if (!array[i]) { array.splice(i, 1); i--; l--; } } }, accept: function accept(object) { if (!object) { return; } /* istanbul ignore next: Sanity code */ if (!this[object.type]) { throw new _exception2['default']('Unknown type: ' + object.type, object); } if (this.current) { this.parents.unshift(this.current); } this.current = object; var ret = this[object.type](object); this.current = this.parents.shift(); if (!this.mutating || ret) { return ret; } else if (ret !== false) { return object; } }, Program: function Program(program) { this.acceptArray(program.body); }, MustacheStatement: visitSubExpression, Decorator: visitSubExpression, BlockStatement: visitBlock, DecoratorBlock: visitBlock, PartialStatement: visitPartial, PartialBlockStatement: function PartialBlockStatement(partial) { visitPartial.call(this, partial); this.acceptKey(partial, 'program'); }, ContentStatement: function ContentStatement() /* content */{}, CommentStatement: function CommentStatement() /* comment */{}, SubExpression: visitSubExpression, PathExpression: function PathExpression() /* path */{}, StringLiteral: function StringLiteral() /* string */{}, NumberLiteral: function NumberLiteral() /* number */{}, BooleanLiteral: function BooleanLiteral() /* bool */{}, UndefinedLiteral: function UndefinedLiteral() /* literal */{}, NullLiteral: function NullLiteral() /* literal */{}, Hash: function Hash(hash) { this.acceptArray(hash.pairs); }, HashPair: function HashPair(pair) { this.acceptRequired(pair, 'value'); } }; function visitSubExpression(mustache) { this.acceptRequired(mustache, 'path'); this.acceptArray(mustache.params); this.acceptKey(mustache, 'hash'); } function visitBlock(block) { visitSubExpression.call(this, block); this.acceptKey(block, 'program'); this.acceptKey(block, 'inverse'); } function visitPartial(partial) { this.acceptRequired(partial, 'name'); this.acceptArray(partial.params); this.acceptKey(partial, 'hash'); } exports['default'] = Visitor; module.exports = exports['default']; /***/ }), /* 50 */ /***/ (function(module, exports, __webpack_require__) { 'use strict'; var _interopRequireDefault = __webpack_require__(1)['default']; exports.__esModule = true; exports.SourceLocation = SourceLocation; exports.id = id; exports.stripFlags = stripFlags; exports.stripComment = stripComment; exports.preparePath = preparePath; exports.prepareMustache = prepareMustache; exports.prepareRawBlock = prepareRawBlock; exports.prepareBlock = prepareBlock; exports.prepareProgram = prepareProgram; exports.preparePartialBlock = preparePartialBlock; var _exception = __webpack_require__(6); var _exception2 = _interopRequireDefault(_exception); function validateClose(open, close) { close = close.path ? close.path.original : close; if (open.path.original !== close) { var errorNode = { loc: open.path.loc }; throw new _exception2['default'](open.path.original + " doesn't match " + close, errorNode); } } function SourceLocation(source, locInfo) { this.source = source; this.start = { line: locInfo.first_line, column: locInfo.first_column }; this.end = { line: locInfo.last_line, column: locInfo.last_column }; } function id(token) { if (/^\[.*\]$/.test(token)) { return token.substring(1, token.length - 1); } else { return token; } } function stripFlags(open, close) { return { open: open.charAt(2) === '~', close: close.charAt(close.length - 3) === '~' }; } function stripComment(comment) { return comment.replace(/^\{\{~?!-?-?/, '').replace(/-?-?~?\}\}$/, ''); } function preparePath(data, parts, loc) { loc = this.locInfo(loc); var original = data ? '@' : '', dig = [], depth = 0; for (var i = 0, l = parts.length; i < l; i++) { var part = parts[i].part, // If we have [] syntax then we do not treat path references as operators, // i.e. foo.[this] resolves to approximately context.foo['this'] isLiteral = parts[i].original !== part; original += (parts[i].separator || '') + part; if (!isLiteral && (part === '..' || part === '.' || part === 'this')) { if (dig.length > 0) { throw new _exception2['default']('Invalid path: ' + original, { loc: loc }); } else if (part === '..') { depth++; } } else { dig.push(part); } } return { type: 'PathExpression', data: data, depth: depth, parts: dig, original: original, loc: loc }; } function prepareMustache(path, params, hash, open, strip, locInfo) { // Must use charAt to support IE pre-10 var escapeFlag = open.charAt(3) || open.charAt(2), escaped = escapeFlag !== '{' && escapeFlag !== '&'; var decorator = /\*/.test(open); return { type: decorator ? 'Decorator' : 'MustacheStatement', path: path, params: params, hash: hash, escaped: escaped, strip: strip, loc: this.locInfo(locInfo) }; } function prepareRawBlock(openRawBlock, contents, close, locInfo) { validateClose(openRawBlock, close); locInfo = this.locInfo(locInfo); var program = { type: 'Program', body: contents, strip: {}, loc: locInfo }; return { type: 'BlockStatement', path: openRawBlock.path, params: openRawBlock.params, hash: openRawBlock.hash, program: program, openStrip: {}, inverseStrip: {}, closeStrip: {}, loc: locInfo }; } function prepareBlock(openBlock, program, inverseAndProgram, close, inverted, locInfo) { if (close && close.path) { validateClose(openBlock, close); } var decorator = /\*/.test(openBlock.open); program.blockParams = openBlock.blockParams; var inverse = undefined, inverseStrip = undefined; if (inverseAndProgram) { if (decorator) { throw new _exception2['default']('Unexpected inverse block on decorator', inverseAndProgram); } if (inverseAndProgram.chain) { inverseAndProgram.program.body[0].closeStrip = close.strip; } inverseStrip = inverseAndProgram.strip; inverse = inverseAndProgram.program; } if (inverted) { inverted = inverse; inverse = program; program = inverted; } return { type: decorator ? 'DecoratorBlock' : 'BlockStatement', path: openBlock.path, params: openBlock.params, hash: openBlock.hash, program: program, inverse: inverse, openStrip: openBlock.strip, inverseStrip: inverseStrip, closeStrip: close && close.strip, loc: this.locInfo(locInfo) }; } function prepareProgram(statements, loc) { if (!loc && statements.length) { var firstLoc = statements[0].loc, lastLoc = statements[statements.length - 1].loc; /* istanbul ignore else */ if (firstLoc && lastLoc) { loc = { source: firstLoc.source, start: { line: firstLoc.start.line, column: firstLoc.start.column }, end: { line: lastLoc.end.line, column: lastLoc.end.column } }; } } return { type: 'Program', body: statements, strip: {}, loc: loc }; } function preparePartialBlock(open, program, close, locInfo) { validateClose(open, close); return { type: 'PartialBlockStatement', name: open.path, params: open.params, hash: open.hash, program: program, openStrip: open.strip, closeStrip: close && close.strip, loc: this.locInfo(locInfo) }; } /***/ }), /* 51 */ /***/ (function(module, exports, __webpack_require__) { /* eslint-disable new-cap */ 'use strict'; var _Object$create = __webpack_require__(34)['default']; var _interopRequireDefault = __webpack_require__(1)['default']; exports.__esModule = true; exports.Compiler = Compiler; exports.precompile = precompile; exports.compile = compile; var _exception = __webpack_require__(6); var _exception2 = _interopRequireDefault(_exception); var _utils = __webpack_require__(5); var _ast = __webpack_require__(45); var _ast2 = _interopRequireDefault(_ast); var slice = [].slice; function Compiler() {} // the foundHelper register will disambiguate helper lookup from finding a // function in a context. This is necessary for mustache compatibility, which // requires that context functions in blocks are evaluated by blockHelperMissing, // and then proceed as if the resulting value was provided to blockHelperMissing. Compiler.prototype = { compiler: Compiler, equals: function equals(other) { var len = this.opcodes.length; if (other.opcodes.length !== len) { return false; } for (var i = 0; i < len; i++) { var opcode = this.opcodes[i], otherOpcode = other.opcodes[i]; if (opcode.opcode !== otherOpcode.opcode || !argEquals(opcode.args, otherOpcode.args)) { return false; } } // We know that length is the same between the two arrays because they are directly tied // to the opcode behavior above. len = this.children.length; for (var i = 0; i < len; i++) { if (!this.children[i].equals(other.children[i])) { return false; } } return true; }, guid: 0, compile: function compile(program, options) { this.sourceNode = []; this.opcodes = []; this.children = []; this.options = options; this.stringParams = options.stringParams; this.trackIds = options.trackIds; options.blockParams = options.blockParams || []; options.knownHelpers = _utils.extend(_Object$create(null), { helperMissing: true, blockHelperMissing: true, each: true, 'if': true, unless: true, 'with': true, log: true, lookup: true }, options.knownHelpers); return this.accept(program); }, compileProgram: function compileProgram(program) { var childCompiler = new this.compiler(), // eslint-disable-line new-cap result = childCompiler.compile(program, this.options), guid = this.guid++; this.usePartial = this.usePartial || result.usePartial; this.children[guid] = result; this.useDepths = this.useDepths || result.useDepths; return guid; }, accept: function accept(node) { /* istanbul ignore next: Sanity code */ if (!this[node.type]) { throw new _exception2['default']('Unknown type: ' + node.type, node); } this.sourceNode.unshift(node); var ret = this[node.type](node); this.sourceNode.shift(); return ret; }, Program: function Program(program) { this.options.blockParams.unshift(program.blockParams); var body = program.body, bodyLength = body.length; for (var i = 0; i < bodyLength; i++) { this.accept(body[i]); } this.options.blockParams.shift(); this.isSimple = bodyLength === 1; this.blockParams = program.blockParams ? program.blockParams.length : 0; return this; }, BlockStatement: function BlockStatement(block) { transformLiteralToPath(block); var program = block.program, inverse = block.inverse; program = program && this.compileProgram(program); inverse = inverse && this.compileProgram(inverse); var type = this.classifySexpr(block); if (type === 'helper') { this.helperSexpr(block, program, inverse); } else if (type === 'simple') { this.simpleSexpr(block); // now that the simple mustache is resolved, we need to // evaluate it by executing `blockHelperMissing` this.opcode('pushProgram', program); this.opcode('pushProgram', inverse); this.opcode('emptyHash'); this.opcode('blockValue', block.path.original); } else { this.ambiguousSexpr(block, program, inverse); // now that the simple mustache is resolved, we need to // evaluate it by executing `blockHelperMissing` this.opcode('pushProgram', program); this.opcode('pushProgram', inverse); this.opcode('emptyHash'); this.opcode('ambiguousBlockValue'); } this.opcode('append'); }, DecoratorBlock: function DecoratorBlock(decorator) { var program = decorator.program && this.compileProgram(decorator.program); var params = this.setupFullMustacheParams(decorator, program, undefined), path = decorator.path; this.useDecorators = true; this.opcode('registerDecorator', params.length, path.original); }, PartialStatement: function PartialStatement(partial) { this.usePartial = true; var program = partial.program; if (program) { program = this.compileProgram(partial.program); } var params = partial.params; if (params.length > 1) { throw new _exception2['default']('Unsupported number of partial arguments: ' + params.length, partial); } else if (!params.length) { if (this.options.explicitPartialContext) { this.opcode('pushLiteral', 'undefined'); } else { params.push({ type: 'PathExpression', parts: [], depth: 0 }); } } var partialName = partial.name.original, isDynamic = partial.name.type === 'SubExpression'; if (isDynamic) { this.accept(partial.name); } this.setupFullMustacheParams(partial, program, undefined, true); var indent = partial.indent || ''; if (this.options.preventIndent && indent) { this.opcode('appendContent', indent); indent = ''; } this.opcode('invokePartial', isDynamic, partialName, indent); this.opcode('append'); }, PartialBlockStatement: function PartialBlockStatement(partialBlock) { this.PartialStatement(partialBlock); }, MustacheStatement: function MustacheStatement(mustache) { this.SubExpression(mustache); if (mustache.escaped && !this.options.noEscape) { this.opcode('appendEscaped'); } else { this.opcode('append'); } }, Decorator: function Decorator(decorator) { this.DecoratorBlock(decorator); }, ContentStatement: function ContentStatement(content) { if (content.value) { this.opcode('appendContent', content.value); } }, CommentStatement: function CommentStatement() {}, SubExpression: function SubExpression(sexpr) { transformLiteralToPath(sexpr); var type = this.classifySexpr(sexpr); if (type === 'simple') { this.simpleSexpr(sexpr); } else if (type === 'helper') { this.helperSexpr(sexpr); } else { this.ambiguousSexpr(sexpr); } }, ambiguousSexpr: function ambiguousSexpr(sexpr, program, inverse) { var path = sexpr.path, name = path.parts[0], isBlock = program != null || inverse != null; this.opcode('getContext', path.depth); this.opcode('pushProgram', program); this.opcode('pushProgram', inverse); path.strict = true; this.accept(path); this.opcode('invokeAmbiguous', name, isBlock); }, simpleSexpr: function simpleSexpr(sexpr) { var path = sexpr.path; path.strict = true; this.accept(path); this.opcode('resolvePossibleLambda'); }, helperSexpr: function helperSexpr(sexpr, program, inverse) { var params = this.setupFullMustacheParams(sexpr, program, inverse), path = sexpr.path, name = path.parts[0]; if (this.options.knownHelpers[name]) { this.opcode('invokeKnownHelper', params.length, name); } else if (this.options.knownHelpersOnly) { throw new _exception2['default']('You specified knownHelpersOnly, but used the unknown helper ' + name, sexpr); } else { path.strict = true; path.falsy = true; this.accept(path); this.opcode('invokeHelper', params.length, path.original, _ast2['default'].helpers.simpleId(path)); } }, PathExpression: function PathExpression(path) { this.addDepth(path.depth); this.opcode('getContext', path.depth); var name = path.parts[0], scoped = _ast2['default'].helpers.scopedId(path), blockParamId = !path.depth && !scoped && this.blockParamIndex(name); if (blockParamId) { this.opcode('lookupBlockParam', blockParamId, path.parts); } else if (!name) { // Context reference, i.e. `{{foo .}}` or `{{foo ..}}` this.opcode('pushContext'); } else if (path.data) { this.options.data = true; this.opcode('lookupData', path.depth, path.parts, path.strict); } else { this.opcode('lookupOnContext', path.parts, path.falsy, path.strict, scoped); } }, StringLiteral: function StringLiteral(string) { this.opcode('pushString', string.value); }, NumberLiteral: function NumberLiteral(number) { this.opcode('pushLiteral', number.value); }, BooleanLiteral: function BooleanLiteral(bool) { this.opcode('pushLiteral', bool.value); }, UndefinedLiteral: function UndefinedLiteral() { this.opcode('pushLiteral', 'undefined'); }, NullLiteral: function NullLiteral() { this.opcode('pushLiteral', 'null'); }, Hash: function Hash(hash) { var pairs = hash.pairs, i = 0, l = pairs.length; this.opcode('pushHash'); for (; i < l; i++) { this.pushParam(pairs[i].value); } while (i--) { this.opcode('assignToHash', pairs[i].key); } this.opcode('popHash'); }, // HELPERS opcode: function opcode(name) { this.opcodes.push({ opcode: name, args: slice.call(arguments, 1), loc: this.sourceNode[0].loc }); }, addDepth: function addDepth(depth) { if (!depth) { return; } this.useDepths = true; }, classifySexpr: function classifySexpr(sexpr) { var isSimple = _ast2['default'].helpers.simpleId(sexpr.path); var isBlockParam = isSimple && !!this.blockParamIndex(sexpr.path.parts[0]); // a mustache is an eligible helper if: // * its id is simple (a single part, not `this` or `..`) var isHelper = !isBlockParam && _ast2['default'].helpers.helperExpression(sexpr); // if a mustache is an eligible helper but not a definite // helper, it is ambiguous, and will be resolved in a later // pass or at runtime. var isEligible = !isBlockParam && (isHelper || isSimple); // if ambiguous, we can possibly resolve the ambiguity now // An eligible helper is one that does not have a complex path, i.e. `this.foo`, `../foo` etc. if (isEligible && !isHelper) { var _name = sexpr.path.parts[0], options = this.options; if (options.knownHelpers[_name]) { isHelper = true; } else if (options.knownHelpersOnly) { isEligible = false; } } if (isHelper) { return 'helper'; } else if (isEligible) { return 'ambiguous'; } else { return 'simple'; } }, pushParams: function pushParams(params) { for (var i = 0, l = params.length; i < l; i++) { this.pushParam(params[i]); } }, pushParam: function pushParam(val) { var value = val.value != null ? val.value : val.original || ''; if (this.stringParams) { if (value.replace) { value = value.replace(/^(\.?\.\/)*/g, '').replace(/\//g, '.'); } if (val.depth) { this.addDepth(val.depth); } this.opcode('getContext', val.depth || 0); this.opcode('pushStringParam', value, val.type); if (val.type === 'SubExpression') { // SubExpressions get evaluated and passed in // in string params mode. this.accept(val); } } else { if (this.trackIds) { var blockParamIndex = undefined; if (val.parts && !_ast2['default'].helpers.scopedId(val) && !val.depth) { blockParamIndex = this.blockParamIndex(val.parts[0]); } if (blockParamIndex) { var blockParamChild = val.parts.slice(1).join('.'); this.opcode('pushId', 'BlockParam', blockParamIndex, blockParamChild); } else { value = val.original || value; if (value.replace) { value = value.replace(/^this(?:\.|$)/, '').replace(/^\.\//, '').replace(/^\.$/, ''); } this.opcode('pushId', val.type, value); } } this.accept(val); } }, setupFullMustacheParams: function setupFullMustacheParams(sexpr, program, inverse, omitEmpty) { var params = sexpr.params; this.pushParams(params); this.opcode('pushProgram', program); this.opcode('pushProgram', inverse); if (sexpr.hash) { this.accept(sexpr.hash); } else { this.opcode('emptyHash', omitEmpty); } return params; }, blockParamIndex: function blockParamIndex(name) { for (var depth = 0, len = this.options.blockParams.length; depth < len; depth++) { var blockParams = this.options.blockParams[depth], param = blockParams && _utils.indexOf(blockParams, name); if (blockParams && param >= 0) { return [depth, param]; } } } }; function precompile(input, options, env) { if (input == null || typeof input !== 'string' && input.type !== 'Program') { throw new _exception2['default']('You must pass a string or Handlebars AST to Handlebars.precompile. You passed ' + input); } options = options || {}; if (!('data' in options)) { options.data = true; } if (options.compat) { options.useDepths = true; } var ast = env.parse(input, options), environment = new env.Compiler().compile(ast, options); return new env.JavaScriptCompiler().compile(environment, options); } function compile(input, options, env) { if (options === undefined) options = {}; if (input == null || typeof input !== 'string' && input.type !== 'Program') { throw new _exception2['default']('You must pass a string or Handlebars AST to Handlebars.compile. You passed ' + input); } options = _utils.extend({}, options); if (!('data' in options)) { options.data = true; } if (options.compat) { options.useDepths = true; } var compiled = undefined; function compileInput() { var ast = env.parse(input, options), environment = new env.Compiler().compile(ast, options), templateSpec = new env.JavaScriptCompiler().compile(environment, options, undefined, true); return env.template(templateSpec); } // Template is only compiled on first use and cached after that point. function ret(context, execOptions) { if (!compiled) { compiled = compileInput(); } return compiled.call(this, context, execOptions); } ret._setup = function (setupOptions) { if (!compiled) { compiled = compileInput(); } return compiled._setup(setupOptions); }; ret._child = function (i, data, blockParams, depths) { if (!compiled) { compiled = compileInput(); } return compiled._child(i, data, blockParams, depths); }; return ret; } function argEquals(a, b) { if (a === b) { return true; } if (_utils.isArray(a) && _utils.isArray(b) && a.length === b.length) { for (var i = 0; i < a.length; i++) { if (!argEquals(a[i], b[i])) { return false; } } return true; } } function transformLiteralToPath(sexpr) { if (!sexpr.path.parts) { var literal = sexpr.path; // Casting to string here to make false and 0 literal values play nicely with the rest // of the system. sexpr.path = { type: 'PathExpression', data: false, depth: 0, parts: [literal.original + ''], original: literal.original + '', loc: literal.loc }; } } /***/ }), /* 52 */ /***/ (function(module, exports, __webpack_require__) { 'use strict'; var _Object$keys = __webpack_require__(13)['default']; var _interopRequireDefault = __webpack_require__(1)['default']; exports.__esModule = true; var _base = __webpack_require__(4); var _exception = __webpack_require__(6); var _exception2 = _interopRequireDefault(_exception); var _utils = __webpack_require__(5); var _codeGen = __webpack_require__(53); var _codeGen2 = _interopRequireDefault(_codeGen); function Literal(value) { this.value = value; } function JavaScriptCompiler() {} JavaScriptCompiler.prototype = { // PUBLIC API: You can override these methods in a subclass to provide // alternative compiled forms for name lookup and buffering semantics nameLookup: function nameLookup(parent, name /*, type */) { return this.internalNameLookup(parent, name); }, depthedLookup: function depthedLookup(name) { return [this.aliasable('container.lookup'), '(depths, ', JSON.stringify(name), ')']; }, compilerInfo: function compilerInfo() { var revision = _base.COMPILER_REVISION, versions = _base.REVISION_CHANGES[revision]; return [revision, versions]; }, appendToBuffer: function appendToBuffer(source, location, explicit) { // Force a source as this simplifies the merge logic. if (!_utils.isArray(source)) { source = [source]; } source = this.source.wrap(source, location); if (this.environment.isSimple) { return ['return ', source, ';']; } else if (explicit) { // This is a case where the buffer operation occurs as a child of another // construct, generally braces. We have to explicitly output these buffer // operations to ensure that the emitted code goes in the correct location. return ['buffer += ', source, ';']; } else { source.appendToBuffer = true; return source; } }, initializeBuffer: function initializeBuffer() { return this.quotedString(''); }, // END PUBLIC API internalNameLookup: function internalNameLookup(parent, name) { this.lookupPropertyFunctionIsUsed = true; return ['lookupProperty(', parent, ',', JSON.stringify(name), ')']; }, lookupPropertyFunctionIsUsed: false, compile: function compile(environment, options, context, asObject) { this.environment = environment; this.options = options; this.stringParams = this.options.stringParams; this.trackIds = this.options.trackIds; this.precompile = !asObject; this.name = this.environment.name; this.isChild = !!context; this.context = context || { decorators: [], programs: [], environments: [] }; this.preamble(); this.stackSlot = 0; this.stackVars = []; this.aliases = {}; this.registers = { list: [] }; this.hashes = []; this.compileStack = []; this.inlineStack = []; this.blockParams = []; this.compileChildren(environment, options); this.useDepths = this.useDepths || environment.useDepths || environment.useDecorators || this.options.compat; this.useBlockParams = this.useBlockParams || environment.useBlockParams; var opcodes = environment.opcodes, opcode = undefined, firstLoc = undefined, i = undefined, l = undefined; for (i = 0, l = opcodes.length; i < l; i++) { opcode = opcodes[i]; this.source.currentLocation = opcode.loc; firstLoc = firstLoc || opcode.loc; this[opcode.opcode].apply(this, opcode.args); } // Flush any trailing content that might be pending. this.source.currentLocation = firstLoc; this.pushSource(''); /* istanbul ignore next */ if (this.stackSlot || this.inlineStack.length || this.compileStack.length) { throw new _exception2['default']('Compile completed with content left on stack'); } if (!this.decorators.isEmpty()) { this.useDecorators = true; this.decorators.prepend(['var decorators = container.decorators, ', this.lookupPropertyFunctionVarDeclaration(), ';\n']); this.decorators.push('return fn;'); if (asObject) { this.decorators = Function.apply(this, ['fn', 'props', 'container', 'depth0', 'data', 'blockParams', 'depths', this.decorators.merge()]); } else { this.decorators.prepend('function(fn, props, container, depth0, data, blockParams, depths) {\n'); this.decorators.push('}\n'); this.decorators = this.decorators.merge(); } } else { this.decorators = undefined; } var fn = this.createFunctionContext(asObject); if (!this.isChild) { var ret = { compiler: this.compilerInfo(), main: fn }; if (this.decorators) { ret.main_d = this.decorators; // eslint-disable-line camelcase ret.useDecorators = true; } var _context = this.context; var programs = _context.programs; var decorators = _context.decorators; for (i = 0, l = programs.length; i < l; i++) { if (programs[i]) { ret[i] = programs[i]; if (decorators[i]) { ret[i + '_d'] = decorators[i]; ret.useDecorators = true; } } } if (this.environment.usePartial) { ret.usePartial = true; } if (this.options.data) { ret.useData = true; } if (this.useDepths) { ret.useDepths = true; } if (this.useBlockParams) { ret.useBlockParams = true; } if (this.options.compat) { ret.compat = true; } if (!asObject) { ret.compiler = JSON.stringify(ret.compiler); this.source.currentLocation = { start: { line: 1, column: 0 } }; ret = this.objectLiteral(ret); if (options.srcName) { ret = ret.toStringWithSourceMap({ file: options.destName }); ret.map = ret.map && ret.map.toString(); } else { ret = ret.toString(); } } else { ret.compilerOptions = this.options; } return ret; } else { return fn; } }, preamble: function preamble() { // track the last context pushed into place to allow skipping the // getContext opcode when it would be a noop this.lastContext = 0; this.source = new _codeGen2['default'](this.options.srcName); this.decorators = new _codeGen2['default'](this.options.srcName); }, createFunctionContext: function createFunctionContext(asObject) { // istanbul ignore next var _this = this; var varDeclarations = ''; var locals = this.stackVars.concat(this.registers.list); if (locals.length > 0) { varDeclarations += ', ' + locals.join(', '); } // Generate minimizer alias mappings // // When using true SourceNodes, this will update all references to the given alias // as the source nodes are reused in situ. For the non-source node compilation mode, // aliases will not be used, but this case is already being run on the client and // we aren't concern about minimizing the template size. var aliasCount = 0; _Object$keys(this.aliases).forEach(function (alias) { var node = _this.aliases[alias]; if (node.children && node.referenceCount > 1) { varDeclarations += ', alias' + ++aliasCount + '=' + alias; node.children[0] = 'alias' + aliasCount; } }); if (this.lookupPropertyFunctionIsUsed) { varDeclarations += ', ' + this.lookupPropertyFunctionVarDeclaration(); } var params = ['container', 'depth0', 'helpers', 'partials', 'data']; if (this.useBlockParams || this.useDepths) { params.push('blockParams'); } if (this.useDepths) { params.push('depths'); } // Perform a second pass over the output to merge content when possible var source = this.mergeSource(varDeclarations); if (asObject) { params.push(source); return Function.apply(this, params); } else { return this.source.wrap(['function(', params.join(','), ') {\n ', source, '}']); } }, mergeSource: function mergeSource(varDeclarations) { var isSimple = this.environment.isSimple, appendOnly = !this.forceBuffer, appendFirst = undefined, sourceSeen = undefined, bufferStart = undefined, bufferEnd = undefined; this.source.each(function (line) { if (line.appendToBuffer) { if (bufferStart) { line.prepend(' + '); } else { bufferStart = line; } bufferEnd = line; } else { if (bufferStart) { if (!sourceSeen) { appendFirst = true; } else { bufferStart.prepend('buffer += '); } bufferEnd.add(';'); bufferStart = bufferEnd = undefined; } sourceSeen = true; if (!isSimple) { appendOnly = false; } } }); if (appendOnly) { if (bufferStart) { bufferStart.prepend('return '); bufferEnd.add(';'); } else if (!sourceSeen) { this.source.push('return "";'); } } else { varDeclarations += ', buffer = ' + (appendFirst ? '' : this.initializeBuffer()); if (bufferStart) { bufferStart.prepend('return buffer + '); bufferEnd.add(';'); } else { this.source.push('return buffer;'); } } if (varDeclarations) { this.source.prepend('var ' + varDeclarations.substring(2) + (appendFirst ? '' : ';\n')); } return this.source.merge(); }, lookupPropertyFunctionVarDeclaration: function lookupPropertyFunctionVarDeclaration() { return '\n lookupProperty = container.lookupProperty || function(parent, propertyName) {\n if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {\n return parent[propertyName];\n }\n return undefined\n }\n '.trim(); }, // [blockValue] // // On stack, before: hash, inverse, program, value // On stack, after: return value of blockHelperMissing // // The purpose of this opcode is to take a block of the form // `{{#this.foo}}...{{/this.foo}}`, resolve the value of `foo`, and // replace it on the stack with the result of properly // invoking blockHelperMissing. blockValue: function blockValue(name) { var blockHelperMissing = this.aliasable('container.hooks.blockHelperMissing'), params = [this.contextName(0)]; this.setupHelperArgs(name, 0, params); var blockName = this.popStack(); params.splice(1, 0, blockName); this.push(this.source.functionCall(blockHelperMissing, 'call', params)); }, // [ambiguousBlockValue] // // On stack, before: hash, inverse, program, value // Compiler value, before: lastHelper=value of last found helper, if any // On stack, after, if no lastHelper: same as [blockValue] // On stack, after, if lastHelper: value ambiguousBlockValue: function ambiguousBlockValue() { // We're being a bit cheeky and reusing the options value from the prior exec var blockHelperMissing = this.aliasable('container.hooks.blockHelperMissing'), params = [this.contextName(0)]; this.setupHelperArgs('', 0, params, true); this.flushInline(); var current = this.topStack(); params.splice(1, 0, current); this.pushSource(['if (!', this.lastHelper, ') { ', current, ' = ', this.source.functionCall(blockHelperMissing, 'call', params), '}']); }, // [appendContent] // // On stack, before: ... // On stack, after: ... // // Appends the string value of `content` to the current buffer appendContent: function appendContent(content) { if (this.pendingContent) { content = this.pendingContent + content; } else { this.pendingLocation = this.source.currentLocation; } this.pendingContent = content; }, // [append] // // On stack, before: value, ... // On stack, after: ... // // Coerces `value` to a String and appends it to the current buffer. // // If `value` is truthy, or 0, it is coerced into a string and appended // Otherwise, the empty string is appended append: function append() { if (this.isInline()) { this.replaceStack(function (current) { return [' != null ? ', current, ' : ""']; }); this.pushSource(this.appendToBuffer(this.popStack())); } else { var local = this.popStack(); this.pushSource(['if (', local, ' != null) { ', this.appendToBuffer(local, undefined, true), ' }']); if (this.environment.isSimple) { this.pushSource(['else { ', this.appendToBuffer("''", undefined, true), ' }']); } } }, // [appendEscaped] // // On stack, before: value, ... // On stack, after: ... // // Escape `value` and append it to the buffer appendEscaped: function appendEscaped() { this.pushSource(this.appendToBuffer([this.aliasable('container.escapeExpression'), '(', this.popStack(), ')'])); }, // [getContext] // // On stack, before: ... // On stack, after: ... // Compiler value, after: lastContext=depth // // Set the value of the `lastContext` compiler value to the depth getContext: function getContext(depth) { this.lastContext = depth; }, // [pushContext] // // On stack, before: ... // On stack, after: currentContext, ... // // Pushes the value of the current context onto the stack. pushContext: function pushContext() { this.pushStackLiteral(this.contextName(this.lastContext)); }, // [lookupOnContext] // // On stack, before: ... // On stack, after: currentContext[name], ... // // Looks up the value of `name` on the current context and pushes // it onto the stack. lookupOnContext: function lookupOnContext(parts, falsy, strict, scoped) { var i = 0; if (!scoped && this.options.compat && !this.lastContext) { // The depthed query is expected to handle the undefined logic for the root level that // is implemented below, so we evaluate that directly in compat mode this.push(this.depthedLookup(parts[i++])); } else { this.pushContext(); } this.resolvePath('context', parts, i, falsy, strict); }, // [lookupBlockParam] // // On stack, before: ... // On stack, after: blockParam[name], ... // // Looks up the value of `parts` on the given block param and pushes // it onto the stack. lookupBlockParam: function lookupBlockParam(blockParamId, parts) { this.useBlockParams = true; this.push(['blockParams[', blockParamId[0], '][', blockParamId[1], ']']); this.resolvePath('context', parts, 1); }, // [lookupData] // // On stack, before: ... // On stack, after: data, ... // // Push the data lookup operator lookupData: function lookupData(depth, parts, strict) { if (!depth) { this.pushStackLiteral('data'); } else { this.pushStackLiteral('container.data(data, ' + depth + ')'); } this.resolvePath('data', parts, 0, true, strict); }, resolvePath: function resolvePath(type, parts, i, falsy, strict) { // istanbul ignore next var _this2 = this; if (this.options.strict || this.options.assumeObjects) { this.push(strictLookup(this.options.strict && strict, this, parts, type)); return; } var len = parts.length; for (; i < len; i++) { /* eslint-disable no-loop-func */ this.replaceStack(function (current) { var lookup = _this2.nameLookup(current, parts[i], type); // We want to ensure that zero and false are handled properly if the context (falsy flag) // needs to have the special handling for these values. if (!falsy) { return [' != null ? ', lookup, ' : ', current]; } else { // Otherwise we can use generic falsy handling return [' && ', lookup]; } }); /* eslint-enable no-loop-func */ } }, // [resolvePossibleLambda] // // On stack, before: value, ... // On stack, after: resolved value, ... // // If the `value` is a lambda, replace it on the stack by // the return value of the lambda resolvePossibleLambda: function resolvePossibleLambda() { this.push([this.aliasable('container.lambda'), '(', this.popStack(), ', ', this.contextName(0), ')']); }, // [pushStringParam] // // On stack, before: ... // On stack, after: string, currentContext, ... // // This opcode is designed for use in string mode, which // provides the string value of a parameter along with its // depth rather than resolving it immediately. pushStringParam: function pushStringParam(string, type) { this.pushContext(); this.pushString(type); // If it's a subexpression, the string result // will be pushed after this opcode. if (type !== 'SubExpression') { if (typeof string === 'string') { this.pushString(string); } else { this.pushStackLiteral(string); } } }, emptyHash: function emptyHash(omitEmpty) { if (this.trackIds) { this.push('{}'); // hashIds } if (this.stringParams) { this.push('{}'); // hashContexts this.push('{}'); // hashTypes } this.pushStackLiteral(omitEmpty ? 'undefined' : '{}'); }, pushHash: function pushHash() { if (this.hash) { this.hashes.push(this.hash); } this.hash = { values: {}, types: [], contexts: [], ids: [] }; }, popHash: function popHash() { var hash = this.hash; this.hash = this.hashes.pop(); if (this.trackIds) { this.push(this.objectLiteral(hash.ids)); } if (this.stringParams) { this.push(this.objectLiteral(hash.contexts)); this.push(this.objectLiteral(hash.types)); } this.push(this.objectLiteral(hash.values)); }, // [pushString] // // On stack, before: ... // On stack, after: quotedString(string), ... // // Push a quoted version of `string` onto the stack pushString: function pushString(string) { this.pushStackLiteral(this.quotedString(string)); }, // [pushLiteral] // // On stack, before: ... // On stack, after: value, ... // // Pushes a value onto the stack. This operation prevents // the compiler from creating a temporary variable to hold // it. pushLiteral: function pushLiteral(value) { this.pushStackLiteral(value); }, // [pushProgram] // // On stack, before: ... // On stack, after: program(guid), ... // // Push a program expression onto the stack. This takes // a compile-time guid and converts it into a runtime-accessible // expression. pushProgram: function pushProgram(guid) { if (guid != null) { this.pushStackLiteral(this.programExpression(guid)); } else { this.pushStackLiteral(null); } }, // [registerDecorator] // // On stack, before: hash, program, params..., ... // On stack, after: ... // // Pops off the decorator's parameters, invokes the decorator, // and inserts the decorator into the decorators list. registerDecorator: function registerDecorator(paramSize, name) { var foundDecorator = this.nameLookup('decorators', name, 'decorator'), options = this.setupHelperArgs(name, paramSize); this.decorators.push(['fn = ', this.decorators.functionCall(foundDecorator, '', ['fn', 'props', 'container', options]), ' || fn;']); }, // [invokeHelper] // // On stack, before: hash, inverse, program, params..., ... // On stack, after: result of helper invocation // // Pops off the helper's parameters, invokes the helper, // and pushes the helper's return value onto the stack. // // If the helper is not found, `helperMissing` is called. invokeHelper: function invokeHelper(paramSize, name, isSimple) { var nonHelper = this.popStack(), helper = this.setupHelper(paramSize, name); var possibleFunctionCalls = []; if (isSimple) { // direct call to helper possibleFunctionCalls.push(helper.name); } // call a function from the input object possibleFunctionCalls.push(nonHelper); if (!this.options.strict) { possibleFunctionCalls.push(this.aliasable('container.hooks.helperMissing')); } var functionLookupCode = ['(', this.itemsSeparatedBy(possibleFunctionCalls, '||'), ')']; var functionCall = this.source.functionCall(functionLookupCode, 'call', helper.callParams); this.push(functionCall); }, itemsSeparatedBy: function itemsSeparatedBy(items, separator) { var result = []; result.push(items[0]); for (var i = 1; i < items.length; i++) { result.push(separator, items[i]); } return result; }, // [invokeKnownHelper] // // On stack, before: hash, inverse, program, params..., ... // On stack, after: result of helper invocation // // This operation is used when the helper is known to exist, // so a `helperMissing` fallback is not required. invokeKnownHelper: function invokeKnownHelper(paramSize, name) { var helper = this.setupHelper(paramSize, name); this.push(this.source.functionCall(helper.name, 'call', helper.callParams)); }, // [invokeAmbiguous] // // On stack, before: hash, inverse, program, params..., ... // On stack, after: result of disambiguation // // This operation is used when an expression like `{{foo}}` // is provided, but we don't know at compile-time whether it // is a helper or a path. // // This operation emits more code than the other options, // and can be avoided by passing the `knownHelpers` and // `knownHelpersOnly` flags at compile-time. invokeAmbiguous: function invokeAmbiguous(name, helperCall) { this.useRegister('helper'); var nonHelper = this.popStack(); this.emptyHash(); var helper = this.setupHelper(0, name, helperCall); var helperName = this.lastHelper = this.nameLookup('helpers', name, 'helper'); var lookup = ['(', '(helper = ', helperName, ' || ', nonHelper, ')']; if (!this.options.strict) { lookup[0] = '(helper = '; lookup.push(' != null ? helper : ', this.aliasable('container.hooks.helperMissing')); } this.push(['(', lookup, helper.paramsInit ? ['),(', helper.paramsInit] : [], '),', '(typeof helper === ', this.aliasable('"function"'), ' ? ', this.source.functionCall('helper', 'call', helper.callParams), ' : helper))']); }, // [invokePartial] // // On stack, before: context, ... // On stack after: result of partial invocation // // This operation pops off a context, invokes a partial with that context, // and pushes the result of the invocation back. invokePartial: function invokePartial(isDynamic, name, indent) { var params = [], options = this.setupParams(name, 1, params); if (isDynamic) { name = this.popStack(); delete options.name; } if (indent) { options.indent = JSON.stringify(indent); } options.helpers = 'helpers'; options.partials = 'partials'; options.decorators = 'container.decorators'; if (!isDynamic) { params.unshift(this.nameLookup('partials', name, 'partial')); } else { params.unshift(name); } if (this.options.compat) { options.depths = 'depths'; } options = this.objectLiteral(options); params.push(options); this.push(this.source.functionCall('container.invokePartial', '', params)); }, // [assignToHash] // // On stack, before: value, ..., hash, ... // On stack, after: ..., hash, ... // // Pops a value off the stack and assigns it to the current hash assignToHash: function assignToHash(key) { var value = this.popStack(), context = undefined, type = undefined, id = undefined; if (this.trackIds) { id = this.popStack(); } if (this.stringParams) { type = this.popStack(); context = this.popStack(); } var hash = this.hash; if (context) { hash.contexts[key] = context; } if (type) { hash.types[key] = type; } if (id) { hash.ids[key] = id; } hash.values[key] = value; }, pushId: function pushId(type, name, child) { if (type === 'BlockParam') { this.pushStackLiteral('blockParams[' + name[0] + '].path[' + name[1] + ']' + (child ? ' + ' + JSON.stringify('.' + child) : '')); } else if (type === 'PathExpression') { this.pushString(name); } else if (type === 'SubExpression') { this.pushStackLiteral('true'); } else { this.pushStackLiteral('null'); } }, // HELPERS compiler: JavaScriptCompiler, compileChildren: function compileChildren(environment, options) { var children = environment.children, child = undefined, compiler = undefined; for (var i = 0, l = children.length; i < l; i++) { child = children[i]; compiler = new this.compiler(); // eslint-disable-line new-cap var existing = this.matchExistingProgram(child); if (existing == null) { this.context.programs.push(''); // Placeholder to prevent name conflicts for nested children var index = this.context.programs.length; child.index = index; child.name = 'program' + index; this.context.programs[index] = compiler.compile(child, options, this.context, !this.precompile); this.context.decorators[index] = compiler.decorators; this.context.environments[index] = child; this.useDepths = this.useDepths || compiler.useDepths; this.useBlockParams = this.useBlockParams || compiler.useBlockParams; child.useDepths = this.useDepths; child.useBlockParams = this.useBlockParams; } else { child.index = existing.index; child.name = 'program' + existing.index; this.useDepths = this.useDepths || existing.useDepths; this.useBlockParams = this.useBlockParams || existing.useBlockParams; } } }, matchExistingProgram: function matchExistingProgram(child) { for (var i = 0, len = this.context.environments.length; i < len; i++) { var environment = this.context.environments[i]; if (environment && environment.equals(child)) { return environment; } } }, programExpression: function programExpression(guid) { var child = this.environment.children[guid], programParams = [child.index, 'data', child.blockParams]; if (this.useBlockParams || this.useDepths) { programParams.push('blockParams'); } if (this.useDepths) { programParams.push('depths'); } return 'container.program(' + programParams.join(', ') + ')'; }, useRegister: function useRegister(name) { if (!this.registers[name]) { this.registers[name] = true; this.registers.list.push(name); } }, push: function push(expr) { if (!(expr instanceof Literal)) { expr = this.source.wrap(expr); } this.inlineStack.push(expr); return expr; }, pushStackLiteral: function pushStackLiteral(item) { this.push(new Literal(item)); }, pushSource: function pushSource(source) { if (this.pendingContent) { this.source.push(this.appendToBuffer(this.source.quotedString(this.pendingContent), this.pendingLocation)); this.pendingContent = undefined; } if (source) { this.source.push(source); } }, replaceStack: function replaceStack(callback) { var prefix = ['('], stack = undefined, createdStack = undefined, usedLiteral = undefined; /* istanbul ignore next */ if (!this.isInline()) { throw new _exception2['default']('replaceStack on non-inline'); } // We want to merge the inline statement into the replacement statement via ',' var top = this.popStack(true); if (top instanceof Literal) { // Literals do not need to be inlined stack = [top.value]; prefix = ['(', stack]; usedLiteral = true; } else { // Get or create the current stack name for use by the inline createdStack = true; var _name = this.incrStack(); prefix = ['((', this.push(_name), ' = ', top, ')']; stack = this.topStack(); } var item = callback.call(this, stack); if (!usedLiteral) { this.popStack(); } if (createdStack) { this.stackSlot--; } this.push(prefix.concat(item, ')')); }, incrStack: function incrStack() { this.stackSlot++; if (this.stackSlot > this.stackVars.length) { this.stackVars.push('stack' + this.stackSlot); } return this.topStackName(); }, topStackName: function topStackName() { return 'stack' + this.stackSlot; }, flushInline: function flushInline() { var inlineStack = this.inlineStack; this.inlineStack = []; for (var i = 0, len = inlineStack.length; i < len; i++) { var entry = inlineStack[i]; /* istanbul ignore if */ if (entry instanceof Literal) { this.compileStack.push(entry); } else { var stack = this.incrStack(); this.pushSource([stack, ' = ', entry, ';']); this.compileStack.push(stack); } } }, isInline: function isInline() { return this.inlineStack.length; }, popStack: function popStack(wrapped) { var inline = this.isInline(), item = (inline ? this.inlineStack : this.compileStack).pop(); if (!wrapped && item instanceof Literal) { return item.value; } else { if (!inline) { /* istanbul ignore next */ if (!this.stackSlot) { throw new _exception2['default']('Invalid stack pop'); } this.stackSlot--; } return item; } }, topStack: function topStack() { var stack = this.isInline() ? this.inlineStack : this.compileStack, item = stack[stack.length - 1]; /* istanbul ignore if */ if (item instanceof Literal) { return item.value; } else { return item; } }, contextName: function contextName(context) { if (this.useDepths && context) { return 'depths[' + context + ']'; } else { return 'depth' + context; } }, quotedString: function quotedString(str) { return this.source.quotedString(str); }, objectLiteral: function objectLiteral(obj) { return this.source.objectLiteral(obj); }, aliasable: function aliasable(name) { var ret = this.aliases[name]; if (ret) { ret.referenceCount++; return ret; } ret = this.aliases[name] = this.source.wrap(name); ret.aliasable = true; ret.referenceCount = 1; return ret; }, setupHelper: function setupHelper(paramSize, name, blockHelper) { var params = [], paramsInit = this.setupHelperArgs(name, paramSize, params, blockHelper); var foundHelper = this.nameLookup('helpers', name, 'helper'), callContext = this.aliasable(this.contextName(0) + ' != null ? ' + this.contextName(0) + ' : (container.nullContext || {})'); return { params: params, paramsInit: paramsInit, name: foundHelper, callParams: [callContext].concat(params) }; }, setupParams: function setupParams(helper, paramSize, params) { var options = {}, contexts = [], types = [], ids = [], objectArgs = !params, param = undefined; if (objectArgs) { params = []; } options.name = this.quotedString(helper); options.hash = this.popStack(); if (this.trackIds) { options.hashIds = this.popStack(); } if (this.stringParams) { options.hashTypes = this.popStack(); options.hashContexts = this.popStack(); } var inverse = this.popStack(), program = this.popStack(); // Avoid setting fn and inverse if neither are set. This allows // helpers to do a check for `if (options.fn)` if (program || inverse) { options.fn = program || 'container.noop'; options.inverse = inverse || 'container.noop'; } // The parameters go on to the stack in order (making sure that they are evaluated in order) // so we need to pop them off the stack in reverse order var i = paramSize; while (i--) { param = this.popStack(); params[i] = param; if (this.trackIds) { ids[i] = this.popStack(); } if (this.stringParams) { types[i] = this.popStack(); contexts[i] = this.popStack(); } } if (objectArgs) { options.args = this.source.generateArray(params); } if (this.trackIds) { options.ids = this.source.generateArray(ids); } if (this.stringParams) { options.types = this.source.generateArray(types); options.contexts = this.source.generateArray(contexts); } if (this.options.data) { options.data = 'data'; } if (this.useBlockParams) { options.blockParams = 'blockParams'; } return options; }, setupHelperArgs: function setupHelperArgs(helper, paramSize, params, useRegister) { var options = this.setupParams(helper, paramSize, params); options.loc = JSON.stringify(this.source.currentLocation); options = this.objectLiteral(options); if (useRegister) { this.useRegister('options'); params.push('options'); return ['options=', options]; } else if (params) { params.push(options); return ''; } else { return options; } } }; (function () { var reservedWords = ('break else new var' + ' case finally return void' + ' catch for switch while' + ' continue function this with' + ' default if throw' + ' delete in try' + ' do instanceof typeof' + ' abstract enum int short' + ' boolean export interface static' + ' byte extends long super' + ' char final native synchronized' + ' class float package throws' + ' const goto private transient' + ' debugger implements protected volatile' + ' double import public let yield await' + ' null true false').split(' '); var compilerWords = JavaScriptCompiler.RESERVED_WORDS = {}; for (var i = 0, l = reservedWords.length; i < l; i++) { compilerWords[reservedWords[i]] = true; } })(); /** * @deprecated May be removed in the next major version */ JavaScriptCompiler.isValidJavaScriptVariableName = function (name) { return !JavaScriptCompiler.RESERVED_WORDS[name] && /^[a-zA-Z_$][0-9a-zA-Z_$]*$/.test(name); }; function strictLookup(requireTerminal, compiler, parts, type) { var stack = compiler.popStack(), i = 0, len = parts.length; if (requireTerminal) { len--; } for (; i < len; i++) { stack = compiler.nameLookup(stack, parts[i], type); } if (requireTerminal) { return [compiler.aliasable('container.strict'), '(', stack, ', ', compiler.quotedString(parts[i]), ', ', JSON.stringify(compiler.source.currentLocation), ' )']; } else { return stack; } } exports['default'] = JavaScriptCompiler; module.exports = exports['default']; /***/ }), /* 53 */ /***/ (function(module, exports, __webpack_require__) { /* global define */ 'use strict'; var _Object$keys = __webpack_require__(13)['default']; exports.__esModule = true; var _utils = __webpack_require__(5); var SourceNode = undefined; try { /* istanbul ignore next */ if (false) { // We don't support this in AMD environments. For these environments, we asusme that // they are running on the browser and thus have no need for the source-map library. var SourceMap = require('source-map'); SourceNode = SourceMap.SourceNode; } } catch (err) {} /* NOP */ /* istanbul ignore if: tested but not covered in istanbul due to dist build */ if (!SourceNode) { SourceNode = function (line, column, srcFile, chunks) { this.src = ''; if (chunks) { this.add(chunks); } }; /* istanbul ignore next */ SourceNode.prototype = { add: function add(chunks) { if (_utils.isArray(chunks)) { chunks = chunks.join(''); } this.src += chunks; }, prepend: function prepend(chunks) { if (_utils.isArray(chunks)) { chunks = chunks.join(''); } this.src = chunks + this.src; }, toStringWithSourceMap: function toStringWithSourceMap() { return { code: this.toString() }; }, toString: function toString() { return this.src; } }; } function castChunk(chunk, codeGen, loc) { if (_utils.isArray(chunk)) { var ret = []; for (var i = 0, len = chunk.length; i < len; i++) { ret.push(codeGen.wrap(chunk[i], loc)); } return ret; } else if (typeof chunk === 'boolean' || typeof chunk === 'number') { // Handle primitives that the SourceNode will throw up on return chunk + ''; } return chunk; } function CodeGen(srcFile) { this.srcFile = srcFile; this.source = []; } CodeGen.prototype = { isEmpty: function isEmpty() { return !this.source.length; }, prepend: function prepend(source, loc) { this.source.unshift(this.wrap(source, loc)); }, push: function push(source, loc) { this.source.push(this.wrap(source, loc)); }, merge: function merge() { var source = this.empty(); this.each(function (line) { source.add([' ', line, '\n']); }); return source; }, each: function each(iter) { for (var i = 0, len = this.source.length; i < len; i++) { iter(this.source[i]); } }, empty: function empty() { var loc = this.currentLocation || { start: {} }; return new SourceNode(loc.start.line, loc.start.column, this.srcFile); }, wrap: function wrap(chunk) { var loc = arguments.length <= 1 || arguments[1] === undefined ? this.currentLocation || { start: {} } : arguments[1]; if (chunk instanceof SourceNode) { return chunk; } chunk = castChunk(chunk, this, loc); return new SourceNode(loc.start.line, loc.start.column, this.srcFile, chunk); }, functionCall: function functionCall(fn, type, params) { params = this.generateList(params); return this.wrap([fn, type ? '.' + type + '(' : '(', params, ')']); }, quotedString: function quotedString(str) { return '"' + (str + '').replace(/\\/g, '\\\\').replace(/"/g, '\\"').replace(/\n/g, '\\n').replace(/\r/g, '\\r').replace(/\u2028/g, '\\u2028') // Per Ecma-262 7.3 + 7.8.4 .replace(/\u2029/g, '\\u2029') + '"'; }, objectLiteral: function objectLiteral(obj) { // istanbul ignore next var _this = this; var pairs = []; _Object$keys(obj).forEach(function (key) { var value = castChunk(obj[key], _this); if (value !== 'undefined') { pairs.push([_this.quotedString(key), ':', value]); } }); var ret = this.generateList(pairs); ret.prepend('{'); ret.add('}'); return ret; }, generateList: function generateList(entries) { var ret = this.empty(); for (var i = 0, len = entries.length; i < len; i++) { if (i) { ret.add(','); } ret.add(castChunk(entries[i], this)); } return ret; }, generateArray: function generateArray(entries) { var ret = this.generateList(entries); ret.prepend('['); ret.add(']'); return ret; } }; exports['default'] = CodeGen; module.exports = exports['default']; /***/ }) /******/ ]) }); ;includes/images/ui-icons_ffffff_256x240.png000064400000010517152214270100014366 0ustar00PNG  IHDRIJ pHYsHHFk>PLTE)[VYtRNS  !"#$'),/12348pHHHH;?l9+WOBX;K@Рr]*[՟@Cv=2`߭BfP B b -خ"m onR0h> dxHPBBBBBBB< AҊր;2e|RgG,4\82< Yw8PȨ"证3䯱\& |%\g>@ƚඅ÷}HHHHHHHHؠ3a ءOP+J69bw}`"*N1I^v 1 o:< Up7x a0ȟۈC&l@N a;h ]ԋq"GnDoH@Dp5&v/K]͐STU*<,QT.^kz?"^r"@FX4ٵu,vA"kfb ȟ+!<, ѸȆXRwt a-գ弉 pW{ *.BfDk"&nһ ڈX }p~5tц.l}>@BZ! :Dk38#&|uzG#$=.6W!T:z:b5nXVf@\ :_-~k' 7}H`kvHt~"w<6l'DDMbt2rwD%:iFG5(珒Un@p; 4]ŽMSi}e@DGoOn' C4ˠ9m\'n4l:ⶋHu2#+ 661ys,ڟب X_нU> t{<3VpZvQĂ/!~@[w?!!!!aPh?X~}n*7.U*B"].;:HG#Bbv@9{#՝/4}sٚ:Z70@>`n7{:v ,ˬ#dF@ 6p BJCct|~C8'G@Ъ  +H Y^*HjWg7{Y2 ?P?e(4pUс[}:sB=M`.-P?sE/? EB8<<pPcDLn0Y@qP iyގysk6&>໘0XgBs0V8 r^1P\uY*B֪BBBB–pyvYv|X SqؓB5?ۓ@ Ā:X4Q&׮r}?Z Je؞in'^\0th׾yJ#y >h27h=_q)\ 9{H}ũʎ3:6 `0G`HbYTcd|xsP +T^6"fp:V&cG@p G)M,bRJ3 Cj[vkU0c}Z-%у>R OAujOwbJɨj yh6j?^#qHEF@f+"(H{{d!M1{vXX06$9v~CL$Tsg ˂oYM~y8Rtbug~O{3 boWvpbZrplsz*׈OC|>9Cx _~ Ωֿc=C|C+ # g;@:WMP L7~h<_kʸӑ: nHtXJr>u,Tc&\ix `mhW u{Ν3 (xf@@B 2Q*2k:uTVMM+yʃBҋ3  _̓@*&^=uxiP?ȸ}jݜ2 2=)+גa/Ls_5g!޿pg G+o̧0uK*|؂uhN?. +I8:=4OO 1O&y駋/f >`T CB`\(p>W~;f* ^ -7}@$bŕG^߯77 58i<#n&uZ^}:7,&$$$$J>Ja9ꊾ~moR@2C9/CgSnGV%K>AB%.k\߁m\O"K^ JVf0 fx|&G X->Rh(`;6< ۀ~*o?ȈrCϑ·%z!/_9h|a V:Y2^&_\M>R\⧭*E{.߆=]@ Խ-ǠW۟z^&d=Roh1j<-K|u0~K'5Z(of8Fk^T0:Ñ[ gۯ%PooUm.vQu^oU9|@L]f|!eWV1'h,]iRs?)㽾`r/l[͗VNNplL7ZTO$/K!{*,  >%kGAwwXHFЁxob&1MJ, ?_|Sk:so'\wN_w'6@walaGߎ̪TW9]U]rBBBBBBB,6y ok˷P}H&@YT- 3@Զ "Y@n> $$$$$$$xUPt_*{%}_p}oC (P j7^UGoЉMiWؗ%tEXtdate:create2015-03-11T14:59:12+00:000i%tEXtdate:modify2015-03-11T14:59:12+00:00AtEXtSoftwareAdobe ImageReadyqe<IENDB`includes/images/ui-bg_highlight-soft_100_eeeeee_1x100.png000064400000000402152214270100017024 0ustar00PNG  IHDRd2 pHYsHHFk>bKGD1DIDATWc@j&U &C'&L L$k2v3?a,6>%tEXtdate:create2015-12-02T23:52:01+00:00(os%tEXtdate:modify2015-12-02T23:52:01+00:00YIENDB`includes/images/ui-bg_diagonals-thick_20_666666_40x40.png000064400000000460152214270100016446 0ustar00PNG  IHDR((; pHYsHHFk>bKGD1rIDATHձ ;QUc1. a6syrr\ \ qXn $ dR\9b0=b m?)ՔjJ5RM ڧ+rqq%tEXtdate:create2015-12-02T23:52:01+00:00(os%tEXtdate:modify2015-12-02T23:52:01+00:00YIENDB`includes/images/ui-icons_ef8c08_256x240.png000064400000010516152214270100014137 0ustar00PNG  IHDRIJPLTEjYtRNS3P/"Uq@f`2 !<BHK Z#'1S,4j8E|)Q$ bJmߜGc?oh@^bKGDH pHYsHHFk>IDATx] c۶Hj蘒]Kd%٫뺮lm:w]H^%SO~; [ r-g`I/1z~ a^RK%`;Wh y}H9pβGU AA,vU7ض- P-MJ-عL>`ӣoBJHHHHHHHؘ'a?HZp]BR⨀EߝҺ'@^!8\DRP5pp5dX`ᰄXܶp VwW:?lV; *t@ ]&"g[=V .p/4|}BY F =qB>U\ ]!Fm~]v ./A sqȄ i!qa_z6XC \HdBBBBBB®be+ұJ\[@8%*Z«;C tqMR;[@$H"2H@dmB 1r%ÀـY#KT]ꎎ<8lEUz78 xoR9E }ЂH`M$ܭ\z[@qkš #ݯQ8<8p|XzHH+$Dtpx`gV.]Oy%0W<]BOC얺f- A~ ~x?+Aӯر;|4ᦏ 9},wN";)O턈I=3N&X}Qo>BDx#P> Qs n7|i*9B,:m62d`w#UU^˕$:m{Mz]vV&sz`e2!&&&oX5A j>4nogJxNۮQ08 8|:@@pX7 [~_y .'$$$$r'gp UFE<7[JyH\# Ba'@G)qOxd^(-hT"g{hcԓo[c.[3[{փ(MfO]Rnbe`&:n֓>Ph]ih,7]Μp0NO`$`ZuA"1!u)G> !_‹>PIÏ p}ky_f8Z1Ԥ@6EJ} hax`ye-(VΜP5p u \ l"D! 8P (1WK@ "=j6֝ࡷ;p~b<~>GTW@<99cáa@% 8 (fPHB@z_W0`?@@{+0 |T#c@dQ@\ZM@ ,E@Nx/,9 Lnntz|y{'b\O*W?s]P㽵Ꟑx$\A0]h֣VSq1x!Yx,oX}ฦ#I X<7 yZ Q< d=1`3MԳ)+\ߏVR;sY;g1ggL(oF툡p~>B9ڟ ZNPBAdAu'_a58dq̸uƢlX8 ٣/>?X?OXA3*6Ԃ v'Opß `Q.n f'&$P-]Z`tVG xc2N7L}VL6^3WW᱇&ha0$^da"??/ФhLлg7ų3#koNQP# ,iI ?X LI5wv,v5kϿT-g-EV'I~7]o ?EW3J &ze@ '+'>/r(4׹3s<4⩉᫯@WP³gpF<\tCoheah8|E{U*P 9ƏOWt>T'X NP\G v`]`+j#75C7߾|7>CpȒQhC&TEf|\c/\\# ޞ*y%yVzqrWadyPSs[x׫/ J1gWOMsN'?=xZr< 8Tꯦ|=F/^=+]]%Qż1=n!c[0n|5 >Epf2p% Gg>"Q$o>x  l3 tbԇnStR}et^ET0gU̓>)kyeSgETB:U[о*{y>ɄբS:t;7c3?>h?43M`l` S|\ ַlZ?٘[C[##JC57pzL6}g|Ci"pSl^zB!u㉱Z>N 0 esK?%k.+lM@FLZh> 4! tڟk`'o'X@LÅ!k&߹7Zs#>vD,(Fx)}g\m٤_N6YńB !Q),?Z]ѻw-w: S UYw(GulȪdsiC5CgIDATx] c۶Hj蘒]Kd%٫뺮lm:w]H^%SO~; [ r-g`I/1z~ a^RK%`;Wh y}H9pβGU AA,vU7ض- P-MJ-عL>`ӣoBJHHHHHHHؘ'a?HZp]BR⨀EߝҺ'@^!8\DRP5pp5dX`ᰄXܶp VwW:?lV; *t@ ]&"g[=V .p/4|}BY F =qB>U\ ]!Fm~]v ./A sqȄ i!qa_z6XC \HdBBBBBB®be+ұJ\[@8%*Z«;C tqMR;[@$H"2H@dmB 1r%ÀـY#KT]ꎎ<8lEUz78 xoR9E }ЂH`M$ܭ\z[@qkš #ݯQ8<8p|XzHH+$Dtpx`gV.]Oy%0W<]BOC얺f- A~ ~x?+Aӯر;|4ᦏ 9},wN";)O턈I=3N&X}Qo>BDx#P> Qs n7|i*9B,:m62d`w#UU^˕$:m{Mz]vV&sz`e2!&&&oX5A j>4nogJxNۮQ08 8|:@@pX7 [~_y .'$$$$r'gp UFE<7[JyH\# Ba'@G)qOxd^(-hT"g{hcԓo[c.[3[{փ(MfO]Rnbe`&:n֓>Ph]ih,7]Μp0NO`$`ZuA"1!u)G> !_‹>PIÏ p}ky_f8Z1Ԥ@6EJ} hax`ye-(VΜP5p u \ l"D! 8P (1WK@ "=j6֝ࡷ;p~b<~>GTW@<99cáa@% 8 (fPHB@z_W0`?@@{+0 |T#c@dQ@\ZM@ ,E@Nx/,9 Lnntz|y{'b\O*W?s]P㽵Ꟑx$\A0]h֣VSq1x!Yx,oX}ฦ#I X<7 yZ Q< d=1`3MԳ)+\ߏVR;sY;g1ggL(oF툡p~>B9ڟ ZNPBAdAu'_a58dq̸uƢlX8 ٣/>?X?OXA3*6Ԃ v'Opß `Q.n f'&$P-]Z`tVG xc2N7L}VL6^3WW᱇&ha0$^da"??/ФhLлg7ų3#koNQP# ,iI ?X LI5wv,v5kϿT-g-EV'I~7]o ?EW3J &ze@ '+'>/r(4׹3s<4⩉᫯@WP³gpF<\tCoheah8|E{U*P 9ƏOWt>T'X NP\G v`]`+j#75C7߾|7>CpȒQhC&TEf|\c/\\# ޞ*y%yVzqrWadyPSs[x׫/ J1gWOMsN'?=xZr< 8Tꯦ|=F/^=+]]%Qż1=n!c[0n|5 >Epf2p% Gg>"Q$o>x  l3 tbԇnStR}et^ET0gU̓>)kyeSgETB:U[о*{y>ɄբS:t;7c3?>h?43M`l` S|\ ַlZ?٘[C[##JC57pzL6}g|Ci"pSl^zB!u㉱Z>N 0 esK?%k.+lM@FLZh> 4! tڟk`'o'X@LÅ!k&߹7Zs#>vD,(Fx)}g\m٤_N6YńB !Q),?Z]ѻw-w: S UYw(GulȪdsiC5CgbKGD XmIDAT(ScL `0 @3@Yg ʀxx"bx1A z^SYlX_Y,j-ú" aSH>G@[%tEXtdate:create2015-12-02T23:52:01+00:00(os%tEXtdate:modify2015-12-02T23:52:01+00:00YIENDB`includes/images/ui-bg_diagonals-thick_18_b81900_40x40.png000064400000000550152214270100016515 0ustar00PNG  IHDR((S y pHYsHHFk>bKGD XIDATh! FὅC4?[ RFq-ώm?6c w>lk~U*֦f`CK8v5M`% XZR `mj@M`?3^i:6?ҏhZ4-MEӢiѴhZ4-MEӢiѴhZ4N ݾ^PM%tEXtdate:create2015-12-02T23:52:01+00:00(os%tEXtdate:modify2015-12-02T23:52:01+00:00YIENDB`includes/images/ui-icons_222222_256x240.png000064400000010517152214270100013676 0ustar00PNG  IHDRIJ pHYsHHFk>PLTE""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""FgYtRNS  !"#$'),/12348pHHHH;?l9+WOBX;K@Рr]*[՟@Cv=2`߭BfP B b -خ"m onR0h> dxHPBBBBBBB< AҊր;2e|RgG,4\82< Yw8PȨ"证3䯱\& |%\g>@ƚඅ÷}HHHHHHHHؠ3a ءOP+J69bw}`"*N1I^v 1 o:< Up7x a0ȟۈC&l@N a;h ]ԋq"GnDoH@Dp5&v/K]͐STU*<,QT.^kz?"^r"@FX4ٵu,vA"kfb ȟ+!<, ѸȆXRwt a-գ弉 pW{ *.BfDk"&nһ ڈX }p~5tц.l}>@BZ! :Dk38#&|uzG#$=.6W!T:z:b5nXVf@\ :_-~k' 7}H`kvHt~"w<6l'DDMbt2rwD%:iFG5(珒Un@p; 4]ŽMSi}e@DGoOn' C4ˠ9m\'n4l:ⶋHu2#+ 661ys,ڟب X_нU> t{<3VpZvQĂ/!~@[w?!!!!aPh?X~}n*7.U*B"].;:HG#Bbv@9{#՝/4}sٚ:Z70@>`n7{:v ,ˬ#dF@ 6p BJCct|~C8'G@Ъ  +H Y^*HjWg7{Y2 ?P?e(4pUс[}:sB=M`.-P?sE/? EB8<<pPcDLn0Y@qP iyގysk6&>໘0XgBs0V8 r^1P\uY*B֪BBBB–pyvYv|X SqؓB5?ۓ@ Ā:X4Q&׮r}?Z Je؞in'^\0th׾yJ#y >h27h=_q)\ 9{H}ũʎ3:6 `0G`HbYTcd|xsP +T^6"fp:V&cG@p G)M,bRJ3 Cj[vkU0c}Z-%у>R OAujOwbJɨj yh6j?^#qHEF@f+"(H{{d!M1{vXX06$9v~CL$Tsg ˂oYM~y8Rtbug~O{3 boWvpbZrplsz*׈OC|>9Cx _~ Ωֿc=C|C+ # g;@:WMP L7~h<_kʸӑ: nHtXJr>u,Tc&\ix `mhW u{Ν3 (xf@@B 2Q*2k:uTVMM+yʃBҋ3  _̓@*&^=uxiP?ȸ}jݜ2 2=)+גa/Ls_5g!޿pg G+o̧0uK*|؂uhN?. +I8:=4OO 1O&y駋/f >`T CB`\(p>W~;f* ^ -7}@$bŕG^߯77 58i<#n&uZ^}:7,&$$$$J>Ja9ꊾ~moR@2C9/CgSnGV%K>AB%.k\߁m\O"K^ JVf0 fx|&G X->Rh(`;6< ۀ~*o?ȈrCϑ·%z!/_9h|a V:Y2^&_\M>R\⧭*E{.߆=]@ Խ-ǠW۟z^&d=Roh1j<-K|u0~K'5Z(of8Fk^T0:Ñ[ gۯ%PooUm.vQu^oU9|@L]f|!eWV1'h,]iRs?)㽾`r/l[͗VNNplL7ZTO$/K!{*,  >%kGAwwXHFЁxob&1MJ, ?_|Sk:so'\wN_w'6@walaGߎ̪TW9]U]rBBBBBBB,6y ok˷P}H&@YT- 3@Զ "Y@n> $$$$$$$xUPt_*{%}_p}oC (P j7^UGoЉMiWؗ%tEXtdate:create2015-03-11T14:59:12+00:000i%tEXtdate:modify2015-03-11T14:59:12+00:00AtEXtSoftwareAdobe ImageReadyqe<IENDB`includes/images/ui-bg_flat_10_000000_40x100.png000064400000000126152214270100014342 0ustar00PNG  IHDR(dΪ9PLTEz=IDATcXTGIENDB`includes/images/ui-bg_glass_65_ffffff_1x400.png000064400000000317152214270100015165 0ustar00PNG  IHDRG#7vbKGD݊ pHYsHHFk>IDAT(ch`ph4i%tEXtdate:create2015-12-02T23:52:01+00:00(os%tEXtdate:modify2015-12-02T23:52:01+00:00YIENDB`includes/images/ui-bg_glass_100_fdf5ce_1x400.png000064400000000512152214270100015141 0ustar00PNG  IHDRA pHYsHHFk>bKGD XIDATH!@yBP R$8j=Mn&& 8>1n,pq~λN6Ү"NL9)Vk%r-( Њ]ĒMQ,8lf"coQ)Ęʗ;|=%tEXtdate:create2015-12-02T23:52:01+00:00(os%tEXtdate:modify2015-12-02T23:52:01+00:00YIENDB`includes/images/ui-icons_228ef1_256x240.png000064400000010516152214270100014051 0ustar00PNG  IHDRIJPLTE""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""3~YtRNS3P/"Uq@f`2 !<BHK Z#'1S,4j8E|)Q$ bJmߜGc?oh@^bKGDH pHYsHHFk>IDATx] c۶Hj蘒]Kd%٫뺮lm:w]H^%SO~; [ r-g`I/1z~ a^RK%`;Wh y}H9pβGU AA,vU7ض- P-MJ-عL>`ӣoBJHHHHHHHؘ'a?HZp]BR⨀EߝҺ'@^!8\DRP5pp5dX`ᰄXܶp VwW:?lV; *t@ ]&"g[=V .p/4|}BY F =qB>U\ ]!Fm~]v ./A sqȄ i!qa_z6XC \HdBBBBBB®be+ұJ\[@8%*Z«;C tqMR;[@$H"2H@dmB 1r%ÀـY#KT]ꎎ<8lEUz78 xoR9E }ЂH`M$ܭ\z[@qkš #ݯQ8<8p|XzHH+$Dtpx`gV.]Oy%0W<]BOC얺f- A~ ~x?+Aӯر;|4ᦏ 9},wN";)O턈I=3N&X}Qo>BDx#P> Qs n7|i*9B,:m62d`w#UU^˕$:m{Mz]vV&sz`e2!&&&oX5A j>4nogJxNۮQ08 8|:@@pX7 [~_y .'$$$$r'gp UFE<7[JyH\# Ba'@G)qOxd^(-hT"g{hcԓo[c.[3[{փ(MfO]Rnbe`&:n֓>Ph]ih,7]Μp0NO`$`ZuA"1!u)G> !_‹>PIÏ p}ky_f8Z1Ԥ@6EJ} hax`ye-(VΜP5p u \ l"D! 8P (1WK@ "=j6֝ࡷ;p~b<~>GTW@<99cáa@% 8 (fPHB@z_W0`?@@{+0 |T#c@dQ@\ZM@ ,E@Nx/,9 Lnntz|y{'b\O*W?s]P㽵Ꟑx$\A0]h֣VSq1x!Yx,oX}ฦ#I X<7 yZ Q< d=1`3MԳ)+\ߏVR;sY;g1ggL(oF툡p~>B9ڟ ZNPBAdAu'_a58dq̸uƢlX8 ٣/>?X?OXA3*6Ԃ v'Opß `Q.n f'&$P-]Z`tVG xc2N7L}VL6^3WW᱇&ha0$^da"??/ФhLлg7ų3#koNQP# ,iI ?X LI5wv,v5kϿT-g-EV'I~7]o ?EW3J &ze@ '+'>/r(4׹3s<4⩉᫯@WP³gpF<\tCoheah8|E{U*P 9ƏOWt>T'X NP\G v`]`+j#75C7߾|7>CpȒQhC&TEf|\c/\\# ޞ*y%yVzqrWadyPSs[x׫/ J1gWOMsN'?=xZr< 8Tꯦ|=F/^=+]]%Qż1=n!c[0n|5 >Epf2p% Gg>"Q$o>x  l3 tbԇnStR}et^ET0gU̓>)kyeSgETB:U[о*{y>ɄբS:t;7c3?>h?43M`l` S|\ ַlZ?٘[C[##JC57pzL6}g|Ci"pSl^zB!u㉱Z>N 0 esK?%k.+lM@FLZh> 4! tڟk`'o'X@LÅ!k&߹7Zs#>vD,(Fx)}g\m٤_N6YńB !Q),?Z]ѻw-w: S UYw(GulȪdsiC5CgbKGD XIDATxo^UITS^"UJ*ԤI؎c'qivŸ6}6!h"P@VB$mji޵QP/(mTTHr!nguwƿ3gGw̙3gfdm&DDDDDl@9#"""""wDDDDD9#""""rpGDDDDD;"""""rpGDDDD;"""""wDDDDD7\~=vO힖c-F='Ch=/b8[̾u~=1Wׅ5yk =y[_Jkyڲ**k0oԨ឵ O赺쌔]#z^juO<2ܺ䵯(ݾ*=t4~+:ؖJVs=5ʚJkW6ΨR^0szuo7m!n5kSNj+wӚcgn^}Zc;=[e\Poy-VL9"""""6i;>c;bOY?Ǿ{KXMaO{D:YG_e>{Wֈ653XZ_zoQs^+Oko)z?GzvOVXi׭7}eO ]z.Of՟C 2fߎҚ~gڌJOZGuog֓֌Uf:Gbbq+5:^˵#驱ZWOR6 kHzf߿J;jr^n(3W5“=P2eX%)19#""""s\wdsmwI(M}\ԈU*s=WKeu٘3\{2:FbUc-(V^[:e3> ѿkJ̗'ַDzT;c|;z";XbT{J'xc> kE?*;=y}N̋}?s52wyʳ6=NF)U1Cjٕ29W;ϼK':sǁӟͧw{Hn{,;ȺCDD&; k\[GiGټwY#_'룰^?VJzӟ 4yNL\wl{Z8ҲB;8k+5GYўW=t3(g};GDDDDĖ NزO_?ADDDDĖ gN~YDDDDDl[6t*~C߰lط{yBϳ['ș<3R;,U%bs5Y5f_X67X(+ZKGەo]5٫R_kCk5µwi>c'޻,"""""l~DDDDDĖ ol[eC_DDDDDl^("""""l?\C]wYϳ֔w)?>mۘ)V !oZg9_7df^JJ޲26[Vjo-uVY-R:NO!""""bˆm[6tݷu"""""l~i[GDDDDĖ ]o"""""lͼ*DDDDDl1k:k_JJ=7}{6=je,zFWbWNLB_ɟRʳuޓjf^<̦/ewgO!j?gңs̫~V\z̧=sXbo{jtOhX{'J?oTF?Ly=ɻߓ{֔ព9]ַR,OS뒒-{%[zk4?=3⩁Jv;rJj25hYi;Jo{S;-轝VښYu]J =QbRzZțR#yo)U?3YfçT.*+U;sYqzm W ǬQ:IJF&x+-7;EDDDDĖ}kf5aƸ~kx +F$KE՟^P㯔Fj(nO_3Q[VLw1}'Swj8.k Wçb(d2wzn?޲1gN?8剞{[9XOlURUEm^ X#PJ^kʸoWG/֫{XӗgW_(jrgX1-m-ѥߕ?ton?oޕ8+wQRTfS<{6o(Z΅>^=z>xT)k}λu'ңYy/FNꩄ|YB(OI֝њEmϩC'ڭ%n>e@eX]䭈qWkXך?gUњB^[Gkw.zf$[yCjR,/ ѿkJ̗'ַDzT;ƊHmwn~=mׇƮ+-O?ׂOS:SzLqKlwe\#ijv: ^gR*{T5c}Tg_Qzk Pjmy5*ʳd说yBl*}89DV،מy檫eӅj\+l%tEXtdate:create2015-12-02T23:52:01+00:00(os%tEXtdate:modify2015-12-02T23:52:01+00:00YIENDB`includes/images/ui-bg_glass_100_f6f6f6_1x400.png000064400000000400152214270100015004 0ustar00PNG  IHDRD pHYsHHFk>bKGD1BIDAT8c5a"*?L*L AL LL eLeL L0v.C c 9h"b _u%tEXtdate:create2015-12-02T23:52:01+00:00(os%tEXtdate:modify2015-12-02T23:52:01+00:00YIENDB`includes/jquery-ui.dialog.extended/jquery-ui.dialog.extended-2-23-7.min.js000064400000011020152214270100022161 0ustar00!function(o){o.widget("ui.dialog",o.ui.dialog,{options:{height:200,closeModalOnClick:!0,dialogClass:"updraft-dialog",forceFullscreen:!1,resizeOnWindowResize:!1,scrollWithViewport:!1,resizeAccordingToViewport:!0,resizeToBestPossibleSize:!1,useContentSize:!1,useAnimation:!0,animateOptions:{duration:500,queue:!1},resized:null},change:function(t,i,e,s){(s="boolean"!=typeof s?this.options.useAnimation:s)?(this.setAriaLive(!0),this.element.one(this.widgetEventPrefix+"resized",this,function(i){i.data.element.html(t),i.data.setAriaLive(!1),i.data.focusTabbable()})):this.element.html(t),this.changeSize(i,e)},changeSize:function(i,t){this._setOptions({width:i,height:t})},_setOption:function(i,t){"width"===i&&(this._oldSize.width=t),"height"===i&&(this._oldSize.height=t),this.options.useAnimation&&this.options.useContentSize&&this._isVisible&&("width"===i&&(t+=this.uiDialog.width()-this.element.width()),"height"===i)&&(t+=this.uiDialog.outerHeight()-this.element.height()),this._super(i,t)},_getSize:function(i){var t=this.options,e=o.position.getWithinInfo(t.position.of),s=e.height>=e.width,e={width:e.width-(this.uiDialog.outerWidth()-this.uiDialog.width()),height:e.height};return t.forceFullscreen?e:(t.resizeToBestPossibleSize&&(i=s?this._calcSize(i,e.width,"width","height"):this._calcSize(i,e.height,"height","width")),(t.resizeAccordingToViewport||t.resizeToBestPossibleSize)&&(e.widtht.width+e&&(t.width=t.minWidth),i=this.uiDialog.css({height:"auto",width:t.width+e}).outerHeight(),e=this._getSize({width:t.width+e,height:t.height+i}),this.uiDialog.css("width",e.width),this.element.height(Math.max(0,e.height-i)),this.uiDialog.is(":data(ui-resizable)")&&this.uiDialog.resizable("option","minHeight",this._minHeight()),o.extend(t,e)},_animateUsing:function(i,t){var e=this;i.left=t.target.left+(t.target.width-this.options.width-(this.uiDialog.outerWidth()-this.uiDialog.width()))/2,i.top=t.target.top+(t.target.height-this.options.height)/2,i.top<0&&(i.top=0),this.uiDialog.animate(i,o.extend({},this.options.animateOptions,{complete:function(){e._trigger("resized")}}))},_animateSize:function(){var i=this.options;this.uiDialog.animate({width:i.width},i.animateOptions),this.element.animate({height:i.height-(this.uiDialog.outerHeight()-this.element.height())},i.animateOptions)},_position:function(){var e=this;this._positionOptions=this.options.position,this.options.useAnimation&&this._isVisible&&(this.options.position.using=function(i,t){e._animateUsing(i,t)}),this._super(),this.options.position=this._positionOptions},setAriaLive:function(i){this.uiDialog.attr({"aria-live":"assertive","aria-relevant":"additions removals text","aria-busy":i})},_create:function(){this._super(),this._isVisible=!1,this._oldSize={width:this.options.width,height:this.options.height},this._on(window,this._windowResizeEvents),o(".updraft-dialog").not(".updraft-container > .updraft-dialog").wrap('
')},_windowResizeEvents:{resize:function(i){this.options.resizeOnWindowResize&&(window===i.target?this._addTimeout(function(){this._setOptions(this._oldSize)}):this._addTimeout(function(){this._position()}))},scroll:function(){this.options.scrollWithViewport&&this.timeout?this._addTimeout(function(){this._position()}):this.timeout=!0}},_addTimeout:function(i){clearTimeout(this.timeout),this._isVisible&&(this.timeout=this._delay(i,250))},_makeResizable:function(){this._super(),this.element.on(this.widgetEventPrefix+"resizestop",this,function(i){i.data.element.css("width","auto"),i.data.uiDialog.css("height","auto")})},_makeDraggable:function(){this._super(),this.element.on(this.widgetEventPrefix+"dragstop",this,function(i){i.data.options.position=i.data._positionOptions})},open:function(){this._super(),this._isVisible=!0},close:function(){this._super(),this._isVisible=!1},focusTabbable:function(){this._focusTabbable()},_createOverlay:function(){this._super(),this.options.modal&&this.options.closeModalOnClick&&this._on(this.overlay,{mousedown:function(i){this.close(i)}})}})}(jQuery);includes/jquery-ui.dialog.extended/jquery-ui.dialog.extended.js000064400000023074152214270100020666 0ustar00/** * v1.0.4 - 05-04-2021 20:10 * * JQuery UI Dialog Extended * * Copyright 2013-2015, Felix Nagel (http://www.felixnagel.com) * Copyright 2021, Team Updraft * Dual licensed under the MIT or GPL Version 2 licenses. * * http://github.com/fnagel/jquery-ui-extensions * * Depends: * jquery.ui.core.js * jquery.ui.widget.js * jquery.ui.dialog.js * * Changes: * Add "updraft-dialog" class for every jQuery UI dialog created by UpdraftPlus plugin. * Wrap all "updraft-dialog" class with "updraft-container" class * to prevent CSS conflict with other plugins that use jQuery UI too. */ (function( $ ) { /* * Option width and height normally set the overall dialog dimensions. * This extensions make these options the dimensions of the content pane if * option useContentSize is enabled. This way it's possible to set the real * content dimensions. * * Please note you won't get the original size but the calculated overall size * when using the width and height option getter. */ $.widget("ui.dialog", $.ui.dialog, { options: { height: 200, // auto is not allowed when using animation closeModalOnClick: true, dialogClass: 'updraft-dialog', // viewport settings forceFullscreen: false, resizeOnWindowResize: false, scrollWithViewport: false, resizeAccordingToViewport: true, resizeToBestPossibleSize: false, // width and height set the content size, not overall size useContentSize: false, // animated options useAnimation: true, animateOptions: { duration: 500, queue: false }, // callbacks resized: null }, // Changes content and resizes dialog change: function(content, width, height, animate) { if (typeof animate !== "boolean") { animate = this.options.useAnimation; } if (animate) { this.setAriaLive(true); this.element.one(this.widgetEventPrefix + "resized", this, function(event) { event.data.element.html(content); event.data.setAriaLive(false); event.data.focusTabbable(); }); } else { this.element.html(content); } this.changeSize(width, height); }, // Changes size changeSize: function(width, height) { this._setOptions({ width: width, height: height }); }, _setOption: function(key, value) { if (key === "width") { this._oldSize.width = value; } if (key === "height") { this._oldSize.height = value; } // we need to adjust the size as we need to set the overall dialog size if (this.options.useAnimation && this.options.useContentSize && this._isVisible) { if (key === "width") { value = value + ( this.uiDialog.width() - this.element.width() ); } if (key === "height") { value = value + ( this.uiDialog.outerHeight() - this.element.height() ); } } this._super(key, value); }, // calculate actual displayed size, data contains already the overall dimensions _getSize: function(data) { var options = this.options, feedback = $.position.getWithinInfo(options.position.of), portrait = ( feedback.height >= feedback.width ) ? true : false, viewport = { width: feedback.width - ( this.uiDialog.outerWidth() - this.uiDialog.width() ), height: feedback.height }; if (options.forceFullscreen) { return viewport; } if (options.resizeToBestPossibleSize) { if (portrait) { data = this._calcSize(data, viewport.width, "width", "height"); } else { data = this._calcSize(data, viewport.height, "height", "width"); } } if (options.resizeAccordingToViewport || options.resizeToBestPossibleSize) { if (viewport.width < data.width) { data = this._calcSize(data, viewport.width, "width", "height"); } if (viewport.height < data.height) { data = this._calcSize(data, viewport.height, "height", "width"); } } return data; }, _calcSize: function( data, value, sortBy, toSort ) { var newData = {}; newData[toSort] = Math.max(0, (data[ toSort ] / data[ sortBy ]) * value); newData[sortBy] = value; return newData; }, _size: function() { // overwrite options with recalculated dimensions $.extend(this.options, this._getSize(this.options)); if (this._isVisible && this.options.useAnimation) { this._animateSize(); return; } if (this.options.useContentSize) { this._contentSize(); return; } this._super(); }, /* * Sets the size of the dialog * * Options width and height define content size, not overall size */ _contentSize: function() { // If the user has resized the dialog, the .ui-dialog and .ui-dialog-content // divs will both have width and height set, so we need to reset them var nonContentHeight, nonContentWidth, actualSize, options = this.options; // Reset content sizing nonContentWidth = this.element.show().css({ width: options.width, minHeight: 0, maxHeight: "none", height: 0 }).outerWidth() - options.width; this.element.css("width", "auto"); if (options.minWidth > options.width + nonContentWidth) { options.width = options.minWidth; } // reset wrapper sizing // determine the height of all the non-content elements nonContentHeight = this.uiDialog.css({ height: "auto", width: options.width + nonContentWidth }) .outerHeight(); actualSize = this._getSize({ width: options.width + nonContentWidth, height: options.height + nonContentHeight }); this.uiDialog.css("width", actualSize.width); this.element.height(Math.max(0, actualSize.height - nonContentHeight)); if (this.uiDialog.is(":data(ui-resizable)") ) { this.uiDialog.resizable("option", "minHeight", this._minHeight()); } // save calculated overall size $.extend(options, actualSize); }, // Processes the animated positioning (position using callback), works with any width and height options _animateUsing: function( position, data ) { var that = this; // calculate new position based on the viewport position.left = ( data.target.left + ( data.target.width - this.options.width - ( this.uiDialog.outerWidth() - this.uiDialog.width() ) ) / 2 ); position.top = ( data.target.top + ( data.target.height - this.options.height ) / 2 ); if (position.top < 0) { position.top = 0; } this.uiDialog.animate(position, $.extend({}, this.options.animateOptions, { complete: function() { that._trigger("resized"); } })); }, // animated the size, uses width and height options like default dialog widget (overall size) _animateSize: function() { var options = this.options; this.uiDialog.animate({ width: options.width }, options.animateOptions); this.element.animate({ // options.height is overall size, we need content size height: options.height - ( this.uiDialog.outerHeight() - this.element.height() ) }, options.animateOptions); }, // position overwrite for animated positioning _position: function() { var that = this; this._positionOptions = this.options.position; // change position.using mechanism if (this.options.useAnimation && this._isVisible) { this.options.position.using = function(position, feedback) { that._animateUsing(position, feedback); }; } this._super(); // reset position.using mechanism this.options.position = this._positionOptions; }, // ARIA helper setAriaLive: function(busy) { this.uiDialog.attr({ "aria-live": "assertive", "aria-relevant": "additions removals text", "aria-busy": busy }); }, // all following functions add a variable to determine if the dialog is visible _create: function() { this._super(); this._isVisible = false; this._oldSize = { width: this.options.width, height: this.options.height }; // make dialog responsive to viewport changes this._on(window, this._windowResizeEvents); // add wrapper to dialog $('.updraft-dialog').not('.updraft-container > .updraft-dialog').wrap('
'); }, _windowResizeEvents: { resize: function(e) { if (this.options.resizeOnWindowResize) { if (window === e.target) { this._addTimeout(function() { this._setOptions(this._oldSize); }); } else { this._addTimeout(function() { this._position(); }); } } }, scroll: function() { // second test prevents initial page load scroll event if (this.options.scrollWithViewport && this.timeout) { this._addTimeout(function() { this._position(); }); } else { this.timeout = true; } } }, _addTimeout: function(callback) { clearTimeout(this.timeout); if (this._isVisible) { this.timeout = this._delay(callback, 250); } }, _makeResizable: function() { this._super(); this.element.on(this.widgetEventPrefix + "resizestop", this, function(event) { event.data.element.css("width", "auto"); event.data.uiDialog.css("height", "auto"); }); }, _makeDraggable: function() { this._super(); this.element.on(this.widgetEventPrefix + "dragstop", this, function(event) { event.data.options.position = event.data._positionOptions; }); }, open: function() { this._super(); this._isVisible = true; }, close: function() { this._super(); this._isVisible = false; }, focusTabbable: function() { this._focusTabbable(); }, _createOverlay: function() { this._super(); if (this.options.modal && this.options.closeModalOnClick) { this._on(this.overlay, { mousedown: function(event) { this.close(event); } }); } } }); }( jQuery )); includes/jquery.serializeJSON/jquery.serializejson.min.js000064400000011033152214270100017660 0ustar00/*! SerializeJSON jQuery plugin. https://github.com/marioizquierdo/jquery.serializeJSON version 3.2.0 (Dec, 2020) Copyright (c) 2012-2021 Mario Izquierdo Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses. */ !function(e){if("function"==typeof define&&define.amd)define(["jquery"],e);else if("object"==typeof exports){var n=require("jquery");module.exports=e(n)}else e(window.jQuery||window.Zepto||window.$)}(function(e){"use strict";var n=/\r?\n/g,r=/^(?:submit|button|image|reset|file)$/i,t=/^(?:input|select|textarea|keygen)/i,i=/^(?:checkbox|radio)$/i;e.fn.serializeJSON=function(n){var r=e.serializeJSON,t=r.setupOpts(n),i=e.extend({},t.defaultTypes,t.customTypes),a=r.serializeArray(this,t),u={};return e.each(a,function(n,a){var s=a.name,l=e(a.el).attr("data-value-type");if(!l&&!t.disableColonTypes){var o=r.splitType(a.name);s=o[0],l=o[1]}if("skip"!==l){l||(l=t.defaultType);var p=r.applyTypeFunc(a.name,a.value,l,a.el,i);if(p||!r.shouldSkipFalsy(a.name,s,l,a.el,t)){var f=r.splitInputNameIntoKeysArray(s);r.deepSet(u,f,p,t)}}}),u},e.serializeJSON={defaultOptions:{},defaultBaseOptions:{checkboxUncheckedValue:void 0,useIntKeysAsArrayIndex:!1,skipFalsyValuesForTypes:[],skipFalsyValuesForFields:[],disableColonTypes:!1,customTypes:{},defaultTypes:{string:function(e){return String(e)},number:function(e){return Number(e)},boolean:function(e){return-1===["false","null","undefined","","0"].indexOf(e)},null:function(e){return-1===["false","null","undefined","","0"].indexOf(e)?e:null},array:function(e){return JSON.parse(e)},object:function(e){return JSON.parse(e)},skip:null},defaultType:"string"},setupOpts:function(n){null==n&&(n={});var r=e.serializeJSON,t=["checkboxUncheckedValue","useIntKeysAsArrayIndex","skipFalsyValuesForTypes","skipFalsyValuesForFields","disableColonTypes","customTypes","defaultTypes","defaultType"];for(var i in n)if(-1===t.indexOf(i))throw new Error("serializeJSON ERROR: invalid option '"+i+"'. Please use one of "+t.join(", "));return e.extend({},r.defaultBaseOptions,r.defaultOptions,n)},serializeArray:function(a,u){null==u&&(u={});var s=e.serializeJSON;return a.map(function(){var n=e.prop(this,"elements");return n?e.makeArray(n):this}).filter(function(){var n=e(this),a=this.type;return this.name&&!n.is(":disabled")&&t.test(this.nodeName)&&!r.test(a)&&(this.checked||!i.test(a)||null!=s.getCheckboxUncheckedValue(n,u))}).map(function(r,t){var a=e(this),l=a.val(),p=this.type;return null==l?null:(i.test(p)&&!this.checked&&(l=s.getCheckboxUncheckedValue(a,u)),o(l)?e.map(l,function(e){return{name:t.name,value:e.replace(n,"\r\n"),el:t}}):{name:t.name,value:l.replace(n,"\r\n"),el:t})}).get()},getCheckboxUncheckedValue:function(e,n){var r=e.attr("data-unchecked-value");return null==r&&(r=n.checkboxUncheckedValue),r},applyTypeFunc:function(e,n,r,t,i){var u=i[r];if(!u)throw new Error("serializeJSON ERROR: Invalid type "+r+" found in input name '"+e+"', please use one of "+a(i).join(", "));return u(n,t)},splitType:function(e){var n=e.split(":");if(n.length>1){var r=n.pop();return[n.join(":"),r]}return[e,""]},shouldSkipFalsy:function(n,r,t,i,a){var u=e(i).attr("data-skip-falsy");if(null!=u)return"false"!==u;var s=a.skipFalsyValuesForFields;if(s&&(-1!==s.indexOf(r)||-1!==s.indexOf(n)))return!0;var l=a.skipFalsyValuesForTypes;return!(!l||-1===l.indexOf(t))},splitInputNameIntoKeysArray:function(n){var r=n.split("[");return""===(r=e.map(r,function(e){return e.replace(/\]/g,"")}))[0]&&r.shift(),r},deepSet:function(n,r,t,i){null==i&&(i={});var a=e.serializeJSON;if(s(n))throw new Error("ArgumentError: param 'o' expected to be an object or array, found undefined");if(!r||0===r.length)throw new Error("ArgumentError: param 'keys' expected to be an array with least one element");var p=r[0];if(1!==r.length){var f=r[1],c=r.slice(1);if(""===p){var d=n.length-1,y=n[d];p=u(y)&&s(a.deepGet(y,c))?d:d+1}""===f?!s(n[p])&&o(n[p])||(n[p]=[]):i.useIntKeysAsArrayIndex&&l(f)?!s(n[p])&&o(n[p])||(n[p]=[]):!s(n[p])&&u(n[p])||(n[p]={}),a.deepSet(n[p],c,t,i)}else""===p?n.push(t):n[p]=t},deepGet:function(n,r){var t=e.serializeJSON;if(s(n)||s(r)||0===r.length||!u(n)&&!o(n))return n;var i=r[0];if(""!==i){if(1===r.length)return n[i];var a=r.slice(1);return t.deepGet(n[i],a)}}};var a=function(e){if(Object.keys)return Object.keys(e);var n,r=[];for(n in e)r.push(n);return r},u=function(e){return e===Object(e)},s=function(e){return void 0===e},l=function(e){return/^[0-9]+$/.test(String(e))},o=Array.isArray||function(e){return"[object Array]"===Object.prototype.toString.call(e)}}); includes/jquery.serializeJSON/jquery.serializejson.js000064400000036376152214270100017117 0ustar00/*! SerializeJSON jQuery plugin. https://github.com/marioizquierdo/jquery.serializeJSON version 3.2.0 (Dec, 2020) Copyright (c) 2012-2021 Mario Izquierdo Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses. */ (function (factory) { /* global define, require, module */ if (typeof define === "function" && define.amd) { // AMD. Register as an anonymous module. define(["jquery"], factory); } else if (typeof exports === "object") { // Node/CommonJS var jQuery = require("jquery"); module.exports = factory(jQuery); } else { // Browser globals (zepto supported) factory(window.jQuery || window.Zepto || window.$); // Zepto supported on browsers as well } }(function ($) { "use strict"; var rCRLF = /\r?\n/g; var rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i; var rsubmittable = /^(?:input|select|textarea|keygen)/i; var rcheckableType = /^(?:checkbox|radio)$/i; $.fn.serializeJSON = function (options) { var f = $.serializeJSON; var $form = this; // NOTE: the set of matched elements is most likely a form, but it could also be a group of inputs var opts = f.setupOpts(options); // validate options and apply defaults var typeFunctions = $.extend({}, opts.defaultTypes, opts.customTypes); // Make a list with {name, value, el} for each input element var serializedArray = f.serializeArray($form, opts); // Convert the serializedArray into a serializedObject with nested keys var serializedObject = {}; $.each(serializedArray, function (_i, obj) { var nameSansType = obj.name; var type = $(obj.el).attr("data-value-type"); if (!type && !opts.disableColonTypes) { // try getting the type from the input name var p = f.splitType(obj.name); // "foo:string" => ["foo", "string"] nameSansType = p[0]; type = p[1]; } if (type === "skip") { return; // ignore fields with type skip } if (!type) { type = opts.defaultType; // "string" by default } var typedValue = f.applyTypeFunc(obj.name, obj.value, type, obj.el, typeFunctions); // Parse type as string, number, etc. if (!typedValue && f.shouldSkipFalsy(obj.name, nameSansType, type, obj.el, opts)) { return; // ignore falsy inputs if specified in the options } var keys = f.splitInputNameIntoKeysArray(nameSansType); f.deepSet(serializedObject, keys, typedValue, opts); }); return serializedObject; }; // Use $.serializeJSON as namespace for the auxiliar functions // and to define defaults $.serializeJSON = { defaultOptions: {}, // reassign to override option defaults for all serializeJSON calls defaultBaseOptions: { // do not modify, use defaultOptions instead checkboxUncheckedValue: undefined, // to include that value for unchecked checkboxes (instead of ignoring them) useIntKeysAsArrayIndex: false, // name="foo[2]" value="v" => {foo: [null, null, "v"]}, instead of {foo: ["2": "v"]} skipFalsyValuesForTypes: [], // skip serialization of falsy values for listed value types skipFalsyValuesForFields: [], // skip serialization of falsy values for listed field names disableColonTypes: false, // do not interpret ":type" suffix as a type customTypes: {}, // extends defaultTypes defaultTypes: { "string": function(str) { return String(str); }, "number": function(str) { return Number(str); }, "boolean": function(str) { var falses = ["false", "null", "undefined", "", "0"]; return falses.indexOf(str) === -1; }, "null": function(str) { var falses = ["false", "null", "undefined", "", "0"]; return falses.indexOf(str) === -1 ? str : null; }, "array": function(str) { return JSON.parse(str); }, "object": function(str) { return JSON.parse(str); }, "skip": null // skip is a special type used to ignore fields }, defaultType: "string", }, // Validate and set defaults setupOpts: function(options) { if (options == null) options = {}; var f = $.serializeJSON; // Validate var validOpts = [ "checkboxUncheckedValue", "useIntKeysAsArrayIndex", "skipFalsyValuesForTypes", "skipFalsyValuesForFields", "disableColonTypes", "customTypes", "defaultTypes", "defaultType" ]; for (var opt in options) { if (validOpts.indexOf(opt) === -1) { throw new Error("serializeJSON ERROR: invalid option '" + opt + "'. Please use one of " + validOpts.join(", ")); } } // Helper to get options or defaults return $.extend({}, f.defaultBaseOptions, f.defaultOptions, options); }, // Just like jQuery's serializeArray method, returns an array of objects with name and value. // but also includes the dom element (el) and is handles unchecked checkboxes if the option or data attribute are provided. serializeArray: function($form, opts) { if (opts == null) { opts = {}; } var f = $.serializeJSON; return $form.map(function() { var elements = $.prop(this, "elements"); // handle propHook "elements" to filter or add form elements return elements ? $.makeArray(elements) : this; }).filter(function() { var $el = $(this); var type = this.type; // Filter with the standard W3C rules for successful controls: http://www.w3.org/TR/html401/interact/forms.html#h-17.13.2 return this.name && // must contain a name attribute !$el.is(":disabled") && // must not be disable (use .is(":disabled") so that fieldset[disabled] works) rsubmittable.test(this.nodeName) && !rsubmitterTypes.test(type) && // only serialize submittable fields (and not buttons) (this.checked || !rcheckableType.test(type) || f.getCheckboxUncheckedValue($el, opts) != null); // skip unchecked checkboxes (unless using opts) }).map(function(_i, el) { var $el = $(this); var val = $el.val(); var type = this.type; // "input", "select", "textarea", "checkbox", etc. if (val == null) { return null; } if (rcheckableType.test(type) && !this.checked) { val = f.getCheckboxUncheckedValue($el, opts); } if (isArray(val)) { return $.map(val, function(val) { return { name: el.name, value: val.replace(rCRLF, "\r\n"), el: el }; } ); } return { name: el.name, value: val.replace(rCRLF, "\r\n"), el: el }; }).get(); }, getCheckboxUncheckedValue: function($el, opts) { var val = $el.attr("data-unchecked-value"); if (val == null) { val = opts.checkboxUncheckedValue; } return val; }, // Parse value with type function applyTypeFunc: function(name, valStr, type, el, typeFunctions) { var typeFunc = typeFunctions[type]; if (!typeFunc) { // quick feedback to user if there is a typo or missconfiguration throw new Error("serializeJSON ERROR: Invalid type " + type + " found in input name '" + name + "', please use one of " + objectKeys(typeFunctions).join(", ")); } return typeFunc(valStr, el); }, // Splits a field name into the name and the type. Examples: // "foo" => ["foo", ""] // "foo:boolean" => ["foo", "boolean"] // "foo[bar]:null" => ["foo[bar]", "null"] splitType : function(name) { var parts = name.split(":"); if (parts.length > 1) { var t = parts.pop(); return [parts.join(":"), t]; } else { return [name, ""]; } }, // Check if this input should be skipped when it has a falsy value, // depending on the options to skip values by name or type, and the data-skip-falsy attribute. shouldSkipFalsy: function(name, nameSansType, type, el, opts) { var skipFromDataAttr = $(el).attr("data-skip-falsy"); if (skipFromDataAttr != null) { return skipFromDataAttr !== "false"; // any value is true, except the string "false" } var optForFields = opts.skipFalsyValuesForFields; if (optForFields && (optForFields.indexOf(nameSansType) !== -1 || optForFields.indexOf(name) !== -1)) { return true; } var optForTypes = opts.skipFalsyValuesForTypes; if (optForTypes && optForTypes.indexOf(type) !== -1) { return true; } return false; }, // Split the input name in programatically readable keys. // Examples: // "foo" => ["foo"] // "[foo]" => ["foo"] // "foo[inn][bar]" => ["foo", "inn", "bar"] // "foo[inn[bar]]" => ["foo", "inn", "bar"] // "foo[inn][arr][0]" => ["foo", "inn", "arr", "0"] // "arr[][val]" => ["arr", "", "val"] splitInputNameIntoKeysArray: function(nameWithNoType) { var keys = nameWithNoType.split("["); // split string into array keys = $.map(keys, function (key) { return key.replace(/\]/g, ""); }); // remove closing brackets if (keys[0] === "") { keys.shift(); } // ensure no opening bracket ("[foo][inn]" should be same as "foo[inn]") return keys; }, // Set a value in an object or array, using multiple keys to set in a nested object or array. // This is the main function of the script, that allows serializeJSON to use nested keys. // Examples: // // deepSet(obj, ["foo"], v) // obj["foo"] = v // deepSet(obj, ["foo", "inn"], v) // obj["foo"]["inn"] = v // Create the inner obj["foo"] object, if needed // deepSet(obj, ["foo", "inn", "123"], v) // obj["foo"]["arr"]["123"] = v // // // deepSet(obj, ["0"], v) // obj["0"] = v // deepSet(arr, ["0"], v, {useIntKeysAsArrayIndex: true}) // arr[0] = v // deepSet(arr, [""], v) // arr.push(v) // deepSet(obj, ["arr", ""], v) // obj["arr"].push(v) // // arr = []; // deepSet(arr, ["", v] // arr => [v] // deepSet(arr, ["", "foo"], v) // arr => [v, {foo: v}] // deepSet(arr, ["", "bar"], v) // arr => [v, {foo: v, bar: v}] // deepSet(arr, ["", "bar"], v) // arr => [v, {foo: v, bar: v}, {bar: v}] // deepSet: function (o, keys, value, opts) { if (opts == null) { opts = {}; } var f = $.serializeJSON; if (isUndefined(o)) { throw new Error("ArgumentError: param 'o' expected to be an object or array, found undefined"); } if (!keys || keys.length === 0) { throw new Error("ArgumentError: param 'keys' expected to be an array with least one element"); } var key = keys[0]; // Only one key, then it's not a deepSet, just assign the value in the object or add it to the array. if (keys.length === 1) { if (key === "") { // push values into an array (o must be an array) o.push(value); } else { o[key] = value; // keys can be object keys (strings) or array indexes (numbers) } return; } var nextKey = keys[1]; // nested key var tailKeys = keys.slice(1); // list of all other nested keys (nextKey is first) if (key === "") { // push nested objects into an array (o must be an array) var lastIdx = o.length - 1; var lastVal = o[lastIdx]; // if the last value is an object or array, and the new key is not set yet if (isObject(lastVal) && isUndefined(f.deepGet(lastVal, tailKeys))) { key = lastIdx; // then set the new value as a new attribute of the same object } else { key = lastIdx + 1; // otherwise, add a new element in the array } } if (nextKey === "") { // "" is used to push values into the nested array "array[]" if (isUndefined(o[key]) || !isArray(o[key])) { o[key] = []; // define (or override) as array to push values } } else { if (opts.useIntKeysAsArrayIndex && isValidArrayIndex(nextKey)) { // if 1, 2, 3 ... then use an array, where nextKey is the index if (isUndefined(o[key]) || !isArray(o[key])) { o[key] = []; // define (or override) as array, to insert values using int keys as array indexes } } else { // nextKey is going to be the nested object's attribute if (isUndefined(o[key]) || !isObject(o[key])) { o[key] = {}; // define (or override) as object, to set nested properties } } } // Recursively set the inner object f.deepSet(o[key], tailKeys, value, opts); }, deepGet: function (o, keys) { var f = $.serializeJSON; if (isUndefined(o) || isUndefined(keys) || keys.length === 0 || (!isObject(o) && !isArray(o))) { return o; } var key = keys[0]; if (key === "") { // "" means next array index (used by deepSet) return undefined; } if (keys.length === 1) { return o[key]; } var tailKeys = keys.slice(1); return f.deepGet(o[key], tailKeys); } }; // polyfill Object.keys to get option keys in IE<9 var objectKeys = function(obj) { if (Object.keys) { return Object.keys(obj); } else { var key, keys = []; for (key in obj) { keys.push(key); } return keys; } }; var isObject = function(obj) { return obj === Object(obj); }; // true for Objects and Arrays var isUndefined = function(obj) { return obj === void 0; }; // safe check for undefined values var isValidArrayIndex = function(val) { return /^[0-9]+$/.test(String(val)); }; // 1,2,3,4 ... are valid array indexes var isArray = Array.isArray || function(obj) { return Object.prototype.toString.call(obj) === "[object Array]"; }; })); includes/jstree/themes/default/throbber.gif000064400000002670152214270100015054 0ustar00GIF89azzzXXX666FFF$$$hhh! NETSCAPE2.0!Created with ajaxload.info! ,@pɇhuʤ" 3 @J@"S , !$JJdσ-ד%LXwVrP5 g*"B` :1 o!Y3 ! ,]BN%I8"d,!p#a BI0![փXʇah@7a([/` (4U%s!sj#! ,ZLX6BG&9!T1@HJ=M!3 R .|V}F5$p19S"! ,\) 275&D %!VAX% QPpr٥!( ` Pㄐ}B  &-! ,EɉBX)!(^gPpX^OaJ0Arɔ>C A9N"BkJfPE! ,k!&S!$N'PaG(!A@L8`Ua0P$،a(4A6O 00"AQfJPh #il~! ,[Xi xJ 2> YH-t i&$h Cq8N#<1Px nSAx\y ĚH;1>8)! ,VI LZ/i] P8Hn !@5H+k±b:SWJq82ڱ4c! ,]X$\guHael4x/( 'Y0B M!8xFC0,v8z~ > !6J9! ,Zji%ZmNLB\TINS ! B İr&Ɓ)Y Ñ8 Cf(-Lsp`u(5&E! ,XIx"PE BRMZӉҢgGCU$p>b34$ 3 W`&Hހ"! ,ZIR|RiㅰY+%$XExpa$N`#0dNӤ@HHN}h<F`}q/)D;includes/jstree/themes/default/style.css000064400000075762152214270100014444 0ustar00/* jsTree default theme */ .jstree-node, .jstree-children, .jstree-container-ul { display: block; margin: 0; padding: 0; list-style-type: none; list-style-image: none; } .jstree-node { white-space: nowrap; } .jstree-anchor { display: inline-block; color: black; white-space: nowrap; padding: 0 4px 0 1px; margin: 0; vertical-align: top; } .jstree-anchor:focus { outline: 0; } .jstree-anchor, .jstree-anchor:link, .jstree-anchor:visited, .jstree-anchor:hover, .jstree-anchor:active { text-decoration: none; color: inherit; } .jstree-icon { display: inline-block; text-decoration: none; margin: 0; padding: 0; vertical-align: top; text-align: center; } .jstree-icon:empty { display: inline-block; text-decoration: none; margin: 0; padding: 0; vertical-align: top; text-align: center; } .jstree-ocl { cursor: pointer; } .jstree-leaf > .jstree-ocl { cursor: default; } .jstree .jstree-open > .jstree-children { display: block; } .jstree .jstree-closed > .jstree-children, .jstree .jstree-leaf > .jstree-children { display: none; } .jstree-anchor > .jstree-themeicon { margin-right: 2px; } .jstree-no-icons .jstree-themeicon, .jstree-anchor > .jstree-themeicon-hidden { display: none; } .jstree-hidden, .jstree-node.jstree-hidden { display: none; } .jstree-rtl .jstree-anchor { padding: 0 1px 0 4px; } .jstree-rtl .jstree-anchor > .jstree-themeicon { margin-left: 2px; margin-right: 0; } .jstree-rtl .jstree-node { margin-left: 0; } .jstree-rtl .jstree-container-ul > .jstree-node { margin-right: 0; } .jstree-wholerow-ul { position: relative; display: inline-block; min-width: 100%; } .jstree-wholerow-ul .jstree-leaf > .jstree-ocl { cursor: pointer; } .jstree-wholerow-ul .jstree-anchor, .jstree-wholerow-ul .jstree-icon { position: relative; } .jstree-wholerow-ul .jstree-wholerow { width: 100%; cursor: pointer; position: absolute; left: 0; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; } .jstree-contextmenu .jstree-anchor { -webkit-user-select: none; /* disable selection/Copy of UIWebView */ -webkit-touch-callout: none; /* disable the IOS popup when long-press on a link */ user-select: none; } .vakata-context { display: none; } .vakata-context, .vakata-context ul { margin: 0; padding: 2px; position: absolute; background: #f5f5f5; border: 1px solid #979797; box-shadow: 2px 2px 2px #999999; } .vakata-context ul { list-style: none; left: 100%; margin-top: -2.7em; margin-left: -4px; } .vakata-context .vakata-context-right ul { left: auto; right: 100%; margin-left: auto; margin-right: -4px; } .vakata-context li { list-style: none; } .vakata-context li > a { display: block; padding: 0 2em 0 2em; text-decoration: none; width: auto; color: black; white-space: nowrap; line-height: 2.4em; text-shadow: 1px 1px 0 white; border-radius: 1px; } .vakata-context li > a:hover { position: relative; background-color: #e8eff7; box-shadow: 0 0 2px #0a6aa1; } .vakata-context li > a.vakata-context-parent { background-image: url("data:image/gif;base64,R0lGODlhCwAHAIAAACgoKP///yH5BAEAAAEALAAAAAALAAcAAAIORI4JlrqN1oMSnmmZDQUAOw=="); background-position: right center; background-repeat: no-repeat; } .vakata-context li > a:focus { outline: 0; } .vakata-context .vakata-context-no-icons { margin-left: 0; } .vakata-context .vakata-context-hover > a { position: relative; background-color: #e8eff7; box-shadow: 0 0 2px #0a6aa1; } .vakata-context .vakata-context-separator > a, .vakata-context .vakata-context-separator > a:hover { background: white; border: 0; border-top: 1px solid #e2e3e3; height: 1px; min-height: 1px; max-height: 1px; padding: 0; margin: 0 0 0 2.4em; border-left: 1px solid #e0e0e0; text-shadow: 0 0 0 transparent; box-shadow: 0 0 0 transparent; border-radius: 0; } .vakata-context .vakata-contextmenu-disabled a, .vakata-context .vakata-contextmenu-disabled a:hover { color: silver; background-color: transparent; border: 0; box-shadow: 0 0 0; } .vakata-context .vakata-contextmenu-disabled > a > i { filter: grayscale(100%); } .vakata-context li > a > i { text-decoration: none; display: inline-block; width: 2.4em; height: 2.4em; background: transparent; margin: 0 0 0 -2em; vertical-align: top; text-align: center; line-height: 2.4em; } .vakata-context li > a > i:empty { width: 2.4em; line-height: 2.4em; } .vakata-context li > a .vakata-contextmenu-sep { display: inline-block; width: 1px; height: 2.4em; background: white; margin: 0 0.5em 0 0; border-left: 1px solid #e2e3e3; } .vakata-context .vakata-contextmenu-shortcut { font-size: 0.8em; color: silver; opacity: 0.5; display: none; } .vakata-context-rtl ul { left: auto; right: 100%; margin-left: auto; margin-right: -4px; } .vakata-context-rtl li > a.vakata-context-parent { background-image: url("data:image/gif;base64,R0lGODlhCwAHAIAAACgoKP///yH5BAEAAAEALAAAAAALAAcAAAINjI+AC7rWHIsPtmoxLAA7"); background-position: left center; background-repeat: no-repeat; } .vakata-context-rtl .vakata-context-separator > a { margin: 0 2.4em 0 0; border-left: 0; border-right: 1px solid #e2e3e3; } .vakata-context-rtl .vakata-context-left ul { right: auto; left: 100%; margin-left: -4px; margin-right: auto; } .vakata-context-rtl li > a > i { margin: 0 -2em 0 0; } .vakata-context-rtl li > a .vakata-contextmenu-sep { margin: 0 0 0 0.5em; border-left-color: white; background: #e2e3e3; } #jstree-marker { position: absolute; top: 0; left: 0; margin: -5px 0 0 0; padding: 0; border-right: 0; border-top: 5px solid transparent; border-bottom: 5px solid transparent; border-left: 5px solid; width: 0; height: 0; font-size: 0; line-height: 0; } #jstree-dnd { line-height: 16px; margin: 0; padding: 4px; } #jstree-dnd .jstree-icon, #jstree-dnd .jstree-copy { display: inline-block; text-decoration: none; margin: 0 2px 0 0; padding: 0; width: 16px; height: 16px; } #jstree-dnd .jstree-ok { background: green; } #jstree-dnd .jstree-er { background: red; } #jstree-dnd .jstree-copy { margin: 0 2px 0 2px; } .jstree-default .jstree-node, .jstree-default .jstree-icon { background-repeat: no-repeat; background-color: transparent; } .jstree-default .jstree-anchor, .jstree-default .jstree-animated, .jstree-default .jstree-wholerow { transition: background-color 0.15s, box-shadow 0.15s; } .jstree-default .jstree-hovered { background: #e7f4f9; border-radius: 2px; box-shadow: inset 0 0 1px #cccccc; } .jstree-default .jstree-context { background: #e7f4f9; border-radius: 2px; box-shadow: inset 0 0 1px #cccccc; } .jstree-default .jstree-clicked { background: #beebff; border-radius: 2px; box-shadow: inset 0 0 1px #999999; } .jstree-default .jstree-no-icons .jstree-anchor > .jstree-themeicon { display: none; } .jstree-default .jstree-disabled { background: transparent; color: #666666; } .jstree-default .jstree-disabled.jstree-hovered { background: transparent; box-shadow: none; } .jstree-default .jstree-disabled.jstree-clicked { background: #efefef; } .jstree-default .jstree-disabled > .jstree-icon { opacity: 0.8; filter: url("data:image/svg+xml;utf8,#jstree-grayscale"); /* Firefox 10+ */ filter: gray; /* IE6-9 */ -webkit-filter: grayscale(100%); /* Chrome 19+ & Safari 6+ */ } .jstree-default .jstree-search { font-style: italic; color: #8b0000; font-weight: bold; } .jstree-default .jstree-no-checkboxes .jstree-checkbox { display: none !important; } .jstree-default.jstree-checkbox-no-clicked .jstree-clicked { background: transparent; box-shadow: none; } .jstree-default.jstree-checkbox-no-clicked .jstree-clicked.jstree-hovered { background: #e7f4f9; } .jstree-default.jstree-checkbox-no-clicked > .jstree-wholerow-ul .jstree-wholerow-clicked { background: transparent; } .jstree-default.jstree-checkbox-no-clicked > .jstree-wholerow-ul .jstree-wholerow-clicked.jstree-wholerow-hovered { background: #e7f4f9; } .jstree-default > .jstree-striped { min-width: 100%; display: inline-block; background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAkCAMAAAB/qqA+AAAABlBMVEUAAAAAAAClZ7nPAAAAAnRSTlMNAMM9s3UAAAAXSURBVHjajcEBAQAAAIKg/H/aCQZ70AUBjAATb6YPDgAAAABJRU5ErkJggg==") left top repeat; } .jstree-default > .jstree-wholerow-ul .jstree-hovered, .jstree-default > .jstree-wholerow-ul .jstree-clicked { background: transparent; box-shadow: none; border-radius: 0; } .jstree-default .jstree-wholerow { -moz-box-sizing: border-box; -webkit-box-sizing: border-box; box-sizing: border-box; } .jstree-default .jstree-wholerow-hovered { background: #e7f4f9; } .jstree-default .jstree-wholerow-clicked { background: #beebff; background: -webkit-linear-gradient(top, #beebff 0%, #a8e4ff 100%); background: linear-gradient(to bottom, #beebff 0%, #a8e4ff 100%); } .jstree-default .jstree-node { min-height: 24px; line-height: 24px; margin-left: 24px; min-width: 24px; } .jstree-default .jstree-anchor { line-height: 24px; height: 24px; } .jstree-default .jstree-icon { width: 24px; height: 24px; line-height: 24px; } .jstree-default .jstree-icon:empty { width: 24px; height: 24px; line-height: 24px; } .jstree-default.jstree-rtl .jstree-node { margin-right: 24px; } .jstree-default .jstree-wholerow { height: 24px; } .jstree-default .jstree-node, .jstree-default .jstree-icon { background-image: url("32px.png"); } .jstree-default .jstree-node { background-position: -292px -4px; background-repeat: repeat-y; } .jstree-default .jstree-last { background-image: none; } .jstree-default .jstree-open > .jstree-ocl { background-position: -132px -4px; } .jstree-default .jstree-closed > .jstree-ocl { background-position: -100px -4px; } .jstree-default .jstree-leaf > .jstree-ocl { background-position: -68px -4px; } .jstree-default .jstree-themeicon { background-position: -260px -4px; } .jstree-default > .jstree-no-dots .jstree-node, .jstree-default > .jstree-no-dots .jstree-leaf > .jstree-ocl { background: transparent; } .jstree-default > .jstree-no-dots .jstree-open > .jstree-ocl { background-position: -36px -4px; } .jstree-default > .jstree-no-dots .jstree-closed > .jstree-ocl { background-position: -4px -4px; } .jstree-default .jstree-disabled { background: transparent; } .jstree-default .jstree-disabled.jstree-hovered { background: transparent; } .jstree-default .jstree-disabled.jstree-clicked { background: #efefef; } .jstree-default .jstree-checkbox { background-position: -164px -4px; } .jstree-default .jstree-checkbox:hover { background-position: -164px -36px; } .jstree-default.jstree-checkbox-selection .jstree-clicked > .jstree-checkbox, .jstree-default .jstree-checked > .jstree-checkbox { background-position: -228px -4px; } .jstree-default.jstree-checkbox-selection .jstree-clicked > .jstree-checkbox:hover, .jstree-default .jstree-checked > .jstree-checkbox:hover { background-position: -228px -36px; } .jstree-default .jstree-anchor > .jstree-undetermined { background-position: -196px -4px; } .jstree-default .jstree-anchor > .jstree-undetermined:hover { background-position: -196px -36px; } .jstree-default .jstree-checkbox-disabled { opacity: 0.8; filter: url("data:image/svg+xml;utf8,#jstree-grayscale"); /* Firefox 10+ */ filter: gray; /* IE6-9 */ -webkit-filter: grayscale(100%); /* Chrome 19+ & Safari 6+ */ } .jstree-default > .jstree-striped { background-size: auto 48px; } .jstree-default.jstree-rtl .jstree-node { background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg=="); background-position: 100% 1px; background-repeat: repeat-y; } .jstree-default.jstree-rtl .jstree-last { background-image: none; } .jstree-default.jstree-rtl .jstree-open > .jstree-ocl { background-position: -132px -36px; } .jstree-default.jstree-rtl .jstree-closed > .jstree-ocl { background-position: -100px -36px; } .jstree-default.jstree-rtl .jstree-leaf > .jstree-ocl { background-position: -68px -36px; } .jstree-default.jstree-rtl > .jstree-no-dots .jstree-node, .jstree-default.jstree-rtl > .jstree-no-dots .jstree-leaf > .jstree-ocl { background: transparent; } .jstree-default.jstree-rtl > .jstree-no-dots .jstree-open > .jstree-ocl { background-position: -36px -36px; } .jstree-default.jstree-rtl > .jstree-no-dots .jstree-closed > .jstree-ocl { background-position: -4px -36px; } .jstree-default .jstree-themeicon-custom { background-color: transparent; background-image: none; background-position: 0 0; } .jstree-default > .jstree-container-ul .jstree-loading > .jstree-ocl { background: url("throbber.gif") center center no-repeat; } .jstree-default .jstree-file { background: url("32px.png") -100px -68px no-repeat; } .jstree-default .jstree-folder { background: url("32px.png") -260px -4px no-repeat; } .jstree-default > .jstree-container-ul > .jstree-node { margin-left: 0; margin-right: 0; } #jstree-dnd.jstree-default { line-height: 24px; padding: 0 4px; } #jstree-dnd.jstree-default .jstree-ok, #jstree-dnd.jstree-default .jstree-er { background-image: url("32px.png"); background-repeat: no-repeat; background-color: transparent; } #jstree-dnd.jstree-default i { background: transparent; width: 24px; height: 24px; line-height: 24px; } #jstree-dnd.jstree-default .jstree-ok { background-position: -4px -68px; } #jstree-dnd.jstree-default .jstree-er { background-position: -36px -68px; } .jstree-default .jstree-ellipsis { overflow: hidden; } .jstree-default .jstree-ellipsis .jstree-anchor { width: calc(100% - 24px + 5px); text-overflow: ellipsis; overflow: hidden; } .jstree-default.jstree-rtl .jstree-node { background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg=="); } .jstree-default.jstree-rtl .jstree-last { background-image: none; } .jstree-default-small .jstree-node { min-height: 18px; line-height: 18px; margin-left: 18px; min-width: 18px; } .jstree-default-small .jstree-anchor { line-height: 18px; height: 18px; } .jstree-default-small .jstree-icon { width: 18px; height: 18px; line-height: 18px; } .jstree-default-small .jstree-icon:empty { width: 18px; height: 18px; line-height: 18px; } .jstree-default-small.jstree-rtl .jstree-node { margin-right: 18px; } .jstree-default-small .jstree-wholerow { height: 18px; } .jstree-default-small .jstree-node, .jstree-default-small .jstree-icon { background-image: url("32px.png"); } .jstree-default-small .jstree-node { background-position: -295px -7px; background-repeat: repeat-y; } .jstree-default-small .jstree-last { background-image: none; } .jstree-default-small .jstree-open > .jstree-ocl { background-position: -135px -7px; } .jstree-default-small .jstree-closed > .jstree-ocl { background-position: -103px -7px; } .jstree-default-small .jstree-leaf > .jstree-ocl { background-position: -71px -7px; } .jstree-default-small .jstree-themeicon { background-position: -263px -7px; } .jstree-default-small > .jstree-no-dots .jstree-node, .jstree-default-small > .jstree-no-dots .jstree-leaf > .jstree-ocl { background: transparent; } .jstree-default-small > .jstree-no-dots .jstree-open > .jstree-ocl { background-position: -39px -7px; } .jstree-default-small > .jstree-no-dots .jstree-closed > .jstree-ocl { background-position: -7px -7px; } .jstree-default-small .jstree-disabled { background: transparent; } .jstree-default-small .jstree-disabled.jstree-hovered { background: transparent; } .jstree-default-small .jstree-disabled.jstree-clicked { background: #efefef; } .jstree-default-small .jstree-checkbox { background-position: -167px -7px; } .jstree-default-small .jstree-checkbox:hover { background-position: -167px -39px; } .jstree-default-small.jstree-checkbox-selection .jstree-clicked > .jstree-checkbox, .jstree-default-small .jstree-checked > .jstree-checkbox { background-position: -231px -7px; } .jstree-default-small.jstree-checkbox-selection .jstree-clicked > .jstree-checkbox:hover, .jstree-default-small .jstree-checked > .jstree-checkbox:hover { background-position: -231px -39px; } .jstree-default-small .jstree-anchor > .jstree-undetermined { background-position: -199px -7px; } .jstree-default-small .jstree-anchor > .jstree-undetermined:hover { background-position: -199px -39px; } .jstree-default-small .jstree-checkbox-disabled { opacity: 0.8; filter: url("data:image/svg+xml;utf8,#jstree-grayscale"); /* Firefox 10+ */ filter: gray; /* IE6-9 */ -webkit-filter: grayscale(100%); /* Chrome 19+ & Safari 6+ */ } .jstree-default-small > .jstree-striped { background-size: auto 36px; } .jstree-default-small.jstree-rtl .jstree-node { background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg=="); background-position: 100% 1px; background-repeat: repeat-y; } .jstree-default-small.jstree-rtl .jstree-last { background-image: none; } .jstree-default-small.jstree-rtl .jstree-open > .jstree-ocl { background-position: -135px -39px; } .jstree-default-small.jstree-rtl .jstree-closed > .jstree-ocl { background-position: -103px -39px; } .jstree-default-small.jstree-rtl .jstree-leaf > .jstree-ocl { background-position: -71px -39px; } .jstree-default-small.jstree-rtl > .jstree-no-dots .jstree-node, .jstree-default-small.jstree-rtl > .jstree-no-dots .jstree-leaf > .jstree-ocl { background: transparent; } .jstree-default-small.jstree-rtl > .jstree-no-dots .jstree-open > .jstree-ocl { background-position: -39px -39px; } .jstree-default-small.jstree-rtl > .jstree-no-dots .jstree-closed > .jstree-ocl { background-position: -7px -39px; } .jstree-default-small .jstree-themeicon-custom { background-color: transparent; background-image: none; background-position: 0 0; } .jstree-default-small > .jstree-container-ul .jstree-loading > .jstree-ocl { background: url("throbber.gif") center center no-repeat; } .jstree-default-small .jstree-file { background: url("32px.png") -103px -71px no-repeat; } .jstree-default-small .jstree-folder { background: url("32px.png") -263px -7px no-repeat; } .jstree-default-small > .jstree-container-ul > .jstree-node { margin-left: 0; margin-right: 0; } #jstree-dnd.jstree-default-small { line-height: 18px; padding: 0 4px; } #jstree-dnd.jstree-default-small .jstree-ok, #jstree-dnd.jstree-default-small .jstree-er { background-image: url("32px.png"); background-repeat: no-repeat; background-color: transparent; } #jstree-dnd.jstree-default-small i { background: transparent; width: 18px; height: 18px; line-height: 18px; } #jstree-dnd.jstree-default-small .jstree-ok { background-position: -7px -71px; } #jstree-dnd.jstree-default-small .jstree-er { background-position: -39px -71px; } .jstree-default-small .jstree-ellipsis { overflow: hidden; } .jstree-default-small .jstree-ellipsis .jstree-anchor { width: calc(100% - 18px + 5px); text-overflow: ellipsis; overflow: hidden; } .jstree-default-small.jstree-rtl .jstree-node { background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAACAQMAAABv1h6PAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMHBgAAiABBI4gz9AAAAABJRU5ErkJggg=="); } .jstree-default-small.jstree-rtl .jstree-last { background-image: none; } .jstree-default-large .jstree-node { min-height: 32px; line-height: 32px; margin-left: 32px; min-width: 32px; } .jstree-default-large .jstree-anchor { line-height: 32px; height: 32px; } .jstree-default-large .jstree-icon { width: 32px; height: 32px; line-height: 32px; } .jstree-default-large .jstree-icon:empty { width: 32px; height: 32px; line-height: 32px; } .jstree-default-large.jstree-rtl .jstree-node { margin-right: 32px; } .jstree-default-large .jstree-wholerow { height: 32px; } .jstree-default-large .jstree-node, .jstree-default-large .jstree-icon { background-image: url("32px.png"); } .jstree-default-large .jstree-node { background-position: -288px 0px; background-repeat: repeat-y; } .jstree-default-large .jstree-last { background-image: none; } .jstree-default-large .jstree-open > .jstree-ocl { background-position: -128px 0px; } .jstree-default-large .jstree-closed > .jstree-ocl { background-position: -96px 0px; } .jstree-default-large .jstree-leaf > .jstree-ocl { background-position: -64px 0px; } .jstree-default-large .jstree-themeicon { background-position: -256px 0px; } .jstree-default-large > .jstree-no-dots .jstree-node, .jstree-default-large > .jstree-no-dots .jstree-leaf > .jstree-ocl { background: transparent; } .jstree-default-large > .jstree-no-dots .jstree-open > .jstree-ocl { background-position: -32px 0px; } .jstree-default-large > .jstree-no-dots .jstree-closed > .jstree-ocl { background-position: 0px 0px; } .jstree-default-large .jstree-disabled { background: transparent; } .jstree-default-large .jstree-disabled.jstree-hovered { background: transparent; } .jstree-default-large .jstree-disabled.jstree-clicked { background: #efefef; } .jstree-default-large .jstree-checkbox { background-position: -160px 0px; } .jstree-default-large .jstree-checkbox:hover { background-position: -160px -32px; } .jstree-default-large.jstree-checkbox-selection .jstree-clicked > .jstree-checkbox, .jstree-default-large .jstree-checked > .jstree-checkbox { background-position: -224px 0px; } .jstree-default-large.jstree-checkbox-selection .jstree-clicked > .jstree-checkbox:hover, .jstree-default-large .jstree-checked > .jstree-checkbox:hover { background-position: -224px -32px; } .jstree-default-large .jstree-anchor > .jstree-undetermined { background-position: -192px 0px; } .jstree-default-large .jstree-anchor > .jstree-undetermined:hover { background-position: -192px -32px; } .jstree-default-large .jstree-checkbox-disabled { opacity: 0.8; filter: url("data:image/svg+xml;utf8,#jstree-grayscale"); /* Firefox 10+ */ filter: gray; /* IE6-9 */ -webkit-filter: grayscale(100%); /* Chrome 19+ & Safari 6+ */ } .jstree-default-large > .jstree-striped { background-size: auto 64px; } .jstree-default-large.jstree-rtl .jstree-node { background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg=="); background-position: 100% 1px; background-repeat: repeat-y; } .jstree-default-large.jstree-rtl .jstree-last { background-image: none; } .jstree-default-large.jstree-rtl .jstree-open > .jstree-ocl { background-position: -128px -32px; } .jstree-default-large.jstree-rtl .jstree-closed > .jstree-ocl { background-position: -96px -32px; } .jstree-default-large.jstree-rtl .jstree-leaf > .jstree-ocl { background-position: -64px -32px; } .jstree-default-large.jstree-rtl > .jstree-no-dots .jstree-node, .jstree-default-large.jstree-rtl > .jstree-no-dots .jstree-leaf > .jstree-ocl { background: transparent; } .jstree-default-large.jstree-rtl > .jstree-no-dots .jstree-open > .jstree-ocl { background-position: -32px -32px; } .jstree-default-large.jstree-rtl > .jstree-no-dots .jstree-closed > .jstree-ocl { background-position: 0px -32px; } .jstree-default-large .jstree-themeicon-custom { background-color: transparent; background-image: none; background-position: 0 0; } .jstree-default-large > .jstree-container-ul .jstree-loading > .jstree-ocl { background: url("throbber.gif") center center no-repeat; } .jstree-default-large .jstree-file { background: url("32px.png") -96px -64px no-repeat; } .jstree-default-large .jstree-folder { background: url("32px.png") -256px 0px no-repeat; } .jstree-default-large > .jstree-container-ul > .jstree-node { margin-left: 0; margin-right: 0; } #jstree-dnd.jstree-default-large { line-height: 32px; padding: 0 4px; } #jstree-dnd.jstree-default-large .jstree-ok, #jstree-dnd.jstree-default-large .jstree-er { background-image: url("32px.png"); background-repeat: no-repeat; background-color: transparent; } #jstree-dnd.jstree-default-large i { background: transparent; width: 32px; height: 32px; line-height: 32px; } #jstree-dnd.jstree-default-large .jstree-ok { background-position: 0px -64px; } #jstree-dnd.jstree-default-large .jstree-er { background-position: -32px -64px; } .jstree-default-large .jstree-ellipsis { overflow: hidden; } .jstree-default-large .jstree-ellipsis .jstree-anchor { width: calc(100% - 32px + 5px); text-overflow: ellipsis; overflow: hidden; } .jstree-default-large.jstree-rtl .jstree-node { background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAACAQMAAAAD0EyKAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjgIIGBgABCgCBvVLXcAAAAABJRU5ErkJggg=="); } .jstree-default-large.jstree-rtl .jstree-last { background-image: none; } @media (max-width: 768px) { #jstree-dnd.jstree-dnd-responsive { line-height: 40px; font-weight: bold; font-size: 1.1em; text-shadow: 1px 1px white; } #jstree-dnd.jstree-dnd-responsive > i { background: transparent; width: 40px; height: 40px; } #jstree-dnd.jstree-dnd-responsive > .jstree-ok { background-image: url("40px.png"); background-position: 0 -200px; background-size: 120px 240px; } #jstree-dnd.jstree-dnd-responsive > .jstree-er { background-image: url("40px.png"); background-position: -40px -200px; background-size: 120px 240px; } #jstree-marker.jstree-dnd-responsive { border-left-width: 10px; border-top-width: 10px; border-bottom-width: 10px; margin-top: -10px; } } @media (max-width: 768px) { .jstree-default-responsive { /* .jstree-open > .jstree-ocl, .jstree-closed > .jstree-ocl { border-radius:20px; background-color:white; } */ } .jstree-default-responsive .jstree-icon { background-image: url("40px.png"); } .jstree-default-responsive .jstree-node, .jstree-default-responsive .jstree-leaf > .jstree-ocl { background: transparent; } .jstree-default-responsive .jstree-node { min-height: 40px; line-height: 40px; margin-left: 40px; min-width: 40px; white-space: nowrap; } .jstree-default-responsive .jstree-anchor { line-height: 40px; height: 40px; } .jstree-default-responsive .jstree-icon, .jstree-default-responsive .jstree-icon:empty { width: 40px; height: 40px; line-height: 40px; } .jstree-default-responsive > .jstree-container-ul > .jstree-node { margin-left: 0; } .jstree-default-responsive.jstree-rtl .jstree-node { margin-left: 0; margin-right: 40px; background: transparent; } .jstree-default-responsive.jstree-rtl .jstree-container-ul > .jstree-node { margin-right: 0; } .jstree-default-responsive .jstree-ocl, .jstree-default-responsive .jstree-themeicon, .jstree-default-responsive .jstree-checkbox { background-size: 120px 240px; } .jstree-default-responsive .jstree-leaf > .jstree-ocl, .jstree-default-responsive.jstree-rtl .jstree-leaf > .jstree-ocl { background: transparent; } .jstree-default-responsive .jstree-open > .jstree-ocl { background-position: 0 0 !important; } .jstree-default-responsive .jstree-closed > .jstree-ocl { background-position: 0 -40px !important; } .jstree-default-responsive.jstree-rtl .jstree-closed > .jstree-ocl { background-position: -40px 0 !important; } .jstree-default-responsive .jstree-themeicon { background-position: -40px -40px; } .jstree-default-responsive .jstree-checkbox, .jstree-default-responsive .jstree-checkbox:hover { background-position: -40px -80px; } .jstree-default-responsive.jstree-checkbox-selection .jstree-clicked > .jstree-checkbox, .jstree-default-responsive.jstree-checkbox-selection .jstree-clicked > .jstree-checkbox:hover, .jstree-default-responsive .jstree-checked > .jstree-checkbox, .jstree-default-responsive .jstree-checked > .jstree-checkbox:hover { background-position: 0 -80px; } .jstree-default-responsive .jstree-anchor > .jstree-undetermined, .jstree-default-responsive .jstree-anchor > .jstree-undetermined:hover { background-position: 0 -120px; } .jstree-default-responsive .jstree-anchor { font-weight: bold; font-size: 1.1em; text-shadow: 1px 1px white; } .jstree-default-responsive > .jstree-striped { background: transparent; } .jstree-default-responsive .jstree-wholerow { border-top: 1px solid rgba(255, 255, 255, 0.7); border-bottom: 1px solid rgba(64, 64, 64, 0.2); background: #ebebeb; height: 40px; } .jstree-default-responsive .jstree-wholerow-hovered { background: #e7f4f9; } .jstree-default-responsive .jstree-wholerow-clicked { background: #beebff; } .jstree-default-responsive .jstree-children .jstree-last > .jstree-wholerow { box-shadow: inset 0 -6px 3px -5px #666666; } .jstree-default-responsive .jstree-children .jstree-open > .jstree-wholerow { box-shadow: inset 0 6px 3px -5px #666666; border-top: 0; } .jstree-default-responsive .jstree-children .jstree-open + .jstree-open { box-shadow: none; } .jstree-default-responsive .jstree-node, .jstree-default-responsive .jstree-icon, .jstree-default-responsive .jstree-node > .jstree-ocl, .jstree-default-responsive .jstree-themeicon, .jstree-default-responsive .jstree-checkbox { background-image: url("40px.png"); background-size: 120px 240px; } .jstree-default-responsive .jstree-node { background-position: -80px 0; background-repeat: repeat-y; } .jstree-default-responsive .jstree-last { background-image: none; } .jstree-default-responsive .jstree-leaf > .jstree-ocl { background-position: -40px -120px; } .jstree-default-responsive .jstree-last > .jstree-ocl { background-position: -40px -160px; } .jstree-default-responsive .jstree-themeicon-custom { background-color: transparent; background-image: none; background-position: 0 0; } .jstree-default-responsive .jstree-file { background: url("40px.png") 0 -160px no-repeat; background-size: 120px 240px; } .jstree-default-responsive .jstree-folder { background: url("40px.png") -40px -40px no-repeat; background-size: 120px 240px; } .jstree-default-responsive > .jstree-container-ul > .jstree-node { margin-left: 0; margin-right: 0; } } includes/jstree/themes/default/40px.png000064400000004247152214270100014061 0ustar00PNG  IHDR*EPLTE333333333333333333333333333333333333333333333333333<<<tRNS !PY\]c7IDATx( Ogͬ-KiقӞ%~xc p.ר]L6k 0`6߼[xwX?"bWB,px/F&fn-w8яOޣ.F/y1qoxۛ '/m={ye>J+9h=a'MW.(5E^ҊWj`+4=Z_$.b=AdNKҫBi",*-_u%Ғ^KY,V$ՙNOI'fiSҋ+Z/I/_.n J+jli´J+.|XY0` 0` 0` 0`gnsoŸ~V^wbhEe?6,S{;mX XH2Xw"I+Zҏ%bcIHl , 6n[7́[b6Ep$E KA%$H% eזufX.:h~A\jqxhhy|aeQb`ʇ4 0` 0` 0` p,'' ÖCy\nJ 츓[Ϯ{ u[Z3xWv? ~WD, o{:;n׷(Q (xŁ9#Q5CQ1x, 4 >ZGF#7)>khٔ3K<4$-Ζféq{``YbsxK-_ė7//`k_/Q^ _EH{ELyaL|i 0` 0` 0` 0`OWܵHs!:pRAmŠ}uPЭ }O~n?+8w e*}4` 0`s a|tIiӴ$[jo1m+yetiRhyZ0` 0` p 0` Ep 0`~:m2\)'fOϳdz<I"-?codã}`?Z8=X<_f0zz2 0` 0`V<d nSvmvxlmï+8|vOR?` ݻ['xK.e zڽWN7畂]z{{\GE'3 NftgBwS7]GSN;;eKM8X<]H>k*3hơVW8 2W"KZY&pKsD`WFk8 xE1ؕG0~7x`WpeKpqu՝#Gp SW^},pԑl4+:u%%]. G]Fa2yת#h|(]׃_GßÕ-e񑖫n.br pfT4[*w,x.x9n>\\=eV^O7Ji A:QOIENDB`includes/jstree/themes/default/32px.png000064400000013034152214270100014054 0ustar00PNG  IHDR@`lK(IDATx tU+ EaW6uAx<7$"Ƨ"2Ge`P A%Ic%!}M:aJΞNBN~] m1s~v;}*ݿoݪn kwo-.crqq^  '@ '@ '0N\Y\\\Y8rqdrqqqdrTPm}3ߣ>;"Tu!((Ȣ,fVmfAtN~G?m}̶uۛub"^~ʂ\/iZ!dy cE"(,X(X.A./+H//G~Q P`̓׉֯L<VTJ5?ɑl*Mi2tN ZK ӐP͗E_ $rYNDMIngӎ" p1#Yq>+n18'm"-m* Ұm x["א)!Tť=z@sJ`o, POİҜ|9yy6ED@Mo?av.Şl6\( a8{s;ƥH]ۀQU{óBԝ_&ȜHYX6܇)Jw`U4H﷠Qt`"jV_3gffe@ZZӑEȗEX 0*,V[[,yXqf&6dY4.BqawR,ZXuSCWcީ11~cwjτ/'`"n_4c/-HrVNJM7zclN_ LMKEJJ*RSӐ~CH0 9B(%"cIf Imv&š>c 2/k6d̿ Ao-j:QObN3=7 F۽@*9>G#}05 _-Q]>$&BE"AWzl#|#`s4ÚT!? IJNE,BP򐰸Xo7ƽ /ӄ8$(4 OF? #c4cM`ԡysk14&}#A $<*sM<$Ml NGlZ>&@e^| .|!?`PikտHJ{$=}^pדe!1eBvؘ('@$?=汞o{cr;Aawa\p\U}7tW\UvCwg ok"6T1P-Hb+^r{`L1pld%DO‹#>.ze$]Oi0:,cĀ 0?BÀP7xĠBx0(<)gh xoNQS-'v/k'%, HB@ =Vއcn~-䗓 .g M:6cPfi;)#.J^ d`JjH'`n~NQ#_-*n}XHR[ ]ǣH>nzt2#e7E{ 7ˬmYY|hq%2jWfy)"@EnM:u.qZ`Y| +RwajpKZk> A.ABN 4J$F4ay,@agwd aN,@ard2  aXY& ϰ92  gXar3,@N ð9r '@aX9rm87B(?92$o߂m#gBfLVӶkI6â,qfǺ)˚?1[^﾿QO;y9q,2fsp=ޏy֑>с^1 ~қ"ހA9!@o߮,K;Kt7ETd\X-!Uҵ`9ĽO/a">ֿibdtl&^1pX@g:#ð}.x-=#ƤaD=!B% ZWj2 XP;7oBomJU{?!@oU;(vIP"`5c!BxUK&{}?&Ĥ0DOuqwtGxSa.ju_u}H n~!mW0p8wP> `}plZ`Sϡz WAY /Cb~VTuIB[ zgv.v k` 7KxB'+PBOAą}B1@yYL*q^$(Q0FɵI"N4STO1~'tgel0MHR ߻,oG} geHVw*:!gf1 ܀tJ8LV)[!ҫQr|"Sn|^7w~? {hV ]rEx|}8|8@vD; H(2>i$tOb76%3-H:EB qw#Z\ ۫{0Mlu6,O&r:x ^b6&?R.#>tC4|%èp%]ffȓ'/M~=!/#ّr脯f> gAÇ!P;VQ 0 '@aXard a '@aXard a '@a8rd aN,@a8d '@ ð9 /Ijw$Rs0 `Fu⛶`A?y\ݝqsm;RKJRk{r_q cg8,_S~K.[oj+h֭C $k֘vwSy (߶tMOHHK8Hj<8Ufƻж-^x5˖h*STǎc V6!2NDŖ-7u4R WWge6 } K\\3K}oF6cےogzȜHYX6܇^>'V KPԾ='OFXXXظزسydCP #%X-b RKBd 2U`=99b0V/wWV;?9Xŗ&⋸Ixm$iB^*D|`$\k ̞ ˜9y%05NB$x9 N,(@ɝ9+敜wxHL zɻC mqdO/(T>(jN}UsX칍KJPc6ZnKbIu F!AZ!O0H=zt(uFha\ZL{xz}gGD߃Ix*TB/[^|= B%RNWKNNr,IK?bzV ^Z'@-!0%B Pc=KLp aV "/DB [&a'T]A{h1w&M(IÕ=iJOiz ?W†,@>_kΓzoN$W/Z\觺mkpe*xDAmR$'($ط/r'OPl!C|,fK7n ,@ڧ5o$t`OB%o> %?g类O;#ɐ+D˖&Yɑ<77cwu4M :l6`550ᮌ]S]# d8jqxEvׯ\e+vE{f㈳3bS)1g춷n#Xv^?gan60xy!sZ 4dSUU&=L&+t̯Z:'pd8jx"-ZT wpsn`  lÄo;k;.xy4Iee&F rd8jx%_Z&@{nnB۶v۩.ʕ"eDwNN豚Km,6֔nDPZ,Cd2և!8ޛ&K{X}M*see***PQ^ʊJTWaq'ANM㰜ڋ̞kp.jstree-ocl{cursor:default}.jstree .jstree-open>.jstree-children{display:block}.jstree .jstree-closed>.jstree-children,.jstree .jstree-leaf>.jstree-children{display:none}.jstree-anchor>.jstree-themeicon{margin-right:2px}.jstree-no-icons .jstree-themeicon,.jstree-anchor>.jstree-themeicon-hidden{display:none}.jstree-hidden,.jstree-node.jstree-hidden{display:none}.jstree-rtl .jstree-anchor{padding:0 1px 0 4px}.jstree-rtl .jstree-anchor>.jstree-themeicon{margin-left:2px;margin-right:0}.jstree-rtl .jstree-node{margin-left:0}.jstree-rtl .jstree-container-ul>.jstree-node{margin-right:0}.jstree-wholerow-ul{position:relative;display:inline-block;min-width:100%}.jstree-wholerow-ul .jstree-leaf>.jstree-ocl{cursor:pointer}.jstree-wholerow-ul .jstree-anchor,.jstree-wholerow-ul .jstree-icon{position:relative}.jstree-wholerow-ul .jstree-wholerow{width:100%;cursor:pointer;position:absolute;left:0;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.jstree-contextmenu .jstree-anchor{-webkit-user-select:none;-webkit-touch-callout:none;user-select:none}.vakata-context{display:none}.vakata-context,.vakata-context ul{margin:0;padding:2px;position:absolute;background:#f5f5f5;border:1px solid #979797;box-shadow:2px 2px 2px #999999}.vakata-context ul{list-style:none;left:100%;margin-top:-2.7em;margin-left:-4px}.vakata-context .vakata-context-right ul{left:auto;right:100%;margin-left:auto;margin-right:-4px}.vakata-context li{list-style:none}.vakata-context li>a{display:block;padding:0 2em 0 2em;text-decoration:none;width:auto;color:black;white-space:nowrap;line-height:2.4em;text-shadow:1px 1px 0 white;border-radius:1px}.vakata-context li>a:hover{position:relative;background-color:#e8eff7;box-shadow:0 0 2px #0a6aa1}.vakata-context li>a.vakata-context-parent{background-image:url("data:image/gif;base64,R0lGODlhCwAHAIAAACgoKP///yH5BAEAAAEALAAAAAALAAcAAAIORI4JlrqN1oMSnmmZDQUAOw==");background-position:right center;background-repeat:no-repeat}.vakata-context li>a:focus{outline:0}.vakata-context .vakata-context-no-icons{margin-left:0}.vakata-context .vakata-context-hover>a{position:relative;background-color:#e8eff7;box-shadow:0 0 2px #0a6aa1}.vakata-context .vakata-context-separator>a,.vakata-context .vakata-context-separator>a:hover{background:white;border:0;border-top:1px solid #e2e3e3;height:1px;min-height:1px;max-height:1px;padding:0;margin:0 0 0 2.4em;border-left:1px solid #e0e0e0;text-shadow:0 0 0 transparent;box-shadow:0 0 0 transparent;border-radius:0}.vakata-context .vakata-contextmenu-disabled a,.vakata-context .vakata-contextmenu-disabled a:hover{color:silver;background-color:transparent;border:0;box-shadow:0 0 0}.vakata-context .vakata-contextmenu-disabled>a>i{filter:grayscale(100%)}.vakata-context li>a>i{text-decoration:none;display:inline-block;width:2.4em;height:2.4em;background:transparent;margin:0 0 0 -2em;vertical-align:top;text-align:center;line-height:2.4em}.vakata-context li>a>i:empty{width:2.4em;line-height:2.4em}.vakata-context li>a .vakata-contextmenu-sep{display:inline-block;width:1px;height:2.4em;background:white;margin:0 .5em 0 0;border-left:1px solid #e2e3e3}.vakata-context .vakata-contextmenu-shortcut{font-size:.8em;color:silver;opacity:.5;display:none}.vakata-context-rtl ul{left:auto;right:100%;margin-left:auto;margin-right:-4px}.vakata-context-rtl li>a.vakata-context-parent{background-image:url("data:image/gif;base64,R0lGODlhCwAHAIAAACgoKP///yH5BAEAAAEALAAAAAALAAcAAAINjI+AC7rWHIsPtmoxLAA7");background-position:left center;background-repeat:no-repeat}.vakata-context-rtl .vakata-context-separator>a{margin:0 2.4em 0 0;border-left:0;border-right:1px solid #e2e3e3}.vakata-context-rtl .vakata-context-left ul{right:auto;left:100%;margin-left:-4px;margin-right:auto}.vakata-context-rtl li>a>i{margin:0 -2em 0 0}.vakata-context-rtl li>a .vakata-contextmenu-sep{margin:0 0 0 .5em;border-left-color:white;background:#e2e3e3}#jstree-marker{position:absolute;top:0;left:0;margin:-5px 0 0 0;padding:0;border-right:0;border-top:5px solid transparent;border-bottom:5px solid transparent;border-left:5px solid;width:0;height:0;font-size:0;line-height:0}#jstree-dnd{line-height:16px;margin:0;padding:4px}#jstree-dnd .jstree-icon,#jstree-dnd .jstree-copy{display:inline-block;text-decoration:none;margin:0 2px 0 0;padding:0;width:16px;height:16px}#jstree-dnd .jstree-ok{background:green}#jstree-dnd .jstree-er{background:red}#jstree-dnd .jstree-copy{margin:0 2px 0 2px}.jstree-default .jstree-node,.jstree-default .jstree-icon{background-repeat:no-repeat;background-color:transparent}.jstree-default .jstree-anchor,.jstree-default .jstree-animated,.jstree-default .jstree-wholerow{transition:background-color .15s,box-shadow .15s}.jstree-default .jstree-hovered{background:#e7f4f9;border-radius:2px;box-shadow:inset 0 0 1px #cccccc}.jstree-default .jstree-context{background:#e7f4f9;border-radius:2px;box-shadow:inset 0 0 1px #cccccc}.jstree-default .jstree-clicked{background:#beebff;border-radius:2px;box-shadow:inset 0 0 1px #999999}.jstree-default .jstree-no-icons .jstree-anchor>.jstree-themeicon{display:none}.jstree-default .jstree-disabled{background:transparent;color:#666666}.jstree-default .jstree-disabled.jstree-hovered{background:transparent;box-shadow:none}.jstree-default .jstree-disabled.jstree-clicked{background:#efefef}.jstree-default .jstree-disabled>.jstree-icon{opacity:.8;filter:url("data:image/svg+xml;utf8,#jstree-grayscale");filter:gray;-webkit-filter:grayscale(100%)}.jstree-default .jstree-search{font-style:italic;color:#8b0000;font-weight:bold}.jstree-default .jstree-no-checkboxes .jstree-checkbox{display:none !important}.jstree-default.jstree-checkbox-no-clicked .jstree-clicked{background:transparent;box-shadow:none}.jstree-default.jstree-checkbox-no-clicked .jstree-clicked.jstree-hovered{background:#e7f4f9}.jstree-default.jstree-checkbox-no-clicked>.jstree-wholerow-ul .jstree-wholerow-clicked{background:transparent}.jstree-default.jstree-checkbox-no-clicked>.jstree-wholerow-ul .jstree-wholerow-clicked.jstree-wholerow-hovered{background:#e7f4f9}.jstree-default>.jstree-striped{min-width:100%;display:inline-block;background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAkCAMAAAB/qqA+AAAABlBMVEUAAAAAAAClZ7nPAAAAAnRSTlMNAMM9s3UAAAAXSURBVHjajcEBAQAAAIKg/H/aCQZ70AUBjAATb6YPDgAAAABJRU5ErkJggg==") left top repeat}.jstree-default>.jstree-wholerow-ul .jstree-hovered,.jstree-default>.jstree-wholerow-ul .jstree-clicked{background:transparent;box-shadow:none;border-radius:0}.jstree-default .jstree-wholerow{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}.jstree-default .jstree-wholerow-hovered{background:#e7f4f9}.jstree-default .jstree-wholerow-clicked{background:#beebff;background:-webkit-linear-gradient(top, #beebff 0%, #a8e4ff 100%);background:linear-gradient(to bottom, #beebff 0%, #a8e4ff 100%)}.jstree-default .jstree-node{min-height:24px;line-height:24px;margin-left:24px;min-width:24px}.jstree-default .jstree-anchor{line-height:24px;height:24px}.jstree-default .jstree-icon{width:24px;height:24px;line-height:24px}.jstree-default .jstree-icon:empty{width:24px;height:24px;line-height:24px}.jstree-default.jstree-rtl .jstree-node{margin-right:24px}.jstree-default .jstree-wholerow{height:24px}.jstree-default .jstree-node,.jstree-default .jstree-icon{background-image:url("32px.png")}.jstree-default .jstree-node{background-position:-292px -4px;background-repeat:repeat-y}.jstree-default .jstree-last{background-image:none}.jstree-default .jstree-open>.jstree-ocl{background-position:-132px -4px}.jstree-default .jstree-closed>.jstree-ocl{background-position:-100px -4px}.jstree-default .jstree-leaf>.jstree-ocl{background-position:-68px -4px}.jstree-default .jstree-themeicon{background-position:-260px -4px}.jstree-default>.jstree-no-dots .jstree-node,.jstree-default>.jstree-no-dots .jstree-leaf>.jstree-ocl{background:transparent}.jstree-default>.jstree-no-dots .jstree-open>.jstree-ocl{background-position:-36px -4px}.jstree-default>.jstree-no-dots .jstree-closed>.jstree-ocl{background-position:-4px -4px}.jstree-default .jstree-disabled{background:transparent}.jstree-default .jstree-disabled.jstree-hovered{background:transparent}.jstree-default .jstree-disabled.jstree-clicked{background:#efefef}.jstree-default .jstree-checkbox{background-position:-164px -4px}.jstree-default .jstree-checkbox:hover{background-position:-164px -36px}.jstree-default.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox,.jstree-default .jstree-checked>.jstree-checkbox{background-position:-228px -4px}.jstree-default.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox:hover,.jstree-default .jstree-checked>.jstree-checkbox:hover{background-position:-228px -36px}.jstree-default .jstree-anchor>.jstree-undetermined{background-position:-196px -4px}.jstree-default .jstree-anchor>.jstree-undetermined:hover{background-position:-196px -36px}.jstree-default .jstree-checkbox-disabled{opacity:.8;filter:url("data:image/svg+xml;utf8,#jstree-grayscale");filter:gray;-webkit-filter:grayscale(100%)}.jstree-default>.jstree-striped{background-size:auto 48px}.jstree-default.jstree-rtl .jstree-node{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg==");background-position:100% 1px;background-repeat:repeat-y}.jstree-default.jstree-rtl .jstree-last{background-image:none}.jstree-default.jstree-rtl .jstree-open>.jstree-ocl{background-position:-132px -36px}.jstree-default.jstree-rtl .jstree-closed>.jstree-ocl{background-position:-100px -36px}.jstree-default.jstree-rtl .jstree-leaf>.jstree-ocl{background-position:-68px -36px}.jstree-default.jstree-rtl>.jstree-no-dots .jstree-node,.jstree-default.jstree-rtl>.jstree-no-dots .jstree-leaf>.jstree-ocl{background:transparent}.jstree-default.jstree-rtl>.jstree-no-dots .jstree-open>.jstree-ocl{background-position:-36px -36px}.jstree-default.jstree-rtl>.jstree-no-dots .jstree-closed>.jstree-ocl{background-position:-4px -36px}.jstree-default .jstree-themeicon-custom{background-color:transparent;background-image:none;background-position:0 0}.jstree-default>.jstree-container-ul .jstree-loading>.jstree-ocl{background:url("throbber.gif") center center no-repeat}.jstree-default .jstree-file{background:url("32px.png") -100px -68px no-repeat}.jstree-default .jstree-folder{background:url("32px.png") -260px -4px no-repeat}.jstree-default>.jstree-container-ul>.jstree-node{margin-left:0;margin-right:0}#jstree-dnd.jstree-default{line-height:24px;padding:0 4px}#jstree-dnd.jstree-default .jstree-ok,#jstree-dnd.jstree-default .jstree-er{background-image:url("32px.png");background-repeat:no-repeat;background-color:transparent}#jstree-dnd.jstree-default i{background:transparent;width:24px;height:24px;line-height:24px}#jstree-dnd.jstree-default .jstree-ok{background-position:-4px -68px}#jstree-dnd.jstree-default .jstree-er{background-position:-36px -68px}.jstree-default .jstree-ellipsis{overflow:hidden}.jstree-default .jstree-ellipsis .jstree-anchor{width:calc(100% - 24px + 5px);text-overflow:ellipsis;overflow:hidden}.jstree-default.jstree-rtl .jstree-node{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg==")}.jstree-default.jstree-rtl .jstree-last{background-image:none}.jstree-default-small .jstree-node{min-height:18px;line-height:18px;margin-left:18px;min-width:18px}.jstree-default-small .jstree-anchor{line-height:18px;height:18px}.jstree-default-small .jstree-icon{width:18px;height:18px;line-height:18px}.jstree-default-small .jstree-icon:empty{width:18px;height:18px;line-height:18px}.jstree-default-small.jstree-rtl .jstree-node{margin-right:18px}.jstree-default-small .jstree-wholerow{height:18px}.jstree-default-small .jstree-node,.jstree-default-small .jstree-icon{background-image:url("32px.png")}.jstree-default-small .jstree-node{background-position:-295px -7px;background-repeat:repeat-y}.jstree-default-small .jstree-last{background-image:none}.jstree-default-small .jstree-open>.jstree-ocl{background-position:-135px -7px}.jstree-default-small .jstree-closed>.jstree-ocl{background-position:-103px -7px}.jstree-default-small .jstree-leaf>.jstree-ocl{background-position:-71px -7px}.jstree-default-small .jstree-themeicon{background-position:-263px -7px}.jstree-default-small>.jstree-no-dots .jstree-node,.jstree-default-small>.jstree-no-dots .jstree-leaf>.jstree-ocl{background:transparent}.jstree-default-small>.jstree-no-dots .jstree-open>.jstree-ocl{background-position:-39px -7px}.jstree-default-small>.jstree-no-dots .jstree-closed>.jstree-ocl{background-position:-7px -7px}.jstree-default-small .jstree-disabled{background:transparent}.jstree-default-small .jstree-disabled.jstree-hovered{background:transparent}.jstree-default-small .jstree-disabled.jstree-clicked{background:#efefef}.jstree-default-small .jstree-checkbox{background-position:-167px -7px}.jstree-default-small .jstree-checkbox:hover{background-position:-167px -39px}.jstree-default-small.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox,.jstree-default-small .jstree-checked>.jstree-checkbox{background-position:-231px -7px}.jstree-default-small.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox:hover,.jstree-default-small .jstree-checked>.jstree-checkbox:hover{background-position:-231px -39px}.jstree-default-small .jstree-anchor>.jstree-undetermined{background-position:-199px -7px}.jstree-default-small .jstree-anchor>.jstree-undetermined:hover{background-position:-199px -39px}.jstree-default-small .jstree-checkbox-disabled{opacity:.8;filter:url("data:image/svg+xml;utf8,#jstree-grayscale");filter:gray;-webkit-filter:grayscale(100%)}.jstree-default-small>.jstree-striped{background-size:auto 36px}.jstree-default-small.jstree-rtl .jstree-node{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg==");background-position:100% 1px;background-repeat:repeat-y}.jstree-default-small.jstree-rtl .jstree-last{background-image:none}.jstree-default-small.jstree-rtl .jstree-open>.jstree-ocl{background-position:-135px -39px}.jstree-default-small.jstree-rtl .jstree-closed>.jstree-ocl{background-position:-103px -39px}.jstree-default-small.jstree-rtl .jstree-leaf>.jstree-ocl{background-position:-71px -39px}.jstree-default-small.jstree-rtl>.jstree-no-dots .jstree-node,.jstree-default-small.jstree-rtl>.jstree-no-dots .jstree-leaf>.jstree-ocl{background:transparent}.jstree-default-small.jstree-rtl>.jstree-no-dots .jstree-open>.jstree-ocl{background-position:-39px -39px}.jstree-default-small.jstree-rtl>.jstree-no-dots .jstree-closed>.jstree-ocl{background-position:-7px -39px}.jstree-default-small .jstree-themeicon-custom{background-color:transparent;background-image:none;background-position:0 0}.jstree-default-small>.jstree-container-ul .jstree-loading>.jstree-ocl{background:url("throbber.gif") center center no-repeat}.jstree-default-small .jstree-file{background:url("32px.png") -103px -71px no-repeat}.jstree-default-small .jstree-folder{background:url("32px.png") -263px -7px no-repeat}.jstree-default-small>.jstree-container-ul>.jstree-node{margin-left:0;margin-right:0}#jstree-dnd.jstree-default-small{line-height:18px;padding:0 4px}#jstree-dnd.jstree-default-small .jstree-ok,#jstree-dnd.jstree-default-small .jstree-er{background-image:url("32px.png");background-repeat:no-repeat;background-color:transparent}#jstree-dnd.jstree-default-small i{background:transparent;width:18px;height:18px;line-height:18px}#jstree-dnd.jstree-default-small .jstree-ok{background-position:-7px -71px}#jstree-dnd.jstree-default-small .jstree-er{background-position:-39px -71px}.jstree-default-small .jstree-ellipsis{overflow:hidden}.jstree-default-small .jstree-ellipsis .jstree-anchor{width:calc(100% - 18px + 5px);text-overflow:ellipsis;overflow:hidden}.jstree-default-small.jstree-rtl .jstree-node{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAACAQMAAABv1h6PAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMHBgAAiABBI4gz9AAAAABJRU5ErkJggg==")}.jstree-default-small.jstree-rtl .jstree-last{background-image:none}.jstree-default-large .jstree-node{min-height:32px;line-height:32px;margin-left:32px;min-width:32px}.jstree-default-large .jstree-anchor{line-height:32px;height:32px}.jstree-default-large .jstree-icon{width:32px;height:32px;line-height:32px}.jstree-default-large .jstree-icon:empty{width:32px;height:32px;line-height:32px}.jstree-default-large.jstree-rtl .jstree-node{margin-right:32px}.jstree-default-large .jstree-wholerow{height:32px}.jstree-default-large .jstree-node,.jstree-default-large .jstree-icon{background-image:url("32px.png")}.jstree-default-large .jstree-node{background-position:-288px 0;background-repeat:repeat-y}.jstree-default-large .jstree-last{background-image:none}.jstree-default-large .jstree-open>.jstree-ocl{background-position:-128px 0}.jstree-default-large .jstree-closed>.jstree-ocl{background-position:-96px 0}.jstree-default-large .jstree-leaf>.jstree-ocl{background-position:-64px 0}.jstree-default-large .jstree-themeicon{background-position:-256px 0}.jstree-default-large>.jstree-no-dots .jstree-node,.jstree-default-large>.jstree-no-dots .jstree-leaf>.jstree-ocl{background:transparent}.jstree-default-large>.jstree-no-dots .jstree-open>.jstree-ocl{background-position:-32px 0}.jstree-default-large>.jstree-no-dots .jstree-closed>.jstree-ocl{background-position:0 0}.jstree-default-large .jstree-disabled{background:transparent}.jstree-default-large .jstree-disabled.jstree-hovered{background:transparent}.jstree-default-large .jstree-disabled.jstree-clicked{background:#efefef}.jstree-default-large .jstree-checkbox{background-position:-160px 0}.jstree-default-large .jstree-checkbox:hover{background-position:-160px -32px}.jstree-default-large.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox,.jstree-default-large .jstree-checked>.jstree-checkbox{background-position:-224px 0}.jstree-default-large.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox:hover,.jstree-default-large .jstree-checked>.jstree-checkbox:hover{background-position:-224px -32px}.jstree-default-large .jstree-anchor>.jstree-undetermined{background-position:-192px 0}.jstree-default-large .jstree-anchor>.jstree-undetermined:hover{background-position:-192px -32px}.jstree-default-large .jstree-checkbox-disabled{opacity:.8;filter:url("data:image/svg+xml;utf8,#jstree-grayscale");filter:gray;-webkit-filter:grayscale(100%)}.jstree-default-large>.jstree-striped{background-size:auto 64px}.jstree-default-large.jstree-rtl .jstree-node{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg==");background-position:100% 1px;background-repeat:repeat-y}.jstree-default-large.jstree-rtl .jstree-last{background-image:none}.jstree-default-large.jstree-rtl .jstree-open>.jstree-ocl{background-position:-128px -32px}.jstree-default-large.jstree-rtl .jstree-closed>.jstree-ocl{background-position:-96px -32px}.jstree-default-large.jstree-rtl .jstree-leaf>.jstree-ocl{background-position:-64px -32px}.jstree-default-large.jstree-rtl>.jstree-no-dots .jstree-node,.jstree-default-large.jstree-rtl>.jstree-no-dots .jstree-leaf>.jstree-ocl{background:transparent}.jstree-default-large.jstree-rtl>.jstree-no-dots .jstree-open>.jstree-ocl{background-position:-32px -32px}.jstree-default-large.jstree-rtl>.jstree-no-dots .jstree-closed>.jstree-ocl{background-position:0 -32px}.jstree-default-large .jstree-themeicon-custom{background-color:transparent;background-image:none;background-position:0 0}.jstree-default-large>.jstree-container-ul .jstree-loading>.jstree-ocl{background:url("throbber.gif") center center no-repeat}.jstree-default-large .jstree-file{background:url("32px.png") -96px -64px no-repeat}.jstree-default-large .jstree-folder{background:url("32px.png") -256px 0 no-repeat}.jstree-default-large>.jstree-container-ul>.jstree-node{margin-left:0;margin-right:0}#jstree-dnd.jstree-default-large{line-height:32px;padding:0 4px}#jstree-dnd.jstree-default-large .jstree-ok,#jstree-dnd.jstree-default-large .jstree-er{background-image:url("32px.png");background-repeat:no-repeat;background-color:transparent}#jstree-dnd.jstree-default-large i{background:transparent;width:32px;height:32px;line-height:32px}#jstree-dnd.jstree-default-large .jstree-ok{background-position:0 -64px}#jstree-dnd.jstree-default-large .jstree-er{background-position:-32px -64px}.jstree-default-large .jstree-ellipsis{overflow:hidden}.jstree-default-large .jstree-ellipsis .jstree-anchor{width:calc(100% - 32px + 5px);text-overflow:ellipsis;overflow:hidden}.jstree-default-large.jstree-rtl .jstree-node{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAACAQMAAAAD0EyKAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjgIIGBgABCgCBvVLXcAAAAABJRU5ErkJggg==")}.jstree-default-large.jstree-rtl .jstree-last{background-image:none}@media (max-width:768px){#jstree-dnd.jstree-dnd-responsive{line-height:40px;font-weight:bold;font-size:1.1em;text-shadow:1px 1px white}#jstree-dnd.jstree-dnd-responsive>i{background:transparent;width:40px;height:40px}#jstree-dnd.jstree-dnd-responsive>.jstree-ok{background-image:url("40px.png");background-position:0 -200px;background-size:120px 240px}#jstree-dnd.jstree-dnd-responsive>.jstree-er{background-image:url("40px.png");background-position:-40px -200px;background-size:120px 240px}#jstree-marker.jstree-dnd-responsive{border-left-width:10px;border-top-width:10px;border-bottom-width:10px;margin-top:-10px}}@media (max-width:768px){.jstree-default-responsive .jstree-icon{background-image:url("40px.png")}.jstree-default-responsive .jstree-node,.jstree-default-responsive .jstree-leaf>.jstree-ocl{background:transparent}.jstree-default-responsive .jstree-node{min-height:40px;line-height:40px;margin-left:40px;min-width:40px;white-space:nowrap}.jstree-default-responsive .jstree-anchor{line-height:40px;height:40px}.jstree-default-responsive .jstree-icon,.jstree-default-responsive .jstree-icon:empty{width:40px;height:40px;line-height:40px}.jstree-default-responsive>.jstree-container-ul>.jstree-node{margin-left:0}.jstree-default-responsive.jstree-rtl .jstree-node{margin-left:0;margin-right:40px;background:transparent}.jstree-default-responsive.jstree-rtl .jstree-container-ul>.jstree-node{margin-right:0}.jstree-default-responsive .jstree-ocl,.jstree-default-responsive .jstree-themeicon,.jstree-default-responsive .jstree-checkbox{background-size:120px 240px}.jstree-default-responsive .jstree-leaf>.jstree-ocl,.jstree-default-responsive.jstree-rtl .jstree-leaf>.jstree-ocl{background:transparent}.jstree-default-responsive .jstree-open>.jstree-ocl{background-position:0 0 !important}.jstree-default-responsive .jstree-closed>.jstree-ocl{background-position:0 -40px !important}.jstree-default-responsive.jstree-rtl .jstree-closed>.jstree-ocl{background-position:-40px 0 !important}.jstree-default-responsive .jstree-themeicon{background-position:-40px -40px}.jstree-default-responsive .jstree-checkbox,.jstree-default-responsive .jstree-checkbox:hover{background-position:-40px -80px}.jstree-default-responsive.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox,.jstree-default-responsive.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox:hover,.jstree-default-responsive .jstree-checked>.jstree-checkbox,.jstree-default-responsive .jstree-checked>.jstree-checkbox:hover{background-position:0 -80px}.jstree-default-responsive .jstree-anchor>.jstree-undetermined,.jstree-default-responsive .jstree-anchor>.jstree-undetermined:hover{background-position:0 -120px}.jstree-default-responsive .jstree-anchor{font-weight:bold;font-size:1.1em;text-shadow:1px 1px white}.jstree-default-responsive>.jstree-striped{background:transparent}.jstree-default-responsive .jstree-wholerow{border-top:1px solid rgba(255,255,255,0.7);border-bottom:1px solid rgba(64,64,64,0.2);background:#ebebeb;height:40px}.jstree-default-responsive .jstree-wholerow-hovered{background:#e7f4f9}.jstree-default-responsive .jstree-wholerow-clicked{background:#beebff}.jstree-default-responsive .jstree-children .jstree-last>.jstree-wholerow{box-shadow:inset 0 -6px 3px -5px #666666}.jstree-default-responsive .jstree-children .jstree-open>.jstree-wholerow{box-shadow:inset 0 6px 3px -5px #666666;border-top:0}.jstree-default-responsive .jstree-children .jstree-open+.jstree-open{box-shadow:none}.jstree-default-responsive .jstree-node,.jstree-default-responsive .jstree-icon,.jstree-default-responsive .jstree-node>.jstree-ocl,.jstree-default-responsive .jstree-themeicon,.jstree-default-responsive .jstree-checkbox{background-image:url("40px.png");background-size:120px 240px}.jstree-default-responsive .jstree-node{background-position:-80px 0;background-repeat:repeat-y}.jstree-default-responsive .jstree-last{background-image:none}.jstree-default-responsive .jstree-leaf>.jstree-ocl{background-position:-40px -120px}.jstree-default-responsive .jstree-last>.jstree-ocl{background-position:-40px -160px}.jstree-default-responsive .jstree-themeicon-custom{background-color:transparent;background-image:none;background-position:0 0}.jstree-default-responsive .jstree-file{background:url("40px.png") 0 -160px no-repeat;background-size:120px 240px}.jstree-default-responsive .jstree-folder{background:url("40px.png") -40px -40px no-repeat;background-size:120px 240px}.jstree-default-responsive>.jstree-container-ul>.jstree-node{margin-left:0;margin-right:0}}includes/jstree/themes/default-dark/throbber.gif000064400000002670152214270100015773 0ustar00GIF89a@@@pppPPP```999hhhXXXxxx333! NETSCAPE2.0!Created with ajaxload.info! ,@pɇhuʤ" 3 @J@"S , !$JJdσ-ד%LXwVrP5 g*"B` :1 o!Y3 ! ,]BN%I8"d,!p#a BI0![փXʇah@7a([/` (4U%s!sj#! ,ZLX6BG&9!T1@HJ=M!3 R .|V}F5$p19S"! ,\) 275&D %!VAX% QPpr٥!( ` Pㄐ}B  &-! ,EɉBX)!(^gPpX^OaJ0Arɔ>C A9N"BkJfPE! ,k!&S!$N'PaG(!A@L8`Ua0P$،a(4A6O 00"AQfJPh #il~! ,[Xi xJ 2> YH-t i&$h Cq8N#<1Px nSAx\y ĚH;1>8)! ,VI LZ/i] P8Hn !@5H+k±b:SWJq82ڱ4c! ,]X$\guHael4x/( 'Y0B M!8xFC0,v8z~ > !6J9! ,Zji%ZmNLB\TINS ! B İr&Ɓ)Y Ñ8 Cf(-Lsp`u(5&E! ,XIx"PE BRMZӉҢgGCU$p>b34$ 3 W`&Hހ"! ,ZIR|RiㅰY+%$XExpa$N`#0dNӤ@HHN}h<F`}q/)D;includes/jstree/themes/default-dark/style.css000064400000103240152214270100015342 0ustar00/* jsTree default dark theme */ .jstree-node, .jstree-children, .jstree-container-ul { display: block; margin: 0; padding: 0; list-style-type: none; list-style-image: none; } .jstree-node { white-space: nowrap; } .jstree-anchor { display: inline-block; color: black; white-space: nowrap; padding: 0 4px 0 1px; margin: 0; vertical-align: top; } .jstree-anchor:focus { outline: 0; } .jstree-anchor, .jstree-anchor:link, .jstree-anchor:visited, .jstree-anchor:hover, .jstree-anchor:active { text-decoration: none; color: inherit; } .jstree-icon { display: inline-block; text-decoration: none; margin: 0; padding: 0; vertical-align: top; text-align: center; } .jstree-icon:empty { display: inline-block; text-decoration: none; margin: 0; padding: 0; vertical-align: top; text-align: center; } .jstree-ocl { cursor: pointer; } .jstree-leaf > .jstree-ocl { cursor: default; } .jstree .jstree-open > .jstree-children { display: block; } .jstree .jstree-closed > .jstree-children, .jstree .jstree-leaf > .jstree-children { display: none; } .jstree-anchor > .jstree-themeicon { margin-right: 2px; } .jstree-no-icons .jstree-themeicon, .jstree-anchor > .jstree-themeicon-hidden { display: none; } .jstree-hidden, .jstree-node.jstree-hidden { display: none; } .jstree-rtl .jstree-anchor { padding: 0 1px 0 4px; } .jstree-rtl .jstree-anchor > .jstree-themeicon { margin-left: 2px; margin-right: 0; } .jstree-rtl .jstree-node { margin-left: 0; } .jstree-rtl .jstree-container-ul > .jstree-node { margin-right: 0; } .jstree-wholerow-ul { position: relative; display: inline-block; min-width: 100%; } .jstree-wholerow-ul .jstree-leaf > .jstree-ocl { cursor: pointer; } .jstree-wholerow-ul .jstree-anchor, .jstree-wholerow-ul .jstree-icon { position: relative; } .jstree-wholerow-ul .jstree-wholerow { width: 100%; cursor: pointer; position: absolute; left: 0; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; } .jstree-contextmenu .jstree-anchor { -webkit-user-select: none; /* disable selection/Copy of UIWebView */ -webkit-touch-callout: none; /* disable the IOS popup when long-press on a link */ user-select: none; } .vakata-context { display: none; } .vakata-context, .vakata-context ul { margin: 0; padding: 2px; position: absolute; background: #f5f5f5; border: 1px solid #979797; box-shadow: 2px 2px 2px #999999; } .vakata-context ul { list-style: none; left: 100%; margin-top: -2.7em; margin-left: -4px; } .vakata-context .vakata-context-right ul { left: auto; right: 100%; margin-left: auto; margin-right: -4px; } .vakata-context li { list-style: none; } .vakata-context li > a { display: block; padding: 0 2em 0 2em; text-decoration: none; width: auto; color: black; white-space: nowrap; line-height: 2.4em; text-shadow: 1px 1px 0 white; border-radius: 1px; } .vakata-context li > a:hover { position: relative; background-color: #e8eff7; box-shadow: 0 0 2px #0a6aa1; } .vakata-context li > a.vakata-context-parent { background-image: url("data:image/gif;base64,R0lGODlhCwAHAIAAACgoKP///yH5BAEAAAEALAAAAAALAAcAAAIORI4JlrqN1oMSnmmZDQUAOw=="); background-position: right center; background-repeat: no-repeat; } .vakata-context li > a:focus { outline: 0; } .vakata-context .vakata-context-no-icons { margin-left: 0; } .vakata-context .vakata-context-hover > a { position: relative; background-color: #e8eff7; box-shadow: 0 0 2px #0a6aa1; } .vakata-context .vakata-context-separator > a, .vakata-context .vakata-context-separator > a:hover { background: white; border: 0; border-top: 1px solid #e2e3e3; height: 1px; min-height: 1px; max-height: 1px; padding: 0; margin: 0 0 0 2.4em; border-left: 1px solid #e0e0e0; text-shadow: 0 0 0 transparent; box-shadow: 0 0 0 transparent; border-radius: 0; } .vakata-context .vakata-contextmenu-disabled a, .vakata-context .vakata-contextmenu-disabled a:hover { color: silver; background-color: transparent; border: 0; box-shadow: 0 0 0; } .vakata-context .vakata-contextmenu-disabled > a > i { filter: grayscale(100%); } .vakata-context li > a > i { text-decoration: none; display: inline-block; width: 2.4em; height: 2.4em; background: transparent; margin: 0 0 0 -2em; vertical-align: top; text-align: center; line-height: 2.4em; } .vakata-context li > a > i:empty { width: 2.4em; line-height: 2.4em; } .vakata-context li > a .vakata-contextmenu-sep { display: inline-block; width: 1px; height: 2.4em; background: white; margin: 0 0.5em 0 0; border-left: 1px solid #e2e3e3; } .vakata-context .vakata-contextmenu-shortcut { font-size: 0.8em; color: silver; opacity: 0.5; display: none; } .vakata-context-rtl ul { left: auto; right: 100%; margin-left: auto; margin-right: -4px; } .vakata-context-rtl li > a.vakata-context-parent { background-image: url("data:image/gif;base64,R0lGODlhCwAHAIAAACgoKP///yH5BAEAAAEALAAAAAALAAcAAAINjI+AC7rWHIsPtmoxLAA7"); background-position: left center; background-repeat: no-repeat; } .vakata-context-rtl .vakata-context-separator > a { margin: 0 2.4em 0 0; border-left: 0; border-right: 1px solid #e2e3e3; } .vakata-context-rtl .vakata-context-left ul { right: auto; left: 100%; margin-left: -4px; margin-right: auto; } .vakata-context-rtl li > a > i { margin: 0 -2em 0 0; } .vakata-context-rtl li > a .vakata-contextmenu-sep { margin: 0 0 0 0.5em; border-left-color: white; background: #e2e3e3; } #jstree-marker { position: absolute; top: 0; left: 0; margin: -5px 0 0 0; padding: 0; border-right: 0; border-top: 5px solid transparent; border-bottom: 5px solid transparent; border-left: 5px solid; width: 0; height: 0; font-size: 0; line-height: 0; } #jstree-dnd { line-height: 16px; margin: 0; padding: 4px; } #jstree-dnd .jstree-icon, #jstree-dnd .jstree-copy { display: inline-block; text-decoration: none; margin: 0 2px 0 0; padding: 0; width: 16px; height: 16px; } #jstree-dnd .jstree-ok { background: green; } #jstree-dnd .jstree-er { background: red; } #jstree-dnd .jstree-copy { margin: 0 2px 0 2px; } .jstree-default-dark .jstree-node, .jstree-default-dark .jstree-icon { background-repeat: no-repeat; background-color: transparent; } .jstree-default-dark .jstree-anchor, .jstree-default-dark .jstree-animated, .jstree-default-dark .jstree-wholerow { transition: background-color 0.15s, box-shadow 0.15s; } .jstree-default-dark .jstree-hovered { background: #555; border-radius: 2px; box-shadow: inset 0 0 1px #555; } .jstree-default-dark .jstree-context { background: #555; border-radius: 2px; box-shadow: inset 0 0 1px #555; } .jstree-default-dark .jstree-clicked { background: #5fa2db; border-radius: 2px; box-shadow: inset 0 0 1px #666666; } .jstree-default-dark .jstree-no-icons .jstree-anchor > .jstree-themeicon { display: none; } .jstree-default-dark .jstree-disabled { background: transparent; color: #666666; } .jstree-default-dark .jstree-disabled.jstree-hovered { background: transparent; box-shadow: none; } .jstree-default-dark .jstree-disabled.jstree-clicked { background: #333333; } .jstree-default-dark .jstree-disabled > .jstree-icon { opacity: 0.8; filter: url("data:image/svg+xml;utf8,#jstree-grayscale"); /* Firefox 10+ */ filter: gray; /* IE6-9 */ -webkit-filter: grayscale(100%); /* Chrome 19+ & Safari 6+ */ } .jstree-default-dark .jstree-search { font-style: italic; color: #ffffff; font-weight: bold; } .jstree-default-dark .jstree-no-checkboxes .jstree-checkbox { display: none !important; } .jstree-default-dark.jstree-checkbox-no-clicked .jstree-clicked { background: transparent; box-shadow: none; } .jstree-default-dark.jstree-checkbox-no-clicked .jstree-clicked.jstree-hovered { background: #555; } .jstree-default-dark.jstree-checkbox-no-clicked > .jstree-wholerow-ul .jstree-wholerow-clicked { background: transparent; } .jstree-default-dark.jstree-checkbox-no-clicked > .jstree-wholerow-ul .jstree-wholerow-clicked.jstree-wholerow-hovered { background: #555; } .jstree-default-dark > .jstree-striped { min-width: 100%; display: inline-block; background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAkCAMAAAB/qqA+AAAABlBMVEUAAAAAAAClZ7nPAAAAAnRSTlMNAMM9s3UAAAAXSURBVHjajcEBAQAAAIKg/H/aCQZ70AUBjAATb6YPDgAAAABJRU5ErkJggg==") left top repeat; } .jstree-default-dark > .jstree-wholerow-ul .jstree-hovered, .jstree-default-dark > .jstree-wholerow-ul .jstree-clicked { background: transparent; box-shadow: none; border-radius: 0; } .jstree-default-dark .jstree-wholerow { -moz-box-sizing: border-box; -webkit-box-sizing: border-box; box-sizing: border-box; } .jstree-default-dark .jstree-wholerow-hovered { background: #555; } .jstree-default-dark .jstree-wholerow-clicked { background: #5fa2db; background: -webkit-linear-gradient(top, #5fa2db 0%, #5fa2db 100%); background: linear-gradient(to bottom, #5fa2db 0%, #5fa2db 100%); } .jstree-default-dark .jstree-node { min-height: 24px; line-height: 24px; margin-left: 24px; min-width: 24px; } .jstree-default-dark .jstree-anchor { line-height: 24px; height: 24px; } .jstree-default-dark .jstree-icon { width: 24px; height: 24px; line-height: 24px; } .jstree-default-dark .jstree-icon:empty { width: 24px; height: 24px; line-height: 24px; } .jstree-default-dark.jstree-rtl .jstree-node { margin-right: 24px; } .jstree-default-dark .jstree-wholerow { height: 24px; } .jstree-default-dark .jstree-node, .jstree-default-dark .jstree-icon { background-image: url("32px.png"); } .jstree-default-dark .jstree-node { background-position: -292px -4px; background-repeat: repeat-y; } .jstree-default-dark .jstree-last { background-image: none; } .jstree-default-dark .jstree-open > .jstree-ocl { background-position: -132px -4px; } .jstree-default-dark .jstree-closed > .jstree-ocl { background-position: -100px -4px; } .jstree-default-dark .jstree-leaf > .jstree-ocl { background-position: -68px -4px; } .jstree-default-dark .jstree-themeicon { background-position: -260px -4px; } .jstree-default-dark > .jstree-no-dots .jstree-node, .jstree-default-dark > .jstree-no-dots .jstree-leaf > .jstree-ocl { background: transparent; } .jstree-default-dark > .jstree-no-dots .jstree-open > .jstree-ocl { background-position: -36px -4px; } .jstree-default-dark > .jstree-no-dots .jstree-closed > .jstree-ocl { background-position: -4px -4px; } .jstree-default-dark .jstree-disabled { background: transparent; } .jstree-default-dark .jstree-disabled.jstree-hovered { background: transparent; } .jstree-default-dark .jstree-disabled.jstree-clicked { background: #efefef; } .jstree-default-dark .jstree-checkbox { background-position: -164px -4px; } .jstree-default-dark .jstree-checkbox:hover { background-position: -164px -36px; } .jstree-default-dark.jstree-checkbox-selection .jstree-clicked > .jstree-checkbox, .jstree-default-dark .jstree-checked > .jstree-checkbox { background-position: -228px -4px; } .jstree-default-dark.jstree-checkbox-selection .jstree-clicked > .jstree-checkbox:hover, .jstree-default-dark .jstree-checked > .jstree-checkbox:hover { background-position: -228px -36px; } .jstree-default-dark .jstree-anchor > .jstree-undetermined { background-position: -196px -4px; } .jstree-default-dark .jstree-anchor > .jstree-undetermined:hover { background-position: -196px -36px; } .jstree-default-dark .jstree-checkbox-disabled { opacity: 0.8; filter: url("data:image/svg+xml;utf8,#jstree-grayscale"); /* Firefox 10+ */ filter: gray; /* IE6-9 */ -webkit-filter: grayscale(100%); /* Chrome 19+ & Safari 6+ */ } .jstree-default-dark > .jstree-striped { background-size: auto 48px; } .jstree-default-dark.jstree-rtl .jstree-node { background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg=="); background-position: 100% 1px; background-repeat: repeat-y; } .jstree-default-dark.jstree-rtl .jstree-last { background-image: none; } .jstree-default-dark.jstree-rtl .jstree-open > .jstree-ocl { background-position: -132px -36px; } .jstree-default-dark.jstree-rtl .jstree-closed > .jstree-ocl { background-position: -100px -36px; } .jstree-default-dark.jstree-rtl .jstree-leaf > .jstree-ocl { background-position: -68px -36px; } .jstree-default-dark.jstree-rtl > .jstree-no-dots .jstree-node, .jstree-default-dark.jstree-rtl > .jstree-no-dots .jstree-leaf > .jstree-ocl { background: transparent; } .jstree-default-dark.jstree-rtl > .jstree-no-dots .jstree-open > .jstree-ocl { background-position: -36px -36px; } .jstree-default-dark.jstree-rtl > .jstree-no-dots .jstree-closed > .jstree-ocl { background-position: -4px -36px; } .jstree-default-dark .jstree-themeicon-custom { background-color: transparent; background-image: none; background-position: 0 0; } .jstree-default-dark > .jstree-container-ul .jstree-loading > .jstree-ocl { background: url("throbber.gif") center center no-repeat; } .jstree-default-dark .jstree-file { background: url("32px.png") -100px -68px no-repeat; } .jstree-default-dark .jstree-folder { background: url("32px.png") -260px -4px no-repeat; } .jstree-default-dark > .jstree-container-ul > .jstree-node { margin-left: 0; margin-right: 0; } #jstree-dnd.jstree-default-dark { line-height: 24px; padding: 0 4px; } #jstree-dnd.jstree-default-dark .jstree-ok, #jstree-dnd.jstree-default-dark .jstree-er { background-image: url("32px.png"); background-repeat: no-repeat; background-color: transparent; } #jstree-dnd.jstree-default-dark i { background: transparent; width: 24px; height: 24px; line-height: 24px; } #jstree-dnd.jstree-default-dark .jstree-ok { background-position: -4px -68px; } #jstree-dnd.jstree-default-dark .jstree-er { background-position: -36px -68px; } .jstree-default-dark .jstree-ellipsis { overflow: hidden; } .jstree-default-dark .jstree-ellipsis .jstree-anchor { width: calc(100% - 24px + 5px); text-overflow: ellipsis; overflow: hidden; } .jstree-default-dark.jstree-rtl .jstree-node { background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg=="); } .jstree-default-dark.jstree-rtl .jstree-last { background-image: none; } .jstree-default-dark-small .jstree-node { min-height: 18px; line-height: 18px; margin-left: 18px; min-width: 18px; } .jstree-default-dark-small .jstree-anchor { line-height: 18px; height: 18px; } .jstree-default-dark-small .jstree-icon { width: 18px; height: 18px; line-height: 18px; } .jstree-default-dark-small .jstree-icon:empty { width: 18px; height: 18px; line-height: 18px; } .jstree-default-dark-small.jstree-rtl .jstree-node { margin-right: 18px; } .jstree-default-dark-small .jstree-wholerow { height: 18px; } .jstree-default-dark-small .jstree-node, .jstree-default-dark-small .jstree-icon { background-image: url("32px.png"); } .jstree-default-dark-small .jstree-node { background-position: -295px -7px; background-repeat: repeat-y; } .jstree-default-dark-small .jstree-last { background-image: none; } .jstree-default-dark-small .jstree-open > .jstree-ocl { background-position: -135px -7px; } .jstree-default-dark-small .jstree-closed > .jstree-ocl { background-position: -103px -7px; } .jstree-default-dark-small .jstree-leaf > .jstree-ocl { background-position: -71px -7px; } .jstree-default-dark-small .jstree-themeicon { background-position: -263px -7px; } .jstree-default-dark-small > .jstree-no-dots .jstree-node, .jstree-default-dark-small > .jstree-no-dots .jstree-leaf > .jstree-ocl { background: transparent; } .jstree-default-dark-small > .jstree-no-dots .jstree-open > .jstree-ocl { background-position: -39px -7px; } .jstree-default-dark-small > .jstree-no-dots .jstree-closed > .jstree-ocl { background-position: -7px -7px; } .jstree-default-dark-small .jstree-disabled { background: transparent; } .jstree-default-dark-small .jstree-disabled.jstree-hovered { background: transparent; } .jstree-default-dark-small .jstree-disabled.jstree-clicked { background: #efefef; } .jstree-default-dark-small .jstree-checkbox { background-position: -167px -7px; } .jstree-default-dark-small .jstree-checkbox:hover { background-position: -167px -39px; } .jstree-default-dark-small.jstree-checkbox-selection .jstree-clicked > .jstree-checkbox, .jstree-default-dark-small .jstree-checked > .jstree-checkbox { background-position: -231px -7px; } .jstree-default-dark-small.jstree-checkbox-selection .jstree-clicked > .jstree-checkbox:hover, .jstree-default-dark-small .jstree-checked > .jstree-checkbox:hover { background-position: -231px -39px; } .jstree-default-dark-small .jstree-anchor > .jstree-undetermined { background-position: -199px -7px; } .jstree-default-dark-small .jstree-anchor > .jstree-undetermined:hover { background-position: -199px -39px; } .jstree-default-dark-small .jstree-checkbox-disabled { opacity: 0.8; filter: url("data:image/svg+xml;utf8,#jstree-grayscale"); /* Firefox 10+ */ filter: gray; /* IE6-9 */ -webkit-filter: grayscale(100%); /* Chrome 19+ & Safari 6+ */ } .jstree-default-dark-small > .jstree-striped { background-size: auto 36px; } .jstree-default-dark-small.jstree-rtl .jstree-node { background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg=="); background-position: 100% 1px; background-repeat: repeat-y; } .jstree-default-dark-small.jstree-rtl .jstree-last { background-image: none; } .jstree-default-dark-small.jstree-rtl .jstree-open > .jstree-ocl { background-position: -135px -39px; } .jstree-default-dark-small.jstree-rtl .jstree-closed > .jstree-ocl { background-position: -103px -39px; } .jstree-default-dark-small.jstree-rtl .jstree-leaf > .jstree-ocl { background-position: -71px -39px; } .jstree-default-dark-small.jstree-rtl > .jstree-no-dots .jstree-node, .jstree-default-dark-small.jstree-rtl > .jstree-no-dots .jstree-leaf > .jstree-ocl { background: transparent; } .jstree-default-dark-small.jstree-rtl > .jstree-no-dots .jstree-open > .jstree-ocl { background-position: -39px -39px; } .jstree-default-dark-small.jstree-rtl > .jstree-no-dots .jstree-closed > .jstree-ocl { background-position: -7px -39px; } .jstree-default-dark-small .jstree-themeicon-custom { background-color: transparent; background-image: none; background-position: 0 0; } .jstree-default-dark-small > .jstree-container-ul .jstree-loading > .jstree-ocl { background: url("throbber.gif") center center no-repeat; } .jstree-default-dark-small .jstree-file { background: url("32px.png") -103px -71px no-repeat; } .jstree-default-dark-small .jstree-folder { background: url("32px.png") -263px -7px no-repeat; } .jstree-default-dark-small > .jstree-container-ul > .jstree-node { margin-left: 0; margin-right: 0; } #jstree-dnd.jstree-default-dark-small { line-height: 18px; padding: 0 4px; } #jstree-dnd.jstree-default-dark-small .jstree-ok, #jstree-dnd.jstree-default-dark-small .jstree-er { background-image: url("32px.png"); background-repeat: no-repeat; background-color: transparent; } #jstree-dnd.jstree-default-dark-small i { background: transparent; width: 18px; height: 18px; line-height: 18px; } #jstree-dnd.jstree-default-dark-small .jstree-ok { background-position: -7px -71px; } #jstree-dnd.jstree-default-dark-small .jstree-er { background-position: -39px -71px; } .jstree-default-dark-small .jstree-ellipsis { overflow: hidden; } .jstree-default-dark-small .jstree-ellipsis .jstree-anchor { width: calc(100% - 18px + 5px); text-overflow: ellipsis; overflow: hidden; } .jstree-default-dark-small.jstree-rtl .jstree-node { background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAACAQMAAABv1h6PAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMHBgAAiABBI4gz9AAAAABJRU5ErkJggg=="); } .jstree-default-dark-small.jstree-rtl .jstree-last { background-image: none; } .jstree-default-dark-large .jstree-node { min-height: 32px; line-height: 32px; margin-left: 32px; min-width: 32px; } .jstree-default-dark-large .jstree-anchor { line-height: 32px; height: 32px; } .jstree-default-dark-large .jstree-icon { width: 32px; height: 32px; line-height: 32px; } .jstree-default-dark-large .jstree-icon:empty { width: 32px; height: 32px; line-height: 32px; } .jstree-default-dark-large.jstree-rtl .jstree-node { margin-right: 32px; } .jstree-default-dark-large .jstree-wholerow { height: 32px; } .jstree-default-dark-large .jstree-node, .jstree-default-dark-large .jstree-icon { background-image: url("32px.png"); } .jstree-default-dark-large .jstree-node { background-position: -288px 0px; background-repeat: repeat-y; } .jstree-default-dark-large .jstree-last { background-image: none; } .jstree-default-dark-large .jstree-open > .jstree-ocl { background-position: -128px 0px; } .jstree-default-dark-large .jstree-closed > .jstree-ocl { background-position: -96px 0px; } .jstree-default-dark-large .jstree-leaf > .jstree-ocl { background-position: -64px 0px; } .jstree-default-dark-large .jstree-themeicon { background-position: -256px 0px; } .jstree-default-dark-large > .jstree-no-dots .jstree-node, .jstree-default-dark-large > .jstree-no-dots .jstree-leaf > .jstree-ocl { background: transparent; } .jstree-default-dark-large > .jstree-no-dots .jstree-open > .jstree-ocl { background-position: -32px 0px; } .jstree-default-dark-large > .jstree-no-dots .jstree-closed > .jstree-ocl { background-position: 0px 0px; } .jstree-default-dark-large .jstree-disabled { background: transparent; } .jstree-default-dark-large .jstree-disabled.jstree-hovered { background: transparent; } .jstree-default-dark-large .jstree-disabled.jstree-clicked { background: #efefef; } .jstree-default-dark-large .jstree-checkbox { background-position: -160px 0px; } .jstree-default-dark-large .jstree-checkbox:hover { background-position: -160px -32px; } .jstree-default-dark-large.jstree-checkbox-selection .jstree-clicked > .jstree-checkbox, .jstree-default-dark-large .jstree-checked > .jstree-checkbox { background-position: -224px 0px; } .jstree-default-dark-large.jstree-checkbox-selection .jstree-clicked > .jstree-checkbox:hover, .jstree-default-dark-large .jstree-checked > .jstree-checkbox:hover { background-position: -224px -32px; } .jstree-default-dark-large .jstree-anchor > .jstree-undetermined { background-position: -192px 0px; } .jstree-default-dark-large .jstree-anchor > .jstree-undetermined:hover { background-position: -192px -32px; } .jstree-default-dark-large .jstree-checkbox-disabled { opacity: 0.8; filter: url("data:image/svg+xml;utf8,#jstree-grayscale"); /* Firefox 10+ */ filter: gray; /* IE6-9 */ -webkit-filter: grayscale(100%); /* Chrome 19+ & Safari 6+ */ } .jstree-default-dark-large > .jstree-striped { background-size: auto 64px; } .jstree-default-dark-large.jstree-rtl .jstree-node { background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg=="); background-position: 100% 1px; background-repeat: repeat-y; } .jstree-default-dark-large.jstree-rtl .jstree-last { background-image: none; } .jstree-default-dark-large.jstree-rtl .jstree-open > .jstree-ocl { background-position: -128px -32px; } .jstree-default-dark-large.jstree-rtl .jstree-closed > .jstree-ocl { background-position: -96px -32px; } .jstree-default-dark-large.jstree-rtl .jstree-leaf > .jstree-ocl { background-position: -64px -32px; } .jstree-default-dark-large.jstree-rtl > .jstree-no-dots .jstree-node, .jstree-default-dark-large.jstree-rtl > .jstree-no-dots .jstree-leaf > .jstree-ocl { background: transparent; } .jstree-default-dark-large.jstree-rtl > .jstree-no-dots .jstree-open > .jstree-ocl { background-position: -32px -32px; } .jstree-default-dark-large.jstree-rtl > .jstree-no-dots .jstree-closed > .jstree-ocl { background-position: 0px -32px; } .jstree-default-dark-large .jstree-themeicon-custom { background-color: transparent; background-image: none; background-position: 0 0; } .jstree-default-dark-large > .jstree-container-ul .jstree-loading > .jstree-ocl { background: url("throbber.gif") center center no-repeat; } .jstree-default-dark-large .jstree-file { background: url("32px.png") -96px -64px no-repeat; } .jstree-default-dark-large .jstree-folder { background: url("32px.png") -256px 0px no-repeat; } .jstree-default-dark-large > .jstree-container-ul > .jstree-node { margin-left: 0; margin-right: 0; } #jstree-dnd.jstree-default-dark-large { line-height: 32px; padding: 0 4px; } #jstree-dnd.jstree-default-dark-large .jstree-ok, #jstree-dnd.jstree-default-dark-large .jstree-er { background-image: url("32px.png"); background-repeat: no-repeat; background-color: transparent; } #jstree-dnd.jstree-default-dark-large i { background: transparent; width: 32px; height: 32px; line-height: 32px; } #jstree-dnd.jstree-default-dark-large .jstree-ok { background-position: 0px -64px; } #jstree-dnd.jstree-default-dark-large .jstree-er { background-position: -32px -64px; } .jstree-default-dark-large .jstree-ellipsis { overflow: hidden; } .jstree-default-dark-large .jstree-ellipsis .jstree-anchor { width: calc(100% - 32px + 5px); text-overflow: ellipsis; overflow: hidden; } .jstree-default-dark-large.jstree-rtl .jstree-node { background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAACAQMAAAAD0EyKAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjgIIGBgABCgCBvVLXcAAAAABJRU5ErkJggg=="); } .jstree-default-dark-large.jstree-rtl .jstree-last { background-image: none; } @media (max-width: 768px) { #jstree-dnd.jstree-dnd-responsive { line-height: 40px; font-weight: bold; font-size: 1.1em; text-shadow: 1px 1px white; } #jstree-dnd.jstree-dnd-responsive > i { background: transparent; width: 40px; height: 40px; } #jstree-dnd.jstree-dnd-responsive > .jstree-ok { background-image: url("40px.png"); background-position: 0 -200px; background-size: 120px 240px; } #jstree-dnd.jstree-dnd-responsive > .jstree-er { background-image: url("40px.png"); background-position: -40px -200px; background-size: 120px 240px; } #jstree-marker.jstree-dnd-responsive { border-left-width: 10px; border-top-width: 10px; border-bottom-width: 10px; margin-top: -10px; } } @media (max-width: 768px) { .jstree-default-dark-responsive { /* .jstree-open > .jstree-ocl, .jstree-closed > .jstree-ocl { border-radius:20px; background-color:white; } */ } .jstree-default-dark-responsive .jstree-icon { background-image: url("40px.png"); } .jstree-default-dark-responsive .jstree-node, .jstree-default-dark-responsive .jstree-leaf > .jstree-ocl { background: transparent; } .jstree-default-dark-responsive .jstree-node { min-height: 40px; line-height: 40px; margin-left: 40px; min-width: 40px; white-space: nowrap; } .jstree-default-dark-responsive .jstree-anchor { line-height: 40px; height: 40px; } .jstree-default-dark-responsive .jstree-icon, .jstree-default-dark-responsive .jstree-icon:empty { width: 40px; height: 40px; line-height: 40px; } .jstree-default-dark-responsive > .jstree-container-ul > .jstree-node { margin-left: 0; } .jstree-default-dark-responsive.jstree-rtl .jstree-node { margin-left: 0; margin-right: 40px; background: transparent; } .jstree-default-dark-responsive.jstree-rtl .jstree-container-ul > .jstree-node { margin-right: 0; } .jstree-default-dark-responsive .jstree-ocl, .jstree-default-dark-responsive .jstree-themeicon, .jstree-default-dark-responsive .jstree-checkbox { background-size: 120px 240px; } .jstree-default-dark-responsive .jstree-leaf > .jstree-ocl, .jstree-default-dark-responsive.jstree-rtl .jstree-leaf > .jstree-ocl { background: transparent; } .jstree-default-dark-responsive .jstree-open > .jstree-ocl { background-position: 0 0 !important; } .jstree-default-dark-responsive .jstree-closed > .jstree-ocl { background-position: 0 -40px !important; } .jstree-default-dark-responsive.jstree-rtl .jstree-closed > .jstree-ocl { background-position: -40px 0 !important; } .jstree-default-dark-responsive .jstree-themeicon { background-position: -40px -40px; } .jstree-default-dark-responsive .jstree-checkbox, .jstree-default-dark-responsive .jstree-checkbox:hover { background-position: -40px -80px; } .jstree-default-dark-responsive.jstree-checkbox-selection .jstree-clicked > .jstree-checkbox, .jstree-default-dark-responsive.jstree-checkbox-selection .jstree-clicked > .jstree-checkbox:hover, .jstree-default-dark-responsive .jstree-checked > .jstree-checkbox, .jstree-default-dark-responsive .jstree-checked > .jstree-checkbox:hover { background-position: 0 -80px; } .jstree-default-dark-responsive .jstree-anchor > .jstree-undetermined, .jstree-default-dark-responsive .jstree-anchor > .jstree-undetermined:hover { background-position: 0 -120px; } .jstree-default-dark-responsive .jstree-anchor { font-weight: bold; font-size: 1.1em; text-shadow: 1px 1px white; } .jstree-default-dark-responsive > .jstree-striped { background: transparent; } .jstree-default-dark-responsive .jstree-wholerow { border-top: 1px solid #666; border-bottom: 1px solid #000; background: #333333; height: 40px; } .jstree-default-dark-responsive .jstree-wholerow-hovered { background: #555; } .jstree-default-dark-responsive .jstree-wholerow-clicked { background: #5fa2db; } .jstree-default-dark-responsive .jstree-children .jstree-last > .jstree-wholerow { box-shadow: inset 0 -6px 3px -5px #111111; } .jstree-default-dark-responsive .jstree-children .jstree-open > .jstree-wholerow { box-shadow: inset 0 6px 3px -5px #111111; border-top: 0; } .jstree-default-dark-responsive .jstree-children .jstree-open + .jstree-open { box-shadow: none; } .jstree-default-dark-responsive .jstree-node, .jstree-default-dark-responsive .jstree-icon, .jstree-default-dark-responsive .jstree-node > .jstree-ocl, .jstree-default-dark-responsive .jstree-themeicon, .jstree-default-dark-responsive .jstree-checkbox { background-image: url("40px.png"); background-size: 120px 240px; } .jstree-default-dark-responsive .jstree-node { background-position: -80px 0; background-repeat: repeat-y; } .jstree-default-dark-responsive .jstree-last { background-image: none; } .jstree-default-dark-responsive .jstree-leaf > .jstree-ocl { background-position: -40px -120px; } .jstree-default-dark-responsive .jstree-last > .jstree-ocl { background-position: -40px -160px; } .jstree-default-dark-responsive .jstree-themeicon-custom { background-color: transparent; background-image: none; background-position: 0 0; } .jstree-default-dark-responsive .jstree-file { background: url("40px.png") 0 -160px no-repeat; background-size: 120px 240px; } .jstree-default-dark-responsive .jstree-folder { background: url("40px.png") -40px -40px no-repeat; background-size: 120px 240px; } .jstree-default-dark-responsive > .jstree-container-ul > .jstree-node { margin-left: 0; margin-right: 0; } } .jstree-default-dark { background: #333; } .jstree-default-dark .jstree-anchor { color: #999; text-shadow: 1px 1px 0 rgba(0, 0, 0, 0.5); } .jstree-default-dark .jstree-clicked, .jstree-default-dark .jstree-checked { color: white; } .jstree-default-dark .jstree-hovered { color: white; } #jstree-marker.jstree-default-dark { border-left-color: #999; background: transparent; } .jstree-default-dark .jstree-anchor > .jstree-icon { opacity: 0.75; } .jstree-default-dark .jstree-clicked > .jstree-icon, .jstree-default-dark .jstree-hovered > .jstree-icon, .jstree-default-dark .jstree-checked > .jstree-icon { opacity: 1; } .jstree-default-dark.jstree-rtl .jstree-node { background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAACZmZl+9SADAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg=="); } .jstree-default-dark.jstree-rtl .jstree-last { background-image: none; } .jstree-default-dark-small.jstree-rtl .jstree-node { background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAACAQMAAABv1h6PAAAABlBMVEUAAACZmZl+9SADAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMHBgAAiABBI4gz9AAAAABJRU5ErkJggg=="); } .jstree-default-dark-small.jstree-rtl .jstree-last { background-image: none; } .jstree-default-dark-large.jstree-rtl .jstree-node { background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAACAQMAAAAD0EyKAAAABlBMVEUAAACZmZl+9SADAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjgIIGBgABCgCBvVLXcAAAAABJRU5ErkJggg=="); } .jstree-default-dark-large.jstree-rtl .jstree-last { background-image: none; } includes/jstree/themes/default-dark/40px.png000064400000014576152214270100015006 0ustar00PNG  IHDR*PLTE333ssstttuuuvvvwwwxxxyyyzzz{{{|||}}}~~~ XXX$$$dddhhhooo000UUUVVVWWWXXXYYYZZZ[[[\\\]]]^^^TTTNNNOOOPPPQQQRRRSSSTTTUUUVVV[[[KKKLLLUtRNS %&(01369:=>>CEGGGGIKTTTTTTTTTTUX\\\\\\\\\\ahhy? IDATxkՙs5#ØEdB[98OLgq͐XXl \l Zl:d9|6Ͱ;J3@]V:sms,2}E6cx`sD#P#lű;Tz|6WB׽. YPQ^7pM5xy]m\gVn.T}M]{mjYxǬ=՛)pڹ5iwݼcuîb8zZh̥=}xP+ mXYJucu!HA)ZB skJ İ.A ]SrTYH)U1:`駚F&owde3 "p[~S !,1~Vm<UBp%Tj"3,zt/w^BN;B|j٣0=띻![Z{{{0 oKHn!֏6 dpi sB-g? ~y, :kkkkkkd*冎R+mjBhǑ߆e4#Xx5ȬTsexjqu~"$d+&63^ -N > bkƫAs՞DGY9/֤3^ $^|ne_~ؙjmpJ2^ [P(Gx5X}woUH}sD kQz A(iqHG٤Ұ4"a ! KͰ4V=Fñ(=񈡸L+~~S؉]Z/[:WقP`@&%2E<5іD"lJe &O?s%޼ :\]g^iؚg/>FMzqњ wS8CMzqeޒ P) 6`,2#f\UBpHޜ1Ǿs d}_M 0?VL'oxĥ>薂;#l"8ʢ 2*Gx3>8oK[۾ؗ{KaExqg^,9eF"y|%SaaGVTOdԎ'}W <>#a]sga ɫηy&C x}-*T0bjY4Dxa` okkkkkkeث&:8/p#5Ve&֨-J.[amѺ4{Udi[yR*0r7v$S}r.#X#cBڛ5/M@6(9~'6zOp^O m:hw]RYoHV@X}|>GܵR .z=9יmL=Dj ŧoyYK;f<_yrn6@xi)uƵ'wK9_35n1M{\:[O<1f}ia6ܘf>^?u\d{D\y7ӾL]14y\0.TPV9D&7^\kyw+T#ӓ*`uU%h];L<|'pT7ZMFh]yskS'&-Sؕ7H_D^N`%X-I^"Fʛ?J_rNFKcʛĻE>  .h $`+[$ 1Ø]oycy=)bT\dD s*5kվOP rTi@̘N :FHp>1\&<t5X5X5X5XGlkkkkkkkk\+mG Uh WA#* pt_P@Q8RG*Uh W_L-‹~pS+W 2_Ucئ{2ncơOkkGܔaj؃r[DMPLMYZX*T,Rpzڍt%U6p_݈P䶢 \mE?>\ŪWc2U RRI _1:nT׈_m?83e0MƃZ+(Vd"jWƬ>dp5Z9=#CJ/}XW /_w;A \%ʿM0֑,HJa"*p_r'JG)U0 WA#*0pT_F$_ #}/t` ` ` I{-)]1zsݞ}fl[=dicwM8MIQ' Lb[<Ȱ4 & ƵڪZ^9jI_r{M h=ڟ&hDS?j3'>?ͯx/>_O8 (0ljϥ%VیK I-#[AӪ4LZ|#j7؈YR^`oD ,DQ  {UNop%!z 1l=%^8F'9L_{,je %v"~'=#,D gZ&+?xO<5Fi3^`sFKji R9m \<ѷb1L֧kp :#_t5X5X58\h ῡ6٘"<ϻ?:a]Fo舆yޅZ8<J6x.El.`(Y :P`wt.9Qϥ|g++:isz>+As_%p \x[Zhsͫy>y[s-\-^bexm6VVU\#_pR[e3t),'bv"Sjw{()\ XvڹΩGRt6%wVx`/rVYX`Ł{fwv7w8c98uoGm}x{+}8owpt!v@]ݚx4^`]xU/y; ~QɉGVx_'}#Z~NO_JA@t}  "gPa~1іoVO_#"z jmEe^'BuBK<*vENSN@"ƌ5.e+e8M:yEzF<#(U@` `;g/;_|?p \:xY QfD @OF`{Ug/n љA I+l:IYj?:Ad7;Z [h1 C^8Zh KII< FQ+}{{ 38?2=,}ck118f:h{^~ײc(%6\;eZys٨=n;7}pYcB/[4Yo'b ~bɩ{d&p$$zޤU8%'֔Z+ߪ4jamvFZ-ĄbAO<*˝:#S;X1}/RHU+,uھ>#k) gWw$W 2 s:u'1Hj."3OC+EE̠Dr}{rJ(z- 2w,})GO9U4;fxQQsaZ*wع4[ϬCJ=j0`ՓB(aLv9g.+EH>}sreLvYa-)v;#>wj;W[ mC0s^Irs.g+}0x_^~ƟxUeuʼnrqd~q\jߗ~)bb_5ߏ{/g<b۳ؘ0pZ/opep"dxAY/"MZqñ;Jkp :۶?9#2=-wNIENDB`includes/jstree/themes/default-dark/32px.png000064400000002765152214270100015004 0ustar00PNG  IHDR@`[[PLTEհ???Ƌ hhh虙ȏxxxt{FtRNS1 =%+Oa;y۵D̐9Fi"IDATx S0IҴ,"(nBZJ[o{ &}@fz?zOk,֛M D v l`Sp:@98դ- t9wMuwONky Ceš ,'\:z(`M¤\0Z3&E/ }M?|EZy~6?+?R )?/!& $‡TW0Z~~ 4 VϐUJY?V<bSx~F$.mKI ]~M'yzxq5Oa(?")#U5=]'I$۽X(0ZAFf 7 s@5dM.tr{meHru0d 0kR'~ԱOu.% @؛=|_z4?h=1ʯW)4?hGT`(WUG_j-5O)8 :ho{>|08Z{VJ @Yy7|;{V87q>׈!/7q>1f=㴷H7""t l R l 1-?8N7zƁ\{e䌣ߎףd6>DAzd|< BL^ǁ_ K!#l,y&)6PgD'G5e"@cXS~s;V]/ǭ VY~:9$?A~@i"w4?bSY3`IEQal(6QďK8` ;챠g0/P'FO"k,K)g4_)FOl *n ~/ӷ@5@4A +l8acPf " -Ql&ѭ\k5 .jstree-ocl{cursor:default}.jstree .jstree-open>.jstree-children{display:block}.jstree .jstree-closed>.jstree-children,.jstree .jstree-leaf>.jstree-children{display:none}.jstree-anchor>.jstree-themeicon{margin-right:2px}.jstree-no-icons .jstree-themeicon,.jstree-anchor>.jstree-themeicon-hidden{display:none}.jstree-hidden,.jstree-node.jstree-hidden{display:none}.jstree-rtl .jstree-anchor{padding:0 1px 0 4px}.jstree-rtl .jstree-anchor>.jstree-themeicon{margin-left:2px;margin-right:0}.jstree-rtl .jstree-node{margin-left:0}.jstree-rtl .jstree-container-ul>.jstree-node{margin-right:0}.jstree-wholerow-ul{position:relative;display:inline-block;min-width:100%}.jstree-wholerow-ul .jstree-leaf>.jstree-ocl{cursor:pointer}.jstree-wholerow-ul .jstree-anchor,.jstree-wholerow-ul .jstree-icon{position:relative}.jstree-wholerow-ul .jstree-wholerow{width:100%;cursor:pointer;position:absolute;left:0;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.jstree-contextmenu .jstree-anchor{-webkit-user-select:none;-webkit-touch-callout:none;user-select:none}.vakata-context{display:none}.vakata-context,.vakata-context ul{margin:0;padding:2px;position:absolute;background:#f5f5f5;border:1px solid #979797;box-shadow:2px 2px 2px #999999}.vakata-context ul{list-style:none;left:100%;margin-top:-2.7em;margin-left:-4px}.vakata-context .vakata-context-right ul{left:auto;right:100%;margin-left:auto;margin-right:-4px}.vakata-context li{list-style:none}.vakata-context li>a{display:block;padding:0 2em 0 2em;text-decoration:none;width:auto;color:black;white-space:nowrap;line-height:2.4em;text-shadow:1px 1px 0 white;border-radius:1px}.vakata-context li>a:hover{position:relative;background-color:#e8eff7;box-shadow:0 0 2px #0a6aa1}.vakata-context li>a.vakata-context-parent{background-image:url("data:image/gif;base64,R0lGODlhCwAHAIAAACgoKP///yH5BAEAAAEALAAAAAALAAcAAAIORI4JlrqN1oMSnmmZDQUAOw==");background-position:right center;background-repeat:no-repeat}.vakata-context li>a:focus{outline:0}.vakata-context .vakata-context-no-icons{margin-left:0}.vakata-context .vakata-context-hover>a{position:relative;background-color:#e8eff7;box-shadow:0 0 2px #0a6aa1}.vakata-context .vakata-context-separator>a,.vakata-context .vakata-context-separator>a:hover{background:white;border:0;border-top:1px solid #e2e3e3;height:1px;min-height:1px;max-height:1px;padding:0;margin:0 0 0 2.4em;border-left:1px solid #e0e0e0;text-shadow:0 0 0 transparent;box-shadow:0 0 0 transparent;border-radius:0}.vakata-context .vakata-contextmenu-disabled a,.vakata-context .vakata-contextmenu-disabled a:hover{color:silver;background-color:transparent;border:0;box-shadow:0 0 0}.vakata-context .vakata-contextmenu-disabled>a>i{filter:grayscale(100%)}.vakata-context li>a>i{text-decoration:none;display:inline-block;width:2.4em;height:2.4em;background:transparent;margin:0 0 0 -2em;vertical-align:top;text-align:center;line-height:2.4em}.vakata-context li>a>i:empty{width:2.4em;line-height:2.4em}.vakata-context li>a .vakata-contextmenu-sep{display:inline-block;width:1px;height:2.4em;background:white;margin:0 .5em 0 0;border-left:1px solid #e2e3e3}.vakata-context .vakata-contextmenu-shortcut{font-size:.8em;color:silver;opacity:.5;display:none}.vakata-context-rtl ul{left:auto;right:100%;margin-left:auto;margin-right:-4px}.vakata-context-rtl li>a.vakata-context-parent{background-image:url("data:image/gif;base64,R0lGODlhCwAHAIAAACgoKP///yH5BAEAAAEALAAAAAALAAcAAAINjI+AC7rWHIsPtmoxLAA7");background-position:left center;background-repeat:no-repeat}.vakata-context-rtl .vakata-context-separator>a{margin:0 2.4em 0 0;border-left:0;border-right:1px solid #e2e3e3}.vakata-context-rtl .vakata-context-left ul{right:auto;left:100%;margin-left:-4px;margin-right:auto}.vakata-context-rtl li>a>i{margin:0 -2em 0 0}.vakata-context-rtl li>a .vakata-contextmenu-sep{margin:0 0 0 .5em;border-left-color:white;background:#e2e3e3}#jstree-marker{position:absolute;top:0;left:0;margin:-5px 0 0 0;padding:0;border-right:0;border-top:5px solid transparent;border-bottom:5px solid transparent;border-left:5px solid;width:0;height:0;font-size:0;line-height:0}#jstree-dnd{line-height:16px;margin:0;padding:4px}#jstree-dnd .jstree-icon,#jstree-dnd .jstree-copy{display:inline-block;text-decoration:none;margin:0 2px 0 0;padding:0;width:16px;height:16px}#jstree-dnd .jstree-ok{background:green}#jstree-dnd .jstree-er{background:red}#jstree-dnd .jstree-copy{margin:0 2px 0 2px}.jstree-default-dark .jstree-node,.jstree-default-dark .jstree-icon{background-repeat:no-repeat;background-color:transparent}.jstree-default-dark .jstree-anchor,.jstree-default-dark .jstree-animated,.jstree-default-dark .jstree-wholerow{transition:background-color .15s,box-shadow .15s}.jstree-default-dark .jstree-hovered{background:#555;border-radius:2px;box-shadow:inset 0 0 1px #555}.jstree-default-dark .jstree-context{background:#555;border-radius:2px;box-shadow:inset 0 0 1px #555}.jstree-default-dark .jstree-clicked{background:#5fa2db;border-radius:2px;box-shadow:inset 0 0 1px #666666}.jstree-default-dark .jstree-no-icons .jstree-anchor>.jstree-themeicon{display:none}.jstree-default-dark .jstree-disabled{background:transparent;color:#666666}.jstree-default-dark .jstree-disabled.jstree-hovered{background:transparent;box-shadow:none}.jstree-default-dark .jstree-disabled.jstree-clicked{background:#333333}.jstree-default-dark .jstree-disabled>.jstree-icon{opacity:.8;filter:url("data:image/svg+xml;utf8,#jstree-grayscale");filter:gray;-webkit-filter:grayscale(100%)}.jstree-default-dark .jstree-search{font-style:italic;color:#ffffff;font-weight:bold}.jstree-default-dark .jstree-no-checkboxes .jstree-checkbox{display:none !important}.jstree-default-dark.jstree-checkbox-no-clicked .jstree-clicked{background:transparent;box-shadow:none}.jstree-default-dark.jstree-checkbox-no-clicked .jstree-clicked.jstree-hovered{background:#555}.jstree-default-dark.jstree-checkbox-no-clicked>.jstree-wholerow-ul .jstree-wholerow-clicked{background:transparent}.jstree-default-dark.jstree-checkbox-no-clicked>.jstree-wholerow-ul .jstree-wholerow-clicked.jstree-wholerow-hovered{background:#555}.jstree-default-dark>.jstree-striped{min-width:100%;display:inline-block;background:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAkCAMAAAB/qqA+AAAABlBMVEUAAAAAAAClZ7nPAAAAAnRSTlMNAMM9s3UAAAAXSURBVHjajcEBAQAAAIKg/H/aCQZ70AUBjAATb6YPDgAAAABJRU5ErkJggg==") left top repeat}.jstree-default-dark>.jstree-wholerow-ul .jstree-hovered,.jstree-default-dark>.jstree-wholerow-ul .jstree-clicked{background:transparent;box-shadow:none;border-radius:0}.jstree-default-dark .jstree-wholerow{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}.jstree-default-dark .jstree-wholerow-hovered{background:#555}.jstree-default-dark .jstree-wholerow-clicked{background:#5fa2db;background:-webkit-linear-gradient(top, #5fa2db 0%, #5fa2db 100%);background:linear-gradient(to bottom, #5fa2db 0%, #5fa2db 100%)}.jstree-default-dark .jstree-node{min-height:24px;line-height:24px;margin-left:24px;min-width:24px}.jstree-default-dark .jstree-anchor{line-height:24px;height:24px}.jstree-default-dark .jstree-icon{width:24px;height:24px;line-height:24px}.jstree-default-dark .jstree-icon:empty{width:24px;height:24px;line-height:24px}.jstree-default-dark.jstree-rtl .jstree-node{margin-right:24px}.jstree-default-dark .jstree-wholerow{height:24px}.jstree-default-dark .jstree-node,.jstree-default-dark .jstree-icon{background-image:url("32px.png")}.jstree-default-dark .jstree-node{background-position:-292px -4px;background-repeat:repeat-y}.jstree-default-dark .jstree-last{background-image:none}.jstree-default-dark .jstree-open>.jstree-ocl{background-position:-132px -4px}.jstree-default-dark .jstree-closed>.jstree-ocl{background-position:-100px -4px}.jstree-default-dark .jstree-leaf>.jstree-ocl{background-position:-68px -4px}.jstree-default-dark .jstree-themeicon{background-position:-260px -4px}.jstree-default-dark>.jstree-no-dots .jstree-node,.jstree-default-dark>.jstree-no-dots .jstree-leaf>.jstree-ocl{background:transparent}.jstree-default-dark>.jstree-no-dots .jstree-open>.jstree-ocl{background-position:-36px -4px}.jstree-default-dark>.jstree-no-dots .jstree-closed>.jstree-ocl{background-position:-4px -4px}.jstree-default-dark .jstree-disabled{background:transparent}.jstree-default-dark .jstree-disabled.jstree-hovered{background:transparent}.jstree-default-dark .jstree-disabled.jstree-clicked{background:#efefef}.jstree-default-dark .jstree-checkbox{background-position:-164px -4px}.jstree-default-dark .jstree-checkbox:hover{background-position:-164px -36px}.jstree-default-dark.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox,.jstree-default-dark .jstree-checked>.jstree-checkbox{background-position:-228px -4px}.jstree-default-dark.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox:hover,.jstree-default-dark .jstree-checked>.jstree-checkbox:hover{background-position:-228px -36px}.jstree-default-dark .jstree-anchor>.jstree-undetermined{background-position:-196px -4px}.jstree-default-dark .jstree-anchor>.jstree-undetermined:hover{background-position:-196px -36px}.jstree-default-dark .jstree-checkbox-disabled{opacity:.8;filter:url("data:image/svg+xml;utf8,#jstree-grayscale");filter:gray;-webkit-filter:grayscale(100%)}.jstree-default-dark>.jstree-striped{background-size:auto 48px}.jstree-default-dark.jstree-rtl .jstree-node{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg==");background-position:100% 1px;background-repeat:repeat-y}.jstree-default-dark.jstree-rtl .jstree-last{background-image:none}.jstree-default-dark.jstree-rtl .jstree-open>.jstree-ocl{background-position:-132px -36px}.jstree-default-dark.jstree-rtl .jstree-closed>.jstree-ocl{background-position:-100px -36px}.jstree-default-dark.jstree-rtl .jstree-leaf>.jstree-ocl{background-position:-68px -36px}.jstree-default-dark.jstree-rtl>.jstree-no-dots .jstree-node,.jstree-default-dark.jstree-rtl>.jstree-no-dots .jstree-leaf>.jstree-ocl{background:transparent}.jstree-default-dark.jstree-rtl>.jstree-no-dots .jstree-open>.jstree-ocl{background-position:-36px -36px}.jstree-default-dark.jstree-rtl>.jstree-no-dots .jstree-closed>.jstree-ocl{background-position:-4px -36px}.jstree-default-dark .jstree-themeicon-custom{background-color:transparent;background-image:none;background-position:0 0}.jstree-default-dark>.jstree-container-ul .jstree-loading>.jstree-ocl{background:url("throbber.gif") center center no-repeat}.jstree-default-dark .jstree-file{background:url("32px.png") -100px -68px no-repeat}.jstree-default-dark .jstree-folder{background:url("32px.png") -260px -4px no-repeat}.jstree-default-dark>.jstree-container-ul>.jstree-node{margin-left:0;margin-right:0}#jstree-dnd.jstree-default-dark{line-height:24px;padding:0 4px}#jstree-dnd.jstree-default-dark .jstree-ok,#jstree-dnd.jstree-default-dark .jstree-er{background-image:url("32px.png");background-repeat:no-repeat;background-color:transparent}#jstree-dnd.jstree-default-dark i{background:transparent;width:24px;height:24px;line-height:24px}#jstree-dnd.jstree-default-dark .jstree-ok{background-position:-4px -68px}#jstree-dnd.jstree-default-dark .jstree-er{background-position:-36px -68px}.jstree-default-dark .jstree-ellipsis{overflow:hidden}.jstree-default-dark .jstree-ellipsis .jstree-anchor{width:calc(100% - 24px + 5px);text-overflow:ellipsis;overflow:hidden}.jstree-default-dark.jstree-rtl .jstree-node{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg==")}.jstree-default-dark.jstree-rtl .jstree-last{background-image:none}.jstree-default-dark-small .jstree-node{min-height:18px;line-height:18px;margin-left:18px;min-width:18px}.jstree-default-dark-small .jstree-anchor{line-height:18px;height:18px}.jstree-default-dark-small .jstree-icon{width:18px;height:18px;line-height:18px}.jstree-default-dark-small .jstree-icon:empty{width:18px;height:18px;line-height:18px}.jstree-default-dark-small.jstree-rtl .jstree-node{margin-right:18px}.jstree-default-dark-small .jstree-wholerow{height:18px}.jstree-default-dark-small .jstree-node,.jstree-default-dark-small .jstree-icon{background-image:url("32px.png")}.jstree-default-dark-small .jstree-node{background-position:-295px -7px;background-repeat:repeat-y}.jstree-default-dark-small .jstree-last{background-image:none}.jstree-default-dark-small .jstree-open>.jstree-ocl{background-position:-135px -7px}.jstree-default-dark-small .jstree-closed>.jstree-ocl{background-position:-103px -7px}.jstree-default-dark-small .jstree-leaf>.jstree-ocl{background-position:-71px -7px}.jstree-default-dark-small .jstree-themeicon{background-position:-263px -7px}.jstree-default-dark-small>.jstree-no-dots .jstree-node,.jstree-default-dark-small>.jstree-no-dots .jstree-leaf>.jstree-ocl{background:transparent}.jstree-default-dark-small>.jstree-no-dots .jstree-open>.jstree-ocl{background-position:-39px -7px}.jstree-default-dark-small>.jstree-no-dots .jstree-closed>.jstree-ocl{background-position:-7px -7px}.jstree-default-dark-small .jstree-disabled{background:transparent}.jstree-default-dark-small .jstree-disabled.jstree-hovered{background:transparent}.jstree-default-dark-small .jstree-disabled.jstree-clicked{background:#efefef}.jstree-default-dark-small .jstree-checkbox{background-position:-167px -7px}.jstree-default-dark-small .jstree-checkbox:hover{background-position:-167px -39px}.jstree-default-dark-small.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox,.jstree-default-dark-small .jstree-checked>.jstree-checkbox{background-position:-231px -7px}.jstree-default-dark-small.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox:hover,.jstree-default-dark-small .jstree-checked>.jstree-checkbox:hover{background-position:-231px -39px}.jstree-default-dark-small .jstree-anchor>.jstree-undetermined{background-position:-199px -7px}.jstree-default-dark-small .jstree-anchor>.jstree-undetermined:hover{background-position:-199px -39px}.jstree-default-dark-small .jstree-checkbox-disabled{opacity:.8;filter:url("data:image/svg+xml;utf8,#jstree-grayscale");filter:gray;-webkit-filter:grayscale(100%)}.jstree-default-dark-small>.jstree-striped{background-size:auto 36px}.jstree-default-dark-small.jstree-rtl .jstree-node{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg==");background-position:100% 1px;background-repeat:repeat-y}.jstree-default-dark-small.jstree-rtl .jstree-last{background-image:none}.jstree-default-dark-small.jstree-rtl .jstree-open>.jstree-ocl{background-position:-135px -39px}.jstree-default-dark-small.jstree-rtl .jstree-closed>.jstree-ocl{background-position:-103px -39px}.jstree-default-dark-small.jstree-rtl .jstree-leaf>.jstree-ocl{background-position:-71px -39px}.jstree-default-dark-small.jstree-rtl>.jstree-no-dots .jstree-node,.jstree-default-dark-small.jstree-rtl>.jstree-no-dots .jstree-leaf>.jstree-ocl{background:transparent}.jstree-default-dark-small.jstree-rtl>.jstree-no-dots .jstree-open>.jstree-ocl{background-position:-39px -39px}.jstree-default-dark-small.jstree-rtl>.jstree-no-dots .jstree-closed>.jstree-ocl{background-position:-7px -39px}.jstree-default-dark-small .jstree-themeicon-custom{background-color:transparent;background-image:none;background-position:0 0}.jstree-default-dark-small>.jstree-container-ul .jstree-loading>.jstree-ocl{background:url("throbber.gif") center center no-repeat}.jstree-default-dark-small .jstree-file{background:url("32px.png") -103px -71px no-repeat}.jstree-default-dark-small .jstree-folder{background:url("32px.png") -263px -7px no-repeat}.jstree-default-dark-small>.jstree-container-ul>.jstree-node{margin-left:0;margin-right:0}#jstree-dnd.jstree-default-dark-small{line-height:18px;padding:0 4px}#jstree-dnd.jstree-default-dark-small .jstree-ok,#jstree-dnd.jstree-default-dark-small .jstree-er{background-image:url("32px.png");background-repeat:no-repeat;background-color:transparent}#jstree-dnd.jstree-default-dark-small i{background:transparent;width:18px;height:18px;line-height:18px}#jstree-dnd.jstree-default-dark-small .jstree-ok{background-position:-7px -71px}#jstree-dnd.jstree-default-dark-small .jstree-er{background-position:-39px -71px}.jstree-default-dark-small .jstree-ellipsis{overflow:hidden}.jstree-default-dark-small .jstree-ellipsis .jstree-anchor{width:calc(100% - 18px + 5px);text-overflow:ellipsis;overflow:hidden}.jstree-default-dark-small.jstree-rtl .jstree-node{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAACAQMAAABv1h6PAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMHBgAAiABBI4gz9AAAAABJRU5ErkJggg==")}.jstree-default-dark-small.jstree-rtl .jstree-last{background-image:none}.jstree-default-dark-large .jstree-node{min-height:32px;line-height:32px;margin-left:32px;min-width:32px}.jstree-default-dark-large .jstree-anchor{line-height:32px;height:32px}.jstree-default-dark-large .jstree-icon{width:32px;height:32px;line-height:32px}.jstree-default-dark-large .jstree-icon:empty{width:32px;height:32px;line-height:32px}.jstree-default-dark-large.jstree-rtl .jstree-node{margin-right:32px}.jstree-default-dark-large .jstree-wholerow{height:32px}.jstree-default-dark-large .jstree-node,.jstree-default-dark-large .jstree-icon{background-image:url("32px.png")}.jstree-default-dark-large .jstree-node{background-position:-288px 0;background-repeat:repeat-y}.jstree-default-dark-large .jstree-last{background-image:none}.jstree-default-dark-large .jstree-open>.jstree-ocl{background-position:-128px 0}.jstree-default-dark-large .jstree-closed>.jstree-ocl{background-position:-96px 0}.jstree-default-dark-large .jstree-leaf>.jstree-ocl{background-position:-64px 0}.jstree-default-dark-large .jstree-themeicon{background-position:-256px 0}.jstree-default-dark-large>.jstree-no-dots .jstree-node,.jstree-default-dark-large>.jstree-no-dots .jstree-leaf>.jstree-ocl{background:transparent}.jstree-default-dark-large>.jstree-no-dots .jstree-open>.jstree-ocl{background-position:-32px 0}.jstree-default-dark-large>.jstree-no-dots .jstree-closed>.jstree-ocl{background-position:0 0}.jstree-default-dark-large .jstree-disabled{background:transparent}.jstree-default-dark-large .jstree-disabled.jstree-hovered{background:transparent}.jstree-default-dark-large .jstree-disabled.jstree-clicked{background:#efefef}.jstree-default-dark-large .jstree-checkbox{background-position:-160px 0}.jstree-default-dark-large .jstree-checkbox:hover{background-position:-160px -32px}.jstree-default-dark-large.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox,.jstree-default-dark-large .jstree-checked>.jstree-checkbox{background-position:-224px 0}.jstree-default-dark-large.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox:hover,.jstree-default-dark-large .jstree-checked>.jstree-checkbox:hover{background-position:-224px -32px}.jstree-default-dark-large .jstree-anchor>.jstree-undetermined{background-position:-192px 0}.jstree-default-dark-large .jstree-anchor>.jstree-undetermined:hover{background-position:-192px -32px}.jstree-default-dark-large .jstree-checkbox-disabled{opacity:.8;filter:url("data:image/svg+xml;utf8,#jstree-grayscale");filter:gray;-webkit-filter:grayscale(100%)}.jstree-default-dark-large>.jstree-striped{background-size:auto 64px}.jstree-default-dark-large.jstree-rtl .jstree-node{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg==");background-position:100% 1px;background-repeat:repeat-y}.jstree-default-dark-large.jstree-rtl .jstree-last{background-image:none}.jstree-default-dark-large.jstree-rtl .jstree-open>.jstree-ocl{background-position:-128px -32px}.jstree-default-dark-large.jstree-rtl .jstree-closed>.jstree-ocl{background-position:-96px -32px}.jstree-default-dark-large.jstree-rtl .jstree-leaf>.jstree-ocl{background-position:-64px -32px}.jstree-default-dark-large.jstree-rtl>.jstree-no-dots .jstree-node,.jstree-default-dark-large.jstree-rtl>.jstree-no-dots .jstree-leaf>.jstree-ocl{background:transparent}.jstree-default-dark-large.jstree-rtl>.jstree-no-dots .jstree-open>.jstree-ocl{background-position:-32px -32px}.jstree-default-dark-large.jstree-rtl>.jstree-no-dots .jstree-closed>.jstree-ocl{background-position:0 -32px}.jstree-default-dark-large .jstree-themeicon-custom{background-color:transparent;background-image:none;background-position:0 0}.jstree-default-dark-large>.jstree-container-ul .jstree-loading>.jstree-ocl{background:url("throbber.gif") center center no-repeat}.jstree-default-dark-large .jstree-file{background:url("32px.png") -96px -64px no-repeat}.jstree-default-dark-large .jstree-folder{background:url("32px.png") -256px 0 no-repeat}.jstree-default-dark-large>.jstree-container-ul>.jstree-node{margin-left:0;margin-right:0}#jstree-dnd.jstree-default-dark-large{line-height:32px;padding:0 4px}#jstree-dnd.jstree-default-dark-large .jstree-ok,#jstree-dnd.jstree-default-dark-large .jstree-er{background-image:url("32px.png");background-repeat:no-repeat;background-color:transparent}#jstree-dnd.jstree-default-dark-large i{background:transparent;width:32px;height:32px;line-height:32px}#jstree-dnd.jstree-default-dark-large .jstree-ok{background-position:0 -64px}#jstree-dnd.jstree-default-dark-large .jstree-er{background-position:-32px -64px}.jstree-default-dark-large .jstree-ellipsis{overflow:hidden}.jstree-default-dark-large .jstree-ellipsis .jstree-anchor{width:calc(100% - 32px + 5px);text-overflow:ellipsis;overflow:hidden}.jstree-default-dark-large.jstree-rtl .jstree-node{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAACAQMAAAAD0EyKAAAABlBMVEUAAAAdHRvEkCwcAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjgIIGBgABCgCBvVLXcAAAAABJRU5ErkJggg==")}.jstree-default-dark-large.jstree-rtl .jstree-last{background-image:none}@media (max-width:768px){#jstree-dnd.jstree-dnd-responsive{line-height:40px;font-weight:bold;font-size:1.1em;text-shadow:1px 1px white}#jstree-dnd.jstree-dnd-responsive>i{background:transparent;width:40px;height:40px}#jstree-dnd.jstree-dnd-responsive>.jstree-ok{background-image:url("40px.png");background-position:0 -200px;background-size:120px 240px}#jstree-dnd.jstree-dnd-responsive>.jstree-er{background-image:url("40px.png");background-position:-40px -200px;background-size:120px 240px}#jstree-marker.jstree-dnd-responsive{border-left-width:10px;border-top-width:10px;border-bottom-width:10px;margin-top:-10px}}@media (max-width:768px){.jstree-default-dark-responsive .jstree-icon{background-image:url("40px.png")}.jstree-default-dark-responsive .jstree-node,.jstree-default-dark-responsive .jstree-leaf>.jstree-ocl{background:transparent}.jstree-default-dark-responsive .jstree-node{min-height:40px;line-height:40px;margin-left:40px;min-width:40px;white-space:nowrap}.jstree-default-dark-responsive .jstree-anchor{line-height:40px;height:40px}.jstree-default-dark-responsive .jstree-icon,.jstree-default-dark-responsive .jstree-icon:empty{width:40px;height:40px;line-height:40px}.jstree-default-dark-responsive>.jstree-container-ul>.jstree-node{margin-left:0}.jstree-default-dark-responsive.jstree-rtl .jstree-node{margin-left:0;margin-right:40px;background:transparent}.jstree-default-dark-responsive.jstree-rtl .jstree-container-ul>.jstree-node{margin-right:0}.jstree-default-dark-responsive .jstree-ocl,.jstree-default-dark-responsive .jstree-themeicon,.jstree-default-dark-responsive .jstree-checkbox{background-size:120px 240px}.jstree-default-dark-responsive .jstree-leaf>.jstree-ocl,.jstree-default-dark-responsive.jstree-rtl .jstree-leaf>.jstree-ocl{background:transparent}.jstree-default-dark-responsive .jstree-open>.jstree-ocl{background-position:0 0 !important}.jstree-default-dark-responsive .jstree-closed>.jstree-ocl{background-position:0 -40px !important}.jstree-default-dark-responsive.jstree-rtl .jstree-closed>.jstree-ocl{background-position:-40px 0 !important}.jstree-default-dark-responsive .jstree-themeicon{background-position:-40px -40px}.jstree-default-dark-responsive .jstree-checkbox,.jstree-default-dark-responsive .jstree-checkbox:hover{background-position:-40px -80px}.jstree-default-dark-responsive.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox,.jstree-default-dark-responsive.jstree-checkbox-selection .jstree-clicked>.jstree-checkbox:hover,.jstree-default-dark-responsive .jstree-checked>.jstree-checkbox,.jstree-default-dark-responsive .jstree-checked>.jstree-checkbox:hover{background-position:0 -80px}.jstree-default-dark-responsive .jstree-anchor>.jstree-undetermined,.jstree-default-dark-responsive .jstree-anchor>.jstree-undetermined:hover{background-position:0 -120px}.jstree-default-dark-responsive .jstree-anchor{font-weight:bold;font-size:1.1em;text-shadow:1px 1px white}.jstree-default-dark-responsive>.jstree-striped{background:transparent}.jstree-default-dark-responsive .jstree-wholerow{border-top:1px solid #666;border-bottom:1px solid #000;background:#333333;height:40px}.jstree-default-dark-responsive .jstree-wholerow-hovered{background:#555}.jstree-default-dark-responsive .jstree-wholerow-clicked{background:#5fa2db}.jstree-default-dark-responsive .jstree-children .jstree-last>.jstree-wholerow{box-shadow:inset 0 -6px 3px -5px #111111}.jstree-default-dark-responsive .jstree-children .jstree-open>.jstree-wholerow{box-shadow:inset 0 6px 3px -5px #111111;border-top:0}.jstree-default-dark-responsive .jstree-children .jstree-open+.jstree-open{box-shadow:none}.jstree-default-dark-responsive .jstree-node,.jstree-default-dark-responsive .jstree-icon,.jstree-default-dark-responsive .jstree-node>.jstree-ocl,.jstree-default-dark-responsive .jstree-themeicon,.jstree-default-dark-responsive .jstree-checkbox{background-image:url("40px.png");background-size:120px 240px}.jstree-default-dark-responsive .jstree-node{background-position:-80px 0;background-repeat:repeat-y}.jstree-default-dark-responsive .jstree-last{background-image:none}.jstree-default-dark-responsive .jstree-leaf>.jstree-ocl{background-position:-40px -120px}.jstree-default-dark-responsive .jstree-last>.jstree-ocl{background-position:-40px -160px}.jstree-default-dark-responsive .jstree-themeicon-custom{background-color:transparent;background-image:none;background-position:0 0}.jstree-default-dark-responsive .jstree-file{background:url("40px.png") 0 -160px no-repeat;background-size:120px 240px}.jstree-default-dark-responsive .jstree-folder{background:url("40px.png") -40px -40px no-repeat;background-size:120px 240px}.jstree-default-dark-responsive>.jstree-container-ul>.jstree-node{margin-left:0;margin-right:0}}.jstree-default-dark{background:#333}.jstree-default-dark .jstree-anchor{color:#999;text-shadow:1px 1px 0 rgba(0,0,0,0.5)}.jstree-default-dark .jstree-clicked,.jstree-default-dark .jstree-checked{color:white}.jstree-default-dark .jstree-hovered{color:white}#jstree-marker.jstree-default-dark{border-left-color:#999;background:transparent}.jstree-default-dark .jstree-anchor>.jstree-icon{opacity:.75}.jstree-default-dark .jstree-clicked>.jstree-icon,.jstree-default-dark .jstree-hovered>.jstree-icon,.jstree-default-dark .jstree-checked>.jstree-icon{opacity:1}.jstree-default-dark.jstree-rtl .jstree-node{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAACAQMAAAB49I5GAAAABlBMVEUAAACZmZl+9SADAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMOBgAAGAAJMwQHdQAAAABJRU5ErkJggg==")}.jstree-default-dark.jstree-rtl .jstree-last{background-image:none}.jstree-default-dark-small.jstree-rtl .jstree-node{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAACAQMAAABv1h6PAAAABlBMVEUAAACZmZl+9SADAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjAAMHBgAAiABBI4gz9AAAAABJRU5ErkJggg==")}.jstree-default-dark-small.jstree-rtl .jstree-last{background-image:none}.jstree-default-dark-large.jstree-rtl .jstree-node{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAACAQMAAAAD0EyKAAAABlBMVEUAAACZmZl+9SADAAAAAXRSTlMAQObYZgAAAAxJREFUCNdjgIIGBgABCgCBvVLXcAAAAABJRU5ErkJggg==")}.jstree-default-dark-large.jstree-rtl .jstree-last{background-image:none}includes/jstree/jstree.min.js000064400000425133152214270100012264 0ustar00/*! jsTree - v3.3.15 - 2023-02-20 - (MIT) */ !function(e){"use strict";"function"==typeof define&&define.amd?define(["jquery"],e):"undefined"!=typeof module&&module.exports?module.exports=e(require("jquery")):e(jQuery)}(function(E,P){"use strict";if(!E.jstree){var s=0,a=!1,n=!1,d=!1,r=[],e=E("script:last").attr("src"),b=window.document,c=window.setImmediate,i=window.Promise;!c&&i&&(c=function(e,t){i.resolve(t).then(e)}),E.jstree={version:"3.3.15",defaults:{plugins:[]},plugins:{},path:e&&-1!==e.indexOf("/")?e.replace(/\/[^\/]+$/,""):"",idregex:/[\\:&!^|()\[\]<>@*'+~#";.,=\- \/${}%?`]/g,root:"#"},E.jstree.create=function(e,i){var r=new E.jstree.core(++s),t=i;return i=E.extend(!0,{},E.jstree.defaults,i),t&&t.plugins&&(i.plugins=t.plugins),E.each(i.plugins,function(e,t){"core"!==e&&(r=r.plugin(t,i[t]))}),E(e).data("jstree",r),r.init(e,i),r},E.jstree.destroy=function(){E(".jstree:jstree").jstree("destroy"),E(b).off(".jstree")},E.jstree.core=function(e){this._id=e,this._cnt=0,this._wrk=null,this._data={core:{themes:{name:!1,dots:!1,icons:!1,ellipsis:!1},selected:[],last_error:{},working:!1,worker_queue:[],focused:null}}},E.jstree.reference=function(t){var i=null,e=null;if(!t||!t.id||t.tagName&&t.nodeType||(t=t.id),!e||!e.length)try{e=E(t)}catch(e){}if(!e||!e.length)try{e=E("#"+t.replace(E.jstree.idregex,"\\$&"))}catch(e){}return e&&e.length&&(e=e.closest(".jstree")).length&&(e=e.data("jstree"))?i=e:E(".jstree").each(function(){var e=E(this).data("jstree");if(e&&e._model.data[t])return i=e,!1}),i},E.fn.jstree=function(i){var r="string"==typeof i,s=Array.prototype.slice.call(arguments,1),a=null;return!(!0===i&&!this.length)&&(this.each(function(){var e=E.jstree.reference(this),t=r&&e?e[i]:null;if(a=r&&t?t.apply(e,s):null,e||r||i!==P&&!E.isPlainObject(i)||E.jstree.create(this,i),null!==(a=e&&!r||!0===i?e||!1:a)&&a!==P)return!1}),null!==a&&a!==P?a:this)},E.expr.pseudos.jstree=E.expr.createPseudo(function(e){return function(e){return E(e).hasClass("jstree")&&E(e).data("jstree")!==P}}),E.jstree.defaults.core={data:!1,strings:!1,check_callback:!1,error:E.noop,animation:200,multiple:!0,themes:{name:!1,url:!1,dir:!1,dots:!0,icons:!0,ellipsis:!1,stripes:!1,variant:!1,responsive:!1},expand_selected_onload:!0,worker:!0,force_text:!1,dblclick_toggle:!0,loaded_state:!1,restore_focus:!0,compute_elements_positions:!1,keyboard:{"ctrl-space":function(e){e.type="click",E(e.currentTarget).trigger(e)},enter:function(e){e.type="click",E(e.currentTarget).trigger(e)},left:function(e){var e;e.preventDefault(),this.is_open(e.currentTarget)?this.close_node(e.currentTarget):(e=this.get_parent(e.currentTarget))&&e.id!==E.jstree.root&&this.get_node(e,!0).children(".jstree-anchor").trigger("focus")},up:function(e){e.preventDefault();var e=this.get_prev_dom(e.currentTarget);e&&e.length&&e.children(".jstree-anchor").trigger("focus")},right:function(e){var e;e.preventDefault(),this.is_closed(e.currentTarget)?this.open_node(e.currentTarget,function(e){this.get_node(e,!0).children(".jstree-anchor").trigger("focus")}):!this.is_open(e.currentTarget)||(e=this.get_node(e.currentTarget,!0).children(".jstree-children")[0])&&E(this._firstChild(e)).children(".jstree-anchor").trigger("focus")},down:function(e){e.preventDefault();var e=this.get_next_dom(e.currentTarget);e&&e.length&&e.children(".jstree-anchor").trigger("focus")},"*":function(e){this.open_all()},home:function(e){e.preventDefault();var e=this._firstChild(this.get_container_ul()[0]);e&&E(e).children(".jstree-anchor").filter(":visible").trigger("focus")},end:function(e){e.preventDefault(),this.element.find(".jstree-anchor").filter(":visible").last().trigger("focus")},f2:function(e){e.preventDefault(),this.edit(e.currentTarget)}}},E.jstree.core.prototype={plugin:function(e,t){var i=E.jstree.plugins[e];return i?(this._data[e]={},i.prototype=this,new i(t,this)):this},init:function(e,t){this._model={data:{},changed:[],force_full_redraw:!1,redraw_timeout:!1,default_state:{loaded:!0,opened:!1,selected:!1,disabled:!1}},this._model.data[E.jstree.root]={id:E.jstree.root,parent:null,parents:[],children:[],children_d:[],state:{loaded:!1}},this.element=E(e).addClass("jstree jstree-"+this._id),this.settings=t,this._data.core.ready=!1,this._data.core.loaded=!1,this._data.core.rtl="rtl"===this.element.css("direction"),this.element[this._data.core.rtl?"addClass":"removeClass"]("jstree-rtl"),this.element.attr("role","tree"),this.settings.core.multiple&&this.element.attr("aria-multiselectable",!0),this.element.attr("tabindex")||this.element.attr("tabindex","0"),this.bind(),this.trigger("init"),this._data.core.original_container_html=this.element.find(" > ul > li").clone(!0),this._data.core.original_container_html.find("li").addBack().contents().filter(function(){return 3===this.nodeType&&(!this.nodeValue||/^\s+$/.test(this.nodeValue))}).remove(),this.element.html(""),this.element.attr("aria-activedescendant","j"+this._id+"_loading"),this._data.core.li_height=this.get_container_ul().children("li").first().outerHeight()||24,this._data.core.node=this._create_prototype_node(),this.trigger("loading"),this.load_node(E.jstree.root)},destroy:function(e){if(this.trigger("destroy"),this._wrk)try{window.URL.revokeObjectURL(this._wrk),this._wrk=null}catch(e){}e||this.element.empty(),this.teardown()},_create_prototype_node:function(){var e=b.createElement("LI"),t,i;return e.setAttribute("role","none"),(t=b.createElement("I")).className="jstree-icon jstree-ocl",t.setAttribute("role","presentation"),e.appendChild(t),(t=b.createElement("A")).className="jstree-anchor",t.setAttribute("href","#"),t.setAttribute("tabindex","-1"),t.setAttribute("role","treeitem"),(i=b.createElement("I")).className="jstree-icon jstree-themeicon",i.setAttribute("role","presentation"),t.appendChild(i),e.appendChild(t),t=i=null,e},_kbevent_to_func:function(e){var t={8:"Backspace",9:"Tab",13:"Enter",19:"Pause",27:"Esc",32:"Space",33:"PageUp",34:"PageDown",35:"End",36:"Home",37:"Left",38:"Up",39:"Right",40:"Down",44:"Print",45:"Insert",46:"Delete",96:"Numpad0",97:"Numpad1",98:"Numpad2",99:"Numpad3",100:"Numpad4",101:"Numpad5",102:"Numpad6",103:"Numpad7",104:"Numpad8",105:"Numpad9","-13":"NumpadEnter",112:"F1",113:"F2",114:"F3",115:"F4",116:"F5",117:"F6",118:"F7",119:"F8",120:"F9",121:"F10",122:"F11",123:"F12",144:"Numlock",145:"Scrolllock",16:"Shift",17:"Ctrl",18:"Alt",48:"0",49:"1",50:"2",51:"3",52:"4",53:"5",54:"6",55:"7",56:"8",57:"9",59:";",61:"=",65:"a",66:"b",67:"c",68:"d",69:"e",70:"f",71:"g",72:"h",73:"i",74:"j",75:"k",76:"l",77:"m",78:"n",79:"o",80:"p",81:"q",82:"r",83:"s",84:"t",85:"u",86:"v",87:"w",88:"x",89:"y",90:"z",107:"+",109:"-",110:".",186:";",187:"=",188:",",189:"-",190:".",191:"/",192:"`",219:"[",220:"\\",221:"]",222:"'",111:"/",106:"*",173:"-"},i=[];if(e.ctrlKey&&i.push("ctrl"),e.altKey&&i.push("alt"),e.shiftKey&&i.push("shift"),i.push(t[e.which]?t[e.which].toLowerCase():e.which),"shift-shift"===(i=i.sort().join("-").toLowerCase())||"ctrl-ctrl"===i||"alt-alt"===i)return null;var r=this.settings.core.keyboard,s,a;for(s in r)if(r.hasOwnProperty(s)&&(a="-"!==(a=s)&&"+"!==a?(a=a.replace("--","-MINUS").replace("+-","-MINUS").replace("++","-PLUS").replace("-+","-PLUS")).split(/-|\+/).sort().join("-").replace("MINUS","-").replace("PLUS","+").toLowerCase():a)===i)return r[s];return null},teardown:function(){this.unbind(),this.element.removeClass("jstree").removeData("jstree").find("[class^='jstree']").addBack().attr("class",function(){return this.className.replace(/jstree[^ ]*|$/gi,"")}),this.element=null},bind:function(){var s="",a=null,t=0;this.element.on("dblclick.jstree",function(e){if(e.target.tagName&&"input"===e.target.tagName.toLowerCase())return!0;if(b.selection&&b.selection.empty)b.selection.empty();else if(window.getSelection){var e=window.getSelection();try{e.removeAllRanges(),e.collapse()}catch(e){}}}).on("mousedown.jstree",function(e){e.target===this.element[0]&&(e.preventDefault(),t=+new Date)}.bind(this)).on("mousedown.jstree",".jstree-ocl",function(e){e.preventDefault()}).on("click.jstree",".jstree-ocl",function(e){this.toggle_node(e.target)}.bind(this)).on("dblclick.jstree",".jstree-anchor",function(e){if(e.target.tagName&&"input"===e.target.tagName.toLowerCase())return!0;this.settings.core.dblclick_toggle&&this.toggle_node(e.target)}.bind(this)).on("click.jstree",".jstree-anchor",function(e){e.preventDefault(),e.currentTarget!==b.activeElement&&E(e.currentTarget).trigger("focus"),this.activate_node(e.currentTarget,e)}.bind(this)).on("keydown.jstree",".jstree-anchor",function(e){if(e.target.tagName&&"input"===e.target.tagName.toLowerCase())return!0;this._data.core.rtl&&(37===e.which?e.which=39:39===e.which&&(e.which=37));var t=this._kbevent_to_func(e);if(t){var e=t.call(this,e);if(!1===e||!0===e)return e}}.bind(this)).on("load_node.jstree",function(e,t){t.status&&(t.node.id!==E.jstree.root||this._data.core.loaded||(this._data.core.loaded=!0,this._firstChild(this.get_container_ul()[0])&&this.element.attr("aria-activedescendant",this._firstChild(this.get_container_ul()[0]).id),this.trigger("loaded")),this._data.core.ready||setTimeout(function(){if(this.element&&!this.get_container_ul().find(".jstree-loading").length){if(this._data.core.ready=!0,this._data.core.selected.length){if(this.settings.core.expand_selected_onload){for(var e=[],t,i,t=0,i=this._data.core.selected.length;t .jstree-anchor").trigger("focus"))}.bind(this)).on("mouseenter.jstree",".jstree-anchor",function(e){this.hover_node(e.currentTarget)}.bind(this)).on("mouseleave.jstree",".jstree-anchor",function(e){this.dehover_node(e.currentTarget)}.bind(this))},unbind:function(){this.element.off(".jstree"),E(b).off(".jstree-"+this._id)},trigger:function(e,t){((t=t||{}).instance=this).element.triggerHandler(e.replace(".jstree","")+".jstree",t)},get_container:function(){return this.element},get_container_ul:function(){return this.element.children(".jstree-children").first()},get_string:function(e){var t=this.settings.core.strings;return E.vakata.is_function(t)?t.call(this,e):t&&t[e]?t[e]:e},_firstChild:function(e){e=e?e.firstChild:null;while(null!==e&&1!==e.nodeType)e=e.nextSibling;return e},_nextSibling:function(e){e=e?e.nextSibling:null;while(null!==e&&1!==e.nodeType)e=e.nextSibling;return e},_previousSibling:function(e){e=e?e.previousSibling:null;while(null!==e&&1!==e.nodeType)e=e.previousSibling;return e},get_node:function(e,t){var i;(e=e&&(e.id||0===e.id)?e.id:e)instanceof E&&e.length&&e[0].id&&(e=e[0].id);try{if(this._model.data[e])e=this._model.data[e];else if("string"==typeof e&&this._model.data[e.replace(/^#/,"")])e=this._model.data[e.replace(/^#/,"")];else if("string"==typeof e&&(i=E("#"+e.replace(E.jstree.idregex,"\\$&"),this.element)).length&&this._model.data[i.closest(".jstree-node").attr("id")])e=this._model.data[i.closest(".jstree-node").attr("id")];else if((i=this.element.find(e)).length&&this._model.data[i.closest(".jstree-node").attr("id")])e=this._model.data[i.closest(".jstree-node").attr("id")];else{if(!(i=this.element.find(e)).length||!i.hasClass("jstree"))return!1;e=this._model.data[E.jstree.root]}return e=t?e.id===E.jstree.root?this.element:E("#"+e.id.replace(E.jstree.idregex,"\\$&"),this.element):e}catch(e){return!1}},get_path:function(e,t,i){if(!(e=e.parents?e:this.get_node(e))||e.id===E.jstree.root||!e.parents)return!1;var r,s,a=[];for(a.push(i?e.id:e.text),r=0,s=e.parents.length;r
").html(t),n.text=this.settings.core.force_text?t.text():t.html(),t=e.data(),n.data=t?E.extend(!0,{},t):null,n.state.opened=e.hasClass("jstree-open"),n.state.selected=e.children("a").hasClass("jstree-clicked"),n.state.disabled=e.children("a").hasClass("jstree-disabled"),n.data&&n.data.jstree)for(d in n.data.jstree)n.data.jstree.hasOwnProperty(d)&&(n.state[d]=n.data.jstree[d]);(t=e.children("a").children(".jstree-themeicon")).length&&(n.icon=!t.hasClass("jstree-themeicon-hidden")&&t.attr("rel")),n.state.icon!==P&&(n.icon=n.state.icon),n.icon!==P&&null!==n.icon&&""!==n.icon||(n.icon=!0),t=e.children("ul").children("li");do{o="j"+this._id+"_"+ ++this._cnt}while(a[o]);return n.id=n.li_attr.id?n.li_attr.id.toString():o,t.length?(t.each(function(e,t){r=this._parse_model_from_html(E(t),n.id,i),s=this._model.data[r],n.children.push(r),s.children_d.length&&(n.children_d=n.children_d.concat(s.children_d))}.bind(this)),n.children_d=n.children_d.concat(n.children)):e.hasClass("jstree-closed")&&(n.state.loaded=!1),n.li_attr.class&&(n.li_attr.class=n.li_attr.class.replace("jstree-closed","").replace("jstree-open","")),n.a_attr.class&&(n.a_attr.class=n.a_attr.class.replace("jstree-clicked","").replace("jstree-disabled","")),(a[n.id]=n).state.selected&&this._data.core.selected.push(n.id),n.id},_parse_model_from_flat_json:function(e,t,i){i=i?i.concat():[],t&&i.unshift(t);var r=e.id.toString(),s=this._model.data,a=this._model.default_state,n,d,o,c,l={id:r,text:e.text||"",icon:e.icon===P||e.icon,parent:t,parents:i,children:e.children||[],children_d:e.children_d||[],data:e.data,state:{},li_attr:{id:!1},a_attr:{href:"#"},original:!1};for(n in a)a.hasOwnProperty(n)&&(l.state[n]=a[n]);if(e&&e.data&&e.data.jstree&&e.data.jstree.icon&&(l.icon=e.data.jstree.icon),l.icon!==P&&null!==l.icon&&""!==l.icon||(l.icon=!0),e&&e.data&&(l.data=e.data,e.data.jstree))for(n in e.data.jstree)e.data.jstree.hasOwnProperty(n)&&(l.state[n]=e.data.jstree[n]);if(e&&"object"==typeof e.state)for(n in e.state)e.state.hasOwnProperty(n)&&(l.state[n]=e.state[n]);if(e&&"object"==typeof e.li_attr)for(n in e.li_attr)e.li_attr.hasOwnProperty(n)&&(l.li_attr[n]=e.li_attr[n]);if(l.li_attr.id||(l.li_attr.id=r),e&&"object"==typeof e.a_attr)for(n in e.a_attr)e.a_attr.hasOwnProperty(n)&&(l.a_attr[n]=e.a_attr[n]);for(e&&e.children&&!0===e.children&&(l.state.loaded=!1,l.children=[],l.children_d=[]),n=0,d=(s[l.id]=l).children.length;n
  • "+this.get_string("Loading ...")+"
  • "),this.element.attr("aria-activedescendant","j"+this._id+"_loading")),this.load_node(E.jstree.root,function(e,t){t&&(this.get_container_ul()[0].className=i,this._firstChild(this.get_container_ul()[0])&&this.element.attr("aria-activedescendant",this._firstChild(this.get_container_ul()[0]).id),this.set_state(E.extend(!0,{},this._data.core.state),function(){this.trigger("refresh")})),this._data.core.state=null})},refresh_node:function(t){if(!(t=this.get_node(t))||t.id===E.jstree.root)return!1;var i=[],e=[],r=this._data.core.selected.concat([]);e.push(t.id),!0===t.state.opened&&i.push(t.id),this.get_node(t,!0).find(".jstree-open").each(function(){e.push(this.id),i.push(this.id)}),this._load_nodes(e,function(e){this.open_node(i,!1,0),this.select_node(r),this.trigger("refresh_node",{node:t,nodes:e})}.bind(this),!1,!0)},set_id:function(e,t){if(!(e=this.get_node(e))||e.id===E.jstree.root)return!1;var i,r,s=this._model.data,a=e.id;for(t=t.toString(),s[e.parent].children[E.inArray(e.id,s[e.parent].children)]=t,i=0,r=e.parents.length;ie.children.length&&(i=e.children.length),t.id===P&&(t.id=!0),!this.check("create_node",t,e,i))return this.settings.core.error.call(this,this._data.core.last_error),!1;if(!0===t.id&&delete t.id,!(t=this._parse_model_from_json(t,e.id,e.parents.concat())))return!1;for(a=this.get_node(t),(n=[]).push(t),n=n.concat(a.children_d),this.trigger("model",{nodes:n,parent:e.id}),e.children_d=e.children_d.concat(n),d=0,o=e.parents.length;dh.children.length&&(i=h.children.length),!this.check("move_node",e,h,i,{core:!0,origin:n,is_multi:_&&_._id&&_._id!==this._id,is_foreign:!_||!_._id}))return this.settings.core.error.call(this,this._data.core.last_error),!1;if(e.parent===h.id){for(u=h.children.concat(),-1!==(f=E.inArray(e.id,u))&&(u=E.vakata.array_remove(u,f),ff.children.length&&(i=f.children.length),!this.check("copy_node",e,f,i,{core:!0,origin:n,is_multi:p&&p._id&&p._id!==this._id,is_foreign:!p||!p._id}))return this.settings.core.error.call(this,this._data.core.last_error),!1;if(!(g=p?p.get_json(e,{no_id:!0,no_data:!0,no_state:!0}):e))return!1;if(!0===g.id&&delete g.id,!(g=this._parse_model_from_json(g,f.id,f.parents.concat())))return!1;for(l=this.get_node(g),e&&e.state&&!1===e.state.loaded&&(l.state.loaded=!1),(c=[]).push(g),c=c.concat(l.children_d),this.trigger("model",{nodes:c,parent:f.id}),h=0,_=f.parents.length;h<_;h++)this._model.data[f.parents[h]].children_d=this._model.data[f.parents[h]].children_d.concat(c);for(c=[],h=0,_=f.children.length;h<_;h++)c[i<=h?h+1:h]=f.children[h];return c[i]=l.id,f.children=c,f.children_d.push(l.id),f.children_d=f.children_d.concat(l.children_d),f.id===E.jstree.root&&(this._model.force_full_redraw=!0),this._model.force_full_redraw||this._node_changed(f.id),a||this.redraw(f.id===E.jstree.root),r&&r.call(this,l,f,i),this.trigger("copy_node",{node:l,original:e,parent:f.id,position:i,old_parent:u,old_position:p&&p._id&&u&&p._model.data[u]&&p._model.data[u].children?E.inArray(e.id,p._model.data[u].children):-1,is_multi:p&&p._id&&p._id!==this._id,is_foreign:!p||!p._id,old_instance:p,new_instance:this}),l.id},cut:function(e){if(e=e||this._data.core.selected.concat(),!(e=!E.vakata.is_array(e)?[e]:e).length)return!1;for(var t=[],i,r,s,r=0,s=e.length;r"),d=e,o=E("
    ",{css:{position:"absolute",top:"-200px",left:t?"0px":"-1000px",visibility:"hidden"}}).appendTo(b.body),c=E("",{value:d,class:"jstree-rename-input",css:{padding:"0",border:"1px solid silver","box-sizing":"border-box",display:"inline-block",height:this._data.core.li_height+"px",lineHeight:this._data.core.li_height+"px",width:"150px"},blur:function(e){e.stopImmediatePropagation(),e.preventDefault();var t,i=n.children(".jstree-rename-input").val(),e=this.settings.core.force_text,e;""===i&&(i=d),o.remove(),n.replaceWith(a),n.remove(),d=e?d:E("
    ").append(E.parseHTML(d)).html(),r=this.get_node(r),this.set_text(r,d),(e=!!this.rename_node(r,e?E("
    ").text(i).text():E("
    ").append(E.parseHTML(i)).html()))||this.set_text(r,d),this._data.core.focused=l.id,setTimeout(function(){var e=this.get_node(l.id,!0);e.length&&(this._data.core.focused=l.id,e.children(".jstree-anchor").trigger("focus"))}.bind(this),0),s&&s.call(this,l,e,h,i),c=null}.bind(this),keydown:function(e){var t=e.which;27===t&&(h=!0,this.value=d),27!==t&&13!==t&&37!==t&&38!==t&&39!==t&&40!==t&&32!==t||e.stopImmediatePropagation(),27!==t&&13!==t||(e.preventDefault(),this.blur())},click:function(e){e.stopImmediatePropagation()},mousedown:function(e){e.stopImmediatePropagation()},keyup:function(e){c.width(Math.min(o.text("pW"+this.value).width(),i))},keypress:function(e){if(13===e.which)return!1}}),t={fontFamily:a.css("fontFamily")||"",fontSize:a.css("fontSize")||"",fontWeight:a.css("fontWeight")||"",fontStyle:a.css("fontStyle")||"",fontStretch:a.css("fontStretch")||"",fontVariant:a.css("fontVariant")||"",letterSpacing:a.css("letterSpacing")||"",wordSpacing:a.css("wordSpacing")||""},n.attr("class",a.attr("class")).append(a.contents().clone()).append(c),a.replaceWith(n),o.css(t),c.css(t).width(Math.min(o.text("pW"+c[0].value).width(),i))[0].select(),void E(b).one("mousedown.jstree touchstart.jstree dnd_start.vakata",function(e){c&&e.target!==c&&E(c).trigger("blur")})):(this.settings.core.error.call(this,this._data.core.last_error),!1))},set_theme:function(e,t){if(!e)return!1;var i,i;(t=!0===t?(i=(i=this.settings.core.themes.dir)||E.jstree.path+"/themes")+"/"+e+"/style.css":t)&&-1===E.inArray(t,r)&&(E("head").append(''),r.push(t)),this._data.core.themes.name&&this.element.removeClass("jstree-"+this._data.core.themes.name),this._data.core.themes.name=e,this.element.addClass("jstree-"+e),this.element[this.settings.core.themes.responsive?"addClass":"removeClass"]("jstree-"+e+"-responsive"),this.trigger("set_theme",{theme:e})},get_theme:function(){return this._data.core.themes.name},set_theme_variant:function(e){this._data.core.themes.variant&&this.element.removeClass("jstree-"+this._data.core.themes.name+"-"+this._data.core.themes.variant),(this._data.core.themes.variant=e)&&this.element.addClass("jstree-"+this._data.core.themes.name+"-"+this._data.core.themes.variant)},get_theme_variant:function(){return this._data.core.themes.variant},show_stripes:function(){this._data.core.themes.stripes=!0,this.get_container_ul().addClass("jstree-striped"),this.trigger("show_stripes")},hide_stripes:function(){this._data.core.themes.stripes=!1,this.get_container_ul().removeClass("jstree-striped"),this.trigger("hide_stripes")},toggle_stripes:function(){this._data.core.themes.stripes?this.hide_stripes():this.show_stripes()},show_dots:function(){this._data.core.themes.dots=!0,this.get_container_ul().removeClass("jstree-no-dots"),this.trigger("show_dots")},hide_dots:function(){this._data.core.themes.dots=!1,this.get_container_ul().addClass("jstree-no-dots"),this.trigger("hide_dots")},toggle_dots:function(){this._data.core.themes.dots?this.hide_dots():this.show_dots()},show_icons:function(){this._data.core.themes.icons=!0,this.get_container_ul().removeClass("jstree-no-icons"),this.trigger("show_icons")},hide_icons:function(){this._data.core.themes.icons=!1,this.get_container_ul().addClass("jstree-no-icons"),this.trigger("hide_icons")},toggle_icons:function(){this._data.core.themes.icons?this.hide_icons():this.show_icons()},show_ellipsis:function(){this._data.core.themes.ellipsis=!0,this.get_container_ul().addClass("jstree-ellipsis"),this.trigger("show_ellipsis")},hide_ellipsis:function(){this._data.core.themes.ellipsis=!1,this.get_container_ul().removeClass("jstree-ellipsis"),this.trigger("hide_ellipsis")},toggle_ellipsis:function(){this._data.core.themes.ellipsis?this.hide_ellipsis():this.show_ellipsis()},set_icon:function(e,t){var i,r,s,a;if(E.vakata.is_array(e)){for(i=0,r=(e=e.slice()).length;i "),r=!1,i+="
  • ",i+="",h.vakata.context.settings.icons&&(i+="'+(t.shortcut_label||"")+"":"")+"",t.submenu&&(s=h.vakata.context._parse(t.submenu,!0))&&(i+=s),i+="
  • ",void(t.separator_after&&(i+="
  •  
  • ",r=!0)))}),i=i.replace(/
  • <\/li\>$/,""),t&&(i+=""),t||(g.html=i,h.vakata.context._trigger("parse")),10"),g.element.on("mouseenter","li",function(e){e.stopImmediatePropagation(),h.contains(this,e.relatedTarget)||(i&&clearTimeout(i),g.element.find(".vakata-context-hover").removeClass("vakata-context-hover").end(),h(this).siblings().find("ul").hide().end().end().parentsUntil(".vakata-context","li").addBack().addClass("vakata-context-hover"),h.vakata.context._show_submenu(this))}).on("mouseleave","li",function(e){h.contains(this,e.relatedTarget)||h(this).find(".vakata-context-hover").addBack().removeClass("vakata-context-hover")}).on("mouseleave",function(e){var t;h(this).find(".vakata-context-hover").removeClass("vakata-context-hover"),h.vakata.context.settings.hide_onmouseleave&&(i=setTimeout((t=this,function(){h.vakata.context.hide()}),h.vakata.context.settings.hide_onmouseleave))}).on("click","a",function(e){e.preventDefault(),h(this).trigger("blur").parent().hasClass("vakata-context-disabled")||!1===h.vakata.context._execute(h(this).attr("rel"))||h.vakata.context.hide()}).on("keydown","a",function(e){var t=null;switch(e.which){case 13:case 32:e.type="click",e.preventDefault(),h(e.currentTarget).trigger(e);break;case 37:g.is_visible&&(g.element.find(".vakata-context-hover").last().closest("li").first().find("ul").hide().find(".vakata-context-hover").removeClass("vakata-context-hover").end().end().children("a").trigger("focus"),e.stopImmediatePropagation(),e.preventDefault());break;case 38:g.is_visible&&((t=!(t=g.element.find("ul:visible").addBack().last().children(".vakata-context-hover").removeClass("vakata-context-hover").prevAll("li:not(.vakata-context-separator)").first()).length?g.element.find("ul:visible").addBack().last().children("li:not(.vakata-context-separator)").last():t).addClass("vakata-context-hover").children("a").trigger("focus"),e.stopImmediatePropagation(),e.preventDefault());break;case 39:g.is_visible&&(g.element.find(".vakata-context-hover").last().children("ul").show().children("li:not(.vakata-context-separator)").removeClass("vakata-context-hover").first().addClass("vakata-context-hover").children("a").trigger("focus"),e.stopImmediatePropagation(),e.preventDefault());break;case 40:g.is_visible&&((t=!(t=g.element.find("ul:visible").addBack().last().children(".vakata-context-hover").removeClass("vakata-context-hover").nextAll("li:not(.vakata-context-separator)").first()).length?g.element.find("ul:visible").addBack().last().children("li:not(.vakata-context-separator)").first():t).addClass("vakata-context-hover").children("a").trigger("focus"),e.stopImmediatePropagation(),e.preventDefault());break;case 27:h.vakata.context.hide(),e.preventDefault()}}).on("keydown",function(e){e.preventDefault();var e=g.element.find(".vakata-contextmenu-shortcut-"+e.which).parent();e.parent().not(".vakata-context-disabled")&&e.trigger("click")}),h(b).on("mousedown.vakata.jstree",function(e){g.is_visible&&g.element[0]!==e.target&&!h.contains(g.element[0],e.target)&&h.vakata.context.hide()}).on("context_show.vakata.jstree",function(e,t){g.element.find("li:has(ul)").children("a").addClass("vakata-context-parent"),_&&g.element.addClass("vakata-context-rtl").css("direction","rtl"),g.element.find("ul").hide().end()})}),E.jstree.defaults.dnd={copy:!0,open_timeout:500,is_draggable:!0,check_while_dragging:!0,always_copy:!1,inside_pos:0,drag_selection:!0,touch:!0,large_drop_target:!1,large_drag_target:!1,use_html5:!1,blank_space_drop:!1},E.jstree.plugins.dnd=function(e,d){this.init=function(e,t){d.init.call(this,e,t),this.settings.dnd.use_html5=this.settings.dnd.use_html5&&"draggable"in b.createElement("span")},this.bind=function(){d.bind.call(this),this.element.on(this.settings.dnd.use_html5?"dragstart.jstree":"mousedown.jstree touchstart.jstree",this.settings.dnd.large_drag_target?".jstree-node":".jstree-anchor",function(e){if(this.settings.dnd.large_drag_target&&E(e.target).closest(".jstree-node")[0]!==e.currentTarget)return!0;if("touchstart"===e.type&&(!this.settings.dnd.touch||"selected"===this.settings.dnd.touch&&!E(e.currentTarget).closest(".jstree-node").children(".jstree-anchor").hasClass("jstree-clicked")))return!0;var t=this.get_node(e.target),i=this.is_selected(t)&&this.settings.dnd.drag_selection?this.get_top_selected().length:1,r=1'+r+'+
  • ');E.vakata.dnd._trigger("start",e,{helper:E(),element:u,data:o})}}.bind(this)),this.settings.dnd.use_html5&&this.element.on("dragover.jstree",function(e){return e.preventDefault(),E.vakata.dnd._trigger("move",e,{helper:E(),element:u,data:o}),!1}).on("drop.jstree",function(e){return e.preventDefault(),E.vakata.dnd._trigger("stop",e,{helper:E(),element:u,data:o}),!1}.bind(this))},this.redraw_node=function(e,t,i,r){if((e=d.redraw_node.apply(this,arguments))&&this.settings.dnd.use_html5)if(this.settings.dnd.large_drag_target)e.setAttribute("draggable",!0);else{for(var s,a,n=null,s=0,a=e.childNodes.length;s 
    ').hide();E(b).on("dragover.vakata.jstree",function(e){u&&E.vakata.dnd._trigger("move",e,{helper:E(),element:u,data:o})}).on("drop.vakata.jstree",function(e){u&&(E.vakata.dnd._trigger("stop",e,{helper:E(),element:u,data:o}),o=u=null)}).on("dnd_start.vakata.jstree",function(e,t){O=N=!1,t&&t.data&&t.data.jstree&&S.appendTo(b.body)}).on("dnd_move.vakata.jstree",function(e,s){var a=s.event.target!==O.target;if(A&&(s.event&&"dragover"===s.event.type&&!a||clearTimeout(A)),s&&s.data&&s.data.jstree&&(!s.event.target.id||"jstree-marker"!==s.event.target.id)){O=s.event;var n=E.jstree.reference(s.event.target),d=!1,o=!1,t=!1,i,c,l,h,_,g,u,f,p,m,v,j,k,b,y,x,w,C;if(n&&n._data&&n._data.dnd)if(S.attr("class","jstree-"+n.get_theme()+(n.settings.core.themes.responsive?" jstree-dnd-responsive":"")),x=s.data.origin&&(s.data.origin.settings.dnd.always_copy||s.data.origin.settings.dnd.copy&&(s.event.metaKey||s.event.ctrlKey)),s.helper.children().attr("class","jstree-"+n.get_theme()+" jstree-"+n.get_theme()+"-"+n.get_theme_variant()+" "+(n.settings.core.themes.responsive?" jstree-dnd-responsive":"")).find(".jstree-copy").first()[x?"show":"hide"](),s.event.target!==n.element[0]&&s.event.target!==n.get_container_ul()[0]||0!==n.get_container_ul().children().length&&!n.settings.dnd.blank_space_drop){if((d=n.settings.dnd.large_drop_target?E(s.event.target).closest(".jstree-node").children(".jstree-anchor"):E(s.event.target).closest(".jstree-anchor"))&&d.length&&d.parent().is(".jstree-closed, .jstree-open, .jstree-leaf")&&(o=d.offset(),t=(s.event.pageY!==P?s.event:s.event.originalEvent).pageY-o.top,h=d.outerHeight(),u=tE.inArray(s.data.nodes[p],k.children)&&--j),!(f=f&&(n&&n.settings&&n.settings.dnd&&!1===n.settings.dnd.check_while_dragging||n.check(v,s.data.origin&&s.data.origin!==n?s.data.origin.get_node(s.data.nodes[p]):s.data.nodes[p],_,j,{dnd:!0,ref:n.get_node(d.parent()),pos:t,origin:s.data.origin,is_multi:s.data.origin&&s.data.origin!==n,is_foreign:!s.data.origin})))){n&&n.last_error&&(T=n.last_error());break}var i,r;if("i"===t&&d.parent().is(".jstree-closed")&&n.settings.dnd.open_timeout&&(s.event&&"dragover"===s.event.type&&!a||(A&&clearTimeout(A),A=setTimeout((r=d,function(){i.open_node(r)}),(i=n).settings.dnd.open_timeout))),f)return(w=n.get_node(_,!0)).hasClass(".jstree-dnd-parent")||(E(".jstree-dnd-parent").removeClass("jstree-dnd-parent"),w.addClass("jstree-dnd-parent")),N={ins:n,par:_,pos:"i"!==t||"last"!==b||0!==g||n.is_loaded(y)?g:"last"},S.css({left:c+"px",top:l+"px"}).show(),S.removeClass("jstree-above jstree-inside jstree-below").addClass(C),s.helper.find(".jstree-icon").first().removeClass("jstree-er").addClass("jstree-ok"),s.event.originalEvent&&s.event.originalEvent.dataTransfer&&(s.event.originalEvent.dataTransfer.dropEffect=x?"copy":"move"),T={},!(u=!0)}),!0===u))return}else{for(f=!0,p=0,m=s.data.nodes.length;p"),escape:function(e){return f.vakata.html.div.text(e).html()},strip:function(e){return f.vakata.html.div.empty().append(f.parseHTML(e)).text()}}),target:!1,is_down:!1,is_drag:!1,helper:!1,helper_w:0,data:!1,init_x:0,init_y:0,scroll_l:0,scroll_t:0,scroll_e:!1,scroll_i:!1,is_touch:!1},f.vakata.dnd={settings:{scroll_speed:10,scroll_proximity:20,helper_left:5,helper_top:10,threshold:5,threshold_touch:10},_trigger:function(e,t,i){(i=i===P?f.vakata.dnd._get():i).event=t,f(b).triggerHandler("dnd_"+e+".vakata",i)},_get:function(){return{data:p.data,element:p.element,helper:p.helper}},_clean:function(){p.helper&&p.helper.remove(),p.scroll_i&&(clearInterval(p.scroll_i),p.scroll_i=!1),p={element:!1,target:!1,is_down:!1,is_drag:!1,helper:!1,helper_w:0,data:!1,init_x:0,init_y:0,scroll_l:0,scroll_t:0,scroll_e:!1,scroll_i:!1,is_touch:!1},u=null,f(b).off("mousemove.vakata.jstree touchmove.vakata.jstree",f.vakata.dnd.drag),f(b).off("mouseup.vakata.jstree touchend.vakata.jstree",f.vakata.dnd.stop)},_scroll:function(e){if(!p.scroll_e||!p.scroll_l&&!p.scroll_t)return p.scroll_i&&(clearInterval(p.scroll_i),p.scroll_i=!1),!1;if(!p.scroll_i)return p.scroll_i=setInterval(f.vakata.dnd._scroll,100),!1;if(!0===e)return!1;var t=p.scroll_e.scrollTop(),e=p.scroll_e.scrollLeft();p.scroll_e.scrollTop(t+p.scroll_t*f.vakata.dnd.settings.scroll_speed),p.scroll_e.scrollLeft(e+p.scroll_l*f.vakata.dnd.settings.scroll_speed),t===p.scroll_e.scrollTop()&&e===p.scroll_e.scrollLeft()||f.vakata.dnd._trigger("scroll",p.scroll_e)},start:function(e,t,i){"touchstart"===e.type&&e.originalEvent&&e.originalEvent.changedTouches&&e.originalEvent.changedTouches[0]&&(e.pageX=e.originalEvent.changedTouches[0].pageX,e.pageY=e.originalEvent.changedTouches[0].pageY,e.target=b.elementFromPoint(e.originalEvent.changedTouches[0].pageX-window.pageXOffset,e.originalEvent.changedTouches[0].pageY-window.pageYOffset)),p.is_drag&&f.vakata.dnd.stop({});try{e.currentTarget.unselectable="on",e.currentTarget.onselectstart=function(){return!1},e.currentTarget.style&&(e.currentTarget.style.touchAction="none",e.currentTarget.style.msTouchAction="none",e.currentTarget.style.MozUserSelect="none")}catch(e){}return p.init_x=e.pageX,p.init_y=e.pageY,p.data=t,p.is_down=!0,p.element=e.currentTarget,p.target=e.target,p.is_touch="touchstart"===e.type,!1!==i&&(p.helper=f("
    ").html(i).css({display:"block",margin:"0",padding:"0",position:"absolute",top:"-2000px",lineHeight:"16px",zIndex:"10000"})),f(b).on("mousemove.vakata.jstree touchmove.vakata.jstree",f.vakata.dnd.drag),f(b).on("mouseup.vakata.jstree touchend.vakata.jstree",f.vakata.dnd.stop),!1},drag:function(i){if("touchmove"===i.type&&i.originalEvent&&i.originalEvent.changedTouches&&i.originalEvent.changedTouches[0]&&(i.pageX=i.originalEvent.changedTouches[0].pageX,i.pageY=i.originalEvent.changedTouches[0].pageY,i.target=b.elementFromPoint(i.originalEvent.changedTouches[0].pageX-window.pageXOffset,i.originalEvent.changedTouches[0].pageY-window.pageYOffset)),p.is_down){if(!p.is_drag){if(!(Math.abs(i.pageX-p.init_x)>(p.is_touch?f.vakata.dnd.settings.threshold_touch:f.vakata.dnd.settings.threshold)||Math.abs(i.pageY-p.init_y)>(p.is_touch?f.vakata.dnd.settings.threshold_touch:f.vakata.dnd.settings.threshold)))return;p.helper&&(p.helper.appendTo(b.body),p.helper_w=p.helper.outerWidth()),p.is_drag=!0,f(p.target).one("click.vakata",!1),f.vakata.dnd._trigger("start",i)}var e=!1,t=!1,r=!1,s=!1,a=!1,n=!1,d=!1,o=!1,c=!1,l=!1;return p.scroll_t=0,p.scroll_l=0,p.scroll_e=!1,f(f(i.target).parentsUntil("body").addBack().get().reverse()).filter(function(){return this.ownerDocument&&/^auto|scroll$/.test(f(this).css("overflow"))&&(this.scrollHeight>this.offsetHeight||this.scrollWidth>this.offsetWidth)}).each(function(){var e=f(this),t=e.offset();if(this.scrollHeight>this.offsetHeight&&(t.top+e.height()-i.pageYthis.offsetWidth&&(t.left+e.width()-i.pageXa&&(l=a-(p.helper_w+2)),p.helper.css({left:l+"px",top:(c=r&&rs)break;c=_}return{isMatch:0<=a,score:u}},!0===e?{search:t}:t(e)},w.vakata.search.defaults={location:0,distance:100,threshold:.6,fuzzy:!1,caseSensitive:!1},E.jstree.defaults.sort=function(e,t){return this.get_text(e)>this.get_text(t)?1:-1};var m=!(E.jstree.plugins.sort=function(e,t){this.bind=function(){t.bind.call(this),this.element.on("model.jstree",function(e,t){this.sort(t.parent,!0)}.bind(this)).on("rename_node.jstree create_node.jstree",function(e,t){this.sort(t.parent||t.node.parent,!1),this.redraw_node(t.parent||t.node.parent,!0)}.bind(this)).on("move_node.jstree copy_node.jstree",function(e,t){this.sort(t.parent,!1),this.redraw_node(t.parent,!0)}.bind(this))},this.sort=function(e,t){var i,r;if((e=this.get_node(e))&&e.children&&e.children.length&&(e.children.sort(this.settings.sort.bind(this)),t))for(i=0,r=e.children_d.length;ii.ttl)&&(!!(i=(i=i&&i.state?i.state:i)&&E.vakata.is_function(this.settings.state.filter)?this.settings.state.filter.call(this,i):i)&&(this.settings.state.preserve_loaded||delete i.core.loaded,this.element.one("set_state.jstree",function(e,t){t.instance.trigger("restore_state",{state:E.extend(!0,{},i)})}),this.set_state(i),!0))},this.clear_state=function(){return E.vakata.storage.del(this.settings.state.key)}},E.vakata.storage={set:function(e,t){return window.localStorage.setItem(e,t)},get:function(e){return window.localStorage.getItem(e)},del:function(e){return window.localStorage.removeItem(e)}},E.jstree.defaults.types={default:{}},E.jstree.defaults.types[E.jstree.root]={},E.jstree.plugins.types=function(e,l){this.init=function(e,t){var i,r;if(t&&t.types&&t.types.default)for(i in t.types)if("default"!==i&&i!==E.jstree.root&&t.types.hasOwnProperty(i))for(r in t.types.default)t.types.default.hasOwnProperty(r)&&t.types[i][r]===P&&(t.types[i][r]=t.types.default[r]);l.init.call(this,e,t),this._model.data[E.jstree.root].type=E.jstree.root},this.refresh=function(e,t){l.refresh.call(this,e,t),this._model.data[E.jstree.root].type=E.jstree.root},this.bind=function(){this.element.on("model.jstree",function(e,t){for(var i=this._model.data,r=t.nodes,s=this.settings.types,a,n,d="default",o,a=0,n=r.length;a .jstree-ocl",function(e){e.stopImmediatePropagation();var t=E.Event("click",{metaKey:e.metaKey,ctrlKey:e.ctrlKey,altKey:e.altKey,shiftKey:e.shiftKey});E(e.currentTarget).closest(".jstree-node").children(".jstree-anchor").first().trigger(t).trigger("focus")}.bind(this)).on("mouseover.jstree",".jstree-wholerow, .jstree-icon",function(e){return e.stopImmediatePropagation(),this.is_disabled(e.currentTarget)||this.hover_node(e.currentTarget),!1}.bind(this)).on("mouseleave.jstree",".jstree-node",function(e){this.dehover_node(e.currentTarget)}.bind(this))},this.teardown=function(){this.settings.wholerow&&this.element.find(".jstree-wholerow").remove(),a.teardown.call(this)},this.redraw_node=function(e,t,i,r){var s;return(e=a.redraw_node.apply(this,arguments))&&(s=j.cloneNode(!0),-1!==E.inArray(e.id,this._data.core.selected)&&(s.className+=" jstree-wholerow-clicked"),this._data.core.focused&&this._data.core.focused===e.id&&(s.className+=" jstree-wholerow-hovered"),e.insertBefore(s,e.childNodes[0])),e}},window.customElements&&Object&&Object.create){var e=Object.create(HTMLElement.prototype);e.createdCallback=function(){var e={core:{},plugins:[]},t;for(t in E.jstree.plugins)E.jstree.plugins.hasOwnProperty(t)&&this.attributes[t]&&(e.plugins.push(t),this.getAttribute(t)&&JSON.parse(this.getAttribute(t))&&(e[t]=JSON.parse(this.getAttribute(t))));for(t in E.jstree.defaults.core)E.jstree.defaults.core.hasOwnProperty(t)&&this.attributes[t]&&(e.core[t]=JSON.parse(this.getAttribute(t))||this.getAttribute(t));E(this).jstree(e)};try{window.customElements.define("vakata-jstree",function(){},{prototype:e})}catch(e){}}}});includes/jstree/jstree.js000064400001136105152214270100011501 0ustar00/*globals jQuery, define, module, exports, require, window, document, postMessage */ (function (factory) { "use strict"; if (typeof define === 'function' && define.amd) { define(['jquery'], factory); } else if(typeof module !== 'undefined' && module.exports) { module.exports = factory(require('jquery')); } else { factory(jQuery); } }(function ($, undefined) { "use strict"; /*! * jsTree 3.3.15 * http://jstree.com/ * * Copyright (c) 2014 Ivan Bozhanov (http://vakata.com) * * Licensed same as jquery - under the terms of the MIT License * http://www.opensource.org/licenses/mit-license.php */ /*! * if using jslint please allow for the jQuery global and use following options: * jslint: loopfunc: true, browser: true, ass: true, bitwise: true, continue: true, nomen: true, plusplus: true, regexp: true, unparam: true, todo: true, white: true */ /*jshint -W083 */ // prevent another load? maybe there is a better way? if($.jstree) { return; } /** * ### jsTree core functionality */ // internal variables var instance_counter = 0, ccp_node = false, ccp_mode = false, ccp_inst = false, themes_loaded = [], src = $('script:last').attr('src'), document = window.document; // local variable is always faster to access then a global var setImmediate = window.setImmediate; var Promise = window.Promise; if (!setImmediate && Promise) { // Good enough approximation of setImmediate setImmediate = function (cb, arg) { Promise.resolve(arg).then(cb); }; } /** * holds all jstree related functions and variables, including the actual class and methods to create, access and manipulate instances. * @name $.jstree */ $.jstree = { /** * specifies the jstree version in use * @name $.jstree.version */ version : '3.3.15', /** * holds all the default options used when creating new instances * @name $.jstree.defaults */ defaults : { /** * configure which plugins will be active on an instance. Should be an array of strings, where each element is a plugin name. The default is `[]` * @name $.jstree.defaults.plugins */ plugins : [] }, /** * stores all loaded jstree plugins (used internally) * @name $.jstree.plugins */ plugins : {}, path : src && src.indexOf('/') !== -1 ? src.replace(/\/[^\/]+$/,'') : '', idregex : /[\\:&!^|()\[\]<>@*'+~#";.,=\- \/${}%?`]/g, root : '#' }; /** * creates a jstree instance * @name $.jstree.create(el [, options]) * @param {DOMElement|jQuery|String} el the element to create the instance on, can be jQuery extended or a selector * @param {Object} options options for this instance (extends `$.jstree.defaults`) * @return {jsTree} the new instance */ $.jstree.create = function (el, options) { var tmp = new $.jstree.core(++instance_counter), opt = options; options = $.extend(true, {}, $.jstree.defaults, options); if(opt && opt.plugins) { options.plugins = opt.plugins; } $.each(options.plugins, function (i, k) { if(i !== 'core') { tmp = tmp.plugin(k, options[k]); } }); $(el).data('jstree', tmp); tmp.init(el, options); return tmp; }; /** * remove all traces of jstree from the DOM and destroy all instances * @name $.jstree.destroy() */ $.jstree.destroy = function () { $('.jstree:jstree').jstree('destroy'); $(document).off('.jstree'); }; /** * the jstree class constructor, used only internally * @private * @name $.jstree.core(id) * @param {Number} id this instance's index */ $.jstree.core = function (id) { this._id = id; this._cnt = 0; this._wrk = null; this._data = { core : { themes : { name : false, dots : false, icons : false, ellipsis : false }, selected : [], last_error : {}, working : false, worker_queue : [], focused : null } }; }; /** * get a reference to an existing instance * * __Examples__ * * // provided a container with an ID of "tree", and a nested node with an ID of "branch" * // all of there will return the same instance * $.jstree.reference('tree'); * $.jstree.reference('#tree'); * $.jstree.reference($('#tree')); * $.jstree.reference(document.getElementByID('tree')); * $.jstree.reference('branch'); * $.jstree.reference('#branch'); * $.jstree.reference($('#branch')); * $.jstree.reference(document.getElementByID('branch')); * * @name $.jstree.reference(needle) * @param {DOMElement|jQuery|String} needle * @return {jsTree|null} the instance or `null` if not found */ $.jstree.reference = function (needle) { var tmp = null, obj = null; if(needle && needle.id && (!needle.tagName || !needle.nodeType)) { needle = needle.id; } if(!obj || !obj.length) { try { obj = $(needle); } catch (ignore) { } } if(!obj || !obj.length) { try { obj = $('#' + needle.replace($.jstree.idregex,'\\$&')); } catch (ignore) { } } if(obj && obj.length && (obj = obj.closest('.jstree')).length && (obj = obj.data('jstree'))) { tmp = obj; } else { $('.jstree').each(function () { var inst = $(this).data('jstree'); if(inst && inst._model.data[needle]) { tmp = inst; return false; } }); } return tmp; }; /** * Create an instance, get an instance or invoke a command on a instance. * * If there is no instance associated with the current node a new one is created and `arg` is used to extend `$.jstree.defaults` for this new instance. There would be no return value (chaining is not broken). * * If there is an existing instance and `arg` is a string the command specified by `arg` is executed on the instance, with any additional arguments passed to the function. If the function returns a value it will be returned (chaining could break depending on function). * * If there is an existing instance and `arg` is not a string the instance itself is returned (similar to `$.jstree.reference`). * * In any other case - nothing is returned and chaining is not broken. * * __Examples__ * * $('#tree1').jstree(); // creates an instance * $('#tree2').jstree({ plugins : [] }); // create an instance with some options * $('#tree1').jstree('open_node', '#branch_1'); // call a method on an existing instance, passing additional arguments * $('#tree2').jstree(); // get an existing instance (or create an instance) * $('#tree2').jstree(true); // get an existing instance (will not create new instance) * $('#branch_1').jstree().select_node('#branch_1'); // get an instance (using a nested element and call a method) * * @name $().jstree([arg]) * @param {String|Object} arg * @return {Mixed} */ $.fn.jstree = function (arg) { // check for string argument var is_method = (typeof arg === 'string'), args = Array.prototype.slice.call(arguments, 1), result = null; if(arg === true && !this.length) { return false; } this.each(function () { // get the instance (if there is one) and method (if it exists) var instance = $.jstree.reference(this), method = is_method && instance ? instance[arg] : null; // if calling a method, and method is available - execute on the instance result = is_method && method ? method.apply(instance, args) : null; // if there is no instance and no method is being called - create one if(!instance && !is_method && (arg === undefined || $.isPlainObject(arg))) { $.jstree.create(this, arg); } // if there is an instance and no method is called - return the instance if( (instance && !is_method) || arg === true ) { result = instance || false; } // if there was a method call which returned a result - break and return the value if(result !== null && result !== undefined) { return false; } }); // if there was a method call with a valid return value - return that, otherwise continue the chain return result !== null && result !== undefined ? result : this; }; /** * used to find elements containing an instance * * __Examples__ * * $('div:jstree').each(function () { * $(this).jstree('destroy'); * }); * * @name $(':jstree') * @return {jQuery} */ $.expr.pseudos.jstree = $.expr.createPseudo(function(search) { return function(a) { return $(a).hasClass('jstree') && $(a).data('jstree') !== undefined; }; }); /** * stores all defaults for the core * @name $.jstree.defaults.core */ $.jstree.defaults.core = { /** * data configuration * * If left as `false` the HTML inside the jstree container element is used to populate the tree (that should be an unordered list with list items). * * You can also pass in a HTML string or a JSON array here. * * It is possible to pass in a standard jQuery-like AJAX config and jstree will automatically determine if the response is JSON or HTML and use that to populate the tree. * In addition to the standard jQuery ajax options here you can supply functions for `data` and `url`, the functions will be run in the current instance's scope and a param will be passed indicating which node is being loaded, the return value of those functions will be used. * * The last option is to specify a function, that function will receive the node being loaded as argument and a second param which is a function which should be called with the result. * * __Examples__ * * // AJAX * $('#tree').jstree({ * 'core' : { * 'data' : { * 'url' : '/get/children/', * 'data' : function (node) { * return { 'id' : node.id }; * } * } * }); * * // direct data * $('#tree').jstree({ * 'core' : { * 'data' : [ * 'Simple root node', * { * 'id' : 'node_2', * 'text' : 'Root node with options', * 'state' : { 'opened' : true, 'selected' : true }, * 'children' : [ { 'text' : 'Child 1' }, 'Child 2'] * } * ] * } * }); * * // function * $('#tree').jstree({ * 'core' : { * 'data' : function (obj, callback) { * callback.call(this, ['Root 1', 'Root 2']); * } * }); * * @name $.jstree.defaults.core.data */ data : false, /** * configure the various strings used throughout the tree * * You can use an object where the key is the string you need to replace and the value is your replacement. * Another option is to specify a function which will be called with an argument of the needed string and should return the replacement. * If left as `false` no replacement is made. * * __Examples__ * * $('#tree').jstree({ * 'core' : { * 'strings' : { * 'Loading ...' : 'Please wait ...' * } * } * }); * * @name $.jstree.defaults.core.strings */ strings : false, /** * determines what happens when a user tries to modify the structure of the tree * If left as `false` all operations like create, rename, delete, move or copy are prevented. * You can set this to `true` to allow all interactions or use a function to have better control. * * __Examples__ * * $('#tree').jstree({ * 'core' : { * 'check_callback' : function (operation, node, node_parent, node_position, more) { * // operation can be 'create_node', 'rename_node', 'delete_node', 'move_node', 'copy_node' or 'edit' * // in case of 'rename_node' node_position is filled with the new node name * return operation === 'rename_node' ? true : false; * } * } * }); * * @name $.jstree.defaults.core.check_callback */ check_callback : false, /** * a callback called with a single object parameter in the instance's scope when something goes wrong (operation prevented, ajax failed, etc) * @name $.jstree.defaults.core.error */ error : $.noop, /** * the open / close animation duration in milliseconds - set this to `false` to disable the animation (default is `200`) * @name $.jstree.defaults.core.animation */ animation : 200, /** * a boolean indicating if multiple nodes can be selected * @name $.jstree.defaults.core.multiple */ multiple : true, /** * theme configuration object * @name $.jstree.defaults.core.themes */ themes : { /** * the name of the theme to use (if left as `false` the default theme is used) * @name $.jstree.defaults.core.themes.name */ name : false, /** * the URL of the theme's CSS file, leave this as `false` if you have manually included the theme CSS (recommended). You can set this to `true` too which will try to autoload the theme. * @name $.jstree.defaults.core.themes.url */ url : false, /** * the location of all jstree themes - only used if `url` is set to `true` * @name $.jstree.defaults.core.themes.dir */ dir : false, /** * a boolean indicating if connecting dots are shown * @name $.jstree.defaults.core.themes.dots */ dots : true, /** * a boolean indicating if node icons are shown * @name $.jstree.defaults.core.themes.icons */ icons : true, /** * a boolean indicating if node ellipsis should be shown - this only works with a fixed with on the container * @name $.jstree.defaults.core.themes.ellipsis */ ellipsis : false, /** * a boolean indicating if the tree background is striped * @name $.jstree.defaults.core.themes.stripes */ stripes : false, /** * a string (or boolean `false`) specifying the theme variant to use (if the theme supports variants) * @name $.jstree.defaults.core.themes.variant */ variant : false, /** * a boolean specifying if a reponsive version of the theme should kick in on smaller screens (if the theme supports it). Defaults to `false`. * @name $.jstree.defaults.core.themes.responsive */ responsive : false }, /** * if left as `true` all parents of all selected nodes will be opened once the tree loads (so that all selected nodes are visible to the user) * @name $.jstree.defaults.core.expand_selected_onload */ expand_selected_onload : true, /** * if left as `true` web workers will be used to parse incoming JSON data where possible, so that the UI will not be blocked by large requests. Workers are however about 30% slower. Defaults to `true` * @name $.jstree.defaults.core.worker */ worker : true, /** * Force node text to plain text (and escape HTML). Defaults to `false` * @name $.jstree.defaults.core.force_text */ force_text : false, /** * Should the node be toggled if the text is double clicked. Defaults to `true` * @name $.jstree.defaults.core.dblclick_toggle */ dblclick_toggle : true, /** * Should the loaded nodes be part of the state. Defaults to `false` * @name $.jstree.defaults.core.loaded_state */ loaded_state : false, /** * Should the last active node be focused when the tree container is blurred and the focused again. This helps working with screen readers. Defaults to `true` * @name $.jstree.defaults.core.restore_focus */ restore_focus : true, /** * Force to compute and set "aria-setsize" and "aria-posinset" explicitly for each treeitem. * Some browsers may compute incorrect elements position and produce wrong announcements for screen readers. Defaults to `false` * @name $.jstree.defaults.core.compute_elements_positions */ compute_elements_positions : false, /** * Default keyboard shortcuts (an object where each key is the button name or combo - like 'enter', 'ctrl-space', 'p', etc and the value is the function to execute in the instance's scope) * @name $.jstree.defaults.core.keyboard */ keyboard : { 'ctrl-space': function (e) { // aria defines space only with Ctrl e.type = "click"; $(e.currentTarget).trigger(e); }, 'enter': function (e) { // enter e.type = "click"; $(e.currentTarget).trigger(e); }, 'left': function (e) { // left e.preventDefault(); if(this.is_open(e.currentTarget)) { this.close_node(e.currentTarget); } else { var o = this.get_parent(e.currentTarget); if(o && o.id !== $.jstree.root) { this.get_node(o, true).children('.jstree-anchor').trigger('focus'); } } }, 'up': function (e) { // up e.preventDefault(); var o = this.get_prev_dom(e.currentTarget); if(o && o.length) { o.children('.jstree-anchor').trigger('focus'); } }, 'right': function (e) { // right e.preventDefault(); if(this.is_closed(e.currentTarget)) { this.open_node(e.currentTarget, function (o) { this.get_node(o, true).children('.jstree-anchor').trigger('focus'); }); } else if (this.is_open(e.currentTarget)) { var o = this.get_node(e.currentTarget, true).children('.jstree-children')[0]; if(o) { $(this._firstChild(o)).children('.jstree-anchor').trigger('focus'); } } }, 'down': function (e) { // down e.preventDefault(); var o = this.get_next_dom(e.currentTarget); if(o && o.length) { o.children('.jstree-anchor').trigger('focus'); } }, '*': function (e) { // aria defines * on numpad as open_all - not very common this.open_all(); }, 'home': function (e) { // home e.preventDefault(); var o = this._firstChild(this.get_container_ul()[0]); if(o) { $(o).children('.jstree-anchor').filter(':visible').trigger('focus'); } }, 'end': function (e) { // end e.preventDefault(); this.element.find('.jstree-anchor').filter(':visible').last().trigger('focus'); }, 'f2': function (e) { // f2 - safe to include - if check_callback is false it will fail e.preventDefault(); this.edit(e.currentTarget); } } }; $.jstree.core.prototype = { /** * used to decorate an instance with a plugin. Used internally. * @private * @name plugin(deco [, opts]) * @param {String} deco the plugin to decorate with * @param {Object} opts options for the plugin * @return {jsTree} */ plugin : function (deco, opts) { var Child = $.jstree.plugins[deco]; if(Child) { this._data[deco] = {}; Child.prototype = this; return new Child(opts, this); } return this; }, /** * initialize the instance. Used internally. * @private * @name init(el, optons) * @param {DOMElement|jQuery|String} el the element we are transforming * @param {Object} options options for this instance * @trigger init.jstree, loading.jstree, loaded.jstree, ready.jstree, changed.jstree */ init : function (el, options) { this._model = { data : {}, changed : [], force_full_redraw : false, redraw_timeout : false, default_state : { loaded : true, opened : false, selected : false, disabled : false } }; this._model.data[$.jstree.root] = { id : $.jstree.root, parent : null, parents : [], children : [], children_d : [], state : { loaded : false } }; this.element = $(el).addClass('jstree jstree-' + this._id); this.settings = options; this._data.core.ready = false; this._data.core.loaded = false; this._data.core.rtl = (this.element.css("direction") === "rtl"); this.element[this._data.core.rtl ? 'addClass' : 'removeClass']("jstree-rtl"); this.element.attr('role','tree'); if(this.settings.core.multiple) { this.element.attr('aria-multiselectable', true); } if(!this.element.attr('tabindex')) { this.element.attr('tabindex','0'); } this.bind(); /** * triggered after all events are bound * @event * @name init.jstree */ this.trigger("init"); this._data.core.original_container_html = this.element.find(" > ul > li").clone(true); this._data.core.original_container_html .find("li").addBack() .contents().filter(function() { return this.nodeType === 3 && (!this.nodeValue || /^\s+$/.test(this.nodeValue)); }) .remove(); this.element.html("<"+"ul class='jstree-container-ul jstree-children' role='group'><"+"li id='j"+this._id+"_loading' class='jstree-initial-node jstree-loading jstree-leaf jstree-last' role='none'><"+"a class='jstree-anchor' role='treeitem' href='#'>" + this.get_string("Loading ...") + ""); this.element.attr('aria-activedescendant','j' + this._id + '_loading'); this._data.core.li_height = this.get_container_ul().children("li").first().outerHeight() || 24; this._data.core.node = this._create_prototype_node(); /** * triggered after the loading text is shown and before loading starts * @event * @name loading.jstree */ this.trigger("loading"); this.load_node($.jstree.root); }, /** * destroy an instance * @name destroy() * @param {Boolean} keep_html if not set to `true` the container will be emptied, otherwise the current DOM elements will be kept intact */ destroy : function (keep_html) { /** * triggered before the tree is destroyed * @event * @name destroy.jstree */ this.trigger("destroy"); if(this._wrk) { try { window.URL.revokeObjectURL(this._wrk); this._wrk = null; } catch (ignore) { } } if(!keep_html) { this.element.empty(); } this.teardown(); }, /** * Create a prototype node * @name _create_prototype_node() * @return {DOMElement} */ _create_prototype_node : function () { var _node = document.createElement('LI'), _temp1, _temp2; _node.setAttribute('role', 'none'); _temp1 = document.createElement('I'); _temp1.className = 'jstree-icon jstree-ocl'; _temp1.setAttribute('role', 'presentation'); _node.appendChild(_temp1); _temp1 = document.createElement('A'); _temp1.className = 'jstree-anchor'; _temp1.setAttribute('href','#'); _temp1.setAttribute('tabindex','-1'); _temp1.setAttribute('role', 'treeitem'); _temp2 = document.createElement('I'); _temp2.className = 'jstree-icon jstree-themeicon'; _temp2.setAttribute('role', 'presentation'); _temp1.appendChild(_temp2); _node.appendChild(_temp1); _temp1 = _temp2 = null; return _node; }, _kbevent_to_func : function (e) { var keys = { 8: "Backspace", 9: "Tab", 13: "Enter", 19: "Pause", 27: "Esc", 32: "Space", 33: "PageUp", 34: "PageDown", 35: "End", 36: "Home", 37: "Left", 38: "Up", 39: "Right", 40: "Down", 44: "Print", 45: "Insert", 46: "Delete", 96: "Numpad0", 97: "Numpad1", 98: "Numpad2", 99 : "Numpad3", 100: "Numpad4", 101: "Numpad5", 102: "Numpad6", 103: "Numpad7", 104: "Numpad8", 105: "Numpad9", '-13': "NumpadEnter", 112: "F1", 113: "F2", 114: "F3", 115: "F4", 116: "F5", 117: "F6", 118: "F7", 119: "F8", 120: "F9", 121: "F10", 122: "F11", 123: "F12", 144: "Numlock", 145: "Scrolllock", 16: 'Shift', 17: 'Ctrl', 18: 'Alt', 48: '0', 49: '1', 50: '2', 51: '3', 52: '4', 53: '5', 54: '6', 55: '7', 56: '8', 57: '9', 59: ';', 61: '=', 65: 'a', 66: 'b', 67: 'c', 68: 'd', 69: 'e', 70: 'f', 71: 'g', 72: 'h', 73: 'i', 74: 'j', 75: 'k', 76: 'l', 77: 'm', 78: 'n', 79: 'o', 80: 'p', 81: 'q', 82: 'r', 83: 's', 84: 't', 85: 'u', 86: 'v', 87: 'w', 88: 'x', 89: 'y', 90: 'z', 107: '+', 109: '-', 110: '.', 186: ';', 187: '=', 188: ',', 189: '-', 190: '.', 191: '/', 192: '`', 219: '[', 220: '\\',221: ']', 222: "'", 111: '/', 106: '*', 173: '-' }; var parts = []; if (e.ctrlKey) { parts.push('ctrl'); } if (e.altKey) { parts.push('alt'); } if (e.shiftKey) { parts.push('shift'); } parts.push(keys[e.which] ? keys[e.which].toLowerCase() : e.which); parts = parts.sort().join('-').toLowerCase(); if (parts === 'shift-shift' || parts === 'ctrl-ctrl' || parts === 'alt-alt') { return null; } var kb = this.settings.core.keyboard, i, tmp; for (i in kb) { if (kb.hasOwnProperty(i)) { tmp = i; if (tmp !== '-' && tmp !== '+') { tmp = tmp.replace('--', '-MINUS').replace('+-', '-MINUS').replace('++', '-PLUS').replace('-+', '-PLUS'); tmp = tmp.split(/-|\+/).sort().join('-').replace('MINUS', '-').replace('PLUS', '+').toLowerCase(); } if (tmp === parts) { return kb[i]; } } } return null; }, /** * part of the destroying of an instance. Used internally. * @private * @name teardown() */ teardown : function () { this.unbind(); this.element .removeClass('jstree') .removeData('jstree') .find("[class^='jstree']") .addBack() .attr("class", function () { return this.className.replace(/jstree[^ ]*|$/ig,''); }); this.element = null; }, /** * bind all events. Used internally. * @private * @name bind() */ bind : function () { var word = '', tout = null, was_click = 0; this.element .on("dblclick.jstree", function (e) { if(e.target.tagName && e.target.tagName.toLowerCase() === "input") { return true; } if(document.selection && document.selection.empty) { document.selection.empty(); } else { if(window.getSelection) { var sel = window.getSelection(); try { sel.removeAllRanges(); sel.collapse(); } catch (ignore) { } } } }) .on("mousedown.jstree", function (e) { if(e.target === this.element[0]) { e.preventDefault(); // prevent losing focus when clicking scroll arrows (FF, Chrome) was_click = +(new Date()); // ie does not allow to prevent losing focus } }.bind(this)) .on("mousedown.jstree", ".jstree-ocl", function (e) { e.preventDefault(); // prevent any node inside from losing focus when clicking the open/close icon }) .on("click.jstree", ".jstree-ocl", function (e) { this.toggle_node(e.target); }.bind(this)) .on("dblclick.jstree", ".jstree-anchor", function (e) { if(e.target.tagName && e.target.tagName.toLowerCase() === "input") { return true; } if(this.settings.core.dblclick_toggle) { this.toggle_node(e.target); } }.bind(this)) .on("click.jstree", ".jstree-anchor", function (e) { e.preventDefault(); if(e.currentTarget !== document.activeElement) { $(e.currentTarget).trigger('focus'); } this.activate_node(e.currentTarget, e); }.bind(this)) .on('keydown.jstree', '.jstree-anchor', function (e) { if(e.target.tagName && e.target.tagName.toLowerCase() === "input") { return true; } if(this._data.core.rtl) { if(e.which === 37) { e.which = 39; } else if(e.which === 39) { e.which = 37; } } var f = this._kbevent_to_func(e); if (f) { var r = f.call(this, e); if (r === false || r === true) { return r; } } }.bind(this)) .on("load_node.jstree", function (e, data) { if(data.status) { if(data.node.id === $.jstree.root && !this._data.core.loaded) { this._data.core.loaded = true; if(this._firstChild(this.get_container_ul()[0])) { this.element.attr('aria-activedescendant',this._firstChild(this.get_container_ul()[0]).id); } /** * triggered after the root node is loaded for the first time * @event * @name loaded.jstree */ this.trigger("loaded"); } if(!this._data.core.ready) { setTimeout(function() { if(this.element && !this.get_container_ul().find('.jstree-loading').length) { this._data.core.ready = true; if(this._data.core.selected.length) { if(this.settings.core.expand_selected_onload) { var tmp = [], i, j; for(i = 0, j = this._data.core.selected.length; i < j; i++) { tmp = tmp.concat(this._model.data[this._data.core.selected[i]].parents); } tmp = $.vakata.array_unique(tmp); for(i = 0, j = tmp.length; i < j; i++) { this.open_node(tmp[i], false, 0); } } this.trigger('changed', { 'action' : 'ready', 'selected' : this._data.core.selected }); } /** * triggered after all nodes are finished loading * @event * @name ready.jstree */ this.trigger("ready"); } }.bind(this), 0); } } }.bind(this)) // quick searching when the tree is focused .on('keypress.jstree', function (e) { if(e.target.tagName && e.target.tagName.toLowerCase() === "input") { return true; } if(tout) { clearTimeout(tout); } tout = setTimeout(function () { word = ''; }, 500); var chr = String.fromCharCode(e.which).toLowerCase(), col = this.element.find('.jstree-anchor').filter(':visible'), ind = col.index(document.activeElement) || 0, end = false; word += chr; // match for whole word from current node down (including the current node) if(word.length > 1) { col.slice(ind).each(function (i, v) { if($(v).text().toLowerCase().indexOf(word) === 0) { $(v).trigger('focus'); end = true; return false; } }.bind(this)); if(end) { return; } // match for whole word from the beginning of the tree col.slice(0, ind).each(function (i, v) { if($(v).text().toLowerCase().indexOf(word) === 0) { $(v).trigger('focus'); end = true; return false; } }.bind(this)); if(end) { return; } } // list nodes that start with that letter (only if word consists of a single char) if(new RegExp('^' + chr.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&') + '+$').test(word)) { // search for the next node starting with that letter col.slice(ind + 1).each(function (i, v) { if($(v).text().toLowerCase().charAt(0) === chr) { $(v).trigger('focus'); end = true; return false; } }.bind(this)); if(end) { return; } // search from the beginning col.slice(0, ind + 1).each(function (i, v) { if($(v).text().toLowerCase().charAt(0) === chr) { $(v).trigger('focus'); end = true; return false; } }.bind(this)); if(end) { return; } } }.bind(this)) // THEME RELATED .on("init.jstree", function () { var s = this.settings.core.themes; this._data.core.themes.dots = s.dots; this._data.core.themes.stripes = s.stripes; this._data.core.themes.icons = s.icons; this._data.core.themes.ellipsis = s.ellipsis; this.set_theme(s.name || "default", s.url); this.set_theme_variant(s.variant); }.bind(this)) .on("loading.jstree", function () { this[ this._data.core.themes.dots ? "show_dots" : "hide_dots" ](); this[ this._data.core.themes.icons ? "show_icons" : "hide_icons" ](); this[ this._data.core.themes.stripes ? "show_stripes" : "hide_stripes" ](); this[ this._data.core.themes.ellipsis ? "show_ellipsis" : "hide_ellipsis" ](); }.bind(this)) .on('blur.jstree', '.jstree-anchor', function (e) { this._data.core.focused = null; $(e.currentTarget).filter('.jstree-hovered').trigger('mouseleave'); this.element.attr('tabindex', '0'); $(e.currentTarget).attr('tabindex', '-1'); }.bind(this)) .on('focus.jstree', '.jstree-anchor', function (e) { var tmp = this.get_node(e.currentTarget); if(tmp && (tmp.id || tmp.id === 0)) { this._data.core.focused = tmp.id; } this.element.find('.jstree-hovered').not(e.currentTarget).trigger('mouseleave'); $(e.currentTarget).trigger('mouseenter'); this.element.attr('tabindex', '-1'); $(e.currentTarget).attr('tabindex', '0'); }.bind(this)) .on('focus.jstree', function () { if(+(new Date()) - was_click > 500 && !this._data.core.focused && this.settings.core.restore_focus) { was_click = 0; var act = this.get_node(this.element.attr('aria-activedescendant'), true); if(act) { act.find('> .jstree-anchor').trigger('focus'); } } }.bind(this)) .on('mouseenter.jstree', '.jstree-anchor', function (e) { this.hover_node(e.currentTarget); }.bind(this)) .on('mouseleave.jstree', '.jstree-anchor', function (e) { this.dehover_node(e.currentTarget); }.bind(this)); }, /** * part of the destroying of an instance. Used internally. * @private * @name unbind() */ unbind : function () { this.element.off('.jstree'); $(document).off('.jstree-' + this._id); }, /** * trigger an event. Used internally. * @private * @name trigger(ev [, data]) * @param {String} ev the name of the event to trigger * @param {Object} data additional data to pass with the event */ trigger : function (ev, data) { if(!data) { data = {}; } data.instance = this; this.element.triggerHandler(ev.replace('.jstree','') + '.jstree', data); }, /** * returns the jQuery extended instance container * @name get_container() * @return {jQuery} */ get_container : function () { return this.element; }, /** * returns the jQuery extended main UL node inside the instance container. Used internally. * @private * @name get_container_ul() * @return {jQuery} */ get_container_ul : function () { return this.element.children(".jstree-children").first(); }, /** * gets string replacements (localization). Used internally. * @private * @name get_string(key) * @param {String} key * @return {String} */ get_string : function (key) { var a = this.settings.core.strings; if($.vakata.is_function(a)) { return a.call(this, key); } if(a && a[key]) { return a[key]; } return key; }, /** * gets the first child of a DOM node. Used internally. * @private * @name _firstChild(dom) * @param {DOMElement} dom * @return {DOMElement} */ _firstChild : function (dom) { dom = dom ? dom.firstChild : null; while(dom !== null && dom.nodeType !== 1) { dom = dom.nextSibling; } return dom; }, /** * gets the next sibling of a DOM node. Used internally. * @private * @name _nextSibling(dom) * @param {DOMElement} dom * @return {DOMElement} */ _nextSibling : function (dom) { dom = dom ? dom.nextSibling : null; while(dom !== null && dom.nodeType !== 1) { dom = dom.nextSibling; } return dom; }, /** * gets the previous sibling of a DOM node. Used internally. * @private * @name _previousSibling(dom) * @param {DOMElement} dom * @return {DOMElement} */ _previousSibling : function (dom) { dom = dom ? dom.previousSibling : null; while(dom !== null && dom.nodeType !== 1) { dom = dom.previousSibling; } return dom; }, /** * get the JSON representation of a node (or the actual jQuery extended DOM node) by using any input (child DOM element, ID string, selector, etc) * @name get_node(obj [, as_dom]) * @param {mixed} obj * @param {Boolean} as_dom * @return {Object|jQuery} */ get_node : function (obj, as_dom) { if(obj && (obj.id || obj.id === 0)) { obj = obj.id; } if (obj instanceof $ && obj.length && obj[0].id) { obj = obj[0].id; } var dom; try { if(this._model.data[obj]) { obj = this._model.data[obj]; } else if(typeof obj === "string" && this._model.data[obj.replace(/^#/, '')]) { obj = this._model.data[obj.replace(/^#/, '')]; } else if(typeof obj === "string" && (dom = $('#' + obj.replace($.jstree.idregex,'\\$&'), this.element)).length && this._model.data[dom.closest('.jstree-node').attr('id')]) { obj = this._model.data[dom.closest('.jstree-node').attr('id')]; } else if((dom = this.element.find(obj)).length && this._model.data[dom.closest('.jstree-node').attr('id')]) { obj = this._model.data[dom.closest('.jstree-node').attr('id')]; } else if((dom = this.element.find(obj)).length && dom.hasClass('jstree')) { obj = this._model.data[$.jstree.root]; } else { return false; } if(as_dom) { obj = obj.id === $.jstree.root ? this.element : $('#' + obj.id.replace($.jstree.idregex,'\\$&'), this.element); } return obj; } catch (ex) { return false; } }, /** * get the path to a node, either consisting of node texts, or of node IDs, optionally glued together (otherwise an array) * @name get_path(obj [, glue, ids]) * @param {mixed} obj the node * @param {String} glue if you want the path as a string - pass the glue here (for example '/'), if a falsy value is supplied here, an array is returned * @param {Boolean} ids if set to true build the path using ID, otherwise node text is used * @return {mixed} */ get_path : function (obj, glue, ids) { obj = obj.parents ? obj : this.get_node(obj); if(!obj || obj.id === $.jstree.root || !obj.parents) { return false; } var i, j, p = []; p.push(ids ? obj.id : obj.text); for(i = 0, j = obj.parents.length; i < j; i++) { p.push(ids ? obj.parents[i] : this.get_text(obj.parents[i])); } p = p.reverse().slice(1); return glue ? p.join(glue) : p; }, /** * get the next visible node that is below the `obj` node. If `strict` is set to `true` only sibling nodes are returned. * @name get_next_dom(obj [, strict]) * @param {mixed} obj * @param {Boolean} strict * @return {jQuery} */ get_next_dom : function (obj, strict) { var tmp; obj = this.get_node(obj, true); if(obj[0] === this.element[0]) { tmp = this._firstChild(this.get_container_ul()[0]); while (tmp && tmp.offsetHeight === 0) { tmp = this._nextSibling(tmp); } return tmp ? $(tmp) : false; } if(!obj || !obj.length) { return false; } if(strict) { tmp = obj[0]; do { tmp = this._nextSibling(tmp); } while (tmp && tmp.offsetHeight === 0); return tmp ? $(tmp) : false; } if(obj.hasClass("jstree-open")) { tmp = this._firstChild(obj.children('.jstree-children')[0]); while (tmp && tmp.offsetHeight === 0) { tmp = this._nextSibling(tmp); } if(tmp !== null) { return $(tmp); } } tmp = obj[0]; do { tmp = this._nextSibling(tmp); } while (tmp && tmp.offsetHeight === 0); if(tmp !== null) { return $(tmp); } return obj.parentsUntil(".jstree",".jstree-node").nextAll(".jstree-node:visible").first(); }, /** * get the previous visible node that is above the `obj` node. If `strict` is set to `true` only sibling nodes are returned. * @name get_prev_dom(obj [, strict]) * @param {mixed} obj * @param {Boolean} strict * @return {jQuery} */ get_prev_dom : function (obj, strict) { var tmp; obj = this.get_node(obj, true); if(obj[0] === this.element[0]) { tmp = this.get_container_ul()[0].lastChild; while (tmp && tmp.offsetHeight === 0) { tmp = this._previousSibling(tmp); } return tmp ? $(tmp) : false; } if(!obj || !obj.length) { return false; } if(strict) { tmp = obj[0]; do { tmp = this._previousSibling(tmp); } while (tmp && tmp.offsetHeight === 0); return tmp ? $(tmp) : false; } tmp = obj[0]; do { tmp = this._previousSibling(tmp); } while (tmp && tmp.offsetHeight === 0); if(tmp !== null) { obj = $(tmp); while(obj.hasClass("jstree-open")) { obj = obj.children(".jstree-children").first().children(".jstree-node:visible:last"); } return obj; } tmp = obj[0].parentNode.parentNode; return tmp && tmp.className && tmp.className.indexOf('jstree-node') !== -1 ? $(tmp) : false; }, /** * get the parent ID of a node * @name get_parent(obj) * @param {mixed} obj * @return {String} */ get_parent : function (obj) { obj = this.get_node(obj); if(!obj || obj.id === $.jstree.root) { return false; } return obj.parent; }, /** * get a jQuery collection of all the children of a node (node must be rendered), returns false on error * @name get_children_dom(obj) * @param {mixed} obj * @return {jQuery} */ get_children_dom : function (obj) { obj = this.get_node(obj, true); if(obj[0] === this.element[0]) { return this.get_container_ul().children(".jstree-node"); } if(!obj || !obj.length) { return false; } return obj.children(".jstree-children").children(".jstree-node"); }, /** * checks if a node has children * @name is_parent(obj) * @param {mixed} obj * @return {Boolean} */ is_parent : function (obj) { obj = this.get_node(obj); return obj && (obj.state.loaded === false || obj.children.length > 0); }, /** * checks if a node is loaded (its children are available) * @name is_loaded(obj) * @param {mixed} obj * @return {Boolean} */ is_loaded : function (obj) { obj = this.get_node(obj); return obj && obj.state.loaded; }, /** * check if a node is currently loading (fetching children) * @name is_loading(obj) * @param {mixed} obj * @return {Boolean} */ is_loading : function (obj) { obj = this.get_node(obj); return obj && obj.state && obj.state.loading; }, /** * check if a node is opened * @name is_open(obj) * @param {mixed} obj * @return {Boolean} */ is_open : function (obj) { obj = this.get_node(obj); return obj && obj.state.opened; }, /** * check if a node is in a closed state * @name is_closed(obj) * @param {mixed} obj * @return {Boolean} */ is_closed : function (obj) { obj = this.get_node(obj); return obj && this.is_parent(obj) && !obj.state.opened; }, /** * check if a node has no children * @name is_leaf(obj) * @param {mixed} obj * @return {Boolean} */ is_leaf : function (obj) { return !this.is_parent(obj); }, /** * loads a node (fetches its children using the `core.data` setting). Multiple nodes can be passed to by using an array. * @name load_node(obj [, callback]) * @param {mixed} obj * @param {function} callback a function to be executed once loading is complete, the function is executed in the instance's scope and receives two arguments - the node and a boolean status * @return {Boolean} * @trigger load_node.jstree */ load_node : function (obj, callback) { var dom = this.get_node(obj, true), k, l, i, j, c; if($.vakata.is_array(obj)) { this._load_nodes(obj.slice(), callback); return true; } obj = this.get_node(obj); if(!obj) { if(callback) { callback.call(this, obj, false); } return false; } // if(obj.state.loading) { } // the node is already loading - just wait for it to load and invoke callback? but if called implicitly it should be loaded again? if(obj.state.loaded) { obj.state.loaded = false; for(i = 0, j = obj.parents.length; i < j; i++) { this._model.data[obj.parents[i]].children_d = $.vakata.array_filter(this._model.data[obj.parents[i]].children_d, function (v) { return $.inArray(v, obj.children_d) === -1; }); } for(k = 0, l = obj.children_d.length; k < l; k++) { if(this._model.data[obj.children_d[k]].state.selected) { c = true; } delete this._model.data[obj.children_d[k]]; } if (c) { this._data.core.selected = $.vakata.array_filter(this._data.core.selected, function (v) { return $.inArray(v, obj.children_d) === -1; }); } obj.children = []; obj.children_d = []; if(c) { this.trigger('changed', { 'action' : 'load_node', 'node' : obj, 'selected' : this._data.core.selected }); } } obj.state.failed = false; obj.state.loading = true; if (obj.id !== $.jstree.root) { dom.children(".jstree-anchor").attr('aria-busy', true); } else { dom.attr('aria-busy', true); } dom.addClass("jstree-loading"); this._load_node(obj, function (status) { obj = this._model.data[obj.id]; obj.state.loading = false; obj.state.loaded = status; obj.state.failed = !obj.state.loaded; var dom = this.get_node(obj, true), i = 0, j = 0, m = this._model.data, has_children = false; for(i = 0, j = obj.children.length; i < j; i++) { if(m[obj.children[i]] && !m[obj.children[i]].state.hidden) { has_children = true; break; } } if(obj.state.loaded && dom && dom.length) { dom.removeClass('jstree-closed jstree-open jstree-leaf'); if (!has_children) { dom.addClass('jstree-leaf'); } else { if (obj.id !== '#') { dom.addClass(obj.state.opened ? 'jstree-open' : 'jstree-closed'); } } } if (obj.id !== $.jstree.root) { dom.children(".jstree-anchor").attr('aria-busy', false); } else { dom.attr('aria-busy', false); } dom.removeClass("jstree-loading"); /** * triggered after a node is loaded * @event * @name load_node.jstree * @param {Object} node the node that was loading * @param {Boolean} status was the node loaded successfully */ this.trigger('load_node', { "node" : obj, "status" : status }); if(callback) { callback.call(this, obj, status); } }.bind(this)); return true; }, /** * load an array of nodes (will also load unavailable nodes as soon as they appear in the structure). Used internally. * @private * @name _load_nodes(nodes [, callback]) * @param {array} nodes * @param {function} callback a function to be executed once loading is complete, the function is executed in the instance's scope and receives one argument - the array passed to _load_nodes */ _load_nodes : function (nodes, callback, is_callback, force_reload) { var r = true, c = function () { this._load_nodes(nodes, callback, true); }, m = this._model.data, i, j, tmp = []; for(i = 0, j = nodes.length; i < j; i++) { if(m[nodes[i]] && ( (!m[nodes[i]].state.loaded && !m[nodes[i]].state.failed) || (!is_callback && force_reload) )) { if(!this.is_loading(nodes[i])) { this.load_node(nodes[i], c); } r = false; } } if(r) { for(i = 0, j = nodes.length; i < j; i++) { if(m[nodes[i]] && m[nodes[i]].state.loaded) { tmp.push(nodes[i]); } } if(callback && !callback.done) { callback.call(this, tmp); callback.done = true; } } }, /** * loads all unloaded nodes * @name load_all([obj, callback]) * @param {mixed} obj the node to load recursively, omit to load all nodes in the tree * @param {function} callback a function to be executed once loading all the nodes is complete, * @trigger load_all.jstree */ load_all : function (obj, callback) { if(!obj) { obj = $.jstree.root; } obj = this.get_node(obj); if(!obj) { return false; } var to_load = [], m = this._model.data, c = m[obj.id].children_d, i, j; if(obj.state && !obj.state.loaded) { to_load.push(obj.id); } for(i = 0, j = c.length; i < j; i++) { if(m[c[i]] && m[c[i]].state && !m[c[i]].state.loaded) { to_load.push(c[i]); } } if(to_load.length) { this._load_nodes(to_load, function () { this.load_all(obj, callback); }); } else { /** * triggered after a load_all call completes * @event * @name load_all.jstree * @param {Object} node the recursively loaded node */ if(callback) { callback.call(this, obj); } this.trigger('load_all', { "node" : obj }); } }, /** * handles the actual loading of a node. Used only internally. * @private * @name _load_node(obj [, callback]) * @param {mixed} obj * @param {function} callback a function to be executed once loading is complete, the function is executed in the instance's scope and receives one argument - a boolean status * @return {Boolean} */ _load_node : function (obj, callback) { var s = this.settings.core.data, t; var notTextOrCommentNode = function notTextOrCommentNode () { return this.nodeType !== 3 && this.nodeType !== 8; }; // use original HTML if(!s) { if(obj.id === $.jstree.root) { return this._append_html_data(obj, this._data.core.original_container_html.clone(true), function (status) { callback.call(this, status); }); } else { return callback.call(this, false); } // return callback.call(this, obj.id === $.jstree.root ? this._append_html_data(obj, this._data.core.original_container_html.clone(true)) : false); } if($.vakata.is_function(s)) { return s.call(this, obj, function (d) { if(d === false) { callback.call(this, false); } else { this[typeof d === 'string' ? '_append_html_data' : '_append_json_data'](obj, typeof d === 'string' ? $($.parseHTML(d)).filter(notTextOrCommentNode) : d, function (status) { callback.call(this, status); }); } // return d === false ? callback.call(this, false) : callback.call(this, this[typeof d === 'string' ? '_append_html_data' : '_append_json_data'](obj, typeof d === 'string' ? $(d) : d)); }.bind(this)); } if(typeof s === 'object') { if(s.url) { s = $.extend(true, {}, s); if($.vakata.is_function(s.url)) { s.url = s.url.call(this, obj); } if($.vakata.is_function(s.data)) { s.data = s.data.call(this, obj); } return $.ajax(s) .done(function (d,t,x) { var type = x.getResponseHeader('Content-Type'); if((type && type.indexOf('json') !== -1) || typeof d === "object") { return this._append_json_data(obj, d, function (status) { callback.call(this, status); }); //return callback.call(this, this._append_json_data(obj, d)); } if((type && type.indexOf('html') !== -1) || typeof d === "string") { return this._append_html_data(obj, $($.parseHTML(d)).filter(notTextOrCommentNode), function (status) { callback.call(this, status); }); // return callback.call(this, this._append_html_data(obj, $(d))); } this._data.core.last_error = { 'error' : 'ajax', 'plugin' : 'core', 'id' : 'core_04', 'reason' : 'Could not load node', 'data' : JSON.stringify({ 'id' : obj.id, 'xhr' : x }) }; this.settings.core.error.call(this, this._data.core.last_error); return callback.call(this, false); }.bind(this)) .fail(function (f) { this._data.core.last_error = { 'error' : 'ajax', 'plugin' : 'core', 'id' : 'core_04', 'reason' : 'Could not load node', 'data' : JSON.stringify({ 'id' : obj.id, 'xhr' : f }) }; callback.call(this, false); this.settings.core.error.call(this, this._data.core.last_error); }.bind(this)); } if ($.vakata.is_array(s)) { t = $.extend(true, [], s); } else if ($.isPlainObject(s)) { t = $.extend(true, {}, s); } else { t = s; } if(obj.id === $.jstree.root) { return this._append_json_data(obj, t, function (status) { callback.call(this, status); }); } else { this._data.core.last_error = { 'error' : 'nodata', 'plugin' : 'core', 'id' : 'core_05', 'reason' : 'Could not load node', 'data' : JSON.stringify({ 'id' : obj.id }) }; this.settings.core.error.call(this, this._data.core.last_error); return callback.call(this, false); } //return callback.call(this, (obj.id === $.jstree.root ? this._append_json_data(obj, t) : false) ); } if(typeof s === 'string') { if(obj.id === $.jstree.root) { return this._append_html_data(obj, $($.parseHTML(s)).filter(notTextOrCommentNode), function (status) { callback.call(this, status); }); } else { this._data.core.last_error = { 'error' : 'nodata', 'plugin' : 'core', 'id' : 'core_06', 'reason' : 'Could not load node', 'data' : JSON.stringify({ 'id' : obj.id }) }; this.settings.core.error.call(this, this._data.core.last_error); return callback.call(this, false); } //return callback.call(this, (obj.id === $.jstree.root ? this._append_html_data(obj, $(s)) : false) ); } return callback.call(this, false); }, /** * adds a node to the list of nodes to redraw. Used only internally. * @private * @name _node_changed(obj [, callback]) * @param {mixed} obj */ _node_changed : function (obj) { obj = this.get_node(obj); if (obj && $.inArray(obj.id, this._model.changed) === -1) { this._model.changed.push(obj.id); } }, /** * appends HTML content to the tree. Used internally. * @private * @name _append_html_data(obj, data) * @param {mixed} obj the node to append to * @param {String} data the HTML string to parse and append * @trigger model.jstree, changed.jstree */ _append_html_data : function (dom, data, cb) { dom = this.get_node(dom); dom.children = []; dom.children_d = []; var dat = data.is('ul') ? data.children() : data, par = dom.id, chd = [], dpc = [], m = this._model.data, p = m[par], s = this._data.core.selected.length, tmp, i, j; dat.each(function (i, v) { tmp = this._parse_model_from_html($(v), par, p.parents.concat()); if(tmp) { chd.push(tmp); dpc.push(tmp); if(m[tmp].children_d.length) { dpc = dpc.concat(m[tmp].children_d); } } }.bind(this)); p.children = chd; p.children_d = dpc; for(i = 0, j = p.parents.length; i < j; i++) { m[p.parents[i]].children_d = m[p.parents[i]].children_d.concat(dpc); } /** * triggered when new data is inserted to the tree model * @event * @name model.jstree * @param {Array} nodes an array of node IDs * @param {String} parent the parent ID of the nodes */ this.trigger('model', { "nodes" : dpc, 'parent' : par }); if(par !== $.jstree.root) { this._node_changed(par); this.redraw(); } else { this.get_container_ul().children('.jstree-initial-node').remove(); this.redraw(true); } if(this._data.core.selected.length !== s) { this.trigger('changed', { 'action' : 'model', 'selected' : this._data.core.selected }); } cb.call(this, true); }, /** * appends JSON content to the tree. Used internally. * @private * @name _append_json_data(obj, data) * @param {mixed} obj the node to append to * @param {String} data the JSON object to parse and append * @param {Boolean} force_processing internal param - do not set * @trigger model.jstree, changed.jstree */ _append_json_data : function (dom, data, cb, force_processing) { if(this.element === null) { return; } dom = this.get_node(dom); dom.children = []; dom.children_d = []; // *%$@!!! if(data.d) { data = data.d; if(typeof data === "string") { data = JSON.parse(data); } } if(!$.vakata.is_array(data)) { data = [data]; } var w = null, args = { 'df' : this._model.default_state, 'dat' : data, 'par' : dom.id, 'm' : this._model.data, 't_id' : this._id, 't_cnt' : this._cnt, 'sel' : this._data.core.selected }, inst = this, func = function (data, undefined) { if(data.data) { data = data.data; } var dat = data.dat, par = data.par, chd = [], dpc = [], add = [], df = data.df, t_id = data.t_id, t_cnt = data.t_cnt, m = data.m, p = m[par], sel = data.sel, tmp, i, j, rslt, parse_flat = function (d, p, ps) { if(!ps) { ps = []; } else { ps = ps.concat(); } if(p) { ps.unshift(p); } var tid = d.id.toString(), i, j, c, e, tmp = { id : tid, text : d.text || '', icon : d.icon !== undefined ? d.icon : true, parent : p, parents : ps, children : d.children || [], children_d : d.children_d || [], data : d.data, state : { }, li_attr : { id : false }, a_attr : { href : '#' }, original : false }; for(i in df) { if(df.hasOwnProperty(i)) { tmp.state[i] = df[i]; } } if(d && d.data && d.data.jstree && d.data.jstree.icon) { tmp.icon = d.data.jstree.icon; } if(tmp.icon === undefined || tmp.icon === null || tmp.icon === "") { tmp.icon = true; } if(d && d.data) { tmp.data = d.data; if(d.data.jstree) { for(i in d.data.jstree) { if(d.data.jstree.hasOwnProperty(i)) { tmp.state[i] = d.data.jstree[i]; } } } } if(d && typeof d.state === 'object') { for (i in d.state) { if(d.state.hasOwnProperty(i)) { tmp.state[i] = d.state[i]; } } } if(d && typeof d.li_attr === 'object') { for (i in d.li_attr) { if(d.li_attr.hasOwnProperty(i)) { tmp.li_attr[i] = d.li_attr[i]; } } } if(!tmp.li_attr.id) { tmp.li_attr.id = tid; } if(d && typeof d.a_attr === 'object') { for (i in d.a_attr) { if(d.a_attr.hasOwnProperty(i)) { tmp.a_attr[i] = d.a_attr[i]; } } } if(d && d.children && d.children === true) { tmp.state.loaded = false; tmp.children = []; tmp.children_d = []; } m[tmp.id] = tmp; for(i = 0, j = tmp.children.length; i < j; i++) { c = parse_flat(m[tmp.children[i]], tmp.id, ps); e = m[c]; tmp.children_d.push(c); if(e.children_d.length) { tmp.children_d = tmp.children_d.concat(e.children_d); } } delete d.data; delete d.children; m[tmp.id].original = d; if(tmp.state.selected) { add.push(tmp.id); } return tmp.id; }, parse_nest = function (d, p, ps) { if(!ps) { ps = []; } else { ps = ps.concat(); } if(p) { ps.unshift(p); } var tid = false, i, j, c, e, tmp; do { tid = 'j' + t_id + '_' + (++t_cnt); } while(m[tid]); tmp = { id : false, text : typeof d === 'string' ? d : '', icon : typeof d === 'object' && d.icon !== undefined ? d.icon : true, parent : p, parents : ps, children : [], children_d : [], data : null, state : { }, li_attr : { id : false }, a_attr : { href : '#' }, original : false }; for(i in df) { if(df.hasOwnProperty(i)) { tmp.state[i] = df[i]; } } if(d && (d.id || d.id === 0)) { tmp.id = d.id.toString(); } if(d && d.text) { tmp.text = d.text; } if(d && d.data && d.data.jstree && d.data.jstree.icon) { tmp.icon = d.data.jstree.icon; } if(tmp.icon === undefined || tmp.icon === null || tmp.icon === "") { tmp.icon = true; } if(d && d.data) { tmp.data = d.data; if(d.data.jstree) { for(i in d.data.jstree) { if(d.data.jstree.hasOwnProperty(i)) { tmp.state[i] = d.data.jstree[i]; } } } } if(d && typeof d.state === 'object') { for (i in d.state) { if(d.state.hasOwnProperty(i)) { tmp.state[i] = d.state[i]; } } } if(d && typeof d.li_attr === 'object') { for (i in d.li_attr) { if(d.li_attr.hasOwnProperty(i)) { tmp.li_attr[i] = d.li_attr[i]; } } } if(tmp.li_attr.id && !(tmp.id || tmp.id === 0)) { tmp.id = tmp.li_attr.id.toString(); } if(!(tmp.id || tmp.id === 0)) { tmp.id = tid; } if(!tmp.li_attr.id) { tmp.li_attr.id = tmp.id; } if(d && typeof d.a_attr === 'object') { for (i in d.a_attr) { if(d.a_attr.hasOwnProperty(i)) { tmp.a_attr[i] = d.a_attr[i]; } } } if(d && d.children && d.children.length) { for(i = 0, j = d.children.length; i < j; i++) { c = parse_nest(d.children[i], tmp.id, ps); e = m[c]; tmp.children.push(c); if(e.children_d.length) { tmp.children_d = tmp.children_d.concat(e.children_d); } } tmp.children_d = tmp.children_d.concat(tmp.children); } if(d && d.children && d.children === true) { tmp.state.loaded = false; tmp.children = []; tmp.children_d = []; } delete d.data; delete d.children; tmp.original = d; m[tmp.id] = tmp; if(tmp.state.selected) { add.push(tmp.id); } return tmp.id; }; if(dat.length && dat[0].id !== undefined && dat[0].parent !== undefined) { // Flat JSON support (for easy import from DB): // 1) convert to object (foreach) for(i = 0, j = dat.length; i < j; i++) { if(!dat[i].children) { dat[i].children = []; } if(!dat[i].state) { dat[i].state = {}; } m[dat[i].id.toString()] = dat[i]; } // 2) populate children (foreach) for(i = 0, j = dat.length; i < j; i++) { if (!m[dat[i].parent.toString()]) { if (typeof inst !== "undefined") { inst._data.core.last_error = { 'error' : 'parse', 'plugin' : 'core', 'id' : 'core_07', 'reason' : 'Node with invalid parent', 'data' : JSON.stringify({ 'id' : dat[i].id.toString(), 'parent' : dat[i].parent.toString() }) }; inst.settings.core.error.call(inst, inst._data.core.last_error); } continue; } m[dat[i].parent.toString()].children.push(dat[i].id.toString()); // populate parent.children_d p.children_d.push(dat[i].id.toString()); } // 3) normalize && populate parents and children_d with recursion for(i = 0, j = p.children.length; i < j; i++) { tmp = parse_flat(m[p.children[i]], par, p.parents.concat()); dpc.push(tmp); if(m[tmp].children_d.length) { dpc = dpc.concat(m[tmp].children_d); } } for(i = 0, j = p.parents.length; i < j; i++) { m[p.parents[i]].children_d = m[p.parents[i]].children_d.concat(dpc); } // ?) three_state selection - p.state.selected && t - (if three_state foreach(dat => ch) -> foreach(parents) if(parent.selected) child.selected = true; rslt = { 'cnt' : t_cnt, 'mod' : m, 'sel' : sel, 'par' : par, 'dpc' : dpc, 'add' : add }; } else { for(i = 0, j = dat.length; i < j; i++) { tmp = parse_nest(dat[i], par, p.parents.concat()); if(tmp) { chd.push(tmp); dpc.push(tmp); if(m[tmp].children_d.length) { dpc = dpc.concat(m[tmp].children_d); } } } p.children = chd; p.children_d = dpc; for(i = 0, j = p.parents.length; i < j; i++) { m[p.parents[i]].children_d = m[p.parents[i]].children_d.concat(dpc); } rslt = { 'cnt' : t_cnt, 'mod' : m, 'sel' : sel, 'par' : par, 'dpc' : dpc, 'add' : add }; } if(typeof window === 'undefined' || typeof window.document === 'undefined') { postMessage(rslt); } else { return rslt; } }, rslt = function (rslt, worker) { if(this.element === null) { return; } this._cnt = rslt.cnt; var i, m = this._model.data; for (i in m) { if (m.hasOwnProperty(i) && m[i].state && m[i].state.loading && rslt.mod[i]) { rslt.mod[i].state.loading = true; } } this._model.data = rslt.mod; // breaks the reference in load_node - careful if(worker) { var j, a = rslt.add, r = rslt.sel, s = this._data.core.selected.slice(); m = this._model.data; // if selection was changed while calculating in worker if(r.length !== s.length || $.vakata.array_unique(r.concat(s)).length !== r.length) { // deselect nodes that are no longer selected for(i = 0, j = r.length; i < j; i++) { if($.inArray(r[i], a) === -1 && $.inArray(r[i], s) === -1) { m[r[i]].state.selected = false; } } // select nodes that were selected in the mean time for(i = 0, j = s.length; i < j; i++) { if($.inArray(s[i], r) === -1) { m[s[i]].state.selected = true; } } } } if(rslt.add.length) { this._data.core.selected = this._data.core.selected.concat(rslt.add); } this.trigger('model', { "nodes" : rslt.dpc, 'parent' : rslt.par }); if(rslt.par !== $.jstree.root) { this._node_changed(rslt.par); this.redraw(); } else { // this.get_container_ul().children('.jstree-initial-node').remove(); this.redraw(true); } if(rslt.add.length) { this.trigger('changed', { 'action' : 'model', 'selected' : this._data.core.selected }); } // If no worker, try to mimic worker behavioour, by invoking cb asynchronously if (!worker && setImmediate) { setImmediate(function(){ cb.call(inst, true); }); } else { cb.call(inst, true); } }; if(this.settings.core.worker && window.Blob && window.URL && window.Worker) { try { if(this._wrk === null) { this._wrk = window.URL.createObjectURL( new window.Blob( ['self.onmessage = ' + func.toString()], {type:"text/javascript"} ) ); } if(!this._data.core.working || force_processing) { this._data.core.working = true; w = new window.Worker(this._wrk); w.onmessage = function (e) { rslt.call(this, e.data, true); try { w.terminate(); w = null; } catch(ignore) { } if(this._data.core.worker_queue.length) { this._append_json_data.apply(this, this._data.core.worker_queue.shift()); } else { this._data.core.working = false; } }.bind(this); w.onerror = function (e) { rslt.call(this, func(args), false); if(this._data.core.worker_queue.length) { this._append_json_data.apply(this, this._data.core.worker_queue.shift()); } else { this._data.core.working = false; } }.bind(this); if(!args.par) { if(this._data.core.worker_queue.length) { this._append_json_data.apply(this, this._data.core.worker_queue.shift()); } else { this._data.core.working = false; } } else { w.postMessage(args); } } else { this._data.core.worker_queue.push([dom, data, cb, true]); } } catch(e) { rslt.call(this, func(args), false); if(this._data.core.worker_queue.length) { this._append_json_data.apply(this, this._data.core.worker_queue.shift()); } else { this._data.core.working = false; } } } else { rslt.call(this, func(args), false); } }, /** * parses a node from a jQuery object and appends them to the in memory tree model. Used internally. * @private * @name _parse_model_from_html(d [, p, ps]) * @param {jQuery} d the jQuery object to parse * @param {String} p the parent ID * @param {Array} ps list of all parents * @return {String} the ID of the object added to the model */ _parse_model_from_html : function (d, p, ps) { if(!ps) { ps = []; } else { ps = [].concat(ps); } if(p) { ps.unshift(p); } var c, e, m = this._model.data, data = { id : false, text : false, icon : true, parent : p, parents : ps, children : [], children_d : [], data : null, state : { }, li_attr : { id : false }, a_attr : { href : '#' }, original : false }, i, tmp, tid; for(i in this._model.default_state) { if(this._model.default_state.hasOwnProperty(i)) { data.state[i] = this._model.default_state[i]; } } tmp = $.vakata.attributes(d, true); $.each(tmp, function (i, v) { v = $.vakata.trim(v); if(!v.length) { return true; } data.li_attr[i] = v; if(i === 'id') { data.id = v.toString(); } }); tmp = d.children('a').first(); if(tmp.length) { tmp = $.vakata.attributes(tmp, true); $.each(tmp, function (i, v) { v = $.vakata.trim(v); if(v.length) { data.a_attr[i] = v; } }); } tmp = d.children("a").first().length ? d.children("a").first().clone() : d.clone(); tmp.children("ins, i, ul").remove(); tmp = tmp.html(); tmp = $('
    ').html(tmp); data.text = this.settings.core.force_text ? tmp.text() : tmp.html(); tmp = d.data(); data.data = tmp ? $.extend(true, {}, tmp) : null; data.state.opened = d.hasClass('jstree-open'); data.state.selected = d.children('a').hasClass('jstree-clicked'); data.state.disabled = d.children('a').hasClass('jstree-disabled'); if(data.data && data.data.jstree) { for(i in data.data.jstree) { if(data.data.jstree.hasOwnProperty(i)) { data.state[i] = data.data.jstree[i]; } } } tmp = d.children("a").children(".jstree-themeicon"); if(tmp.length) { data.icon = tmp.hasClass('jstree-themeicon-hidden') ? false : tmp.attr('rel'); } if(data.state.icon !== undefined) { data.icon = data.state.icon; } if(data.icon === undefined || data.icon === null || data.icon === "") { data.icon = true; } tmp = d.children("ul").children("li"); do { tid = 'j' + this._id + '_' + (++this._cnt); } while(m[tid]); data.id = data.li_attr.id ? data.li_attr.id.toString() : tid; if(tmp.length) { tmp.each(function (i, v) { c = this._parse_model_from_html($(v), data.id, ps); e = this._model.data[c]; data.children.push(c); if(e.children_d.length) { data.children_d = data.children_d.concat(e.children_d); } }.bind(this)); data.children_d = data.children_d.concat(data.children); } else { if(d.hasClass('jstree-closed')) { data.state.loaded = false; } } if(data.li_attr['class']) { data.li_attr['class'] = data.li_attr['class'].replace('jstree-closed','').replace('jstree-open',''); } if(data.a_attr['class']) { data.a_attr['class'] = data.a_attr['class'].replace('jstree-clicked','').replace('jstree-disabled',''); } m[data.id] = data; if(data.state.selected) { this._data.core.selected.push(data.id); } return data.id; }, /** * parses a node from a JSON object (used when dealing with flat data, which has no nesting of children, but has id and parent properties) and appends it to the in memory tree model. Used internally. * @private * @name _parse_model_from_flat_json(d [, p, ps]) * @param {Object} d the JSON object to parse * @param {String} p the parent ID * @param {Array} ps list of all parents * @return {String} the ID of the object added to the model */ _parse_model_from_flat_json : function (d, p, ps) { if(!ps) { ps = []; } else { ps = ps.concat(); } if(p) { ps.unshift(p); } var tid = d.id.toString(), m = this._model.data, df = this._model.default_state, i, j, c, e, tmp = { id : tid, text : d.text || '', icon : d.icon !== undefined ? d.icon : true, parent : p, parents : ps, children : d.children || [], children_d : d.children_d || [], data : d.data, state : { }, li_attr : { id : false }, a_attr : { href : '#' }, original : false }; for(i in df) { if(df.hasOwnProperty(i)) { tmp.state[i] = df[i]; } } if(d && d.data && d.data.jstree && d.data.jstree.icon) { tmp.icon = d.data.jstree.icon; } if(tmp.icon === undefined || tmp.icon === null || tmp.icon === "") { tmp.icon = true; } if(d && d.data) { tmp.data = d.data; if(d.data.jstree) { for(i in d.data.jstree) { if(d.data.jstree.hasOwnProperty(i)) { tmp.state[i] = d.data.jstree[i]; } } } } if(d && typeof d.state === 'object') { for (i in d.state) { if(d.state.hasOwnProperty(i)) { tmp.state[i] = d.state[i]; } } } if(d && typeof d.li_attr === 'object') { for (i in d.li_attr) { if(d.li_attr.hasOwnProperty(i)) { tmp.li_attr[i] = d.li_attr[i]; } } } if(!tmp.li_attr.id) { tmp.li_attr.id = tid; } if(d && typeof d.a_attr === 'object') { for (i in d.a_attr) { if(d.a_attr.hasOwnProperty(i)) { tmp.a_attr[i] = d.a_attr[i]; } } } if(d && d.children && d.children === true) { tmp.state.loaded = false; tmp.children = []; tmp.children_d = []; } m[tmp.id] = tmp; for(i = 0, j = tmp.children.length; i < j; i++) { c = this._parse_model_from_flat_json(m[tmp.children[i]], tmp.id, ps); e = m[c]; tmp.children_d.push(c); if(e.children_d.length) { tmp.children_d = tmp.children_d.concat(e.children_d); } } delete d.data; delete d.children; m[tmp.id].original = d; if(tmp.state.selected) { this._data.core.selected.push(tmp.id); } return tmp.id; }, /** * parses a node from a JSON object and appends it to the in memory tree model. Used internally. * @private * @name _parse_model_from_json(d [, p, ps]) * @param {Object} d the JSON object to parse * @param {String} p the parent ID * @param {Array} ps list of all parents * @return {String} the ID of the object added to the model */ _parse_model_from_json : function (d, p, ps) { if(!ps) { ps = []; } else { ps = ps.concat(); } if(p) { ps.unshift(p); } var tid = false, i, j, c, e, m = this._model.data, df = this._model.default_state, tmp; do { tid = 'j' + this._id + '_' + (++this._cnt); } while(m[tid]); tmp = { id : false, text : typeof d === 'string' ? d : '', icon : typeof d === 'object' && d.icon !== undefined ? d.icon : true, parent : p, parents : ps, children : [], children_d : [], data : null, state : { }, li_attr : { id : false }, a_attr : { href : '#' }, original : false }; for(i in df) { if(df.hasOwnProperty(i)) { tmp.state[i] = df[i]; } } if(d && (d.id || d.id === 0)) { tmp.id = d.id.toString(); } if(d && d.text) { tmp.text = d.text; } if(d && d.data && d.data.jstree && d.data.jstree.icon) { tmp.icon = d.data.jstree.icon; } if(tmp.icon === undefined || tmp.icon === null || tmp.icon === "") { tmp.icon = true; } if(d && d.data) { tmp.data = d.data; if(d.data.jstree) { for(i in d.data.jstree) { if(d.data.jstree.hasOwnProperty(i)) { tmp.state[i] = d.data.jstree[i]; } } } } if(d && typeof d.state === 'object') { for (i in d.state) { if(d.state.hasOwnProperty(i)) { tmp.state[i] = d.state[i]; } } } if(d && typeof d.li_attr === 'object') { for (i in d.li_attr) { if(d.li_attr.hasOwnProperty(i)) { tmp.li_attr[i] = d.li_attr[i]; } } } if(tmp.li_attr.id && !(tmp.id || tmp.id === 0)) { tmp.id = tmp.li_attr.id.toString(); } if(!(tmp.id || tmp.id === 0)) { tmp.id = tid; } if(!tmp.li_attr.id) { tmp.li_attr.id = tmp.id; } if(d && typeof d.a_attr === 'object') { for (i in d.a_attr) { if(d.a_attr.hasOwnProperty(i)) { tmp.a_attr[i] = d.a_attr[i]; } } } if(d && d.children && d.children.length) { for(i = 0, j = d.children.length; i < j; i++) { c = this._parse_model_from_json(d.children[i], tmp.id, ps); e = m[c]; tmp.children.push(c); if(e.children_d.length) { tmp.children_d = tmp.children_d.concat(e.children_d); } } tmp.children_d = tmp.children.concat(tmp.children_d); } if(d && d.children && d.children === true) { tmp.state.loaded = false; tmp.children = []; tmp.children_d = []; } delete d.data; delete d.children; tmp.original = d; m[tmp.id] = tmp; if(tmp.state.selected) { this._data.core.selected.push(tmp.id); } return tmp.id; }, /** * redraws all nodes that need to be redrawn. Used internally. * @private * @name _redraw() * @trigger redraw.jstree */ _redraw : function () { var nodes = this._model.force_full_redraw ? this._model.data[$.jstree.root].children.concat([]) : this._model.changed.concat([]), f = document.createElement('UL'), tmp, i, j, fe = this._data.core.focused; for(i = 0, j = nodes.length; i < j; i++) { tmp = this.redraw_node(nodes[i], true, this._model.force_full_redraw); if(tmp && this._model.force_full_redraw) { f.appendChild(tmp); } } if(this._model.force_full_redraw) { f.className = this.get_container_ul()[0].className; f.setAttribute('role','presentation'); this.element.empty().append(f); //this.get_container_ul()[0].appendChild(f); } if(fe !== null && this.settings.core.restore_focus) { tmp = this.get_node(fe, true); if(tmp && tmp.length && tmp.children('.jstree-anchor')[0] !== document.activeElement) { tmp.children('.jstree-anchor').trigger('focus'); } else { this._data.core.focused = null; } } this._model.force_full_redraw = false; this._model.changed = []; /** * triggered after nodes are redrawn * @event * @name redraw.jstree * @param {array} nodes the redrawn nodes */ this.trigger('redraw', { "nodes" : nodes }); }, /** * redraws all nodes that need to be redrawn or optionally - the whole tree * @name redraw([full]) * @param {Boolean} full if set to `true` all nodes are redrawn. */ redraw : function (full) { if(full) { this._model.force_full_redraw = true; } //if(this._model.redraw_timeout) { // clearTimeout(this._model.redraw_timeout); //} //this._model.redraw_timeout = setTimeout($.proxy(this._redraw, this),0); this._redraw(); }, /** * redraws a single node's children. Used internally. * @private * @name draw_children(node) * @param {mixed} node the node whose children will be redrawn */ draw_children : function (node) { var obj = this.get_node(node), i = false, j = false, k = false, d = document; if(!obj) { return false; } if(obj.id === $.jstree.root) { return this.redraw(true); } node = this.get_node(node, true); if(!node || !node.length) { return false; } // TODO: quick toggle node.children('.jstree-children').remove(); node = node[0]; if(obj.children.length && obj.state.loaded) { k = d.createElement('UL'); k.setAttribute('role', 'group'); k.className = 'jstree-children'; for(i = 0, j = obj.children.length; i < j; i++) { k.appendChild(this.redraw_node(obj.children[i], true, true)); } node.appendChild(k); } }, /** * redraws a single node. Used internally. * @private * @name redraw_node(node, deep, is_callback, force_render) * @param {mixed} node the node to redraw * @param {Boolean} deep should child nodes be redrawn too * @param {Boolean} is_callback is this a recursion call * @param {Boolean} force_render should children of closed parents be drawn anyway */ redraw_node : function (node, deep, is_callback, force_render) { var obj = this.get_node(node), par = false, ind = false, old = false, i = false, j = false, k = false, c = '', d = document, m = this._model.data, f = false, s = false, tmp = null, t = 0, l = 0, has_children = false, last_sibling = false; if(!obj) { return false; } if(obj.id === $.jstree.root) { return this.redraw(true); } deep = deep || obj.children.length === 0; node = !document.querySelector ? document.getElementById(obj.id) : this.element[0].querySelector('#' + ("0123456789".indexOf(obj.id[0]) !== -1 ? '\\3' + obj.id[0] + ' ' + obj.id.substr(1).replace($.jstree.idregex,'\\$&') : obj.id.replace($.jstree.idregex,'\\$&')) ); //, this.element); if(!node) { deep = true; //node = d.createElement('LI'); if(!is_callback) { par = obj.parent !== $.jstree.root ? $('#' + obj.parent.replace($.jstree.idregex,'\\$&'), this.element)[0] : null; if(par !== null && (!par || !m[obj.parent].state.opened)) { return false; } ind = $.inArray(obj.id, par === null ? m[$.jstree.root].children : m[obj.parent].children); } } else { node = $(node); if(!is_callback) { par = node.parent().parent()[0]; if(par === this.element[0]) { par = null; } ind = node.index(); } // m[obj.id].data = node.data(); // use only node's data, no need to touch jquery storage if(!deep && obj.children.length && !node.children('.jstree-children').length) { deep = true; } if(!deep) { old = node.children('.jstree-children')[0]; } f = node.children('.jstree-anchor')[0] === document.activeElement; node.remove(); //node = d.createElement('LI'); //node = node[0]; } node = this._data.core.node.cloneNode(true); // node is DOM, deep is boolean c = 'jstree-node '; for(i in obj.li_attr) { if(obj.li_attr.hasOwnProperty(i)) { if(i === 'id') { continue; } if(i !== 'class') { node.setAttribute(i, obj.li_attr[i]); } else { c += obj.li_attr[i]; } } } if(!obj.a_attr.id) { obj.a_attr.id = obj.id + '_anchor'; } node.childNodes[1].setAttribute('aria-selected', !!obj.state.selected); node.childNodes[1].setAttribute('aria-level', obj.parents.length); if(this.settings.core.compute_elements_positions) { node.childNodes[1].setAttribute('aria-setsize', m[obj.parent].children.length); node.childNodes[1].setAttribute('aria-posinset', m[obj.parent].children.indexOf(obj.id) + 1); } if(obj.state.disabled) { node.childNodes[1].setAttribute('aria-disabled', true); } for(i = 0, j = obj.children.length; i < j; i++) { if(!m[obj.children[i]].state.hidden) { has_children = true; break; } } if(obj.parent !== null && m[obj.parent] && !obj.state.hidden) { i = $.inArray(obj.id, m[obj.parent].children); last_sibling = obj.id; if(i !== -1) { i++; for(j = m[obj.parent].children.length; i < j; i++) { if(!m[m[obj.parent].children[i]].state.hidden) { last_sibling = m[obj.parent].children[i]; } if(last_sibling !== obj.id) { break; } } } } if(obj.state.hidden) { c += ' jstree-hidden'; } if (obj.state.loading) { c += ' jstree-loading'; } if(obj.state.loaded && !has_children) { c += ' jstree-leaf'; } else { c += obj.state.opened && obj.state.loaded ? ' jstree-open' : ' jstree-closed'; node.childNodes[1].setAttribute('aria-expanded', (obj.state.opened && obj.state.loaded) ); } if(last_sibling === obj.id) { c += ' jstree-last'; } node.id = obj.id; node.className = c; c = ( obj.state.selected ? ' jstree-clicked' : '') + ( obj.state.disabled ? ' jstree-disabled' : ''); for(j in obj.a_attr) { if(obj.a_attr.hasOwnProperty(j)) { if(j === 'href' && obj.a_attr[j] === '#') { continue; } if(j !== 'class') { node.childNodes[1].setAttribute(j, obj.a_attr[j]); } else { c += ' ' + obj.a_attr[j]; } } } if(c.length) { node.childNodes[1].className = 'jstree-anchor ' + c; } if((obj.icon && obj.icon !== true) || obj.icon === false) { if(obj.icon === false) { node.childNodes[1].childNodes[0].className += ' jstree-themeicon-hidden'; } else if(obj.icon.indexOf('/') === -1 && obj.icon.indexOf('.') === -1) { node.childNodes[1].childNodes[0].className += ' ' + obj.icon + ' jstree-themeicon-custom'; } else { node.childNodes[1].childNodes[0].style.backgroundImage = 'url("'+obj.icon+'")'; node.childNodes[1].childNodes[0].style.backgroundPosition = 'center center'; node.childNodes[1].childNodes[0].style.backgroundSize = 'auto'; node.childNodes[1].childNodes[0].className += ' jstree-themeicon-custom'; } } if(this.settings.core.force_text) { node.childNodes[1].appendChild(d.createTextNode(obj.text)); } else { node.childNodes[1].innerHTML += obj.text; } if(deep && obj.children.length && (obj.state.opened || force_render) && obj.state.loaded) { k = d.createElement('UL'); k.setAttribute('role', 'group'); k.className = 'jstree-children'; for(i = 0, j = obj.children.length; i < j; i++) { k.appendChild(this.redraw_node(obj.children[i], deep, true)); } node.appendChild(k); } if(old) { node.appendChild(old); } if(!is_callback) { // append back using par / ind if(!par) { par = this.element[0]; } for(i = 0, j = par.childNodes.length; i < j; i++) { if(par.childNodes[i] && par.childNodes[i].className && par.childNodes[i].className.indexOf('jstree-children') !== -1) { tmp = par.childNodes[i]; break; } } if(!tmp) { tmp = d.createElement('UL'); tmp.setAttribute('role', 'group'); tmp.className = 'jstree-children'; par.appendChild(tmp); } par = tmp; if(ind < par.childNodes.length) { par.insertBefore(node, par.childNodes[ind]); } else { par.appendChild(node); } if(f) { t = this.element[0].scrollTop; l = this.element[0].scrollLeft; node.childNodes[1].focus(); this.element[0].scrollTop = t; this.element[0].scrollLeft = l; } } if(obj.state.opened && !obj.state.loaded) { obj.state.opened = false; setTimeout(function () { this.open_node(obj.id, false, 0); }.bind(this), 0); } return node; }, /** * opens a node, revealing its children. If the node is not loaded it will be loaded and opened once ready. * @name open_node(obj [, callback, animation]) * @param {mixed} obj the node to open * @param {Function} callback a function to execute once the node is opened * @param {Number} animation the animation duration in milliseconds when opening the node (overrides the `core.animation` setting). Use `false` for no animation. * @trigger open_node.jstree, after_open.jstree, before_open.jstree */ open_node : function (obj, callback, animation) { var t1, t2, d, t; if($.vakata.is_array(obj)) { obj = obj.slice(); for(t1 = 0, t2 = obj.length; t1 < t2; t1++) { this.open_node(obj[t1], callback, animation); } return true; } obj = this.get_node(obj); if(!obj || obj.id === $.jstree.root) { return false; } animation = animation === undefined ? this.settings.core.animation : animation; if(!this.is_closed(obj)) { if(callback) { callback.call(this, obj, false); } return false; } if(!this.is_loaded(obj)) { if(this.is_loading(obj)) { return setTimeout(function () { this.open_node(obj, callback, animation); }.bind(this), 500); } this.load_node(obj, function (o, ok) { return ok ? this.open_node(o, callback, animation) : (callback ? callback.call(this, o, false) : false); }); } else { d = this.get_node(obj, true); t = this; if(d.length) { if(animation && d.children(".jstree-children").length) { d.children(".jstree-children").stop(true, true); } if(obj.children.length && !this._firstChild(d.children('.jstree-children')[0])) { this.draw_children(obj); //d = this.get_node(obj, true); } if(!animation) { this.trigger('before_open', { "node" : obj }); d[0].className = d[0].className.replace('jstree-closed', 'jstree-open'); d[0].childNodes[1].setAttribute("aria-expanded", true); } else { this.trigger('before_open', { "node" : obj }); d .children(".jstree-children").css("display","none").end() .removeClass("jstree-closed").addClass("jstree-open") .children('.jstree-anchor').attr("aria-expanded", true).end() .children(".jstree-children").stop(true, true) .slideDown(animation, function () { this.style.display = ""; if (t.element) { t.trigger("after_open", { "node" : obj }); } }); } } obj.state.opened = true; if(callback) { callback.call(this, obj, true); } if(!d.length) { /** * triggered when a node is about to be opened (if the node is supposed to be in the DOM, it will be, but it won't be visible yet) * @event * @name before_open.jstree * @param {Object} node the opened node */ this.trigger('before_open', { "node" : obj }); } /** * triggered when a node is opened (if there is an animation it will not be completed yet) * @event * @name open_node.jstree * @param {Object} node the opened node */ this.trigger('open_node', { "node" : obj }); if(!animation || !d.length) { /** * triggered when a node is opened and the animation is complete * @event * @name after_open.jstree * @param {Object} node the opened node */ this.trigger("after_open", { "node" : obj }); } return true; } }, /** * opens every parent of a node (node should be loaded) * @name _open_to(obj) * @param {mixed} obj the node to reveal * @private */ _open_to : function (obj) { obj = this.get_node(obj); if(!obj || obj.id === $.jstree.root) { return false; } var i, j, p = obj.parents; for(i = 0, j = p.length; i < j; i+=1) { if(i !== $.jstree.root) { this.open_node(p[i], false, 0); } } return $('#' + obj.id.replace($.jstree.idregex,'\\$&'), this.element); }, /** * closes a node, hiding its children * @name close_node(obj [, animation]) * @param {mixed} obj the node to close * @param {Number} animation the animation duration in milliseconds when closing the node (overrides the `core.animation` setting). Use `false` for no animation. * @trigger close_node.jstree, after_close.jstree */ close_node : function (obj, animation) { var t1, t2, t, d; if($.vakata.is_array(obj)) { obj = obj.slice(); for(t1 = 0, t2 = obj.length; t1 < t2; t1++) { this.close_node(obj[t1], animation); } return true; } obj = this.get_node(obj); if(!obj || obj.id === $.jstree.root) { return false; } if(this.is_closed(obj)) { return false; } animation = animation === undefined ? this.settings.core.animation : animation; t = this; d = this.get_node(obj, true); obj.state.opened = false; /** * triggered when a node is closed (if there is an animation it will not be complete yet) * @event * @name close_node.jstree * @param {Object} node the closed node */ this.trigger('close_node',{ "node" : obj }); if(!d.length) { /** * triggered when a node is closed and the animation is complete * @event * @name after_close.jstree * @param {Object} node the closed node */ this.trigger("after_close", { "node" : obj }); } else { if(!animation) { d[0].className = d[0].className.replace('jstree-open', 'jstree-closed'); d.children('.jstree-anchor').attr("aria-expanded", false); d.children('.jstree-children').remove(); this.trigger("after_close", { "node" : obj }); } else { d .children(".jstree-children").attr("style","display:block !important").end() .removeClass("jstree-open").addClass("jstree-closed") .children('.jstree-anchor').attr("aria-expanded", false).end() .children(".jstree-children").stop(true, true).slideUp(animation, function () { this.style.display = ""; d.children('.jstree-children').remove(); if (t.element) { t.trigger("after_close", { "node" : obj }); } }); } } }, /** * toggles a node - closing it if it is open, opening it if it is closed * @name toggle_node(obj) * @param {mixed} obj the node to toggle */ toggle_node : function (obj) { var t1, t2; if($.vakata.is_array(obj)) { obj = obj.slice(); for(t1 = 0, t2 = obj.length; t1 < t2; t1++) { this.toggle_node(obj[t1]); } return true; } if(this.is_closed(obj)) { return this.open_node(obj); } if(this.is_open(obj)) { return this.close_node(obj); } }, /** * opens all nodes within a node (or the tree), revealing their children. If the node is not loaded it will be loaded and opened once ready. * @name open_all([obj, animation, original_obj]) * @param {mixed} obj the node to open recursively, omit to open all nodes in the tree * @param {Number} animation the animation duration in milliseconds when opening the nodes, the default is no animation * @param {jQuery} reference to the node that started the process (internal use) * @trigger open_all.jstree */ open_all : function (obj, animation, original_obj) { if(!obj) { obj = $.jstree.root; } obj = this.get_node(obj); if(!obj) { return false; } var dom = obj.id === $.jstree.root ? this.get_container_ul() : this.get_node(obj, true), i, j, _this; if(!dom.length) { for(i = 0, j = obj.children_d.length; i < j; i++) { if(this.is_closed(this._model.data[obj.children_d[i]])) { this._model.data[obj.children_d[i]].state.opened = true; } } return this.trigger('open_all', { "node" : obj }); } original_obj = original_obj || dom; _this = this; dom = this.is_closed(obj) ? dom.find('.jstree-closed').addBack() : dom.find('.jstree-closed'); dom.each(function () { _this.open_node( this, function(node, status) { if(status && this.is_parent(node)) { this.open_all(node, animation, original_obj); } }, animation || 0 ); }); if(original_obj.find('.jstree-closed').length === 0) { /** * triggered when an `open_all` call completes * @event * @name open_all.jstree * @param {Object} node the opened node */ this.trigger('open_all', { "node" : this.get_node(original_obj) }); } }, /** * closes all nodes within a node (or the tree), revealing their children * @name close_all([obj, animation]) * @param {mixed} obj the node to close recursively, omit to close all nodes in the tree * @param {Number} animation the animation duration in milliseconds when closing the nodes, the default is no animation * @trigger close_all.jstree */ close_all : function (obj, animation) { if(!obj) { obj = $.jstree.root; } obj = this.get_node(obj); if(!obj) { return false; } var dom = obj.id === $.jstree.root ? this.get_container_ul() : this.get_node(obj, true), _this = this, i, j; if(dom.length) { dom = this.is_open(obj) ? dom.find('.jstree-open').addBack() : dom.find('.jstree-open'); $(dom.get().reverse()).each(function () { _this.close_node(this, animation || 0); }); } for(i = 0, j = obj.children_d.length; i < j; i++) { this._model.data[obj.children_d[i]].state.opened = false; } /** * triggered when an `close_all` call completes * @event * @name close_all.jstree * @param {Object} node the closed node */ this.trigger('close_all', { "node" : obj }); }, /** * checks if a node is disabled (not selectable) * @name is_disabled(obj) * @param {mixed} obj * @return {Boolean} */ is_disabled : function (obj) { obj = this.get_node(obj); return obj && obj.state && obj.state.disabled; }, /** * enables a node - so that it can be selected * @name enable_node(obj) * @param {mixed} obj the node to enable * @trigger enable_node.jstree */ enable_node : function (obj) { var t1, t2; if($.vakata.is_array(obj)) { obj = obj.slice(); for(t1 = 0, t2 = obj.length; t1 < t2; t1++) { this.enable_node(obj[t1]); } return true; } obj = this.get_node(obj); if(!obj || obj.id === $.jstree.root) { return false; } obj.state.disabled = false; this.get_node(obj,true).children('.jstree-anchor').removeClass('jstree-disabled').attr('aria-disabled', false); /** * triggered when an node is enabled * @event * @name enable_node.jstree * @param {Object} node the enabled node */ this.trigger('enable_node', { 'node' : obj }); }, /** * disables a node - so that it can not be selected * @name disable_node(obj) * @param {mixed} obj the node to disable * @trigger disable_node.jstree */ disable_node : function (obj) { var t1, t2; if($.vakata.is_array(obj)) { obj = obj.slice(); for(t1 = 0, t2 = obj.length; t1 < t2; t1++) { this.disable_node(obj[t1]); } return true; } obj = this.get_node(obj); if(!obj || obj.id === $.jstree.root) { return false; } obj.state.disabled = true; this.get_node(obj,true).children('.jstree-anchor').addClass('jstree-disabled').attr('aria-disabled', true); /** * triggered when an node is disabled * @event * @name disable_node.jstree * @param {Object} node the disabled node */ this.trigger('disable_node', { 'node' : obj }); }, /** * determines if a node is hidden * @name is_hidden(obj) * @param {mixed} obj the node */ is_hidden : function (obj) { obj = this.get_node(obj); return obj.state.hidden === true; }, /** * hides a node - it is still in the structure but will not be visible * @name hide_node(obj) * @param {mixed} obj the node to hide * @param {Boolean} skip_redraw internal parameter controlling if redraw is called * @trigger hide_node.jstree */ hide_node : function (obj, skip_redraw) { var t1, t2; if($.vakata.is_array(obj)) { obj = obj.slice(); for(t1 = 0, t2 = obj.length; t1 < t2; t1++) { this.hide_node(obj[t1], true); } if (!skip_redraw) { this.redraw(); } return true; } obj = this.get_node(obj); if(!obj || obj.id === $.jstree.root) { return false; } if(!obj.state.hidden) { obj.state.hidden = true; this._node_changed(obj.parent); if(!skip_redraw) { this.redraw(); } /** * triggered when an node is hidden * @event * @name hide_node.jstree * @param {Object} node the hidden node */ this.trigger('hide_node', { 'node' : obj }); } }, /** * shows a node * @name show_node(obj) * @param {mixed} obj the node to show * @param {Boolean} skip_redraw internal parameter controlling if redraw is called * @trigger show_node.jstree */ show_node : function (obj, skip_redraw) { var t1, t2; if($.vakata.is_array(obj)) { obj = obj.slice(); for(t1 = 0, t2 = obj.length; t1 < t2; t1++) { this.show_node(obj[t1], true); } if (!skip_redraw) { this.redraw(); } return true; } obj = this.get_node(obj); if(!obj || obj.id === $.jstree.root) { return false; } if(obj.state.hidden) { obj.state.hidden = false; this._node_changed(obj.parent); if(!skip_redraw) { this.redraw(); } /** * triggered when an node is shown * @event * @name show_node.jstree * @param {Object} node the shown node */ this.trigger('show_node', { 'node' : obj }); } }, /** * hides all nodes * @name hide_all() * @trigger hide_all.jstree */ hide_all : function (skip_redraw) { var i, m = this._model.data, ids = []; for(i in m) { if(m.hasOwnProperty(i) && i !== $.jstree.root && !m[i].state.hidden) { m[i].state.hidden = true; ids.push(i); } } this._model.force_full_redraw = true; if(!skip_redraw) { this.redraw(); } /** * triggered when all nodes are hidden * @event * @name hide_all.jstree * @param {Array} nodes the IDs of all hidden nodes */ this.trigger('hide_all', { 'nodes' : ids }); return ids; }, /** * shows all nodes * @name show_all() * @trigger show_all.jstree */ show_all : function (skip_redraw) { var i, m = this._model.data, ids = []; for(i in m) { if(m.hasOwnProperty(i) && i !== $.jstree.root && m[i].state.hidden) { m[i].state.hidden = false; ids.push(i); } } this._model.force_full_redraw = true; if(!skip_redraw) { this.redraw(); } /** * triggered when all nodes are shown * @event * @name show_all.jstree * @param {Array} nodes the IDs of all shown nodes */ this.trigger('show_all', { 'nodes' : ids }); return ids; }, /** * called when a node is selected by the user. Used internally. * @private * @name activate_node(obj, e) * @param {mixed} obj the node * @param {Object} e the related event * @trigger activate_node.jstree, changed.jstree */ activate_node : function (obj, e) { if(this.is_disabled(obj)) { return false; } if(!e || typeof e !== 'object') { e = {}; } // ensure last_clicked is still in the DOM, make it fresh (maybe it was moved?) and make sure it is still selected, if not - make last_clicked the last selected node this._data.core.last_clicked = this._data.core.last_clicked && this._data.core.last_clicked.id !== undefined ? this.get_node(this._data.core.last_clicked.id) : null; if(this._data.core.last_clicked && !this._data.core.last_clicked.state.selected) { this._data.core.last_clicked = null; } if(!this._data.core.last_clicked && this._data.core.selected.length) { this._data.core.last_clicked = this.get_node(this._data.core.selected[this._data.core.selected.length - 1]); } if(!this.settings.core.multiple || (!e.metaKey && !e.ctrlKey && !e.shiftKey) || (e.shiftKey && (!this._data.core.last_clicked || !this.get_parent(obj) || this.get_parent(obj) !== this._data.core.last_clicked.parent ) )) { if(!this.settings.core.multiple && (e.metaKey || e.ctrlKey || e.shiftKey) && this.is_selected(obj)) { this.deselect_node(obj, false, e); } else { if (!this.is_selected(obj) || this._data.core.selected.length !== 1) { this.deselect_all(true); this.select_node(obj, false, false, e); } this._data.core.last_clicked = this.get_node(obj); } } else { if(e.shiftKey) { var o = this.get_node(obj).id, l = this._data.core.last_clicked.id, p = this.get_node(this._data.core.last_clicked.parent).children, c = false, i, j; for(i = 0, j = p.length; i < j; i += 1) { // separate IFs work whem o and l are the same if(p[i] === o) { c = !c; } if(p[i] === l) { c = !c; } if(!this.is_disabled(p[i]) && (c || p[i] === o || p[i] === l)) { if (!this.is_hidden(p[i])) { this.select_node(p[i], true, false, e); } } else { if (!e.ctrlKey) { this.deselect_node(p[i], true, e); } } } this.trigger('changed', { 'action' : 'select_node', 'node' : this.get_node(obj), 'selected' : this._data.core.selected, 'event' : e }); } else { if(!this.is_selected(obj)) { if (e.ctrlKey) { this._data.core.last_clicked = this.get_node(obj); } this.select_node(obj, false, false, e); } else { this.deselect_node(obj, false, e); } } } /** * triggered when an node is clicked or intercated with by the user * @event * @name activate_node.jstree * @param {Object} node * @param {Object} event the ooriginal event (if any) which triggered the call (may be an empty object) */ this.trigger('activate_node', { 'node' : this.get_node(obj), 'event' : e }); }, /** * applies the hover state on a node, called when a node is hovered by the user. Used internally. * @private * @name hover_node(obj) * @param {mixed} obj * @trigger hover_node.jstree */ hover_node : function (obj) { obj = this.get_node(obj, true); if(!obj || !obj.length || obj.children('.jstree-hovered').length) { return false; } var o = this.element.find('.jstree-hovered'), t = this.element; if(o && o.length) { this.dehover_node(o); } obj.children('.jstree-anchor').addClass('jstree-hovered'); /** * triggered when an node is hovered * @event * @name hover_node.jstree * @param {Object} node */ this.trigger('hover_node', { 'node' : this.get_node(obj) }); setTimeout(function () { t.attr('aria-activedescendant', obj[0].id); }, 0); }, /** * removes the hover state from a nodecalled when a node is no longer hovered by the user. Used internally. * @private * @name dehover_node(obj) * @param {mixed} obj * @trigger dehover_node.jstree */ dehover_node : function (obj) { obj = this.get_node(obj, true); if(!obj || !obj.length || !obj.children('.jstree-hovered').length) { return false; } obj.children('.jstree-anchor').removeClass('jstree-hovered'); /** * triggered when an node is no longer hovered * @event * @name dehover_node.jstree * @param {Object} node */ this.trigger('dehover_node', { 'node' : this.get_node(obj) }); }, /** * select a node * @name select_node(obj [, supress_event, prevent_open]) * @param {mixed} obj an array can be used to select multiple nodes * @param {Boolean} supress_event if set to `true` the `changed.jstree` event won't be triggered * @param {Boolean} prevent_open if set to `true` parents of the selected node won't be opened * @trigger select_node.jstree, changed.jstree */ select_node : function (obj, supress_event, prevent_open, e) { var dom, t1, t2, th; if($.vakata.is_array(obj)) { obj = obj.slice(); for(t1 = 0, t2 = obj.length; t1 < t2; t1++) { this.select_node(obj[t1], supress_event, prevent_open, e); } return true; } obj = this.get_node(obj); if(!obj || obj.id === $.jstree.root) { return false; } dom = this.get_node(obj, true); if(!obj.state.selected) { obj.state.selected = true; this._data.core.selected.push(obj.id); if(!prevent_open) { dom = this._open_to(obj); } if(dom && dom.length) { dom.children('.jstree-anchor').addClass('jstree-clicked').attr('aria-selected', true); } /** * triggered when an node is selected * @event * @name select_node.jstree * @param {Object} node * @param {Array} selected the current selection * @param {Object} event the event (if any) that triggered this select_node */ this.trigger('select_node', { 'node' : obj, 'selected' : this._data.core.selected, 'event' : e }); if(!supress_event) { /** * triggered when selection changes * @event * @name changed.jstree * @param {Object} node * @param {Object} action the action that caused the selection to change * @param {Array} selected the current selection * @param {Object} event the event (if any) that triggered this changed event */ this.trigger('changed', { 'action' : 'select_node', 'node' : obj, 'selected' : this._data.core.selected, 'event' : e }); } } }, /** * deselect a node * @name deselect_node(obj [, supress_event]) * @param {mixed} obj an array can be used to deselect multiple nodes * @param {Boolean} supress_event if set to `true` the `changed.jstree` event won't be triggered * @trigger deselect_node.jstree, changed.jstree */ deselect_node : function (obj, supress_event, e) { var t1, t2, dom; if($.vakata.is_array(obj)) { obj = obj.slice(); for(t1 = 0, t2 = obj.length; t1 < t2; t1++) { this.deselect_node(obj[t1], supress_event, e); } return true; } obj = this.get_node(obj); if(!obj || obj.id === $.jstree.root) { return false; } dom = this.get_node(obj, true); if(obj.state.selected) { obj.state.selected = false; this._data.core.selected = $.vakata.array_remove_item(this._data.core.selected, obj.id); if(dom.length) { dom.children('.jstree-anchor').removeClass('jstree-clicked').attr('aria-selected', false); } /** * triggered when an node is deselected * @event * @name deselect_node.jstree * @param {Object} node * @param {Array} selected the current selection * @param {Object} event the event (if any) that triggered this deselect_node */ this.trigger('deselect_node', { 'node' : obj, 'selected' : this._data.core.selected, 'event' : e }); if(!supress_event) { this.trigger('changed', { 'action' : 'deselect_node', 'node' : obj, 'selected' : this._data.core.selected, 'event' : e }); } } }, /** * select all nodes in the tree * @name select_all([supress_event]) * @param {Boolean} supress_event if set to `true` the `changed.jstree` event won't be triggered * @trigger select_all.jstree, changed.jstree */ select_all : function (supress_event) { var tmp = this._data.core.selected.concat([]), i, j; this._data.core.selected = this._model.data[$.jstree.root].children_d.concat(); for(i = 0, j = this._data.core.selected.length; i < j; i++) { if(this._model.data[this._data.core.selected[i]]) { this._model.data[this._data.core.selected[i]].state.selected = true; } } this.redraw(true); /** * triggered when all nodes are selected * @event * @name select_all.jstree * @param {Array} selected the current selection */ this.trigger('select_all', { 'selected' : this._data.core.selected }); if(!supress_event) { this.trigger('changed', { 'action' : 'select_all', 'selected' : this._data.core.selected, 'old_selection' : tmp }); } }, /** * deselect all selected nodes * @name deselect_all([supress_event]) * @param {Boolean} supress_event if set to `true` the `changed.jstree` event won't be triggered * @trigger deselect_all.jstree, changed.jstree */ deselect_all : function (supress_event) { var tmp = this._data.core.selected.concat([]), i, j; for(i = 0, j = this._data.core.selected.length; i < j; i++) { if(this._model.data[this._data.core.selected[i]]) { this._model.data[this._data.core.selected[i]].state.selected = false; } } this._data.core.selected = []; this.element.find('.jstree-clicked').removeClass('jstree-clicked').attr('aria-selected', false); /** * triggered when all nodes are deselected * @event * @name deselect_all.jstree * @param {Object} node the previous selection * @param {Array} selected the current selection */ this.trigger('deselect_all', { 'selected' : this._data.core.selected, 'node' : tmp }); if(!supress_event) { this.trigger('changed', { 'action' : 'deselect_all', 'selected' : this._data.core.selected, 'old_selection' : tmp }); } }, /** * checks if a node is selected * @name is_selected(obj) * @param {mixed} obj * @return {Boolean} */ is_selected : function (obj) { obj = this.get_node(obj); if(!obj || obj.id === $.jstree.root) { return false; } return obj.state.selected; }, /** * get an array of all selected nodes * @name get_selected([full]) * @param {mixed} full if set to `true` the returned array will consist of the full node objects, otherwise - only IDs will be returned * @return {Array} */ get_selected : function (full) { return full ? $.map(this._data.core.selected, function (i) { return this.get_node(i); }.bind(this)) : this._data.core.selected.slice(); }, /** * get an array of all top level selected nodes (ignoring children of selected nodes) * @name get_top_selected([full]) * @param {mixed} full if set to `true` the returned array will consist of the full node objects, otherwise - only IDs will be returned * @return {Array} */ get_top_selected : function (full) { var tmp = this.get_selected(true), obj = {}, i, j, k, l; for(i = 0, j = tmp.length; i < j; i++) { obj[tmp[i].id] = tmp[i]; } for(i = 0, j = tmp.length; i < j; i++) { for(k = 0, l = tmp[i].children_d.length; k < l; k++) { if(obj[tmp[i].children_d[k]]) { delete obj[tmp[i].children_d[k]]; } } } tmp = []; for(i in obj) { if(obj.hasOwnProperty(i)) { tmp.push(i); } } return full ? $.map(tmp, function (i) { return this.get_node(i); }.bind(this)) : tmp; }, /** * get an array of all bottom level selected nodes (ignoring selected parents) * @name get_bottom_selected([full]) * @param {mixed} full if set to `true` the returned array will consist of the full node objects, otherwise - only IDs will be returned * @return {Array} */ get_bottom_selected : function (full) { var tmp = this.get_selected(true), obj = [], i, j; for(i = 0, j = tmp.length; i < j; i++) { if(!tmp[i].children.length) { obj.push(tmp[i].id); } } return full ? $.map(obj, function (i) { return this.get_node(i); }.bind(this)) : obj; }, /** * gets the current state of the tree so that it can be restored later with `set_state(state)`. Used internally. * @name get_state() * @private * @return {Object} */ get_state : function () { var state = { 'core' : { 'open' : [], 'loaded' : [], 'scroll' : { 'left' : this.element.scrollLeft(), 'top' : this.element.scrollTop() }, /*! 'themes' : { 'name' : this.get_theme(), 'icons' : this._data.core.themes.icons, 'dots' : this._data.core.themes.dots }, */ 'selected' : [] } }, i; for(i in this._model.data) { if(this._model.data.hasOwnProperty(i)) { if(i !== $.jstree.root) { if(this._model.data[i].state.loaded && this.settings.core.loaded_state) { state.core.loaded.push(i); } if(this._model.data[i].state.opened) { state.core.open.push(i); } if(this._model.data[i].state.selected) { state.core.selected.push(i); } } } } return state; }, /** * sets the state of the tree. Used internally. * @name set_state(state [, callback]) * @private * @param {Object} state the state to restore. Keep in mind this object is passed by reference and jstree will modify it. * @param {Function} callback an optional function to execute once the state is restored. * @trigger set_state.jstree */ set_state : function (state, callback) { if(state) { if(state.core && state.core.selected && state.core.initial_selection === undefined) { state.core.initial_selection = this._data.core.selected.concat([]).sort().join(','); } if(state.core) { var res, n, t, _this, i; if(state.core.loaded) { if(!this.settings.core.loaded_state || !$.vakata.is_array(state.core.loaded) || !state.core.loaded.length) { delete state.core.loaded; this.set_state(state, callback); } else { this._load_nodes(state.core.loaded, function (nodes) { delete state.core.loaded; this.set_state(state, callback); }); } return false; } if(state.core.open) { if(!$.vakata.is_array(state.core.open) || !state.core.open.length) { delete state.core.open; this.set_state(state, callback); } else { this._load_nodes(state.core.open, function (nodes) { this.open_node(nodes, false, 0); delete state.core.open; this.set_state(state, callback); }); } return false; } if(state.core.scroll) { if(state.core.scroll && state.core.scroll.left !== undefined) { this.element.scrollLeft(state.core.scroll.left); } if(state.core.scroll && state.core.scroll.top !== undefined) { this.element.scrollTop(state.core.scroll.top); } delete state.core.scroll; this.set_state(state, callback); return false; } if(state.core.selected) { _this = this; if (state.core.initial_selection === undefined || state.core.initial_selection === this._data.core.selected.concat([]).sort().join(',') ) { this.deselect_all(); $.each(state.core.selected, function (i, v) { _this.select_node(v, false, true); }); } delete state.core.initial_selection; delete state.core.selected; this.set_state(state, callback); return false; } for(i in state) { if(state.hasOwnProperty(i) && i !== "core" && $.inArray(i, this.settings.plugins) === -1) { delete state[i]; } } if($.isEmptyObject(state.core)) { delete state.core; this.set_state(state, callback); return false; } } if($.isEmptyObject(state)) { state = null; if(callback) { callback.call(this); } /** * triggered when a `set_state` call completes * @event * @name set_state.jstree */ this.trigger('set_state'); return false; } return true; } return false; }, /** * refreshes the tree - all nodes are reloaded with calls to `load_node`. * @name refresh() * @param {Boolean} skip_loading an option to skip showing the loading indicator * @param {Mixed} forget_state if set to `true` state will not be reapplied, if set to a function (receiving the current state as argument) the result of that function will be used as state * @trigger refresh.jstree */ refresh : function (skip_loading, forget_state) { this._data.core.state = forget_state === true ? {} : this.get_state(); if(forget_state && $.vakata.is_function(forget_state)) { this._data.core.state = forget_state.call(this, this._data.core.state); } this._cnt = 0; this._model.data = {}; this._model.data[$.jstree.root] = { id : $.jstree.root, parent : null, parents : [], children : [], children_d : [], state : { loaded : false } }; this._data.core.selected = []; this._data.core.last_clicked = null; this._data.core.focused = null; var c = this.get_container_ul()[0].className; if(!skip_loading) { this.element.html("<"+"ul class='"+c+"' role='group'><"+"li class='jstree-initial-node jstree-loading jstree-leaf jstree-last' role='none' id='j"+this._id+"_loading'><"+"a class='jstree-anchor' role='treeitem' href='#'>" + this.get_string("Loading ...") + ""); this.element.attr('aria-activedescendant','j'+this._id+'_loading'); } this.load_node($.jstree.root, function (o, s) { if(s) { this.get_container_ul()[0].className = c; if(this._firstChild(this.get_container_ul()[0])) { this.element.attr('aria-activedescendant',this._firstChild(this.get_container_ul()[0]).id); } this.set_state($.extend(true, {}, this._data.core.state), function () { /** * triggered when a `refresh` call completes * @event * @name refresh.jstree */ this.trigger('refresh'); }); } this._data.core.state = null; }); }, /** * refreshes a node in the tree (reload its children) all opened nodes inside that node are reloaded with calls to `load_node`. * @name refresh_node(obj) * @param {mixed} obj the node * @trigger refresh_node.jstree */ refresh_node : function (obj) { obj = this.get_node(obj); if(!obj || obj.id === $.jstree.root) { return false; } var opened = [], to_load = [], s = this._data.core.selected.concat([]); to_load.push(obj.id); if(obj.state.opened === true) { opened.push(obj.id); } this.get_node(obj, true).find('.jstree-open').each(function() { to_load.push(this.id); opened.push(this.id); }); this._load_nodes(to_load, function (nodes) { this.open_node(opened, false, 0); this.select_node(s); /** * triggered when a node is refreshed * @event * @name refresh_node.jstree * @param {Object} node - the refreshed node * @param {Array} nodes - an array of the IDs of the nodes that were reloaded */ this.trigger('refresh_node', { 'node' : obj, 'nodes' : nodes }); }.bind(this), false, true); }, /** * set (change) the ID of a node * @name set_id(obj, id) * @param {mixed} obj the node * @param {String} id the new ID * @return {Boolean} * @trigger set_id.jstree */ set_id : function (obj, id) { obj = this.get_node(obj); if(!obj || obj.id === $.jstree.root) { return false; } var i, j, m = this._model.data, old = obj.id; id = id.toString(); // update parents (replace current ID with new one in children and children_d) m[obj.parent].children[$.inArray(obj.id, m[obj.parent].children)] = id; for(i = 0, j = obj.parents.length; i < j; i++) { m[obj.parents[i]].children_d[$.inArray(obj.id, m[obj.parents[i]].children_d)] = id; } // update children (replace current ID with new one in parent and parents) for(i = 0, j = obj.children.length; i < j; i++) { m[obj.children[i]].parent = id; } for(i = 0, j = obj.children_d.length; i < j; i++) { m[obj.children_d[i]].parents[$.inArray(obj.id, m[obj.children_d[i]].parents)] = id; } i = $.inArray(obj.id, this._data.core.selected); if(i !== -1) { this._data.core.selected[i] = id; } // update model and obj itself (obj.id, this._model.data[KEY]) i = this.get_node(obj.id, true); if(i) { i.attr('id', id); //.children('.jstree-anchor').attr('id', id + '_anchor').end().attr('aria-labelledby', id + '_anchor'); if(this.element.attr('aria-activedescendant') === obj.id) { this.element.attr('aria-activedescendant', id); } } delete m[obj.id]; obj.id = id; obj.li_attr.id = id; m[id] = obj; /** * triggered when a node id value is changed * @event * @name set_id.jstree * @param {Object} node * @param {String} old the old id */ this.trigger('set_id',{ "node" : obj, "new" : obj.id, "old" : old }); return true; }, /** * get the text value of a node * @name get_text(obj) * @param {mixed} obj the node * @return {String} */ get_text : function (obj) { obj = this.get_node(obj); return (!obj || obj.id === $.jstree.root) ? false : obj.text; }, /** * set the text value of a node. Used internally, please use `rename_node(obj, val)`. * @private * @name set_text(obj, val) * @param {mixed} obj the node, you can pass an array to set the text on multiple nodes * @param {String} val the new text value * @return {Boolean} * @trigger set_text.jstree */ set_text : function (obj, val) { var t1, t2; if($.vakata.is_array(obj)) { obj = obj.slice(); for(t1 = 0, t2 = obj.length; t1 < t2; t1++) { this.set_text(obj[t1], val); } return true; } obj = this.get_node(obj); if(!obj || obj.id === $.jstree.root) { return false; } obj.text = val; if(this.get_node(obj, true).length) { this.redraw_node(obj.id); } /** * triggered when a node text value is changed * @event * @name set_text.jstree * @param {Object} obj * @param {String} text the new value */ this.trigger('set_text',{ "obj" : obj, "text" : val }); return true; }, /** * gets a JSON representation of a node (or the whole tree) * @name get_json([obj, options]) * @param {mixed} obj * @param {Object} options * @param {Boolean} options.no_state do not return state information * @param {Boolean} options.no_id do not return ID * @param {Boolean} options.no_children do not include children * @param {Boolean} options.no_data do not include node data * @param {Boolean} options.no_li_attr do not include LI attributes * @param {Boolean} options.no_a_attr do not include A attributes * @param {Boolean} options.flat return flat JSON instead of nested * @return {Object} */ get_json : function (obj, options, flat) { obj = this.get_node(obj || $.jstree.root); if(!obj) { return false; } if(options && options.flat && !flat) { flat = []; } var tmp = { 'id' : obj.id, 'text' : obj.text, 'icon' : this.get_icon(obj), 'li_attr' : $.extend(true, {}, obj.li_attr), 'a_attr' : $.extend(true, {}, obj.a_attr), 'state' : {}, 'data' : options && options.no_data ? false : $.extend(true, $.vakata.is_array(obj.data)?[]:{}, obj.data) //( this.get_node(obj, true).length ? this.get_node(obj, true).data() : obj.data ), }, i, j; if(options && options.flat) { tmp.parent = obj.parent; } else { tmp.children = []; } if(!options || !options.no_state) { for(i in obj.state) { if(obj.state.hasOwnProperty(i)) { tmp.state[i] = obj.state[i]; } } } else { delete tmp.state; } if(options && options.no_li_attr) { delete tmp.li_attr; } if(options && options.no_a_attr) { delete tmp.a_attr; } if(options && options.no_id) { delete tmp.id; if(tmp.li_attr && tmp.li_attr.id) { delete tmp.li_attr.id; } if(tmp.a_attr && tmp.a_attr.id) { delete tmp.a_attr.id; } } if(options && options.flat && obj.id !== $.jstree.root) { flat.push(tmp); } if(!options || !options.no_children) { for(i = 0, j = obj.children.length; i < j; i++) { if(options && options.flat) { this.get_json(obj.children[i], options, flat); } else { tmp.children.push(this.get_json(obj.children[i], options)); } } } return options && options.flat ? flat : (obj.id === $.jstree.root ? tmp.children : tmp); }, /** * create a new node (do not confuse with load_node) * @name create_node([par, node, pos, callback, is_loaded]) * @param {mixed} par the parent node (to create a root node use either "#" (string) or `null`) * @param {mixed} node the data for the new node (a valid JSON object, or a simple string with the name) * @param {mixed} pos the index at which to insert the node, "first" and "last" are also supported, default is "last" * @param {Function} callback a function to be called once the node is created * @param {Boolean} is_loaded internal argument indicating if the parent node was succesfully loaded * @return {String} the ID of the newly create node * @trigger model.jstree, create_node.jstree */ create_node : function (par, node, pos, callback, is_loaded) { if(par === null) { par = $.jstree.root; } par = this.get_node(par); if(!par) { return false; } pos = pos === undefined ? "last" : pos; if(!pos.toString().match(/^(before|after)$/) && !is_loaded && !this.is_loaded(par)) { return this.load_node(par, function () { this.create_node(par, node, pos, callback, true); }); } if(!node) { node = { "text" : this.get_string('New node') }; } if(typeof node === "string") { node = { "text" : node }; } else { node = $.extend(true, {}, node); } if(node.text === undefined) { node.text = this.get_string('New node'); } var tmp, dpc, i, j; if(par.id === $.jstree.root) { if(pos === "before") { pos = "first"; } if(pos === "after") { pos = "last"; } } switch(pos) { case "before": tmp = this.get_node(par.parent); pos = $.inArray(par.id, tmp.children); par = tmp; break; case "after" : tmp = this.get_node(par.parent); pos = $.inArray(par.id, tmp.children) + 1; par = tmp; break; case "inside": case "first": pos = 0; break; case "last": pos = par.children.length; break; default: if(!pos) { pos = 0; } break; } if(pos > par.children.length) { pos = par.children.length; } if(node.id === undefined) { node.id = true; } if(!this.check("create_node", node, par, pos)) { this.settings.core.error.call(this, this._data.core.last_error); return false; } if(node.id === true) { delete node.id; } node = this._parse_model_from_json(node, par.id, par.parents.concat()); if(!node) { return false; } tmp = this.get_node(node); dpc = []; dpc.push(node); dpc = dpc.concat(tmp.children_d); this.trigger('model', { "nodes" : dpc, "parent" : par.id }); par.children_d = par.children_d.concat(dpc); for(i = 0, j = par.parents.length; i < j; i++) { this._model.data[par.parents[i]].children_d = this._model.data[par.parents[i]].children_d.concat(dpc); } node = tmp; tmp = []; for(i = 0, j = par.children.length; i < j; i++) { tmp[i >= pos ? i+1 : i] = par.children[i]; } tmp[pos] = node.id; par.children = tmp; this.redraw_node(par, true); /** * triggered when a node is created * @event * @name create_node.jstree * @param {Object} node * @param {String} parent the parent's ID * @param {Number} position the position of the new node among the parent's children */ this.trigger('create_node', { "node" : this.get_node(node), "parent" : par.id, "position" : pos }); if(callback) { callback.call(this, this.get_node(node)); } return node.id; }, /** * set the text value of a node * @name rename_node(obj, val) * @param {mixed} obj the node, you can pass an array to rename multiple nodes to the same name * @param {String} val the new text value * @return {Boolean} * @trigger rename_node.jstree */ rename_node : function (obj, val) { var t1, t2, old; if($.vakata.is_array(obj)) { obj = obj.slice(); for(t1 = 0, t2 = obj.length; t1 < t2; t1++) { this.rename_node(obj[t1], val); } return true; } obj = this.get_node(obj); if(!obj || obj.id === $.jstree.root) { return false; } old = obj.text; if(!this.check("rename_node", obj, this.get_parent(obj), val)) { this.settings.core.error.call(this, this._data.core.last_error); return false; } this.set_text(obj, val); // .apply(this, Array.prototype.slice.call(arguments)) /** * triggered when a node is renamed * @event * @name rename_node.jstree * @param {Object} node * @param {String} text the new value * @param {String} old the old value */ this.trigger('rename_node', { "node" : obj, "text" : val, "old" : old }); return true; }, /** * remove a node * @name delete_node(obj) * @param {mixed} obj the node, you can pass an array to delete multiple nodes * @return {Boolean} * @trigger delete_node.jstree, changed.jstree */ delete_node : function (obj) { var t1, t2, par, pos, tmp, i, j, k, l, c, top, lft; if($.vakata.is_array(obj)) { obj = obj.slice(); for(t1 = 0, t2 = obj.length; t1 < t2; t1++) { this.delete_node(obj[t1]); } return true; } obj = this.get_node(obj); if(!obj || obj.id === $.jstree.root) { return false; } par = this.get_node(obj.parent); pos = $.inArray(obj.id, par.children); c = false; if(!this.check("delete_node", obj, par, pos)) { this.settings.core.error.call(this, this._data.core.last_error); return false; } if(pos !== -1) { par.children = $.vakata.array_remove(par.children, pos); } tmp = obj.children_d.concat([]); tmp.push(obj.id); for(i = 0, j = obj.parents.length; i < j; i++) { this._model.data[obj.parents[i]].children_d = $.vakata.array_filter(this._model.data[obj.parents[i]].children_d, function (v) { return $.inArray(v, tmp) === -1; }); } for(k = 0, l = tmp.length; k < l; k++) { if(this._model.data[tmp[k]].state.selected) { c = true; break; } } if (c) { this._data.core.selected = $.vakata.array_filter(this._data.core.selected, function (v) { return $.inArray(v, tmp) === -1; }); } /** * triggered when a node is deleted * @event * @name delete_node.jstree * @param {Object} node * @param {String} parent the parent's ID */ this.trigger('delete_node', { "node" : obj, "parent" : par.id }); if(c) { this.trigger('changed', { 'action' : 'delete_node', 'node' : obj, 'selected' : this._data.core.selected, 'parent' : par.id }); } for(k = 0, l = tmp.length; k < l; k++) { delete this._model.data[tmp[k]]; } if($.inArray(this._data.core.focused, tmp) !== -1) { this._data.core.focused = null; top = this.element[0].scrollTop; lft = this.element[0].scrollLeft; if(par.id === $.jstree.root) { if (this._model.data[$.jstree.root].children[0]) { this.get_node(this._model.data[$.jstree.root].children[0], true).children('.jstree-anchor').trigger('focus'); } } else { this.get_node(par, true).children('.jstree-anchor').trigger('focus'); } this.element[0].scrollTop = top; this.element[0].scrollLeft = lft; } this.redraw_node(par, true); return true; }, /** * check if an operation is premitted on the tree. Used internally. * @private * @name check(chk, obj, par, pos) * @param {String} chk the operation to check, can be "create_node", "rename_node", "delete_node", "copy_node" or "move_node" * @param {mixed} obj the node * @param {mixed} par the parent * @param {mixed} pos the position to insert at, or if "rename_node" - the new name * @param {mixed} more some various additional information, for example if a "move_node" operations is triggered by DND this will be the hovered node * @return {Boolean} */ check : function (chk, obj, par, pos, more) { obj = obj && obj.id ? obj : this.get_node(obj); par = par && par.id ? par : this.get_node(par); var tmp = chk.match(/^(move_node|copy_node|create_node)$/i) ? par : obj, chc = this.settings.core.check_callback; if(chk === "move_node" || chk === "copy_node") { if((!more || !more.is_multi) && (chk === "move_node" && $.inArray(obj.id, par.children) === pos)) { this._data.core.last_error = { 'error' : 'check', 'plugin' : 'core', 'id' : 'core_08', 'reason' : 'Moving node to its current position', 'data' : JSON.stringify({ 'chk' : chk, 'pos' : pos, 'obj' : obj && obj.id ? obj.id : false, 'par' : par && par.id ? par.id : false }) }; return false; } if((!more || !more.is_multi) && (obj.id === par.id || (chk === "move_node" && $.inArray(obj.id, par.children) === pos) || $.inArray(par.id, obj.children_d) !== -1)) { this._data.core.last_error = { 'error' : 'check', 'plugin' : 'core', 'id' : 'core_01', 'reason' : 'Moving parent inside child', 'data' : JSON.stringify({ 'chk' : chk, 'pos' : pos, 'obj' : obj && obj.id ? obj.id : false, 'par' : par && par.id ? par.id : false }) }; return false; } } if(tmp && tmp.data) { tmp = tmp.data; } if(tmp && tmp.functions && (tmp.functions[chk] === false || tmp.functions[chk] === true)) { if(tmp.functions[chk] === false) { this._data.core.last_error = { 'error' : 'check', 'plugin' : 'core', 'id' : 'core_02', 'reason' : 'Node data prevents function: ' + chk, 'data' : JSON.stringify({ 'chk' : chk, 'pos' : pos, 'obj' : obj && obj.id ? obj.id : false, 'par' : par && par.id ? par.id : false }) }; } return tmp.functions[chk]; } if(chc === false || ($.vakata.is_function(chc) && chc.call(this, chk, obj, par, pos, more) === false) || (chc && chc[chk] === false)) { this._data.core.last_error = { 'error' : 'check', 'plugin' : 'core', 'id' : 'core_03', 'reason' : 'User config for core.check_callback prevents function: ' + chk, 'data' : JSON.stringify({ 'chk' : chk, 'pos' : pos, 'obj' : obj && obj.id ? obj.id : false, 'par' : par && par.id ? par.id : false }) }; return false; } return true; }, /** * get the last error * @name last_error() * @return {Object} */ last_error : function () { return this._data.core.last_error; }, /** * move a node to a new parent * @name move_node(obj, par [, pos, callback, is_loaded]) * @param {mixed} obj the node to move, pass an array to move multiple nodes * @param {mixed} par the new parent * @param {mixed} pos the position to insert at (besides integer values, "first" and "last" are supported, as well as "before" and "after"), defaults to integer `0` * @param {function} callback a function to call once the move is completed, receives 3 arguments - the node, the new parent and the position * @param {Boolean} is_loaded internal parameter indicating if the parent node has been loaded * @param {Boolean} skip_redraw internal parameter indicating if the tree should be redrawn * @param {Boolean} instance internal parameter indicating if the node comes from another instance * @trigger move_node.jstree */ move_node : function (obj, par, pos, callback, is_loaded, skip_redraw, origin) { var t1, t2, old_par, old_pos, new_par, old_ins, is_multi, dpc, tmp, i, j, k, l, p; par = this.get_node(par); pos = pos === undefined ? 0 : pos; if(!par) { return false; } if(!pos.toString().match(/^(before|after)$/) && !is_loaded && !this.is_loaded(par)) { return this.load_node(par, function () { this.move_node(obj, par, pos, callback, true, false, origin); }); } if($.vakata.is_array(obj)) { if(obj.length === 1) { obj = obj[0]; } else { //obj = obj.slice(); for(t1 = 0, t2 = obj.length; t1 < t2; t1++) { if((tmp = this.move_node(obj[t1], par, pos, callback, is_loaded, false, origin))) { par = tmp; pos = "after"; } } this.redraw(); return true; } } obj = obj && (obj.id !== undefined) ? obj : this.get_node(obj); if(!obj || obj.id === $.jstree.root) { return false; } old_par = (obj.parent || $.jstree.root).toString(); new_par = (!pos.toString().match(/^(before|after)$/) || par.id === $.jstree.root) ? par : this.get_node(par.parent); old_ins = origin ? origin : (this._model.data[obj.id] ? this : $.jstree.reference(obj.id)); is_multi = !old_ins || !old_ins._id || (this._id !== old_ins._id); old_pos = old_ins && old_ins._id && old_par && old_ins._model.data[old_par] && old_ins._model.data[old_par].children ? $.inArray(obj.id, old_ins._model.data[old_par].children) : -1; if(old_ins && old_ins._id) { obj = old_ins._model.data[obj.id]; } if(is_multi) { if((tmp = this.copy_node(obj, par, pos, callback, is_loaded, false, origin))) { if(old_ins) { old_ins.delete_node(obj); } return tmp; } return false; } //var m = this._model.data; if(par.id === $.jstree.root) { if(pos === "before") { pos = "first"; } if(pos === "after") { pos = "last"; } } switch(pos) { case "before": pos = $.inArray(par.id, new_par.children); break; case "after" : pos = $.inArray(par.id, new_par.children) + 1; break; case "inside": case "first": pos = 0; break; case "last": pos = new_par.children.length; break; default: if(!pos) { pos = 0; } break; } if(pos > new_par.children.length) { pos = new_par.children.length; } if(!this.check("move_node", obj, new_par, pos, { 'core' : true, 'origin' : origin, 'is_multi' : (old_ins && old_ins._id && old_ins._id !== this._id), 'is_foreign' : (!old_ins || !old_ins._id) })) { this.settings.core.error.call(this, this._data.core.last_error); return false; } if(obj.parent === new_par.id) { dpc = new_par.children.concat(); tmp = $.inArray(obj.id, dpc); if(tmp !== -1) { dpc = $.vakata.array_remove(dpc, tmp); if(pos > tmp) { pos--; } } tmp = []; for(i = 0, j = dpc.length; i < j; i++) { tmp[i >= pos ? i+1 : i] = dpc[i]; } tmp[pos] = obj.id; new_par.children = tmp; this._node_changed(new_par.id); this.redraw(new_par.id === $.jstree.root); } else { // clean old parent and up tmp = obj.children_d.concat(); tmp.push(obj.id); for(i = 0, j = obj.parents.length; i < j; i++) { dpc = []; p = old_ins._model.data[obj.parents[i]].children_d; for(k = 0, l = p.length; k < l; k++) { if($.inArray(p[k], tmp) === -1) { dpc.push(p[k]); } } old_ins._model.data[obj.parents[i]].children_d = dpc; } old_ins._model.data[old_par].children = $.vakata.array_remove_item(old_ins._model.data[old_par].children, obj.id); // insert into new parent and up for(i = 0, j = new_par.parents.length; i < j; i++) { this._model.data[new_par.parents[i]].children_d = this._model.data[new_par.parents[i]].children_d.concat(tmp); } dpc = []; for(i = 0, j = new_par.children.length; i < j; i++) { dpc[i >= pos ? i+1 : i] = new_par.children[i]; } dpc[pos] = obj.id; new_par.children = dpc; new_par.children_d.push(obj.id); new_par.children_d = new_par.children_d.concat(obj.children_d); // update object obj.parent = new_par.id; tmp = new_par.parents.concat(); tmp.unshift(new_par.id); p = obj.parents.length; obj.parents = tmp; // update object children tmp = tmp.concat(); for(i = 0, j = obj.children_d.length; i < j; i++) { this._model.data[obj.children_d[i]].parents = this._model.data[obj.children_d[i]].parents.slice(0,p*-1); Array.prototype.push.apply(this._model.data[obj.children_d[i]].parents, tmp); } if(old_par === $.jstree.root || new_par.id === $.jstree.root) { this._model.force_full_redraw = true; } if(!this._model.force_full_redraw) { this._node_changed(old_par); this._node_changed(new_par.id); } if(!skip_redraw) { this.redraw(); } } if(callback) { callback.call(this, obj, new_par, pos); } /** * triggered when a node is moved * @event * @name move_node.jstree * @param {Object} node * @param {String} parent the parent's ID * @param {Number} position the position of the node among the parent's children * @param {String} old_parent the old parent of the node * @param {Number} old_position the old position of the node * @param {Boolean} is_multi do the node and new parent belong to different instances * @param {jsTree} old_instance the instance the node came from * @param {jsTree} new_instance the instance of the new parent */ this.trigger('move_node', { "node" : obj, "parent" : new_par.id, "position" : pos, "old_parent" : old_par, "old_position" : old_pos, 'is_multi' : (old_ins && old_ins._id && old_ins._id !== this._id), 'is_foreign' : (!old_ins || !old_ins._id), 'old_instance' : old_ins, 'new_instance' : this }); return obj.id; }, /** * copy a node to a new parent * @name copy_node(obj, par [, pos, callback, is_loaded]) * @param {mixed} obj the node to copy, pass an array to copy multiple nodes * @param {mixed} par the new parent * @param {mixed} pos the position to insert at (besides integer values, "first" and "last" are supported, as well as "before" and "after"), defaults to integer `0` * @param {function} callback a function to call once the move is completed, receives 3 arguments - the node, the new parent and the position * @param {Boolean} is_loaded internal parameter indicating if the parent node has been loaded * @param {Boolean} skip_redraw internal parameter indicating if the tree should be redrawn * @param {Boolean} instance internal parameter indicating if the node comes from another instance * @trigger model.jstree copy_node.jstree */ copy_node : function (obj, par, pos, callback, is_loaded, skip_redraw, origin) { var t1, t2, dpc, tmp, i, j, node, old_par, new_par, old_ins, is_multi; par = this.get_node(par); pos = pos === undefined ? 0 : pos; if(!par) { return false; } if(!pos.toString().match(/^(before|after)$/) && !is_loaded && !this.is_loaded(par)) { return this.load_node(par, function () { this.copy_node(obj, par, pos, callback, true, false, origin); }); } if($.vakata.is_array(obj)) { if(obj.length === 1) { obj = obj[0]; } else { //obj = obj.slice(); for(t1 = 0, t2 = obj.length; t1 < t2; t1++) { if((tmp = this.copy_node(obj[t1], par, pos, callback, is_loaded, true, origin))) { par = tmp; pos = "after"; } } this.redraw(); return true; } } obj = obj && (obj.id !== undefined) ? obj : this.get_node(obj); if(!obj || obj.id === $.jstree.root) { return false; } old_par = (obj.parent || $.jstree.root).toString(); new_par = (!pos.toString().match(/^(before|after)$/) || par.id === $.jstree.root) ? par : this.get_node(par.parent); old_ins = origin ? origin : (this._model.data[obj.id] ? this : $.jstree.reference(obj.id)); is_multi = !old_ins || !old_ins._id || (this._id !== old_ins._id); if(old_ins && old_ins._id) { obj = old_ins._model.data[obj.id]; } if(par.id === $.jstree.root) { if(pos === "before") { pos = "first"; } if(pos === "after") { pos = "last"; } } switch(pos) { case "before": pos = $.inArray(par.id, new_par.children); break; case "after" : pos = $.inArray(par.id, new_par.children) + 1; break; case "inside": case "first": pos = 0; break; case "last": pos = new_par.children.length; break; default: if(!pos) { pos = 0; } break; } if(pos > new_par.children.length) { pos = new_par.children.length; } if(!this.check("copy_node", obj, new_par, pos, { 'core' : true, 'origin' : origin, 'is_multi' : (old_ins && old_ins._id && old_ins._id !== this._id), 'is_foreign' : (!old_ins || !old_ins._id) })) { this.settings.core.error.call(this, this._data.core.last_error); return false; } node = old_ins ? old_ins.get_json(obj, { no_id : true, no_data : true, no_state : true }) : obj; if(!node) { return false; } if(node.id === true) { delete node.id; } node = this._parse_model_from_json(node, new_par.id, new_par.parents.concat()); if(!node) { return false; } tmp = this.get_node(node); if(obj && obj.state && obj.state.loaded === false) { tmp.state.loaded = false; } dpc = []; dpc.push(node); dpc = dpc.concat(tmp.children_d); this.trigger('model', { "nodes" : dpc, "parent" : new_par.id }); // insert into new parent and up for(i = 0, j = new_par.parents.length; i < j; i++) { this._model.data[new_par.parents[i]].children_d = this._model.data[new_par.parents[i]].children_d.concat(dpc); } dpc = []; for(i = 0, j = new_par.children.length; i < j; i++) { dpc[i >= pos ? i+1 : i] = new_par.children[i]; } dpc[pos] = tmp.id; new_par.children = dpc; new_par.children_d.push(tmp.id); new_par.children_d = new_par.children_d.concat(tmp.children_d); if(new_par.id === $.jstree.root) { this._model.force_full_redraw = true; } if(!this._model.force_full_redraw) { this._node_changed(new_par.id); } if(!skip_redraw) { this.redraw(new_par.id === $.jstree.root); } if(callback) { callback.call(this, tmp, new_par, pos); } /** * triggered when a node is copied * @event * @name copy_node.jstree * @param {Object} node the copied node * @param {Object} original the original node * @param {String} parent the parent's ID * @param {Number} position the position of the node among the parent's children * @param {String} old_parent the old parent of the node * @param {Number} old_position the position of the original node * @param {Boolean} is_multi do the node and new parent belong to different instances * @param {jsTree} old_instance the instance the node came from * @param {jsTree} new_instance the instance of the new parent */ this.trigger('copy_node', { "node" : tmp, "original" : obj, "parent" : new_par.id, "position" : pos, "old_parent" : old_par, "old_position" : old_ins && old_ins._id && old_par && old_ins._model.data[old_par] && old_ins._model.data[old_par].children ? $.inArray(obj.id, old_ins._model.data[old_par].children) : -1,'is_multi' : (old_ins && old_ins._id && old_ins._id !== this._id), 'is_foreign' : (!old_ins || !old_ins._id), 'old_instance' : old_ins, 'new_instance' : this }); return tmp.id; }, /** * cut a node (a later call to `paste(obj)` would move the node) * @name cut(obj) * @param {mixed} obj multiple objects can be passed using an array * @trigger cut.jstree */ cut : function (obj) { if(!obj) { obj = this._data.core.selected.concat(); } if(!$.vakata.is_array(obj)) { obj = [obj]; } if(!obj.length) { return false; } var tmp = [], o, t1, t2; for(t1 = 0, t2 = obj.length; t1 < t2; t1++) { o = this.get_node(obj[t1]); if(o && (o.id || o.id === 0) && o.id !== $.jstree.root) { tmp.push(o); } } if(!tmp.length) { return false; } ccp_node = tmp; ccp_inst = this; ccp_mode = 'move_node'; /** * triggered when nodes are added to the buffer for moving * @event * @name cut.jstree * @param {Array} node */ this.trigger('cut', { "node" : obj }); }, /** * copy a node (a later call to `paste(obj)` would copy the node) * @name copy(obj) * @param {mixed} obj multiple objects can be passed using an array * @trigger copy.jstree */ copy : function (obj) { if(!obj) { obj = this._data.core.selected.concat(); } if(!$.vakata.is_array(obj)) { obj = [obj]; } if(!obj.length) { return false; } var tmp = [], o, t1, t2; for(t1 = 0, t2 = obj.length; t1 < t2; t1++) { o = this.get_node(obj[t1]); if(o && (o.id !== undefined) && o.id !== $.jstree.root) { tmp.push(o); } } if(!tmp.length) { return false; } ccp_node = tmp; ccp_inst = this; ccp_mode = 'copy_node'; /** * triggered when nodes are added to the buffer for copying * @event * @name copy.jstree * @param {Array} node */ this.trigger('copy', { "node" : obj }); }, /** * get the current buffer (any nodes that are waiting for a paste operation) * @name get_buffer() * @return {Object} an object consisting of `mode` ("copy_node" or "move_node"), `node` (an array of objects) and `inst` (the instance) */ get_buffer : function () { return { 'mode' : ccp_mode, 'node' : ccp_node, 'inst' : ccp_inst }; }, /** * check if there is something in the buffer to paste * @name can_paste() * @return {Boolean} */ can_paste : function () { return ccp_mode !== false && ccp_node !== false; // && ccp_inst._model.data[ccp_node]; }, /** * copy or move the previously cut or copied nodes to a new parent * @name paste(obj [, pos]) * @param {mixed} obj the new parent * @param {mixed} pos the position to insert at (besides integer, "first" and "last" are supported), defaults to integer `0` * @trigger paste.jstree */ paste : function (obj, pos) { obj = this.get_node(obj); if(!obj || !ccp_mode || !ccp_mode.match(/^(copy_node|move_node)$/) || !ccp_node) { return false; } if(this[ccp_mode](ccp_node, obj, pos, false, false, false, ccp_inst)) { /** * triggered when paste is invoked * @event * @name paste.jstree * @param {String} parent the ID of the receiving node * @param {Array} node the nodes in the buffer * @param {String} mode the performed operation - "copy_node" or "move_node" */ this.trigger('paste', { "parent" : obj.id, "node" : ccp_node, "mode" : ccp_mode }); } ccp_node = false; ccp_mode = false; ccp_inst = false; }, /** * clear the buffer of previously copied or cut nodes * @name clear_buffer() * @trigger clear_buffer.jstree */ clear_buffer : function () { ccp_node = false; ccp_mode = false; ccp_inst = false; /** * triggered when the copy / cut buffer is cleared * @event * @name clear_buffer.jstree */ this.trigger('clear_buffer'); }, /** * put a node in edit mode (input field to rename the node) * @name edit(obj [, default_text, callback]) * @param {mixed} obj * @param {String} default_text the text to populate the input with (if omitted or set to a non-string value the node's text value is used) * @param {Function} callback a function to be called once the text box is blurred, it is called in the instance's scope and receives the node, a status parameter (true if the rename is successful, false otherwise), a boolean indicating if the user cancelled the edit and the original unescaped value provided by the user. You can also access the node's title using .text */ edit : function (obj, default_text, callback) { var rtl, w, a, s, t, h1, h2, fn, tmp, cancel = false; obj = this.get_node(obj); if(!obj) { return false; } if(!this.check("edit", obj, this.get_parent(obj))) { this.settings.core.error.call(this, this._data.core.last_error); return false; } tmp = obj; default_text = typeof default_text === 'string' ? default_text : obj.text; this.set_text(obj, ""); obj = this._open_to(obj); tmp.text = default_text; rtl = this._data.core.rtl; w = this.element.width(); this._data.core.focused = tmp.id; a = obj.children('.jstree-anchor').trigger('focus'); s = $(''); /*! oi = obj.children("i:visible"), ai = a.children("i:visible"), w1 = oi.width() * oi.length, w2 = ai.width() * ai.length, */ t = default_text; h1 = $("<"+"div>", { css : { "position" : "absolute", "top" : "-200px", "left" : (rtl ? "0px" : "-1000px"), "visibility" : "hidden" } }).appendTo(document.body); h2 = $("<"+"input />", { "value" : t, "class" : "jstree-rename-input", // "size" : t.length, "css" : { "padding" : "0", "border" : "1px solid silver", "box-sizing" : "border-box", "display" : "inline-block", "height" : (this._data.core.li_height) + "px", "lineHeight" : (this._data.core.li_height) + "px", "width" : "150px" // will be set a bit further down }, "blur" : function (e) { e.stopImmediatePropagation(); e.preventDefault(); var i = s.children(".jstree-rename-input"), v = i.val(), f = this.settings.core.force_text, nv; if(v === "") { v = t; } h1.remove(); s.replaceWith(a); s.remove(); t = f ? t : $('
    ').append($.parseHTML(t)).html(); obj = this.get_node(obj); this.set_text(obj, t); nv = !!this.rename_node(obj, f ? $('
    ').text(v).text() : $('
    ').append($.parseHTML(v)).html()); if(!nv) { this.set_text(obj, t); // move this up? and fix #483 } this._data.core.focused = tmp.id; setTimeout(function () { var node = this.get_node(tmp.id, true); if(node.length) { this._data.core.focused = tmp.id; node.children('.jstree-anchor').trigger('focus'); } }.bind(this), 0); if(callback) { callback.call(this, tmp, nv, cancel, v); } h2 = null; }.bind(this), "keydown" : function (e) { var key = e.which; if(key === 27) { cancel = true; this.value = t; } if(key === 27 || key === 13 || key === 37 || key === 38 || key === 39 || key === 40 || key === 32) { e.stopImmediatePropagation(); } if(key === 27 || key === 13) { e.preventDefault(); this.blur(); } }, "click" : function (e) { e.stopImmediatePropagation(); }, "mousedown" : function (e) { e.stopImmediatePropagation(); }, "keyup" : function (e) { h2.width(Math.min(h1.text("pW" + this.value).width(),w)); }, "keypress" : function(e) { if(e.which === 13) { return false; } } }); fn = { fontFamily : a.css('fontFamily') || '', fontSize : a.css('fontSize') || '', fontWeight : a.css('fontWeight') || '', fontStyle : a.css('fontStyle') || '', fontStretch : a.css('fontStretch') || '', fontVariant : a.css('fontVariant') || '', letterSpacing : a.css('letterSpacing') || '', wordSpacing : a.css('wordSpacing') || '' }; s.attr('class', a.attr('class')).append(a.contents().clone()).append(h2); a.replaceWith(s); h1.css(fn); h2.css(fn).width(Math.min(h1.text("pW" + h2[0].value).width(),w))[0].select(); $(document).one('mousedown.jstree touchstart.jstree dnd_start.vakata', function (e) { if (h2 && e.target !== h2) { $(h2).trigger('blur'); } }); }, /** * changes the theme * @name set_theme(theme_name [, theme_url]) * @param {String} theme_name the name of the new theme to apply * @param {mixed} theme_url the location of the CSS file for this theme. Omit or set to `false` if you manually included the file. Set to `true` to autoload from the `core.themes.dir` directory. * @trigger set_theme.jstree */ set_theme : function (theme_name, theme_url) { if(!theme_name) { return false; } if(theme_url === true) { var dir = this.settings.core.themes.dir; if(!dir) { dir = $.jstree.path + '/themes'; } theme_url = dir + '/' + theme_name + '/style.css'; } if(theme_url && $.inArray(theme_url, themes_loaded) === -1) { $('head').append('<'+'link rel="stylesheet" href="' + theme_url + '" type="text/css" />'); themes_loaded.push(theme_url); } if(this._data.core.themes.name) { this.element.removeClass('jstree-' + this._data.core.themes.name); } this._data.core.themes.name = theme_name; this.element.addClass('jstree-' + theme_name); this.element[this.settings.core.themes.responsive ? 'addClass' : 'removeClass' ]('jstree-' + theme_name + '-responsive'); /** * triggered when a theme is set * @event * @name set_theme.jstree * @param {String} theme the new theme */ this.trigger('set_theme', { 'theme' : theme_name }); }, /** * gets the name of the currently applied theme name * @name get_theme() * @return {String} */ get_theme : function () { return this._data.core.themes.name; }, /** * changes the theme variant (if the theme has variants) * @name set_theme_variant(variant_name) * @param {String|Boolean} variant_name the variant to apply (if `false` is used the current variant is removed) */ set_theme_variant : function (variant_name) { if(this._data.core.themes.variant) { this.element.removeClass('jstree-' + this._data.core.themes.name + '-' + this._data.core.themes.variant); } this._data.core.themes.variant = variant_name; if(variant_name) { this.element.addClass('jstree-' + this._data.core.themes.name + '-' + this._data.core.themes.variant); } }, /** * gets the name of the currently applied theme variant * @name get_theme() * @return {String} */ get_theme_variant : function () { return this._data.core.themes.variant; }, /** * shows a striped background on the container (if the theme supports it) * @name show_stripes() */ show_stripes : function () { this._data.core.themes.stripes = true; this.get_container_ul().addClass("jstree-striped"); /** * triggered when stripes are shown * @event * @name show_stripes.jstree */ this.trigger('show_stripes'); }, /** * hides the striped background on the container * @name hide_stripes() */ hide_stripes : function () { this._data.core.themes.stripes = false; this.get_container_ul().removeClass("jstree-striped"); /** * triggered when stripes are hidden * @event * @name hide_stripes.jstree */ this.trigger('hide_stripes'); }, /** * toggles the striped background on the container * @name toggle_stripes() */ toggle_stripes : function () { if(this._data.core.themes.stripes) { this.hide_stripes(); } else { this.show_stripes(); } }, /** * shows the connecting dots (if the theme supports it) * @name show_dots() */ show_dots : function () { this._data.core.themes.dots = true; this.get_container_ul().removeClass("jstree-no-dots"); /** * triggered when dots are shown * @event * @name show_dots.jstree */ this.trigger('show_dots'); }, /** * hides the connecting dots * @name hide_dots() */ hide_dots : function () { this._data.core.themes.dots = false; this.get_container_ul().addClass("jstree-no-dots"); /** * triggered when dots are hidden * @event * @name hide_dots.jstree */ this.trigger('hide_dots'); }, /** * toggles the connecting dots * @name toggle_dots() */ toggle_dots : function () { if(this._data.core.themes.dots) { this.hide_dots(); } else { this.show_dots(); } }, /** * show the node icons * @name show_icons() */ show_icons : function () { this._data.core.themes.icons = true; this.get_container_ul().removeClass("jstree-no-icons"); /** * triggered when icons are shown * @event * @name show_icons.jstree */ this.trigger('show_icons'); }, /** * hide the node icons * @name hide_icons() */ hide_icons : function () { this._data.core.themes.icons = false; this.get_container_ul().addClass("jstree-no-icons"); /** * triggered when icons are hidden * @event * @name hide_icons.jstree */ this.trigger('hide_icons'); }, /** * toggle the node icons * @name toggle_icons() */ toggle_icons : function () { if(this._data.core.themes.icons) { this.hide_icons(); } else { this.show_icons(); } }, /** * show the node ellipsis * @name show_icons() */ show_ellipsis : function () { this._data.core.themes.ellipsis = true; this.get_container_ul().addClass("jstree-ellipsis"); /** * triggered when ellisis is shown * @event * @name show_ellipsis.jstree */ this.trigger('show_ellipsis'); }, /** * hide the node ellipsis * @name hide_ellipsis() */ hide_ellipsis : function () { this._data.core.themes.ellipsis = false; this.get_container_ul().removeClass("jstree-ellipsis"); /** * triggered when ellisis is hidden * @event * @name hide_ellipsis.jstree */ this.trigger('hide_ellipsis'); }, /** * toggle the node ellipsis * @name toggle_icons() */ toggle_ellipsis : function () { if(this._data.core.themes.ellipsis) { this.hide_ellipsis(); } else { this.show_ellipsis(); } }, /** * set the node icon for a node * @name set_icon(obj, icon) * @param {mixed} obj * @param {String} icon the new icon - can be a path to an icon or a className, if using an image that is in the current directory use a `./` prefix, otherwise it will be detected as a class */ set_icon : function (obj, icon) { var t1, t2, dom, old; if($.vakata.is_array(obj)) { obj = obj.slice(); for(t1 = 0, t2 = obj.length; t1 < t2; t1++) { this.set_icon(obj[t1], icon); } return true; } obj = this.get_node(obj); if(!obj || obj.id === $.jstree.root) { return false; } old = obj.icon; obj.icon = icon === true || icon === null || icon === undefined || icon === '' ? true : icon; dom = this.get_node(obj, true).children(".jstree-anchor").children(".jstree-themeicon"); if(icon === false) { dom.removeClass('jstree-themeicon-custom ' + old).css("background","").removeAttr("rel"); this.hide_icon(obj); } else if(icon === true || icon === null || icon === undefined || icon === '') { dom.removeClass('jstree-themeicon-custom ' + old).css("background","").removeAttr("rel"); if(old === false) { this.show_icon(obj); } } else if(icon.indexOf("/") === -1 && icon.indexOf(".") === -1) { dom.removeClass(old).css("background",""); dom.addClass(icon + ' jstree-themeicon-custom').attr("rel",icon); if(old === false) { this.show_icon(obj); } } else { dom.removeClass(old).css("background",""); dom.addClass('jstree-themeicon-custom').css("background", "url('" + icon + "') center center no-repeat").attr("rel",icon); if(old === false) { this.show_icon(obj); } } return true; }, /** * get the node icon for a node * @name get_icon(obj) * @param {mixed} obj * @return {String} */ get_icon : function (obj) { obj = this.get_node(obj); return (!obj || obj.id === $.jstree.root) ? false : obj.icon; }, /** * hide the icon on an individual node * @name hide_icon(obj) * @param {mixed} obj */ hide_icon : function (obj) { var t1, t2; if($.vakata.is_array(obj)) { obj = obj.slice(); for(t1 = 0, t2 = obj.length; t1 < t2; t1++) { this.hide_icon(obj[t1]); } return true; } obj = this.get_node(obj); if(!obj || obj === $.jstree.root) { return false; } obj.icon = false; this.get_node(obj, true).children(".jstree-anchor").children(".jstree-themeicon").addClass('jstree-themeicon-hidden'); return true; }, /** * show the icon on an individual node * @name show_icon(obj) * @param {mixed} obj */ show_icon : function (obj) { var t1, t2, dom; if($.vakata.is_array(obj)) { obj = obj.slice(); for(t1 = 0, t2 = obj.length; t1 < t2; t1++) { this.show_icon(obj[t1]); } return true; } obj = this.get_node(obj); if(!obj || obj === $.jstree.root) { return false; } dom = this.get_node(obj, true); obj.icon = dom.length ? dom.children(".jstree-anchor").children(".jstree-themeicon").attr('rel') : true; if(!obj.icon) { obj.icon = true; } dom.children(".jstree-anchor").children(".jstree-themeicon").removeClass('jstree-themeicon-hidden'); return true; } }; // helpers $.vakata = {}; // collect attributes $.vakata.attributes = function(node, with_values) { node = $(node)[0]; var attr = with_values ? {} : []; if(node && node.attributes) { $.each(node.attributes, function (i, v) { if($.inArray(v.name.toLowerCase(),['style','contenteditable','hasfocus','tabindex']) !== -1) { return; } if(v.value !== null && $.vakata.trim(v.value) !== '') { if(with_values) { attr[v.name] = v.value; } else { attr.push(v.name); } } }); } return attr; }; $.vakata.array_unique = function(array) { var a = [], i, j, l, o = {}; for(i = 0, l = array.length; i < l; i++) { if(o[array[i]] === undefined) { a.push(array[i]); o[array[i]] = true; } } return a; }; // remove item from array $.vakata.array_remove = function(array, from) { array.splice(from, 1); return array; //var rest = array.slice((to || from) + 1 || array.length); //array.length = from < 0 ? array.length + from : from; //array.push.apply(array, rest); //return array; }; // remove item from array $.vakata.array_remove_item = function(array, item) { var tmp = $.inArray(item, array); return tmp !== -1 ? $.vakata.array_remove(array, tmp) : array; }; $.vakata.array_filter = function(c,a,b,d,e) { if (c.filter) { return c.filter(a, b); } d=[]; for (e in c) { if (~~e+''===e+'' && e>=0 && a.call(b,c[e],+e,c)) { d.push(c[e]); } } return d; }; $.vakata.trim = function (text) { return String.prototype.trim ? String.prototype.trim.call(text.toString()) : text.toString().replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, ''); }; $.vakata.is_function = function(obj) { return typeof obj === "function" && typeof obj.nodeType !== "number"; }; $.vakata.is_array = Array.isArray || function (obj) { return Object.prototype.toString.call(obj) === "[object Array]"; }; // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_objects/Function/bind#polyfill if (!Function.prototype.bind) { Function.prototype.bind = function () { var thatFunc = this, thatArg = arguments[0]; var args = Array.prototype.slice.call(arguments, 1); if (typeof thatFunc !== 'function') { // closest thing possible to the ECMAScript 5 // internal IsCallable function throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable'); } return function(){ var funcArgs = args.concat(Array.prototype.slice.call(arguments)); return thatFunc.apply(thatArg, funcArgs); }; }; } /** * ### Changed plugin * * This plugin adds more information to the `changed.jstree` event. The new data is contained in the `changed` event data property, and contains a lists of `selected` and `deselected` nodes. */ $.jstree.plugins.changed = function (options, parent) { var last = []; this.trigger = function (ev, data) { var i, j; if(!data) { data = {}; } if(ev.replace('.jstree','') === 'changed') { data.changed = { selected : [], deselected : [] }; var tmp = {}; for(i = 0, j = last.length; i < j; i++) { tmp[last[i]] = 1; } for(i = 0, j = data.selected.length; i < j; i++) { if(!tmp[data.selected[i]]) { data.changed.selected.push(data.selected[i]); } else { tmp[data.selected[i]] = 2; } } for(i = 0, j = last.length; i < j; i++) { if(tmp[last[i]] === 1) { data.changed.deselected.push(last[i]); } } last = data.selected.slice(); } /** * triggered when selection changes (the "changed" plugin enhances the original event with more data) * @event * @name changed.jstree * @param {Object} node * @param {Object} action the action that caused the selection to change * @param {Array} selected the current selection * @param {Object} changed an object containing two properties `selected` and `deselected` - both arrays of node IDs, which were selected or deselected since the last changed event * @param {Object} event the event (if any) that triggered this changed event * @plugin changed */ parent.trigger.call(this, ev, data); }; this.refresh = function (skip_loading, forget_state) { last = []; return parent.refresh.apply(this, arguments); }; }; /** * ### Checkbox plugin * * This plugin renders checkbox icons in front of each node, making multiple selection much easier. * It also supports tri-state behavior, meaning that if a node has a few of its children checked it will be rendered as undetermined, and state will be propagated up. */ var _i = document.createElement('I'); _i.className = 'jstree-icon jstree-checkbox'; _i.setAttribute('role', 'presentation'); /** * stores all defaults for the checkbox plugin * @name $.jstree.defaults.checkbox * @plugin checkbox */ $.jstree.defaults.checkbox = { /** * a boolean indicating if checkboxes should be visible (can be changed at a later time using `show_checkboxes()` and `hide_checkboxes`). Defaults to `true`. * @name $.jstree.defaults.checkbox.visible * @plugin checkbox */ visible : true, /** * a boolean indicating if checkboxes should cascade down and have an undetermined state. Defaults to `true`. * @name $.jstree.defaults.checkbox.three_state * @plugin checkbox */ three_state : true, /** * a boolean indicating if clicking anywhere on the node should act as clicking on the checkbox. Defaults to `true`. * @name $.jstree.defaults.checkbox.whole_node * @plugin checkbox */ whole_node : true, /** * a boolean indicating if the selected style of a node should be kept, or removed. Defaults to `true`. * @name $.jstree.defaults.checkbox.keep_selected_style * @plugin checkbox */ keep_selected_style : true, /** * This setting controls how cascading and undetermined nodes are applied. * If 'up' is in the string - cascading up is enabled, if 'down' is in the string - cascading down is enabled, if 'undetermined' is in the string - undetermined nodes will be used. * If `three_state` is set to `true` this setting is automatically set to 'up+down+undetermined'. Defaults to ''. * @name $.jstree.defaults.checkbox.cascade * @plugin checkbox */ cascade : '', /** * This setting controls if checkbox are bound to the general tree selection or to an internal array maintained by the checkbox plugin. Defaults to `true`, only set to `false` if you know exactly what you are doing. * @name $.jstree.defaults.checkbox.tie_selection * @plugin checkbox */ tie_selection : true, /** * This setting controls if cascading down affects disabled checkboxes * @name $.jstree.defaults.checkbox.cascade_to_disabled * @plugin checkbox */ cascade_to_disabled : true, /** * This setting controls if cascading down affects hidden checkboxes * @name $.jstree.defaults.checkbox.cascade_to_hidden * @plugin checkbox */ cascade_to_hidden : true }; $.jstree.plugins.checkbox = function (options, parent) { this.bind = function () { parent.bind.call(this); this._data.checkbox.uto = false; this._data.checkbox.selected = []; if(this.settings.checkbox.three_state) { this.settings.checkbox.cascade = 'up+down+undetermined'; } this.element .on("init.jstree", function () { this._data.checkbox.visible = this.settings.checkbox.visible; if(!this.settings.checkbox.keep_selected_style) { this.element.addClass('jstree-checkbox-no-clicked'); } if(this.settings.checkbox.tie_selection) { this.element.addClass('jstree-checkbox-selection'); } }.bind(this)) .on("loading.jstree", function () { this[ this._data.checkbox.visible ? 'show_checkboxes' : 'hide_checkboxes' ](); }.bind(this)); if(this.settings.checkbox.cascade.indexOf('undetermined') !== -1) { this.element .on('changed.jstree uncheck_node.jstree check_node.jstree uncheck_all.jstree check_all.jstree move_node.jstree copy_node.jstree redraw.jstree open_node.jstree', function () { // only if undetermined is in setting if(this._data.checkbox.uto) { clearTimeout(this._data.checkbox.uto); } this._data.checkbox.uto = setTimeout(this._undetermined.bind(this), 50); }.bind(this)); } if(!this.settings.checkbox.tie_selection) { this.element .on('model.jstree', function (e, data) { var m = this._model.data, p = m[data.parent], dpc = data.nodes, i, j; for(i = 0, j = dpc.length; i < j; i++) { m[dpc[i]].state.checked = m[dpc[i]].state.checked || (m[dpc[i]].original && m[dpc[i]].original.state && m[dpc[i]].original.state.checked); if(m[dpc[i]].state.checked) { this._data.checkbox.selected.push(dpc[i]); } } }.bind(this)); } if(this.settings.checkbox.cascade.indexOf('up') !== -1 || this.settings.checkbox.cascade.indexOf('down') !== -1) { this.element .on('model.jstree', function (e, data) { var m = this._model.data, p = m[data.parent], dpc = data.nodes, chd = [], c, i, j, k, l, tmp, s = this.settings.checkbox.cascade, t = this.settings.checkbox.tie_selection; if(s.indexOf('down') !== -1) { // apply down if(p.state[ t ? 'selected' : 'checked' ]) { for(i = 0, j = dpc.length; i < j; i++) { m[dpc[i]].state[ t ? 'selected' : 'checked' ] = true; } this._data[ t ? 'core' : 'checkbox' ].selected = this._data[ t ? 'core' : 'checkbox' ].selected.concat(dpc); } else { for(i = 0, j = dpc.length; i < j; i++) { if(m[dpc[i]].state[ t ? 'selected' : 'checked' ]) { for(k = 0, l = m[dpc[i]].children_d.length; k < l; k++) { m[m[dpc[i]].children_d[k]].state[ t ? 'selected' : 'checked' ] = true; } this._data[ t ? 'core' : 'checkbox' ].selected = this._data[ t ? 'core' : 'checkbox' ].selected.concat(m[dpc[i]].children_d); } } } } if(s.indexOf('up') !== -1) { // apply up for(i = 0, j = p.children_d.length; i < j; i++) { if(!m[p.children_d[i]].children.length) { chd.push(m[p.children_d[i]].parent); } } chd = $.vakata.array_unique(chd); for(k = 0, l = chd.length; k < l; k++) { p = m[chd[k]]; while(p && p.id !== $.jstree.root) { c = 0; for(i = 0, j = p.children.length; i < j; i++) { c += m[p.children[i]].state[ t ? 'selected' : 'checked' ]; } if(c === j) { p.state[ t ? 'selected' : 'checked' ] = true; this._data[ t ? 'core' : 'checkbox' ].selected.push(p.id); tmp = this.get_node(p, true); if(tmp && tmp.length) { tmp.children('.jstree-anchor').attr('aria-selected', true).addClass( t ? 'jstree-clicked' : 'jstree-checked'); } } else { break; } p = this.get_node(p.parent); } } } this._data[ t ? 'core' : 'checkbox' ].selected = $.vakata.array_unique(this._data[ t ? 'core' : 'checkbox' ].selected); }.bind(this)) .on(this.settings.checkbox.tie_selection ? 'select_node.jstree' : 'check_node.jstree', function (e, data) { var self = this, obj = data.node, m = this._model.data, par = this.get_node(obj.parent), i, j, c, tmp, s = this.settings.checkbox.cascade, t = this.settings.checkbox.tie_selection, sel = {}, cur = this._data[ t ? 'core' : 'checkbox' ].selected; for (i = 0, j = cur.length; i < j; i++) { sel[cur[i]] = true; } // apply down if(s.indexOf('down') !== -1) { //this._data[ t ? 'core' : 'checkbox' ].selected = $.vakata.array_unique(this._data[ t ? 'core' : 'checkbox' ].selected.concat(obj.children_d)); var selectedIds = this._cascade_new_checked_state(obj.id, true); var temp = obj.children_d.concat(obj.id); for (i = 0, j = temp.length; i < j; i++) { if (selectedIds.indexOf(temp[i]) > -1) { sel[temp[i]] = true; } else { delete sel[temp[i]]; } } } // apply up if(s.indexOf('up') !== -1) { while(par && par.id !== $.jstree.root) { c = 0; for(i = 0, j = par.children.length; i < j; i++) { c += m[par.children[i]].state[ t ? 'selected' : 'checked' ]; } if(c === j) { par.state[ t ? 'selected' : 'checked' ] = true; sel[par.id] = true; //this._data[ t ? 'core' : 'checkbox' ].selected.push(par.id); tmp = this.get_node(par, true); if(tmp && tmp.length) { tmp.children('.jstree-anchor').attr('aria-selected', true).addClass(t ? 'jstree-clicked' : 'jstree-checked'); } } else { break; } par = this.get_node(par.parent); } } cur = []; for (i in sel) { if (sel.hasOwnProperty(i)) { cur.push(i); } } this._data[ t ? 'core' : 'checkbox' ].selected = cur; }.bind(this)) .on(this.settings.checkbox.tie_selection ? 'deselect_all.jstree' : 'uncheck_all.jstree', function (e, data) { var obj = this.get_node($.jstree.root), m = this._model.data, i, j, tmp; for(i = 0, j = obj.children_d.length; i < j; i++) { tmp = m[obj.children_d[i]]; if(tmp && tmp.original && tmp.original.state && tmp.original.state.undetermined) { tmp.original.state.undetermined = false; } } }.bind(this)) .on(this.settings.checkbox.tie_selection ? 'deselect_node.jstree' : 'uncheck_node.jstree', function (e, data) { var self = this, obj = data.node, dom = this.get_node(obj, true), i, j, tmp, s = this.settings.checkbox.cascade, t = this.settings.checkbox.tie_selection, cur = this._data[ t ? 'core' : 'checkbox' ].selected, sel = {}, stillSelectedIds = [], allIds = obj.children_d.concat(obj.id); // apply down if(s.indexOf('down') !== -1) { var selectedIds = this._cascade_new_checked_state(obj.id, false); cur = $.vakata.array_filter(cur, function(id) { return allIds.indexOf(id) === -1 || selectedIds.indexOf(id) > -1; }); } // only apply up if cascade up is enabled and if this node is not selected // (if all child nodes are disabled and cascade_to_disabled === false then this node will till be selected). if(s.indexOf('up') !== -1 && cur.indexOf(obj.id) === -1) { for(i = 0, j = obj.parents.length; i < j; i++) { tmp = this._model.data[obj.parents[i]]; tmp.state[ t ? 'selected' : 'checked' ] = false; if(tmp && tmp.original && tmp.original.state && tmp.original.state.undetermined) { tmp.original.state.undetermined = false; } tmp = this.get_node(obj.parents[i], true); if(tmp && tmp.length) { tmp.children('.jstree-anchor').attr('aria-selected', false).removeClass(t ? 'jstree-clicked' : 'jstree-checked'); } } cur = $.vakata.array_filter(cur, function(id) { return obj.parents.indexOf(id) === -1; }); } this._data[ t ? 'core' : 'checkbox' ].selected = cur; }.bind(this)); } if(this.settings.checkbox.cascade.indexOf('up') !== -1) { this.element .on('delete_node.jstree', function (e, data) { // apply up (whole handler) var p = this.get_node(data.parent), m = this._model.data, i, j, c, tmp, t = this.settings.checkbox.tie_selection; while(p && p.id !== $.jstree.root && !p.state[ t ? 'selected' : 'checked' ]) { c = 0; for(i = 0, j = p.children.length; i < j; i++) { c += m[p.children[i]].state[ t ? 'selected' : 'checked' ]; } if(j > 0 && c === j) { p.state[ t ? 'selected' : 'checked' ] = true; this._data[ t ? 'core' : 'checkbox' ].selected.push(p.id); tmp = this.get_node(p, true); if(tmp && tmp.length) { tmp.children('.jstree-anchor').attr('aria-selected', true).addClass(t ? 'jstree-clicked' : 'jstree-checked'); } } else { break; } p = this.get_node(p.parent); } }.bind(this)) .on('move_node.jstree', function (e, data) { // apply up (whole handler) var is_multi = data.is_multi, old_par = data.old_parent, new_par = this.get_node(data.parent), m = this._model.data, p, c, i, j, tmp, t = this.settings.checkbox.tie_selection; if(!is_multi) { p = this.get_node(old_par); while(p && p.id !== $.jstree.root && !p.state[ t ? 'selected' : 'checked' ]) { c = 0; for(i = 0, j = p.children.length; i < j; i++) { c += m[p.children[i]].state[ t ? 'selected' : 'checked' ]; } if(j > 0 && c === j) { p.state[ t ? 'selected' : 'checked' ] = true; this._data[ t ? 'core' : 'checkbox' ].selected.push(p.id); tmp = this.get_node(p, true); if(tmp && tmp.length) { tmp.children('.jstree-anchor').attr('aria-selected', true).addClass(t ? 'jstree-clicked' : 'jstree-checked'); } } else { break; } p = this.get_node(p.parent); } } p = new_par; while(p && p.id !== $.jstree.root) { c = 0; for(i = 0, j = p.children.length; i < j; i++) { c += m[p.children[i]].state[ t ? 'selected' : 'checked' ]; } if(c === j) { if(!p.state[ t ? 'selected' : 'checked' ]) { p.state[ t ? 'selected' : 'checked' ] = true; this._data[ t ? 'core' : 'checkbox' ].selected.push(p.id); tmp = this.get_node(p, true); if(tmp && tmp.length) { tmp.children('.jstree-anchor').attr('aria-selected', true).addClass(t ? 'jstree-clicked' : 'jstree-checked'); } } } else { if(p.state[ t ? 'selected' : 'checked' ]) { p.state[ t ? 'selected' : 'checked' ] = false; this._data[ t ? 'core' : 'checkbox' ].selected = $.vakata.array_remove_item(this._data[ t ? 'core' : 'checkbox' ].selected, p.id); tmp = this.get_node(p, true); if(tmp && tmp.length) { tmp.children('.jstree-anchor').attr('aria-selected', false).removeClass(t ? 'jstree-clicked' : 'jstree-checked'); } } else { break; } } p = this.get_node(p.parent); } }.bind(this)); } }; /** * get an array of all nodes whose state is "undetermined" * @name get_undetermined([full]) * @param {boolean} full: if set to `true` the returned array will consist of the full node objects, otherwise - only IDs will be returned * @return {Array} * @plugin checkbox */ this.get_undetermined = function (full) { if (this.settings.checkbox.cascade.indexOf('undetermined') === -1) { return []; } var i, j, k, l, o = {}, m = this._model.data, t = this.settings.checkbox.tie_selection, s = this._data[ t ? 'core' : 'checkbox' ].selected, p = [], tt = this, r = []; for(i = 0, j = s.length; i < j; i++) { if(m[s[i]] && m[s[i]].parents) { for(k = 0, l = m[s[i]].parents.length; k < l; k++) { if(o[m[s[i]].parents[k]] !== undefined) { break; } if(m[s[i]].parents[k] !== $.jstree.root) { o[m[s[i]].parents[k]] = true; p.push(m[s[i]].parents[k]); } } } } // attempt for server side undetermined state this.element.find('.jstree-closed').not(':has(.jstree-children)') .each(function () { var tmp = tt.get_node(this), tmp2; if(!tmp) { return; } if(!tmp.state.loaded) { if(tmp.original && tmp.original.state && tmp.original.state.undetermined && tmp.original.state.undetermined === true) { if(o[tmp.id] === undefined && tmp.id !== $.jstree.root) { o[tmp.id] = true; p.push(tmp.id); } for(k = 0, l = tmp.parents.length; k < l; k++) { if(o[tmp.parents[k]] === undefined && tmp.parents[k] !== $.jstree.root) { o[tmp.parents[k]] = true; p.push(tmp.parents[k]); } } } } else { for(i = 0, j = tmp.children_d.length; i < j; i++) { tmp2 = m[tmp.children_d[i]]; if(!tmp2.state.loaded && tmp2.original && tmp2.original.state && tmp2.original.state.undetermined && tmp2.original.state.undetermined === true) { if(o[tmp2.id] === undefined && tmp2.id !== $.jstree.root) { o[tmp2.id] = true; p.push(tmp2.id); } for(k = 0, l = tmp2.parents.length; k < l; k++) { if(o[tmp2.parents[k]] === undefined && tmp2.parents[k] !== $.jstree.root) { o[tmp2.parents[k]] = true; p.push(tmp2.parents[k]); } } } } } }); for (i = 0, j = p.length; i < j; i++) { if(!m[p[i]].state[ t ? 'selected' : 'checked' ]) { r.push(full ? m[p[i]] : p[i]); } } return r; }; /** * set the undetermined state where and if necessary. Used internally. * @private * @name _undetermined() * @plugin checkbox */ this._undetermined = function () { if(this.element === null) { return; } var p = this.get_undetermined(false), i, j, s; this.element.find('.jstree-undetermined').removeClass('jstree-undetermined'); for (i = 0, j = p.length; i < j; i++) { s = this.get_node(p[i], true); if(s && s.length) { s.children('.jstree-anchor').children('.jstree-checkbox').addClass('jstree-undetermined'); } } }; this.redraw_node = function(obj, deep, is_callback, force_render) { obj = parent.redraw_node.apply(this, arguments); if(obj) { var i, j, tmp = null, icon = null; for(i = 0, j = obj.childNodes.length; i < j; i++) { if(obj.childNodes[i] && obj.childNodes[i].className && obj.childNodes[i].className.indexOf("jstree-anchor") !== -1) { tmp = obj.childNodes[i]; break; } } if(tmp) { if(!this.settings.checkbox.tie_selection && this._model.data[obj.id].state.checked) { tmp.className += ' jstree-checked'; } icon = _i.cloneNode(false); if(this._model.data[obj.id].state.checkbox_disabled) { icon.className += ' jstree-checkbox-disabled'; } tmp.insertBefore(icon, tmp.childNodes[0]); } } if(!is_callback && this.settings.checkbox.cascade.indexOf('undetermined') !== -1) { if(this._data.checkbox.uto) { clearTimeout(this._data.checkbox.uto); } this._data.checkbox.uto = setTimeout(this._undetermined.bind(this), 50); } return obj; }; /** * show the node checkbox icons * @name show_checkboxes() * @plugin checkbox */ this.show_checkboxes = function () { this._data.core.themes.checkboxes = true; this.get_container_ul().removeClass("jstree-no-checkboxes"); }; /** * hide the node checkbox icons * @name hide_checkboxes() * @plugin checkbox */ this.hide_checkboxes = function () { this._data.core.themes.checkboxes = false; this.get_container_ul().addClass("jstree-no-checkboxes"); }; /** * toggle the node icons * @name toggle_checkboxes() * @plugin checkbox */ this.toggle_checkboxes = function () { if(this._data.core.themes.checkboxes) { this.hide_checkboxes(); } else { this.show_checkboxes(); } }; /** * checks if a node is in an undetermined state * @name is_undetermined(obj) * @param {mixed} obj * @return {Boolean} */ this.is_undetermined = function (obj) { obj = this.get_node(obj); var s = this.settings.checkbox.cascade, i, j, t = this.settings.checkbox.tie_selection, d = this._data[ t ? 'core' : 'checkbox' ].selected, m = this._model.data; if(!obj || obj.state[ t ? 'selected' : 'checked' ] === true || s.indexOf('undetermined') === -1 || (s.indexOf('down') === -1 && s.indexOf('up') === -1)) { return false; } if(!obj.state.loaded && obj.original.state.undetermined === true) { return true; } for(i = 0, j = obj.children_d.length; i < j; i++) { if($.inArray(obj.children_d[i], d) !== -1 || (!m[obj.children_d[i]].state.loaded && m[obj.children_d[i]].original.state.undetermined)) { return true; } } return false; }; /** * disable a node's checkbox * @name disable_checkbox(obj) * @param {mixed} obj an array can be used too * @trigger disable_checkbox.jstree * @plugin checkbox */ this.disable_checkbox = function (obj) { var t1, t2, dom; if($.vakata.is_array(obj)) { obj = obj.slice(); for(t1 = 0, t2 = obj.length; t1 < t2; t1++) { this.disable_checkbox(obj[t1]); } return true; } obj = this.get_node(obj); if(!obj || obj.id === $.jstree.root) { return false; } dom = this.get_node(obj, true); if(!obj.state.checkbox_disabled) { obj.state.checkbox_disabled = true; if(dom && dom.length) { dom.children('.jstree-anchor').children('.jstree-checkbox').addClass('jstree-checkbox-disabled'); } /** * triggered when an node's checkbox is disabled * @event * @name disable_checkbox.jstree * @param {Object} node * @plugin checkbox */ this.trigger('disable_checkbox', { 'node' : obj }); } }; /** * enable a node's checkbox * @name enable_checkbox(obj) * @param {mixed} obj an array can be used too * @trigger enable_checkbox.jstree * @plugin checkbox */ this.enable_checkbox = function (obj) { var t1, t2, dom; if($.vakata.is_array(obj)) { obj = obj.slice(); for(t1 = 0, t2 = obj.length; t1 < t2; t1++) { this.enable_checkbox(obj[t1]); } return true; } obj = this.get_node(obj); if(!obj || obj.id === $.jstree.root) { return false; } dom = this.get_node(obj, true); if(obj.state.checkbox_disabled) { obj.state.checkbox_disabled = false; if(dom && dom.length) { dom.children('.jstree-anchor').children('.jstree-checkbox').removeClass('jstree-checkbox-disabled'); } /** * triggered when an node's checkbox is enabled * @event * @name enable_checkbox.jstree * @param {Object} node * @plugin checkbox */ this.trigger('enable_checkbox', { 'node' : obj }); } }; this.activate_node = function (obj, e) { if($(e.target).hasClass('jstree-checkbox-disabled')) { return false; } if(this.settings.checkbox.tie_selection && (this.settings.checkbox.whole_node || $(e.target).hasClass('jstree-checkbox'))) { e.ctrlKey = true; } if(this.settings.checkbox.tie_selection || (!this.settings.checkbox.whole_node && !$(e.target).hasClass('jstree-checkbox'))) { return parent.activate_node.call(this, obj, e); } if(this.is_disabled(obj)) { return false; } if(this.is_checked(obj)) { this.uncheck_node(obj, e); } else { this.check_node(obj, e); } this.trigger('activate_node', { 'node' : this.get_node(obj) }); }; this.delete_node = function (obj) { if(this.settings.checkbox.tie_selection || $.vakata.is_array(obj)) { return parent.delete_node.call(this, obj); } var tmp, k, l, c = false; obj = this.get_node(obj); if(!obj || obj.id === $.jstree.root) { return false; } tmp = obj.children_d.concat([]); tmp.push(obj.id); for(k = 0, l = tmp.length; k < l; k++) { if(this._model.data[tmp[k]].state.checked) { c = true; break; } } if (c) { this._data.checkbox.selected = $.vakata.array_filter(this._data.checkbox.selected, function (v) { return $.inArray(v, tmp) === -1; }); } return parent.delete_node.call(this, obj); }; /** * Cascades checked state to a node and all its descendants. This function does NOT affect hidden and disabled nodes (or their descendants). * However if these unaffected nodes are already selected their ids will be included in the returned array. * @private * @name _cascade_new_checked_state(id, checkedState) * @param {string} id the node ID * @param {bool} checkedState should the nodes be checked or not * @returns {Array} Array of all node id's (in this tree branch) that are checked. */ this._cascade_new_checked_state = function (id, checkedState) { var self = this; var t = this.settings.checkbox.tie_selection; var node = this._model.data[id]; var selectedNodeIds = []; var selectedChildrenIds = [], i, j, selectedChildIds; if ( (this.settings.checkbox.cascade_to_disabled || !node.state.disabled) && (this.settings.checkbox.cascade_to_hidden || !node.state.hidden) ) { //First try and check/uncheck the children if (node.children) { for (i = 0, j = node.children.length; i < j; i++) { var childId = node.children[i]; selectedChildIds = self._cascade_new_checked_state(childId, checkedState); selectedNodeIds = selectedNodeIds.concat(selectedChildIds); if (selectedChildIds.indexOf(childId) > -1) { selectedChildrenIds.push(childId); } } } var dom = self.get_node(node, true); //A node's state is undetermined if some but not all of it's children are checked/selected . var undetermined = selectedChildrenIds.length > 0 && selectedChildrenIds.length < node.children.length; if(node.original && node.original.state && node.original.state.undetermined) { node.original.state.undetermined = undetermined; } //If a node is undetermined then remove selected class if (undetermined) { node.state[ t ? 'selected' : 'checked' ] = false; dom.children('.jstree-anchor').attr('aria-selected', false).removeClass(t ? 'jstree-clicked' : 'jstree-checked'); } //Otherwise, if the checkedState === true (i.e. the node is being checked now) and all of the node's children are checked (if it has any children), //check the node and style it correctly. else if (checkedState && selectedChildrenIds.length === node.children.length) { node.state[ t ? 'selected' : 'checked' ] = checkedState; selectedNodeIds.push(node.id); dom.children('.jstree-anchor').attr('aria-selected', true).addClass(t ? 'jstree-clicked' : 'jstree-checked'); } else { node.state[ t ? 'selected' : 'checked' ] = false; dom.children('.jstree-anchor').attr('aria-selected', false).removeClass(t ? 'jstree-clicked' : 'jstree-checked'); } } else { selectedChildIds = this.get_checked_descendants(id); if (node.state[ t ? 'selected' : 'checked' ]) { selectedChildIds.push(node.id); } selectedNodeIds = selectedNodeIds.concat(selectedChildIds); } return selectedNodeIds; }; /** * Gets ids of nodes selected in branch (of tree) specified by id (does not include the node specified by id) * @name get_checked_descendants(obj) * @param {string} id the node ID * @return {Array} array of IDs * @plugin checkbox */ this.get_checked_descendants = function (id) { var self = this; var t = self.settings.checkbox.tie_selection; var node = self._model.data[id]; return $.vakata.array_filter(node.children_d, function(_id) { return self._model.data[_id].state[ t ? 'selected' : 'checked' ]; }); }; /** * check a node (only if tie_selection in checkbox settings is false, otherwise select_node will be called internally) * @name check_node(obj) * @param {mixed} obj an array can be used to check multiple nodes * @trigger check_node.jstree * @plugin checkbox */ this.check_node = function (obj, e) { if(this.settings.checkbox.tie_selection) { return this.select_node(obj, false, true, e); } var dom, t1, t2, th; if($.vakata.is_array(obj)) { obj = obj.slice(); for(t1 = 0, t2 = obj.length; t1 < t2; t1++) { this.check_node(obj[t1], e); } return true; } obj = this.get_node(obj); if(!obj || obj.id === $.jstree.root) { return false; } dom = this.get_node(obj, true); if(!obj.state.checked) { obj.state.checked = true; this._data.checkbox.selected.push(obj.id); if(dom && dom.length) { dom.children('.jstree-anchor').addClass('jstree-checked'); } /** * triggered when an node is checked (only if tie_selection in checkbox settings is false) * @event * @name check_node.jstree * @param {Object} node * @param {Array} selected the current selection * @param {Object} event the event (if any) that triggered this check_node * @plugin checkbox */ this.trigger('check_node', { 'node' : obj, 'selected' : this._data.checkbox.selected, 'event' : e }); } }; /** * uncheck a node (only if tie_selection in checkbox settings is false, otherwise deselect_node will be called internally) * @name uncheck_node(obj) * @param {mixed} obj an array can be used to uncheck multiple nodes * @trigger uncheck_node.jstree * @plugin checkbox */ this.uncheck_node = function (obj, e) { if(this.settings.checkbox.tie_selection) { return this.deselect_node(obj, false, e); } var t1, t2, dom; if($.vakata.is_array(obj)) { obj = obj.slice(); for(t1 = 0, t2 = obj.length; t1 < t2; t1++) { this.uncheck_node(obj[t1], e); } return true; } obj = this.get_node(obj); if(!obj || obj.id === $.jstree.root) { return false; } dom = this.get_node(obj, true); if(obj.state.checked) { obj.state.checked = false; this._data.checkbox.selected = $.vakata.array_remove_item(this._data.checkbox.selected, obj.id); if(dom.length) { dom.children('.jstree-anchor').removeClass('jstree-checked'); } /** * triggered when an node is unchecked (only if tie_selection in checkbox settings is false) * @event * @name uncheck_node.jstree * @param {Object} node * @param {Array} selected the current selection * @param {Object} event the event (if any) that triggered this uncheck_node * @plugin checkbox */ this.trigger('uncheck_node', { 'node' : obj, 'selected' : this._data.checkbox.selected, 'event' : e }); } }; /** * checks all nodes in the tree (only if tie_selection in checkbox settings is false, otherwise select_all will be called internally) * @name check_all() * @trigger check_all.jstree, changed.jstree * @plugin checkbox */ this.check_all = function () { if(this.settings.checkbox.tie_selection) { return this.select_all(); } var tmp = this._data.checkbox.selected.concat([]), i, j; this._data.checkbox.selected = this._model.data[$.jstree.root].children_d.concat(); for(i = 0, j = this._data.checkbox.selected.length; i < j; i++) { if(this._model.data[this._data.checkbox.selected[i]]) { this._model.data[this._data.checkbox.selected[i]].state.checked = true; } } this.redraw(true); /** * triggered when all nodes are checked (only if tie_selection in checkbox settings is false) * @event * @name check_all.jstree * @param {Array} selected the current selection * @plugin checkbox */ this.trigger('check_all', { 'selected' : this._data.checkbox.selected }); }; /** * uncheck all checked nodes (only if tie_selection in checkbox settings is false, otherwise deselect_all will be called internally) * @name uncheck_all() * @trigger uncheck_all.jstree * @plugin checkbox */ this.uncheck_all = function () { if(this.settings.checkbox.tie_selection) { return this.deselect_all(); } var tmp = this._data.checkbox.selected.concat([]), i, j; for(i = 0, j = this._data.checkbox.selected.length; i < j; i++) { if(this._model.data[this._data.checkbox.selected[i]]) { this._model.data[this._data.checkbox.selected[i]].state.checked = false; } } this._data.checkbox.selected = []; this.element.find('.jstree-checked').removeClass('jstree-checked'); /** * triggered when all nodes are unchecked (only if tie_selection in checkbox settings is false) * @event * @name uncheck_all.jstree * @param {Object} node the previous selection * @param {Array} selected the current selection * @plugin checkbox */ this.trigger('uncheck_all', { 'selected' : this._data.checkbox.selected, 'node' : tmp }); }; /** * checks if a node is checked (if tie_selection is on in the settings this function will return the same as is_selected) * @name is_checked(obj) * @param {mixed} obj * @return {Boolean} * @plugin checkbox */ this.is_checked = function (obj) { if(this.settings.checkbox.tie_selection) { return this.is_selected(obj); } obj = this.get_node(obj); if(!obj || obj.id === $.jstree.root) { return false; } return obj.state.checked; }; /** * get an array of all checked nodes (if tie_selection is on in the settings this function will return the same as get_selected) * @name get_checked([full]) * @param {mixed} full if set to `true` the returned array will consist of the full node objects, otherwise - only IDs will be returned * @return {Array} * @plugin checkbox */ this.get_checked = function (full) { if(this.settings.checkbox.tie_selection) { return this.get_selected(full); } return full ? $.map(this._data.checkbox.selected, function (i) { return this.get_node(i); }.bind(this)) : this._data.checkbox.selected.slice(); }; /** * get an array of all top level checked nodes (ignoring children of checked nodes) (if tie_selection is on in the settings this function will return the same as get_top_selected) * @name get_top_checked([full]) * @param {mixed} full if set to `true` the returned array will consist of the full node objects, otherwise - only IDs will be returned * @return {Array} * @plugin checkbox */ this.get_top_checked = function (full) { if(this.settings.checkbox.tie_selection) { return this.get_top_selected(full); } var tmp = this.get_checked(true), obj = {}, i, j, k, l; for(i = 0, j = tmp.length; i < j; i++) { obj[tmp[i].id] = tmp[i]; } for(i = 0, j = tmp.length; i < j; i++) { for(k = 0, l = tmp[i].children_d.length; k < l; k++) { if(obj[tmp[i].children_d[k]]) { delete obj[tmp[i].children_d[k]]; } } } tmp = []; for(i in obj) { if(obj.hasOwnProperty(i)) { tmp.push(i); } } return full ? $.map(tmp, function (i) { return this.get_node(i); }.bind(this)) : tmp; }; /** * get an array of all bottom level checked nodes (ignoring selected parents) (if tie_selection is on in the settings this function will return the same as get_bottom_selected) * @name get_bottom_checked([full]) * @param {mixed} full if set to `true` the returned array will consist of the full node objects, otherwise - only IDs will be returned * @return {Array} * @plugin checkbox */ this.get_bottom_checked = function (full) { if(this.settings.checkbox.tie_selection) { return this.get_bottom_selected(full); } var tmp = this.get_checked(true), obj = [], i, j; for(i = 0, j = tmp.length; i < j; i++) { if(!tmp[i].children.length) { obj.push(tmp[i].id); } } return full ? $.map(obj, function (i) { return this.get_node(i); }.bind(this)) : obj; }; this.load_node = function (obj, callback) { var k, l, i, j, c, tmp; if(!$.vakata.is_array(obj) && !this.settings.checkbox.tie_selection) { tmp = this.get_node(obj); if(tmp && tmp.state.loaded) { for(k = 0, l = tmp.children_d.length; k < l; k++) { if(this._model.data[tmp.children_d[k]].state.checked) { c = true; this._data.checkbox.selected = $.vakata.array_remove_item(this._data.checkbox.selected, tmp.children_d[k]); } } } } return parent.load_node.apply(this, arguments); }; this.get_state = function () { var state = parent.get_state.apply(this, arguments); if(this.settings.checkbox.tie_selection) { return state; } state.checkbox = this._data.checkbox.selected.slice(); return state; }; this.set_state = function (state, callback) { var res = parent.set_state.apply(this, arguments); if(res && state.checkbox) { if(!this.settings.checkbox.tie_selection) { this.uncheck_all(); var _this = this; $.each(state.checkbox, function (i, v) { _this.check_node(v); }); } delete state.checkbox; this.set_state(state, callback); return false; } return res; }; this.refresh = function (skip_loading, forget_state) { if(this.settings.checkbox.tie_selection) { this._data.checkbox.selected = []; } return parent.refresh.apply(this, arguments); }; }; // include the checkbox plugin by default // $.jstree.defaults.plugins.push("checkbox"); /** * ### Conditionalselect plugin * * This plugin allows defining a callback to allow or deny node selection by user input (activate node method). */ /** * a callback (function) which is invoked in the instance's scope and receives two arguments - the node and the event that triggered the `activate_node` call. Returning false prevents working with the node, returning true allows invoking activate_node. Defaults to returning `true`. * @name $.jstree.defaults.checkbox.visible * @plugin checkbox */ $.jstree.defaults.conditionalselect = function () { return true; }; $.jstree.plugins.conditionalselect = function (options, parent) { // own function this.activate_node = function (obj, e) { if(this.settings.conditionalselect.call(this, this.get_node(obj), e)) { return parent.activate_node.call(this, obj, e); } }; }; /** * ### Contextmenu plugin * * Shows a context menu when a node is right-clicked. */ /** * stores all defaults for the contextmenu plugin * @name $.jstree.defaults.contextmenu * @plugin contextmenu */ $.jstree.defaults.contextmenu = { /** * a boolean indicating if the node should be selected when the context menu is invoked on it. Defaults to `true`. * @name $.jstree.defaults.contextmenu.select_node * @plugin contextmenu */ select_node : true, /** * a boolean indicating if the menu should be shown aligned with the node. Defaults to `true`, otherwise the mouse coordinates are used. * @name $.jstree.defaults.contextmenu.show_at_node * @plugin contextmenu */ show_at_node : true, /** * an object of actions, or a function that accepts a node and a callback function and calls the callback function with an object of actions available for that node (you can also return the items too). * * Each action consists of a key (a unique name) and a value which is an object with the following properties (only label and action are required). Once a menu item is activated the `action` function will be invoked with an object containing the following keys: item - the contextmenu item definition as seen below, reference - the DOM node that was used (the tree node), element - the contextmenu DOM element, position - an object with x/y properties indicating the position of the menu. * * * `separator_before` - a boolean indicating if there should be a separator before this item * * `separator_after` - a boolean indicating if there should be a separator after this item * * `_disabled` - a boolean indicating if this action should be disabled * * `label` - a string - the name of the action (could be a function returning a string) * * `title` - a string - an optional tooltip for the item * * `action` - a function to be executed if this item is chosen, the function will receive * * `icon` - a string, can be a path to an icon or a className, if using an image that is in the current directory use a `./` prefix, otherwise it will be detected as a class * * `shortcut` - keyCode which will trigger the action if the menu is open (for example `113` for rename, which equals F2) * * `shortcut_label` - shortcut label (like for example `F2` for rename) * * `submenu` - an object with the same structure as $.jstree.defaults.contextmenu.items which can be used to create a submenu - each key will be rendered as a separate option in a submenu that will appear once the current item is hovered * * @name $.jstree.defaults.contextmenu.items * @plugin contextmenu */ items : function (o, cb) { // Could be an object directly return { "create" : { "separator_before" : false, "separator_after" : true, "_disabled" : false, //(this.check("create_node", data.reference, {}, "last")), "label" : "Create", "action" : function (data) { var inst = $.jstree.reference(data.reference), obj = inst.get_node(data.reference); inst.create_node(obj, {}, "last", function (new_node) { try { inst.edit(new_node); } catch (ex) { setTimeout(function () { inst.edit(new_node); },0); } }); } }, "rename" : { "separator_before" : false, "separator_after" : false, "_disabled" : false, //(this.check("rename_node", data.reference, this.get_parent(data.reference), "")), "label" : "Rename", /*! "shortcut" : 113, "shortcut_label" : 'F2', "icon" : "glyphicon glyphicon-leaf", */ "action" : function (data) { var inst = $.jstree.reference(data.reference), obj = inst.get_node(data.reference); inst.edit(obj); } }, "remove" : { "separator_before" : false, "icon" : false, "separator_after" : false, "_disabled" : false, //(this.check("delete_node", data.reference, this.get_parent(data.reference), "")), "label" : "Delete", "action" : function (data) { var inst = $.jstree.reference(data.reference), obj = inst.get_node(data.reference); if(inst.is_selected(obj)) { inst.delete_node(inst.get_selected()); } else { inst.delete_node(obj); } } }, "ccp" : { "separator_before" : true, "icon" : false, "separator_after" : false, "label" : "Edit", "action" : false, "submenu" : { "cut" : { "separator_before" : false, "separator_after" : false, "label" : "Cut", "action" : function (data) { var inst = $.jstree.reference(data.reference), obj = inst.get_node(data.reference); if(inst.is_selected(obj)) { inst.cut(inst.get_top_selected()); } else { inst.cut(obj); } } }, "copy" : { "separator_before" : false, "icon" : false, "separator_after" : false, "label" : "Copy", "action" : function (data) { var inst = $.jstree.reference(data.reference), obj = inst.get_node(data.reference); if(inst.is_selected(obj)) { inst.copy(inst.get_top_selected()); } else { inst.copy(obj); } } }, "paste" : { "separator_before" : false, "icon" : false, "_disabled" : function (data) { return !$.jstree.reference(data.reference).can_paste(); }, "separator_after" : false, "label" : "Paste", "action" : function (data) { var inst = $.jstree.reference(data.reference), obj = inst.get_node(data.reference); inst.paste(obj); } } } } }; } }; $.jstree.plugins.contextmenu = function (options, parent) { this.bind = function () { parent.bind.call(this); var last_ts = 0, cto = null, ex, ey; this.element .on("init.jstree loading.jstree ready.jstree", function () { this.get_container_ul().addClass('jstree-contextmenu'); }.bind(this)) .on("contextmenu.jstree", ".jstree-anchor", function (e, data) { if (e.target.tagName.toLowerCase() === 'input') { return; } e.preventDefault(); last_ts = e.ctrlKey ? +new Date() : 0; if(data || cto) { last_ts = (+new Date()) + 10000; } if(cto) { clearTimeout(cto); } if(!this.is_loading(e.currentTarget)) { this.show_contextmenu(e.currentTarget, e.pageX, e.pageY, e); } }.bind(this)) .on("click.jstree", ".jstree-anchor", function (e) { if(this._data.contextmenu.visible && (!last_ts || (+new Date()) - last_ts > 250)) { // work around safari & macOS ctrl+click $.vakata.context.hide(); } last_ts = 0; }.bind(this)) .on("touchstart.jstree", ".jstree-anchor", function (e) { if(!e.originalEvent || !e.originalEvent.changedTouches || !e.originalEvent.changedTouches[0]) { return; } ex = e.originalEvent.changedTouches[0].clientX; ey = e.originalEvent.changedTouches[0].clientY; cto = setTimeout(function () { $(e.currentTarget).trigger('contextmenu', true); }, 750); }) .on('touchmove.vakata.jstree', function (e) { if(cto && e.originalEvent && e.originalEvent.changedTouches && e.originalEvent.changedTouches[0] && (Math.abs(ex - e.originalEvent.changedTouches[0].clientX) > 10 || Math.abs(ey - e.originalEvent.changedTouches[0].clientY) > 10)) { clearTimeout(cto); $.vakata.context.hide(); } }) .on('touchend.vakata.jstree', function (e) { if(cto) { clearTimeout(cto); } }); /*! if(!('oncontextmenu' in document.body) && ('ontouchstart' in document.body)) { var el = null, tm = null; this.element .on("touchstart", ".jstree-anchor", function (e) { el = e.currentTarget; tm = +new Date(); $(document).one("touchend", function (e) { e.target = document.elementFromPoint(e.originalEvent.targetTouches[0].pageX - window.pageXOffset, e.originalEvent.targetTouches[0].pageY - window.pageYOffset); e.currentTarget = e.target; tm = ((+(new Date())) - tm); if(e.target === el && tm > 600 && tm < 1000) { e.preventDefault(); $(el).trigger('contextmenu', e); } el = null; tm = null; }); }); } */ $(document).on("context_hide.vakata.jstree", function (e, data) { this._data.contextmenu.visible = false; $(data.reference).removeClass('jstree-context'); }.bind(this)); }; this.teardown = function () { if(this._data.contextmenu.visible) { $.vakata.context.hide(); } $(document).off("context_hide.vakata.jstree"); parent.teardown.call(this); }; /** * prepare and show the context menu for a node * @name show_contextmenu(obj [, x, y]) * @param {mixed} obj the node * @param {Number} x the x-coordinate relative to the document to show the menu at * @param {Number} y the y-coordinate relative to the document to show the menu at * @param {Object} e the event if available that triggered the contextmenu * @plugin contextmenu * @trigger show_contextmenu.jstree */ this.show_contextmenu = function (obj, x, y, e) { obj = this.get_node(obj); if(!obj || obj.id === $.jstree.root) { return false; } var s = this.settings.contextmenu, d = this.get_node(obj, true), a = d.children(".jstree-anchor"), o = false, i = false; if(s.show_at_node || x === undefined || y === undefined) { o = a.offset(); x = o.left; y = o.top + this._data.core.li_height; } if(this.settings.contextmenu.select_node && !this.is_selected(obj)) { this.activate_node(obj, e); } i = s.items; if($.vakata.is_function(i)) { i = i.call(this, obj, function (i) { this._show_contextmenu(obj, x, y, i); }.bind(this)); } if($.isPlainObject(i)) { this._show_contextmenu(obj, x, y, i); } }; /** * show the prepared context menu for a node * @name _show_contextmenu(obj, x, y, i) * @param {mixed} obj the node * @param {Number} x the x-coordinate relative to the document to show the menu at * @param {Number} y the y-coordinate relative to the document to show the menu at * @param {Number} i the object of items to show * @plugin contextmenu * @trigger show_contextmenu.jstree * @private */ this._show_contextmenu = function (obj, x, y, i) { var d = this.get_node(obj, true), a = d.children(".jstree-anchor"); $(document).one("context_show.vakata.jstree", function (e, data) { var cls = 'jstree-contextmenu jstree-' + this.get_theme() + '-contextmenu'; $(data.element).addClass(cls); a.addClass('jstree-context'); }.bind(this)); this._data.contextmenu.visible = true; $.vakata.context.show(a, { 'x' : x, 'y' : y }, i); /** * triggered when the contextmenu is shown for a node * @event * @name show_contextmenu.jstree * @param {Object} node the node * @param {Number} x the x-coordinate of the menu relative to the document * @param {Number} y the y-coordinate of the menu relative to the document * @plugin contextmenu */ this.trigger('show_contextmenu', { "node" : obj, "x" : x, "y" : y }); }; }; // contextmenu helper (function ($) { var right_to_left = false, vakata_context = { element : false, reference : false, position_x : 0, position_y : 0, items : [], html : "", is_visible : false }; $.vakata.context = { settings : { hide_onmouseleave : 0, icons : true }, _trigger : function (event_name) { $(document).triggerHandler("context_" + event_name + ".vakata", { "reference" : vakata_context.reference, "element" : vakata_context.element, "position" : { "x" : vakata_context.position_x, "y" : vakata_context.position_y } }); }, _execute : function (i) { i = vakata_context.items[i]; return i && (!i._disabled || ($.vakata.is_function(i._disabled) && !i._disabled({ "item" : i, "reference" : vakata_context.reference, "element" : vakata_context.element }))) && i.action ? i.action.call(null, { "item" : i, "reference" : vakata_context.reference, "element" : vakata_context.element, "position" : { "x" : vakata_context.position_x, "y" : vakata_context.position_y } }) : false; }, _parse : function (o, is_callback) { if(!o) { return false; } if(!is_callback) { vakata_context.html = ""; vakata_context.items = []; } var str = "", sep = false, tmp; if(is_callback) { str += "<"+"ul>"; } $.each(o, function (i, val) { if(!val) { return true; } vakata_context.items.push(val); if(!sep && val.separator_before) { str += "<"+"li class='vakata-context-separator'><"+"a href='#' " + ($.vakata.context.settings.icons ? '' : 'class="vakata-context-no-icons"') + "> <"+"/a><"+"/li>"; } sep = false; str += "<"+"li class='" + (val._class || "") + (val._disabled === true || ($.vakata.is_function(val._disabled) && val._disabled({ "item" : val, "reference" : vakata_context.reference, "element" : vakata_context.element })) ? " vakata-contextmenu-disabled " : "") + "' "+(val.shortcut?" data-shortcut='"+val.shortcut+"' ":'')+">"; str += "<"+"a href='#' rel='" + (vakata_context.items.length - 1) + "' " + (val.title ? "title='" + val.title + "'" : "") + ">"; if($.vakata.context.settings.icons) { str += "<"+"i "; if(val.icon) { if(val.icon.indexOf("/") !== -1 || val.icon.indexOf(".") !== -1) { str += " style='background:url(\"" + val.icon + "\") center center no-repeat' "; } else { str += " class='" + val.icon + "' "; } } str += "><"+"/i><"+"span class='vakata-contextmenu-sep'> <"+"/span>"; } str += ($.vakata.is_function(val.label) ? val.label({ "item" : i, "reference" : vakata_context.reference, "element" : vakata_context.element }) : val.label) + (val.shortcut?' '+ (val.shortcut_label || '') +'':'') + "<"+"/a>"; if(val.submenu) { tmp = $.vakata.context._parse(val.submenu, true); if(tmp) { str += tmp; } } str += "<"+"/li>"; if(val.separator_after) { str += "<"+"li class='vakata-context-separator'><"+"a href='#' " + ($.vakata.context.settings.icons ? '' : 'class="vakata-context-no-icons"') + "> <"+"/a><"+"/li>"; sep = true; } }); str = str.replace(/
  • <\/li\>$/,""); if(is_callback) { str += ""; } /** * triggered on the document when the contextmenu is parsed (HTML is built) * @event * @plugin contextmenu * @name context_parse.vakata * @param {jQuery} reference the element that was right clicked * @param {jQuery} element the DOM element of the menu itself * @param {Object} position the x & y coordinates of the menu */ if(!is_callback) { vakata_context.html = str; $.vakata.context._trigger("parse"); } return str.length > 10 ? str : false; }, _show_submenu : function (o) { o = $(o); if(!o.length || !o.children("ul").length) { return; } var e = o.children("ul"), xl = o.offset().left, x = xl + o.outerWidth(), y = o.offset().top, w = e.width(), h = e.height(), dw = $(window).width() + $(window).scrollLeft(), dh = $(window).height() + $(window).scrollTop(); // може да се спести е една проверка - дали няма някой от класовете вече нагоре if(right_to_left) { o[x - (w + 10 + o.outerWidth()) < 0 ? "addClass" : "removeClass"]("vakata-context-left"); } else { o[x + w > dw && xl > dw - x ? "addClass" : "removeClass"]("vakata-context-right"); } if(y + h + 10 > dh) { e.css("bottom","-1px"); } //if does not fit - stick it to the side if (o.hasClass('vakata-context-right')) { if (xl < w) { e.css("margin-right", xl - w); } } else { if (dw - x < w) { e.css("margin-left", dw - x - w); } } e.show(); }, show : function (reference, position, data) { var o, e, x, y, w, h, dw, dh, cond = true; if(vakata_context.element && vakata_context.element.length) { vakata_context.element.width(''); } switch(cond) { case (!position && !reference): return false; case (!!position && !!reference): vakata_context.reference = reference; vakata_context.position_x = position.x; vakata_context.position_y = position.y; break; case (!position && !!reference): vakata_context.reference = reference; o = reference.offset(); vakata_context.position_x = o.left + reference.outerHeight(); vakata_context.position_y = o.top; break; case (!!position && !reference): vakata_context.position_x = position.x; vakata_context.position_y = position.y; break; } if(!!reference && !data && $(reference).data('vakata_contextmenu')) { data = $(reference).data('vakata_contextmenu'); } if($.vakata.context._parse(data)) { vakata_context.element.html(vakata_context.html); } if(vakata_context.items.length) { vakata_context.element.appendTo(document.body); e = vakata_context.element; x = vakata_context.position_x; y = vakata_context.position_y; w = e.width(); h = e.height(); dw = $(window).width() + $(window).scrollLeft(); dh = $(window).height() + $(window).scrollTop(); if(right_to_left) { x -= (e.outerWidth() - $(reference).outerWidth()); if(x < $(window).scrollLeft() + 20) { x = $(window).scrollLeft() + 20; } } if(x + w + 20 > dw) { x = dw - (w + 20); } if(y + h + 20 > dh) { y = dh - (h + 20); } vakata_context.element .css({ "left" : x, "top" : y }) .show() .find('a').first().trigger('focus').parent().addClass("vakata-context-hover"); vakata_context.is_visible = true; /** * triggered on the document when the contextmenu is shown * @event * @plugin contextmenu * @name context_show.vakata * @param {jQuery} reference the element that was right clicked * @param {jQuery} element the DOM element of the menu itself * @param {Object} position the x & y coordinates of the menu */ $.vakata.context._trigger("show"); } }, hide : function () { if(vakata_context.is_visible) { vakata_context.element.hide().find("ul").hide().end().find(':focus').trigger('blur').end().detach(); vakata_context.is_visible = false; /** * triggered on the document when the contextmenu is hidden * @event * @plugin contextmenu * @name context_hide.vakata * @param {jQuery} reference the element that was right clicked * @param {jQuery} element the DOM element of the menu itself * @param {Object} position the x & y coordinates of the menu */ $.vakata.context._trigger("hide"); } } }; $(function () { right_to_left = $(document.body).css("direction") === "rtl"; var to = false; vakata_context.element = $("
      "); vakata_context.element .on("mouseenter", "li", function (e) { e.stopImmediatePropagation(); if($.contains(this, e.relatedTarget)) { // премахнато заради delegate mouseleave по-долу // $(this).find(".vakata-context-hover").removeClass("vakata-context-hover"); return; } if(to) { clearTimeout(to); } vakata_context.element.find(".vakata-context-hover").removeClass("vakata-context-hover").end(); $(this) .siblings().find("ul").hide().end().end() .parentsUntil(".vakata-context", "li").addBack().addClass("vakata-context-hover"); $.vakata.context._show_submenu(this); }) // тестово - дали не натоварва? .on("mouseleave", "li", function (e) { if($.contains(this, e.relatedTarget)) { return; } $(this).find(".vakata-context-hover").addBack().removeClass("vakata-context-hover"); }) .on("mouseleave", function (e) { $(this).find(".vakata-context-hover").removeClass("vakata-context-hover"); if($.vakata.context.settings.hide_onmouseleave) { to = setTimeout( (function (t) { return function () { $.vakata.context.hide(); }; }(this)), $.vakata.context.settings.hide_onmouseleave); } }) .on("click", "a", function (e) { e.preventDefault(); //}) //.on("mouseup", "a", function (e) { if(!$(this).trigger('blur').parent().hasClass("vakata-context-disabled") && $.vakata.context._execute($(this).attr("rel")) !== false) { $.vakata.context.hide(); } }) .on('keydown', 'a', function (e) { var o = null; switch(e.which) { case 13: case 32: e.type = "click"; e.preventDefault(); $(e.currentTarget).trigger(e); break; case 37: if(vakata_context.is_visible) { vakata_context.element.find(".vakata-context-hover").last().closest("li").first().find("ul").hide().find(".vakata-context-hover").removeClass("vakata-context-hover").end().end().children('a').trigger('focus'); e.stopImmediatePropagation(); e.preventDefault(); } break; case 38: if(vakata_context.is_visible) { o = vakata_context.element.find("ul:visible").addBack().last().children(".vakata-context-hover").removeClass("vakata-context-hover").prevAll("li:not(.vakata-context-separator)").first(); if(!o.length) { o = vakata_context.element.find("ul:visible").addBack().last().children("li:not(.vakata-context-separator)").last(); } o.addClass("vakata-context-hover").children('a').trigger('focus'); e.stopImmediatePropagation(); e.preventDefault(); } break; case 39: if(vakata_context.is_visible) { vakata_context.element.find(".vakata-context-hover").last().children("ul").show().children("li:not(.vakata-context-separator)").removeClass("vakata-context-hover").first().addClass("vakata-context-hover").children('a').trigger('focus'); e.stopImmediatePropagation(); e.preventDefault(); } break; case 40: if(vakata_context.is_visible) { o = vakata_context.element.find("ul:visible").addBack().last().children(".vakata-context-hover").removeClass("vakata-context-hover").nextAll("li:not(.vakata-context-separator)").first(); if(!o.length) { o = vakata_context.element.find("ul:visible").addBack().last().children("li:not(.vakata-context-separator)").first(); } o.addClass("vakata-context-hover").children('a').trigger('focus'); e.stopImmediatePropagation(); e.preventDefault(); } break; case 27: $.vakata.context.hide(); e.preventDefault(); break; default: //console.log(e.which); break; } }) .on('keydown', function (e) { e.preventDefault(); var a = vakata_context.element.find('.vakata-contextmenu-shortcut-' + e.which).parent(); if(a.parent().not('.vakata-context-disabled')) { a.trigger('click'); } }); $(document) .on("mousedown.vakata.jstree", function (e) { if(vakata_context.is_visible && vakata_context.element[0] !== e.target && !$.contains(vakata_context.element[0], e.target)) { $.vakata.context.hide(); } }) .on("context_show.vakata.jstree", function (e, data) { vakata_context.element.find("li:has(ul)").children("a").addClass("vakata-context-parent"); if(right_to_left) { vakata_context.element.addClass("vakata-context-rtl").css("direction", "rtl"); } // also apply a RTL class? vakata_context.element.find("ul").hide().end(); }); }); }($)); // $.jstree.defaults.plugins.push("contextmenu"); /** * ### Drag'n'drop plugin * * Enables dragging and dropping of nodes in the tree, resulting in a move or copy operations. */ /** * stores all defaults for the drag'n'drop plugin * @name $.jstree.defaults.dnd * @plugin dnd */ $.jstree.defaults.dnd = { /** * a boolean indicating if a copy should be possible while dragging (by pressint the meta key or Ctrl). Defaults to `true`. * @name $.jstree.defaults.dnd.copy * @plugin dnd */ copy : true, /** * a number indicating how long a node should remain hovered while dragging to be opened. Defaults to `500`. * @name $.jstree.defaults.dnd.open_timeout * @plugin dnd */ open_timeout : 500, /** * a function invoked each time a node is about to be dragged, invoked in the tree's scope and receives the nodes about to be dragged as an argument (array) and the event that started the drag - return `false` to prevent dragging * @name $.jstree.defaults.dnd.is_draggable * @plugin dnd */ is_draggable : true, /** * a boolean indicating if checks should constantly be made while the user is dragging the node (as opposed to checking only on drop), default is `true` * @name $.jstree.defaults.dnd.check_while_dragging * @plugin dnd */ check_while_dragging : true, /** * a boolean indicating if nodes from this tree should only be copied with dnd (as opposed to moved), default is `false` * @name $.jstree.defaults.dnd.always_copy * @plugin dnd */ always_copy : false, /** * when dropping a node "inside", this setting indicates the position the node should go to - it can be an integer or a string: "first" (same as 0) or "last", default is `0` * @name $.jstree.defaults.dnd.inside_pos * @plugin dnd */ inside_pos : 0, /** * when starting the drag on a node that is selected this setting controls if all selected nodes are dragged or only the single node, default is `true`, which means all selected nodes are dragged when the drag is started on a selected node * @name $.jstree.defaults.dnd.drag_selection * @plugin dnd */ drag_selection : true, /** * controls whether dnd works on touch devices. If left as boolean true dnd will work the same as in desktop browsers, which in some cases may impair scrolling. If set to boolean false dnd will not work on touch devices. There is a special third option - string "selected" which means only selected nodes can be dragged on touch devices. * @name $.jstree.defaults.dnd.touch * @plugin dnd */ touch : true, /** * controls whether items can be dropped anywhere on the node, not just on the anchor, by default only the node anchor is a valid drop target. Works best with the wholerow plugin. If enabled on mobile depending on the interface it might be hard for the user to cancel the drop, since the whole tree container will be a valid drop target. * @name $.jstree.defaults.dnd.large_drop_target * @plugin dnd */ large_drop_target : false, /** * controls whether a drag can be initiated from any part of the node and not just the text/icon part, works best with the wholerow plugin. Keep in mind it can cause problems with tree scrolling on mobile depending on the interface - in that case set the touch option to "selected". * @name $.jstree.defaults.dnd.large_drag_target * @plugin dnd */ large_drag_target : false, /** * controls whether use HTML5 dnd api instead of classical. That will allow better integration of dnd events with other HTML5 controls. * @reference http://caniuse.com/#feat=dragndrop * @name $.jstree.defaults.dnd.use_html5 * @plugin dnd */ use_html5: false, /** * controls whether items can be dropped anywhere on the tree. * @name $.jstree.defaults.dnd.blank_space_drop * @plugin dnd */ blank_space_drop: false }; var drg, elm; // TODO: now check works by checking for each node individually, how about max_children, unique, etc? $.jstree.plugins.dnd = function (options, parent) { this.init = function (el, options) { parent.init.call(this, el, options); this.settings.dnd.use_html5 = this.settings.dnd.use_html5 && ('draggable' in document.createElement('span')); }; this.bind = function () { parent.bind.call(this); this.element .on(this.settings.dnd.use_html5 ? 'dragstart.jstree' : 'mousedown.jstree touchstart.jstree', this.settings.dnd.large_drag_target ? '.jstree-node' : '.jstree-anchor', function (e) { if(this.settings.dnd.large_drag_target && $(e.target).closest('.jstree-node')[0] !== e.currentTarget) { return true; } if(e.type === "touchstart" && (!this.settings.dnd.touch || (this.settings.dnd.touch === 'selected' && !$(e.currentTarget).closest('.jstree-node').children('.jstree-anchor').hasClass('jstree-clicked')))) { return true; } var obj = this.get_node(e.target), mlt = this.is_selected(obj) && this.settings.dnd.drag_selection ? this.get_top_selected().length : 1, txt = (mlt > 1 ? mlt + ' ' + this.get_string('nodes') : this.get_text(e.currentTarget)); if(this.settings.core.force_text) { txt = $.vakata.html.escape(txt); } if(obj && (obj.id || obj.id === 0) && obj.id !== $.jstree.root && (e.which === 1 || e.type === "touchstart" || e.type === "dragstart") && (this.settings.dnd.is_draggable === true || ($.vakata.is_function(this.settings.dnd.is_draggable) && this.settings.dnd.is_draggable.call(this, (mlt > 1 ? this.get_top_selected(true) : [obj]), e))) ) { drg = { 'jstree' : true, 'origin' : this, 'obj' : this.get_node(obj,true), 'nodes' : mlt > 1 ? this.get_top_selected() : [obj.id] }; elm = e.currentTarget; if (this.settings.dnd.use_html5) { $.vakata.dnd._trigger('start', e, { 'helper': $(), 'element': elm, 'data': drg }); } else { this.element.trigger('mousedown.jstree'); return $.vakata.dnd.start(e, drg, '
      ' + txt + '+
      '); } } }.bind(this)); if (this.settings.dnd.use_html5) { this.element .on('dragover.jstree', function (e) { e.preventDefault(); $.vakata.dnd._trigger('move', e, { 'helper': $(), 'element': elm, 'data': drg }); return false; }) //.on('dragenter.jstree', this.settings.dnd.large_drop_target ? '.jstree-node' : '.jstree-anchor', $.proxy(function (e) { // e.preventDefault(); // $.vakata.dnd._trigger('move', e, { 'helper': $(), 'element': elm, 'data': drg }); // return false; // }, this)) .on('drop.jstree', function (e) { e.preventDefault(); $.vakata.dnd._trigger('stop', e, { 'helper': $(), 'element': elm, 'data': drg }); return false; }.bind(this)); } }; this.redraw_node = function(obj, deep, callback, force_render) { obj = parent.redraw_node.apply(this, arguments); if (obj && this.settings.dnd.use_html5) { if (this.settings.dnd.large_drag_target) { obj.setAttribute('draggable', true); } else { var i, j, tmp = null; for(i = 0, j = obj.childNodes.length; i < j; i++) { if(obj.childNodes[i] && obj.childNodes[i].className && obj.childNodes[i].className.indexOf("jstree-anchor") !== -1) { tmp = obj.childNodes[i]; break; } } if(tmp) { tmp.setAttribute('draggable', true); } } } return obj; }; }; $(function() { // bind only once for all instances var lastmv = false, laster = false, lastev = false, opento = false, marker = $('
       
      ').hide(); //.appendTo('body'); $(document) .on('dragover.vakata.jstree', function (e) { if (elm) { $.vakata.dnd._trigger('move', e, { 'helper': $(), 'element': elm, 'data': drg }); } }) .on('drop.vakata.jstree', function (e) { if (elm) { $.vakata.dnd._trigger('stop', e, { 'helper': $(), 'element': elm, 'data': drg }); elm = null; drg = null; } }) .on('dnd_start.vakata.jstree', function (e, data) { lastmv = false; lastev = false; if(!data || !data.data || !data.data.jstree) { return; } marker.appendTo(document.body); //.show(); }) .on('dnd_move.vakata.jstree', function (e, data) { var isDifferentNode = data.event.target !== lastev.target; if(opento) { if (!data.event || data.event.type !== 'dragover' || isDifferentNode) { clearTimeout(opento); } } if(!data || !data.data || !data.data.jstree) { return; } // if we are hovering the marker image do nothing (can happen on "inside" drags) if(data.event.target.id && data.event.target.id === 'jstree-marker') { return; } lastev = data.event; var ins = $.jstree.reference(data.event.target), ref = false, off = false, rel = false, tmp, l, t, h, p, i, o, ok, t1, t2, op, ps, pr, ip, tm, is_copy, pn, c; // if we are over an instance if(ins && ins._data && ins._data.dnd) { marker.attr('class', 'jstree-' + ins.get_theme() + ( ins.settings.core.themes.responsive ? ' jstree-dnd-responsive' : '' )); is_copy = data.data.origin && (data.data.origin.settings.dnd.always_copy || (data.data.origin.settings.dnd.copy && (data.event.metaKey || data.event.ctrlKey))); data.helper .children().attr('class', 'jstree-' + ins.get_theme() + ' jstree-' + ins.get_theme() + '-' + ins.get_theme_variant() + ' ' + ( ins.settings.core.themes.responsive ? ' jstree-dnd-responsive' : '' )) .find('.jstree-copy').first()[ is_copy ? 'show' : 'hide' ](); // if are hovering the container itself add a new root node //console.log(data.event); if( (data.event.target === ins.element[0] || data.event.target === ins.get_container_ul()[0]) && (ins.get_container_ul().children().length === 0 || ins.settings.dnd.blank_space_drop)) { ok = true; for(t1 = 0, t2 = data.data.nodes.length; t1 < t2; t1++) { ok = ok && ins.check( (data.data.origin && (data.data.origin.settings.dnd.always_copy || (data.data.origin.settings.dnd.copy && (data.event.metaKey || data.event.ctrlKey)) ) ? "copy_node" : "move_node"), (data.data.origin && data.data.origin !== ins ? data.data.origin.get_node(data.data.nodes[t1]) : data.data.nodes[t1]), $.jstree.root, 'last', { 'dnd' : true, 'ref' : ins.get_node($.jstree.root), 'pos' : 'i', 'origin' : data.data.origin, 'is_multi' : (data.data.origin && data.data.origin !== ins), 'is_foreign' : (!data.data.origin) }); if(!ok) { break; } } if(ok) { lastmv = { 'ins' : ins, 'par' : $.jstree.root, 'pos' : 'last' }; marker.hide(); data.helper.find('.jstree-icon').first().removeClass('jstree-er').addClass('jstree-ok'); if (data.event.originalEvent && data.event.originalEvent.dataTransfer) { data.event.originalEvent.dataTransfer.dropEffect = is_copy ? 'copy' : 'move'; } return; } } else { // if we are hovering a tree node ref = ins.settings.dnd.large_drop_target ? $(data.event.target).closest('.jstree-node').children('.jstree-anchor') : $(data.event.target).closest('.jstree-anchor'); if(ref && ref.length && ref.parent().is('.jstree-closed, .jstree-open, .jstree-leaf')) { off = ref.offset(); rel = (data.event.pageY !== undefined ? data.event.pageY : data.event.originalEvent.pageY) - off.top; h = ref.outerHeight(); if(rel < h / 3) { o = ['b', 'i', 'a']; } else if(rel > h - h / 3) { o = ['a', 'i', 'b']; } else { o = rel > h / 2 ? ['i', 'a', 'b'] : ['i', 'b', 'a']; } $.each(o, function (j, v) { switch(v) { case 'b': l = off.left - 6; t = off.top; p = ins.get_parent(ref); i = ref.parent().index(); c = 'jstree-below'; break; case 'i': ip = ins.settings.dnd.inside_pos; tm = ins.get_node(ref.parent()); l = off.left - 2; t = off.top + h / 2 + 1; p = tm.id; i = ip === 'first' ? 0 : (ip === 'last' ? tm.children.length : Math.min(ip, tm.children.length)); c = 'jstree-inside'; break; case 'a': l = off.left - 6; t = off.top + h; p = ins.get_parent(ref); i = ref.parent().index() + 1; c = 'jstree-above'; break; } ok = true; for(t1 = 0, t2 = data.data.nodes.length; t1 < t2; t1++) { op = data.data.origin && (data.data.origin.settings.dnd.always_copy || (data.data.origin.settings.dnd.copy && (data.event.metaKey || data.event.ctrlKey))) ? "copy_node" : "move_node"; ps = i; if(op === "move_node" && v === 'a' && (data.data.origin && data.data.origin === ins) && p === ins.get_parent(data.data.nodes[t1])) { pr = ins.get_node(p); if(ps > $.inArray(data.data.nodes[t1], pr.children)) { ps -= 1; } } ok = ok && ( (ins && ins.settings && ins.settings.dnd && ins.settings.dnd.check_while_dragging === false) || ins.check(op, (data.data.origin && data.data.origin !== ins ? data.data.origin.get_node(data.data.nodes[t1]) : data.data.nodes[t1]), p, ps, { 'dnd' : true, 'ref' : ins.get_node(ref.parent()), 'pos' : v, 'origin' : data.data.origin, 'is_multi' : (data.data.origin && data.data.origin !== ins), 'is_foreign' : (!data.data.origin) }) ); if(!ok) { if(ins && ins.last_error) { laster = ins.last_error(); } break; } } if(v === 'i' && ref.parent().is('.jstree-closed') && ins.settings.dnd.open_timeout) { if (!data.event || data.event.type !== 'dragover' || isDifferentNode) { if (opento) { clearTimeout(opento); } opento = setTimeout((function (x, z) { return function () { x.open_node(z); }; }(ins, ref)), ins.settings.dnd.open_timeout); } } if(ok) { pn = ins.get_node(p, true); if (!pn.hasClass('.jstree-dnd-parent')) { $('.jstree-dnd-parent').removeClass('jstree-dnd-parent'); pn.addClass('jstree-dnd-parent'); } lastmv = { 'ins' : ins, 'par' : p, 'pos' : v === 'i' && ip === 'last' && i === 0 && !ins.is_loaded(tm) ? 'last' : i }; marker.css({ 'left' : l + 'px', 'top' : t + 'px' }).show(); marker.removeClass('jstree-above jstree-inside jstree-below').addClass(c); data.helper.find('.jstree-icon').first().removeClass('jstree-er').addClass('jstree-ok'); if (data.event.originalEvent && data.event.originalEvent.dataTransfer) { data.event.originalEvent.dataTransfer.dropEffect = is_copy ? 'copy' : 'move'; } laster = {}; o = true; return false; } }); if(o === true) { return; } } } } $('.jstree-dnd-parent').removeClass('jstree-dnd-parent'); lastmv = false; data.helper.find('.jstree-icon').removeClass('jstree-ok').addClass('jstree-er'); if (data.event.originalEvent && data.event.originalEvent.dataTransfer) { //data.event.originalEvent.dataTransfer.dropEffect = 'none'; } marker.hide(); }) .on('dnd_scroll.vakata.jstree', function (e, data) { if(!data || !data.data || !data.data.jstree) { return; } marker.hide(); lastmv = false; lastev = false; data.helper.find('.jstree-icon').first().removeClass('jstree-ok').addClass('jstree-er'); }) .on('dnd_stop.vakata.jstree', function (e, data) { $('.jstree-dnd-parent').removeClass('jstree-dnd-parent'); if(opento) { clearTimeout(opento); } if(!data || !data.data || !data.data.jstree) { return; } marker.hide().detach(); var i, j, nodes = []; if(lastmv) { for(i = 0, j = data.data.nodes.length; i < j; i++) { nodes[i] = data.data.origin ? data.data.origin.get_node(data.data.nodes[i]) : data.data.nodes[i]; } lastmv.ins[ data.data.origin && (data.data.origin.settings.dnd.always_copy || (data.data.origin.settings.dnd.copy && (data.event.metaKey || data.event.ctrlKey))) ? 'copy_node' : 'move_node' ](nodes, lastmv.par, lastmv.pos, false, false, false, data.data.origin); } else { i = $(data.event.target).closest('.jstree'); if(i.length && laster && laster.error && laster.error === 'check') { i = i.jstree(true); if(i) { i.settings.core.error.call(this, laster); } } } lastev = false; lastmv = false; }) .on('keyup.jstree keydown.jstree', function (e, data) { data = $.vakata.dnd._get(); if(data && data.data && data.data.jstree) { if (e.type === "keyup" && e.which === 27) { if (opento) { clearTimeout(opento); } lastmv = false; laster = false; lastev = false; opento = false; marker.hide().detach(); $.vakata.dnd._clean(); } else { data.helper.find('.jstree-copy').first()[ data.data.origin && (data.data.origin.settings.dnd.always_copy || (data.data.origin.settings.dnd.copy && (e.metaKey || e.ctrlKey))) ? 'show' : 'hide' ](); if(lastev) { lastev.metaKey = e.metaKey; lastev.ctrlKey = e.ctrlKey; $.vakata.dnd._trigger('move', lastev); } } } }); }); // helpers (function ($) { $.vakata.html = { div : $('
      '), escape : function (str) { return $.vakata.html.div.text(str).html(); }, strip : function (str) { return $.vakata.html.div.empty().append($.parseHTML(str)).text(); } }; // private variable var vakata_dnd = { element : false, target : false, is_down : false, is_drag : false, helper : false, helper_w: 0, data : false, init_x : 0, init_y : 0, scroll_l: 0, scroll_t: 0, scroll_e: false, scroll_i: false, is_touch: false }; $.vakata.dnd = { settings : { scroll_speed : 10, scroll_proximity : 20, helper_left : 5, helper_top : 10, threshold : 5, threshold_touch : 10 }, _trigger : function (event_name, e, data) { if (data === undefined) { data = $.vakata.dnd._get(); } data.event = e; $(document).triggerHandler("dnd_" + event_name + ".vakata", data); }, _get : function () { return { "data" : vakata_dnd.data, "element" : vakata_dnd.element, "helper" : vakata_dnd.helper }; }, _clean : function () { if(vakata_dnd.helper) { vakata_dnd.helper.remove(); } if(vakata_dnd.scroll_i) { clearInterval(vakata_dnd.scroll_i); vakata_dnd.scroll_i = false; } vakata_dnd = { element : false, target : false, is_down : false, is_drag : false, helper : false, helper_w: 0, data : false, init_x : 0, init_y : 0, scroll_l: 0, scroll_t: 0, scroll_e: false, scroll_i: false, is_touch: false }; elm = null; $(document).off("mousemove.vakata.jstree touchmove.vakata.jstree", $.vakata.dnd.drag); $(document).off("mouseup.vakata.jstree touchend.vakata.jstree", $.vakata.dnd.stop); }, _scroll : function (init_only) { if(!vakata_dnd.scroll_e || (!vakata_dnd.scroll_l && !vakata_dnd.scroll_t)) { if(vakata_dnd.scroll_i) { clearInterval(vakata_dnd.scroll_i); vakata_dnd.scroll_i = false; } return false; } if(!vakata_dnd.scroll_i) { vakata_dnd.scroll_i = setInterval($.vakata.dnd._scroll, 100); return false; } if(init_only === true) { return false; } var i = vakata_dnd.scroll_e.scrollTop(), j = vakata_dnd.scroll_e.scrollLeft(); vakata_dnd.scroll_e.scrollTop(i + vakata_dnd.scroll_t * $.vakata.dnd.settings.scroll_speed); vakata_dnd.scroll_e.scrollLeft(j + vakata_dnd.scroll_l * $.vakata.dnd.settings.scroll_speed); if(i !== vakata_dnd.scroll_e.scrollTop() || j !== vakata_dnd.scroll_e.scrollLeft()) { /** * triggered on the document when a drag causes an element to scroll * @event * @plugin dnd * @name dnd_scroll.vakata * @param {Mixed} data any data supplied with the call to $.vakata.dnd.start * @param {DOM} element the DOM element being dragged * @param {jQuery} helper the helper shown next to the mouse * @param {jQuery} event the element that is scrolling */ $.vakata.dnd._trigger("scroll", vakata_dnd.scroll_e); } }, start : function (e, data, html) { if(e.type === "touchstart" && e.originalEvent && e.originalEvent.changedTouches && e.originalEvent.changedTouches[0]) { e.pageX = e.originalEvent.changedTouches[0].pageX; e.pageY = e.originalEvent.changedTouches[0].pageY; e.target = document.elementFromPoint(e.originalEvent.changedTouches[0].pageX - window.pageXOffset, e.originalEvent.changedTouches[0].pageY - window.pageYOffset); } if(vakata_dnd.is_drag) { $.vakata.dnd.stop({}); } try { e.currentTarget.unselectable = "on"; e.currentTarget.onselectstart = function() { return false; }; if(e.currentTarget.style) { e.currentTarget.style.touchAction = "none"; e.currentTarget.style.msTouchAction = "none"; e.currentTarget.style.MozUserSelect = "none"; } } catch(ignore) { } vakata_dnd.init_x = e.pageX; vakata_dnd.init_y = e.pageY; vakata_dnd.data = data; vakata_dnd.is_down = true; vakata_dnd.element = e.currentTarget; vakata_dnd.target = e.target; vakata_dnd.is_touch = e.type === "touchstart"; if(html !== false) { vakata_dnd.helper = $("
      ").html(html).css({ "display" : "block", "margin" : "0", "padding" : "0", "position" : "absolute", "top" : "-2000px", "lineHeight" : "16px", "zIndex" : "10000" }); } $(document).on("mousemove.vakata.jstree touchmove.vakata.jstree", $.vakata.dnd.drag); $(document).on("mouseup.vakata.jstree touchend.vakata.jstree", $.vakata.dnd.stop); return false; }, drag : function (e) { if(e.type === "touchmove" && e.originalEvent && e.originalEvent.changedTouches && e.originalEvent.changedTouches[0]) { e.pageX = e.originalEvent.changedTouches[0].pageX; e.pageY = e.originalEvent.changedTouches[0].pageY; e.target = document.elementFromPoint(e.originalEvent.changedTouches[0].pageX - window.pageXOffset, e.originalEvent.changedTouches[0].pageY - window.pageYOffset); } if(!vakata_dnd.is_down) { return; } if(!vakata_dnd.is_drag) { if( Math.abs(e.pageX - vakata_dnd.init_x) > (vakata_dnd.is_touch ? $.vakata.dnd.settings.threshold_touch : $.vakata.dnd.settings.threshold) || Math.abs(e.pageY - vakata_dnd.init_y) > (vakata_dnd.is_touch ? $.vakata.dnd.settings.threshold_touch : $.vakata.dnd.settings.threshold) ) { if(vakata_dnd.helper) { vakata_dnd.helper.appendTo(document.body); vakata_dnd.helper_w = vakata_dnd.helper.outerWidth(); } vakata_dnd.is_drag = true; $(vakata_dnd.target).one('click.vakata', false); /** * triggered on the document when a drag starts * @event * @plugin dnd * @name dnd_start.vakata * @param {Mixed} data any data supplied with the call to $.vakata.dnd.start * @param {DOM} element the DOM element being dragged * @param {jQuery} helper the helper shown next to the mouse * @param {Object} event the event that caused the start (probably mousemove) */ $.vakata.dnd._trigger("start", e); } else { return; } } var d = false, w = false, dh = false, wh = false, dw = false, ww = false, dt = false, dl = false, ht = false, hl = false; vakata_dnd.scroll_t = 0; vakata_dnd.scroll_l = 0; vakata_dnd.scroll_e = false; $($(e.target).parentsUntil("body").addBack().get().reverse()) .filter(function () { return this.ownerDocument && (/^auto|scroll$/).test($(this).css("overflow")) && (this.scrollHeight > this.offsetHeight || this.scrollWidth > this.offsetWidth); }) .each(function () { var t = $(this), o = t.offset(); if(this.scrollHeight > this.offsetHeight) { if(o.top + t.height() - e.pageY < $.vakata.dnd.settings.scroll_proximity) { vakata_dnd.scroll_t = 1; } if(e.pageY - o.top < $.vakata.dnd.settings.scroll_proximity) { vakata_dnd.scroll_t = -1; } } if(this.scrollWidth > this.offsetWidth) { if(o.left + t.width() - e.pageX < $.vakata.dnd.settings.scroll_proximity) { vakata_dnd.scroll_l = 1; } if(e.pageX - o.left < $.vakata.dnd.settings.scroll_proximity) { vakata_dnd.scroll_l = -1; } } if(vakata_dnd.scroll_t || vakata_dnd.scroll_l) { vakata_dnd.scroll_e = $(this); return false; } }); if(!vakata_dnd.scroll_e) { d = $(document); w = $(window); dh = d.height(); wh = w.height(); dw = d.width(); ww = w.width(); dt = d.scrollTop(); dl = d.scrollLeft(); if(dh > wh && e.pageY - dt < $.vakata.dnd.settings.scroll_proximity) { vakata_dnd.scroll_t = -1; } if(dh > wh && wh - (e.pageY - dt) < $.vakata.dnd.settings.scroll_proximity) { vakata_dnd.scroll_t = 1; } if(dw > ww && e.pageX - dl < $.vakata.dnd.settings.scroll_proximity) { vakata_dnd.scroll_l = -1; } if(dw > ww && ww - (e.pageX - dl) < $.vakata.dnd.settings.scroll_proximity) { vakata_dnd.scroll_l = 1; } if(vakata_dnd.scroll_t || vakata_dnd.scroll_l) { vakata_dnd.scroll_e = d; } } if(vakata_dnd.scroll_e) { $.vakata.dnd._scroll(true); } if(vakata_dnd.helper) { ht = parseInt(e.pageY + $.vakata.dnd.settings.helper_top, 10); hl = parseInt(e.pageX + $.vakata.dnd.settings.helper_left, 10); if(dh && ht + 25 > dh) { ht = dh - 50; } if(dw && hl + vakata_dnd.helper_w > dw) { hl = dw - (vakata_dnd.helper_w + 2); } vakata_dnd.helper.css({ left : hl + "px", top : ht + "px" }); } /** * triggered on the document when a drag is in progress * @event * @plugin dnd * @name dnd_move.vakata * @param {Mixed} data any data supplied with the call to $.vakata.dnd.start * @param {DOM} element the DOM element being dragged * @param {jQuery} helper the helper shown next to the mouse * @param {Object} event the event that caused this to trigger (most likely mousemove) */ $.vakata.dnd._trigger("move", e); return false; }, stop : function (e) { if(e.type === "touchend" && e.originalEvent && e.originalEvent.changedTouches && e.originalEvent.changedTouches[0]) { e.pageX = e.originalEvent.changedTouches[0].pageX; e.pageY = e.originalEvent.changedTouches[0].pageY; e.target = document.elementFromPoint(e.originalEvent.changedTouches[0].pageX - window.pageXOffset, e.originalEvent.changedTouches[0].pageY - window.pageYOffset); } if(vakata_dnd.is_drag) { /** * triggered on the document when a drag stops (the dragged element is dropped) * @event * @plugin dnd * @name dnd_stop.vakata * @param {Mixed} data any data supplied with the call to $.vakata.dnd.start * @param {DOM} element the DOM element being dragged * @param {jQuery} helper the helper shown next to the mouse * @param {Object} event the event that caused the stop */ if (e.target !== vakata_dnd.target) { $(vakata_dnd.target).off('click.vakata'); } $.vakata.dnd._trigger("stop", e); } else { if(e.type === "touchend" && e.target === vakata_dnd.target) { var to = setTimeout(function () { $(e.target).trigger('click'); }, 100); $(e.target).one('click', function() { if(to) { clearTimeout(to); } }); } } $.vakata.dnd._clean(); return false; } }; }($)); // include the dnd plugin by default // $.jstree.defaults.plugins.push("dnd"); /** * ### Massload plugin * * Adds massload functionality to jsTree, so that multiple nodes can be loaded in a single request (only useful with lazy loading). */ /** * massload configuration * * It is possible to set this to a standard jQuery-like AJAX config. * In addition to the standard jQuery ajax options here you can supply functions for `data` and `url`, the functions will be run in the current instance's scope and a param will be passed indicating which node IDs need to be loaded, the return value of those functions will be used. * * You can also set this to a function, that function will receive the node IDs being loaded as argument and a second param which is a function (callback) which should be called with the result. * * Both the AJAX and the function approach rely on the same return value - an object where the keys are the node IDs, and the value is the children of that node as an array. * * { * "id1" : [{ "text" : "Child of ID1", "id" : "c1" }, { "text" : "Another child of ID1", "id" : "c2" }], * "id2" : [{ "text" : "Child of ID2", "id" : "c3" }] * } * * @name $.jstree.defaults.massload * @plugin massload */ $.jstree.defaults.massload = null; $.jstree.plugins.massload = function (options, parent) { this.init = function (el, options) { this._data.massload = {}; parent.init.call(this, el, options); }; this._load_nodes = function (nodes, callback, is_callback, force_reload) { var s = this.settings.massload, toLoad = [], m = this._model.data, i, j, dom; if (!is_callback) { for(i = 0, j = nodes.length; i < j; i++) { if(!m[nodes[i]] || ( (!m[nodes[i]].state.loaded && !m[nodes[i]].state.failed) || force_reload) ) { toLoad.push(nodes[i]); dom = this.get_node(nodes[i], true); if (dom && dom.length) { dom.addClass("jstree-loading").attr('aria-busy',true); } } } this._data.massload = {}; if (toLoad.length) { if($.vakata.is_function(s)) { return s.call(this, toLoad, function (data) { var i, j; if(data) { for(i in data) { if(data.hasOwnProperty(i)) { this._data.massload[i] = data[i]; } } } for(i = 0, j = nodes.length; i < j; i++) { dom = this.get_node(nodes[i], true); if (dom && dom.length) { dom.removeClass("jstree-loading").attr('aria-busy',false); } } parent._load_nodes.call(this, nodes, callback, is_callback, force_reload); }.bind(this)); } if(typeof s === 'object' && s && s.url) { s = $.extend(true, {}, s); if($.vakata.is_function(s.url)) { s.url = s.url.call(this, toLoad); } if($.vakata.is_function(s.data)) { s.data = s.data.call(this, toLoad); } return $.ajax(s) .done(function (data,t,x) { var i, j; if(data) { for(i in data) { if(data.hasOwnProperty(i)) { this._data.massload[i] = data[i]; } } } for(i = 0, j = nodes.length; i < j; i++) { dom = this.get_node(nodes[i], true); if (dom && dom.length) { dom.removeClass("jstree-loading").attr('aria-busy',false); } } parent._load_nodes.call(this, nodes, callback, is_callback, force_reload); }.bind(this)) .fail(function (f) { parent._load_nodes.call(this, nodes, callback, is_callback, force_reload); }.bind(this)); } } } return parent._load_nodes.call(this, nodes, callback, is_callback, force_reload); }; this._load_node = function (obj, callback) { var data = this._data.massload[obj.id], rslt = null, dom; if(data) { rslt = this[typeof data === 'string' ? '_append_html_data' : '_append_json_data']( obj, typeof data === 'string' ? $($.parseHTML(data)).filter(function () { return this.nodeType !== 3; }) : data, function (status) { callback.call(this, status); } ); dom = this.get_node(obj.id, true); if (dom && dom.length) { dom.removeClass("jstree-loading").attr('aria-busy',false); } delete this._data.massload[obj.id]; return rslt; } return parent._load_node.call(this, obj, callback); }; }; /** * ### Search plugin * * Adds search functionality to jsTree. */ /** * stores all defaults for the search plugin * @name $.jstree.defaults.search * @plugin search */ $.jstree.defaults.search = { /** * a jQuery-like AJAX config, which jstree uses if a server should be queried for results. * * A `str` (which is the search string) parameter will be added with the request, an optional `inside` parameter will be added if the search is limited to a node id. The expected result is a JSON array with nodes that need to be opened so that matching nodes will be revealed. * Leave this setting as `false` to not query the server. You can also set this to a function, which will be invoked in the instance's scope and receive 3 parameters - the search string, the callback to call with the array of nodes to load, and the optional node ID to limit the search to * @name $.jstree.defaults.search.ajax * @plugin search */ ajax : false, /** * Indicates if the search should be fuzzy or not (should `chnd3` match `child node 3`). Default is `false`. * @name $.jstree.defaults.search.fuzzy * @plugin search */ fuzzy : false, /** * Indicates if the search should be case sensitive. Default is `false`. * @name $.jstree.defaults.search.case_sensitive * @plugin search */ case_sensitive : false, /** * Indicates if the tree should be filtered (by default) to show only matching nodes (keep in mind this can be a heavy on large trees in old browsers). * This setting can be changed at runtime when calling the search method. Default is `false`. * @name $.jstree.defaults.search.show_only_matches * @plugin search */ show_only_matches : false, /** * Indicates if the children of matched element are shown (when show_only_matches is true) * This setting can be changed at runtime when calling the search method. Default is `false`. * @name $.jstree.defaults.search.show_only_matches_children * @plugin search */ show_only_matches_children : false, /** * Indicates if all nodes opened to reveal the search result, should be closed when the search is cleared or a new search is performed. Default is `true`. * @name $.jstree.defaults.search.close_opened_onclear * @plugin search */ close_opened_onclear : true, /** * Indicates if only leaf nodes should be included in search results. Default is `false`. * @name $.jstree.defaults.search.search_leaves_only * @plugin search */ search_leaves_only : false, /** * If set to a function it wil be called in the instance's scope with two arguments - search string and node (where node will be every node in the structure, so use with caution). * If the function returns a truthy value the node will be considered a match (it might not be displayed if search_only_leaves is set to true and the node is not a leaf). Default is `false`. * @name $.jstree.defaults.search.search_callback * @plugin search */ search_callback : false }; $.jstree.plugins.search = function (options, parent) { this.bind = function () { parent.bind.call(this); this._data.search.str = ""; this._data.search.dom = $(); this._data.search.res = []; this._data.search.opn = []; this._data.search.som = false; this._data.search.smc = false; this._data.search.hdn = []; this.element .on("search.jstree", function (e, data) { if(this._data.search.som && data.res.length) { var m = this._model.data, i, j, p = [], k, l; for(i = 0, j = data.res.length; i < j; i++) { if(m[data.res[i]] && !m[data.res[i]].state.hidden) { p.push(data.res[i]); p = p.concat(m[data.res[i]].parents); if(this._data.search.smc) { for (k = 0, l = m[data.res[i]].children_d.length; k < l; k++) { if (m[m[data.res[i]].children_d[k]] && !m[m[data.res[i]].children_d[k]].state.hidden) { p.push(m[data.res[i]].children_d[k]); } } } } } p = $.vakata.array_remove_item($.vakata.array_unique(p), $.jstree.root); this._data.search.hdn = this.hide_all(true); this.show_node(p, true); this.redraw(true); } }.bind(this)) .on("clear_search.jstree", function (e, data) { if(this._data.search.som && data.res.length) { this.show_node(this._data.search.hdn, true); this.redraw(true); } }.bind(this)); }; /** * used to search the tree nodes for a given string * @name search(str [, skip_async]) * @param {String} str the search string * @param {Boolean} skip_async if set to true server will not be queried even if configured * @param {Boolean} show_only_matches if set to true only matching nodes will be shown (keep in mind this can be very slow on large trees or old browsers) * @param {mixed} inside an optional node to whose children to limit the search * @param {Boolean} append if set to true the results of this search are appended to the previous search * @plugin search * @trigger search.jstree */ this.search = function (str, skip_async, show_only_matches, inside, append, show_only_matches_children) { if(str === false || $.vakata.trim(str.toString()) === "") { return this.clear_search(); } inside = this.get_node(inside); inside = inside && (inside.id || inside.id === 0) ? inside.id : null; str = str.toString(); var s = this.settings.search, a = s.ajax ? s.ajax : false, m = this._model.data, f = null, r = [], p = [], i, j; if(this._data.search.res.length && !append) { this.clear_search(); } if(show_only_matches === undefined) { show_only_matches = s.show_only_matches; } if(show_only_matches_children === undefined) { show_only_matches_children = s.show_only_matches_children; } if(!skip_async && a !== false) { if($.vakata.is_function(a)) { return a.call(this, str, function (d) { if(d && d.d) { d = d.d; } this._load_nodes(!$.vakata.is_array(d) ? [] : $.vakata.array_unique(d), function () { this.search(str, true, show_only_matches, inside, append, show_only_matches_children); }); }.bind(this), inside); } else { a = $.extend({}, a); if(!a.data) { a.data = {}; } a.data.str = str; if(inside) { a.data.inside = inside; } if (this._data.search.lastRequest) { this._data.search.lastRequest.abort(); } this._data.search.lastRequest = $.ajax(a) .fail(function () { this._data.core.last_error = { 'error' : 'ajax', 'plugin' : 'search', 'id' : 'search_01', 'reason' : 'Could not load search parents', 'data' : JSON.stringify(a) }; this.settings.core.error.call(this, this._data.core.last_error); }.bind(this)) .done(function (d) { if(d && d.d) { d = d.d; } this._load_nodes(!$.vakata.is_array(d) ? [] : $.vakata.array_unique(d), function () { this.search(str, true, show_only_matches, inside, append, show_only_matches_children); }); }.bind(this)); return this._data.search.lastRequest; } } if(!append) { this._data.search.str = str; this._data.search.dom = $(); this._data.search.res = []; this._data.search.opn = []; this._data.search.som = show_only_matches; this._data.search.smc = show_only_matches_children; } f = new $.vakata.search(str, true, { caseSensitive : s.case_sensitive, fuzzy : s.fuzzy }); $.each(m[inside ? inside : $.jstree.root].children_d, function (ii, i) { var v = m[i]; if(v.text && !v.state.hidden && (!s.search_leaves_only || (v.state.loaded && v.children.length === 0)) && ( (s.search_callback && s.search_callback.call(this, str, v)) || (!s.search_callback && f.search(v.text).isMatch) ) ) { r.push(i); p = p.concat(v.parents); } }); if(r.length) { p = $.vakata.array_unique(p); for(i = 0, j = p.length; i < j; i++) { if(p[i] !== $.jstree.root && m[p[i]] && this.open_node(p[i], null, 0) === true) { this._data.search.opn.push(p[i]); } } if(!append) { this._data.search.dom = $(this.element[0].querySelectorAll('#' + $.map(r, function (v) { return "0123456789".indexOf(v[0]) !== -1 ? '\\3' + v[0] + ' ' + v.substr(1).replace($.jstree.idregex,'\\$&') : v.replace($.jstree.idregex,'\\$&'); }).join(', #'))); this._data.search.res = r; } else { this._data.search.dom = this._data.search.dom.add($(this.element[0].querySelectorAll('#' + $.map(r, function (v) { return "0123456789".indexOf(v[0]) !== -1 ? '\\3' + v[0] + ' ' + v.substr(1).replace($.jstree.idregex,'\\$&') : v.replace($.jstree.idregex,'\\$&'); }).join(', #')))); this._data.search.res = $.vakata.array_unique(this._data.search.res.concat(r)); } this._data.search.dom.children(".jstree-anchor").addClass('jstree-search'); } /** * triggered after search is complete * @event * @name search.jstree * @param {jQuery} nodes a jQuery collection of matching nodes * @param {String} str the search string * @param {Array} res a collection of objects represeing the matching nodes * @plugin search */ this.trigger('search', { nodes : this._data.search.dom, str : str, res : this._data.search.res, show_only_matches : show_only_matches }); }; /** * used to clear the last search (removes classes and shows all nodes if filtering is on) * @name clear_search() * @plugin search * @trigger clear_search.jstree */ this.clear_search = function () { if(this.settings.search.close_opened_onclear) { this.close_node(this._data.search.opn, 0); } /** * triggered after search is complete * @event * @name clear_search.jstree * @param {jQuery} nodes a jQuery collection of matching nodes (the result from the last search) * @param {String} str the search string (the last search string) * @param {Array} res a collection of objects represeing the matching nodes (the result from the last search) * @plugin search */ this.trigger('clear_search', { 'nodes' : this._data.search.dom, str : this._data.search.str, res : this._data.search.res }); if(this._data.search.res.length) { this._data.search.dom = $(this.element[0].querySelectorAll('#' + $.map(this._data.search.res, function (v) { return "0123456789".indexOf(v[0]) !== -1 ? '\\3' + v[0] + ' ' + v.substr(1).replace($.jstree.idregex,'\\$&') : v.replace($.jstree.idregex,'\\$&'); }).join(', #'))); this._data.search.dom.children(".jstree-anchor").removeClass("jstree-search"); } this._data.search.str = ""; this._data.search.res = []; this._data.search.opn = []; this._data.search.dom = $(); }; this.redraw_node = function(obj, deep, callback, force_render) { obj = parent.redraw_node.apply(this, arguments); if(obj) { if($.inArray(obj.id, this._data.search.res) !== -1) { var i, j, tmp = null; for(i = 0, j = obj.childNodes.length; i < j; i++) { if(obj.childNodes[i] && obj.childNodes[i].className && obj.childNodes[i].className.indexOf("jstree-anchor") !== -1) { tmp = obj.childNodes[i]; break; } } if(tmp) { tmp.className += ' jstree-search'; } } } return obj; }; }; // helpers (function ($) { // from http://kiro.me/projects/fuse.html $.vakata.search = function(pattern, txt, options) { options = options || {}; options = $.extend({}, $.vakata.search.defaults, options); if(options.fuzzy !== false) { options.fuzzy = true; } pattern = options.caseSensitive ? pattern : pattern.toLowerCase(); var MATCH_LOCATION = options.location, MATCH_DISTANCE = options.distance, MATCH_THRESHOLD = options.threshold, patternLen = pattern.length, matchmask, pattern_alphabet, match_bitapScore, search; if(patternLen > 32) { options.fuzzy = false; } if(options.fuzzy) { matchmask = 1 << (patternLen - 1); pattern_alphabet = (function () { var mask = {}, i = 0; for (i = 0; i < patternLen; i++) { mask[pattern.charAt(i)] = 0; } for (i = 0; i < patternLen; i++) { mask[pattern.charAt(i)] |= 1 << (patternLen - i - 1); } return mask; }()); match_bitapScore = function (e, x) { var accuracy = e / patternLen, proximity = Math.abs(MATCH_LOCATION - x); if(!MATCH_DISTANCE) { return proximity ? 1.0 : accuracy; } return accuracy + (proximity / MATCH_DISTANCE); }; } search = function (text) { text = options.caseSensitive ? text.toString() : text.toString().toLowerCase(); if(pattern === text || text.indexOf(pattern) !== -1) { return { isMatch: true, score: 0 }; } if(!options.fuzzy) { return { isMatch: false, score: 1 }; } var i, j, textLen = text.length, scoreThreshold = MATCH_THRESHOLD, bestLoc = text.indexOf(pattern, MATCH_LOCATION), binMin, binMid, binMax = patternLen + textLen, lastRd, start, finish, rd, charMatch, score = 1, locations = []; if (bestLoc !== -1) { scoreThreshold = Math.min(match_bitapScore(0, bestLoc), scoreThreshold); bestLoc = text.lastIndexOf(pattern, MATCH_LOCATION + patternLen); if (bestLoc !== -1) { scoreThreshold = Math.min(match_bitapScore(0, bestLoc), scoreThreshold); } } bestLoc = -1; for (i = 0; i < patternLen; i++) { binMin = 0; binMid = binMax; while (binMin < binMid) { if (match_bitapScore(i, MATCH_LOCATION + binMid) <= scoreThreshold) { binMin = binMid; } else { binMax = binMid; } binMid = Math.floor((binMax - binMin) / 2 + binMin); } binMax = binMid; start = Math.max(1, MATCH_LOCATION - binMid + 1); finish = Math.min(MATCH_LOCATION + binMid, textLen) + patternLen; rd = new Array(finish + 2); rd[finish + 1] = (1 << i) - 1; for (j = finish; j >= start; j--) { charMatch = pattern_alphabet[text.charAt(j - 1)]; if (i === 0) { rd[j] = ((rd[j + 1] << 1) | 1) & charMatch; } else { rd[j] = ((rd[j + 1] << 1) | 1) & charMatch | (((lastRd[j + 1] | lastRd[j]) << 1) | 1) | lastRd[j + 1]; } if (rd[j] & matchmask) { score = match_bitapScore(i, j - 1); if (score <= scoreThreshold) { scoreThreshold = score; bestLoc = j - 1; locations.push(bestLoc); if (bestLoc > MATCH_LOCATION) { start = Math.max(1, 2 * MATCH_LOCATION - bestLoc); } else { break; } } } } if (match_bitapScore(i + 1, MATCH_LOCATION) > scoreThreshold) { break; } lastRd = rd; } return { isMatch: bestLoc >= 0, score: score }; }; return txt === true ? { 'search' : search } : search(txt); }; $.vakata.search.defaults = { location : 0, distance : 100, threshold : 0.6, fuzzy : false, caseSensitive : false }; }($)); // include the search plugin by default // $.jstree.defaults.plugins.push("search"); /** * ### Sort plugin * * Automatically sorts all siblings in the tree according to a sorting function. */ /** * the settings function used to sort the nodes. * It is executed in the tree's context, accepts two nodes as arguments and should return `1` or `-1`. * @name $.jstree.defaults.sort * @plugin sort */ $.jstree.defaults.sort = function (a, b) { //return this.get_type(a) === this.get_type(b) ? (this.get_text(a) > this.get_text(b) ? 1 : -1) : this.get_type(a) >= this.get_type(b); return this.get_text(a) > this.get_text(b) ? 1 : -1; }; $.jstree.plugins.sort = function (options, parent) { this.bind = function () { parent.bind.call(this); this.element .on("model.jstree", function (e, data) { this.sort(data.parent, true); }.bind(this)) .on("rename_node.jstree create_node.jstree", function (e, data) { this.sort(data.parent || data.node.parent, false); this.redraw_node(data.parent || data.node.parent, true); }.bind(this)) .on("move_node.jstree copy_node.jstree", function (e, data) { this.sort(data.parent, false); this.redraw_node(data.parent, true); }.bind(this)); }; /** * used to sort a node's children * @private * @name sort(obj [, deep]) * @param {mixed} obj the node * @param {Boolean} deep if set to `true` nodes are sorted recursively. * @plugin sort * @trigger search.jstree */ this.sort = function (obj, deep) { var i, j; obj = this.get_node(obj); if(obj && obj.children && obj.children.length) { obj.children.sort(this.settings.sort.bind(this)); if(deep) { for(i = 0, j = obj.children_d.length; i < j; i++) { this.sort(obj.children_d[i], false); } } } }; }; // include the sort plugin by default // $.jstree.defaults.plugins.push("sort"); /** * ### State plugin * * Saves the state of the tree (selected nodes, opened nodes) on the user's computer using available options (localStorage, cookies, etc) */ var to = false; /** * stores all defaults for the state plugin * @name $.jstree.defaults.state * @plugin state */ $.jstree.defaults.state = { /** * A string for the key to use when saving the current tree (change if using multiple trees in your project). Defaults to `jstree`. * @name $.jstree.defaults.state.key * @plugin state */ key : 'jstree', /** * A space separated list of events that trigger a state save. Defaults to `changed.jstree open_node.jstree close_node.jstree`. * @name $.jstree.defaults.state.events * @plugin state */ events : 'changed.jstree open_node.jstree close_node.jstree check_node.jstree uncheck_node.jstree', /** * Time in milliseconds after which the state will expire. Defaults to 'false' meaning - no expire. * @name $.jstree.defaults.state.ttl * @plugin state */ ttl : false, /** * A function that will be executed prior to restoring state with one argument - the state object. Can be used to clear unwanted parts of the state. * @name $.jstree.defaults.state.filter * @plugin state */ filter : false, /** * Should loaded nodes be restored (setting this to true means that it is possible that the whole tree will be loaded for some users - use with caution). Defaults to `false` * @name $.jstree.defaults.state.preserve_loaded * @plugin state */ preserve_loaded : false }; $.jstree.plugins.state = function (options, parent) { this.bind = function () { parent.bind.call(this); var bind = function () { this.element.on(this.settings.state.events, function () { if(to) { clearTimeout(to); } to = setTimeout(function () { this.save_state(); }.bind(this), 100); }.bind(this)); /** * triggered when the state plugin is finished restoring the state (and immediately after ready if there is no state to restore). * @event * @name state_ready.jstree * @plugin state */ this.trigger('state_ready'); }.bind(this); this.element .on("ready.jstree", function (e, data) { this.element.one("restore_state.jstree", bind); if(!this.restore_state()) { bind(); } }.bind(this)); }; /** * save the state * @name save_state() * @plugin state */ this.save_state = function () { var tm = this.get_state(); if (!this.settings.state.preserve_loaded) { delete tm.core.loaded; } var st = { 'state' : tm, 'ttl' : this.settings.state.ttl, 'sec' : +(new Date()) }; $.vakata.storage.set(this.settings.state.key, JSON.stringify(st)); }; /** * restore the state from the user's computer * @name restore_state() * @plugin state */ this.restore_state = function () { var k = $.vakata.storage.get(this.settings.state.key); if(!!k) { try { k = JSON.parse(k); } catch(ex) { return false; } } if(!!k && k.ttl && k.sec && +(new Date()) - k.sec > k.ttl) { return false; } if(!!k && k.state) { k = k.state; } if(!!k && $.vakata.is_function(this.settings.state.filter)) { k = this.settings.state.filter.call(this, k); } if(!!k) { if (!this.settings.state.preserve_loaded) { delete k.core.loaded; } this.element.one("set_state.jstree", function (e, data) { data.instance.trigger('restore_state', { 'state' : $.extend(true, {}, k) }); }); this.set_state(k); return true; } return false; }; /** * clear the state on the user's computer * @name clear_state() * @plugin state */ this.clear_state = function () { return $.vakata.storage.del(this.settings.state.key); }; }; (function ($, undefined) { $.vakata.storage = { // simply specifying the functions in FF throws an error set : function (key, val) { return window.localStorage.setItem(key, val); }, get : function (key) { return window.localStorage.getItem(key); }, del : function (key) { return window.localStorage.removeItem(key); } }; }($)); // include the state plugin by default // $.jstree.defaults.plugins.push("state"); /** * ### Types plugin * * Makes it possible to add predefined types for groups of nodes, which make it possible to easily control nesting rules and icon for each group. */ /** * An object storing all types as key value pairs, where the key is the type name and the value is an object that could contain following keys (all optional). * * * `max_children` the maximum number of immediate children this node type can have. Do not specify or set to `-1` for unlimited. * * `max_depth` the maximum number of nesting this node type can have. A value of `1` would mean that the node can have children, but no grandchildren. Do not specify or set to `-1` for unlimited. * * `valid_children` an array of node type strings, that nodes of this type can have as children. Do not specify or set to `-1` for no limits. * * `icon` a string - can be a path to an icon or a className, if using an image that is in the current directory use a `./` prefix, otherwise it will be detected as a class. Omit to use the default icon from your theme. * * `li_attr` an object of values which will be used to add HTML attributes on the resulting LI DOM node (merged with the node's own data) * * `a_attr` an object of values which will be used to add HTML attributes on the resulting A DOM node (merged with the node's own data) * * There are two predefined types: * * * `#` represents the root of the tree, for example `max_children` would control the maximum number of root nodes. * * `default` represents the default node - any settings here will be applied to all nodes that do not have a type specified. * * @name $.jstree.defaults.types * @plugin types */ $.jstree.defaults.types = { 'default' : {} }; $.jstree.defaults.types[$.jstree.root] = {}; $.jstree.plugins.types = function (options, parent) { this.init = function (el, options) { var i, j; if(options && options.types && options.types['default']) { for(i in options.types) { if(i !== "default" && i !== $.jstree.root && options.types.hasOwnProperty(i)) { for(j in options.types['default']) { if(options.types['default'].hasOwnProperty(j) && options.types[i][j] === undefined) { options.types[i][j] = options.types['default'][j]; } } } } } parent.init.call(this, el, options); this._model.data[$.jstree.root].type = $.jstree.root; }; this.refresh = function (skip_loading, forget_state) { parent.refresh.call(this, skip_loading, forget_state); this._model.data[$.jstree.root].type = $.jstree.root; }; this.bind = function () { this.element .on('model.jstree', function (e, data) { var m = this._model.data, dpc = data.nodes, t = this.settings.types, i, j, c = 'default', k; for(i = 0, j = dpc.length; i < j; i++) { c = 'default'; if(m[dpc[i]].original && m[dpc[i]].original.type && t[m[dpc[i]].original.type]) { c = m[dpc[i]].original.type; } if(m[dpc[i]].data && m[dpc[i]].data.jstree && m[dpc[i]].data.jstree.type && t[m[dpc[i]].data.jstree.type]) { c = m[dpc[i]].data.jstree.type; } m[dpc[i]].type = c; if(m[dpc[i]].icon === true && t[c].icon !== undefined) { m[dpc[i]].icon = t[c].icon; } if(t[c].li_attr !== undefined && typeof t[c].li_attr === 'object') { for (k in t[c].li_attr) { if (t[c].li_attr.hasOwnProperty(k)) { if (k === 'id') { continue; } else if (m[dpc[i]].li_attr[k] === undefined) { m[dpc[i]].li_attr[k] = t[c].li_attr[k]; } else if (k === 'class') { m[dpc[i]].li_attr['class'] = t[c].li_attr['class'] + ' ' + m[dpc[i]].li_attr['class']; } } } } if(t[c].a_attr !== undefined && typeof t[c].a_attr === 'object') { for (k in t[c].a_attr) { if (t[c].a_attr.hasOwnProperty(k)) { if (k === 'id') { continue; } else if (m[dpc[i]].a_attr[k] === undefined) { m[dpc[i]].a_attr[k] = t[c].a_attr[k]; } else if (k === 'href' && m[dpc[i]].a_attr[k] === '#') { m[dpc[i]].a_attr['href'] = t[c].a_attr['href']; } else if (k === 'class') { m[dpc[i]].a_attr['class'] = t[c].a_attr['class'] + ' ' + m[dpc[i]].a_attr['class']; } } } } } m[$.jstree.root].type = $.jstree.root; }.bind(this)); parent.bind.call(this); }; this.get_json = function (obj, options, flat) { var i, j, m = this._model.data, opt = options ? $.extend(true, {}, options, {no_id:false}) : {}, tmp = parent.get_json.call(this, obj, opt, flat); if(tmp === false) { return false; } if($.vakata.is_array(tmp)) { for(i = 0, j = tmp.length; i < j; i++) { tmp[i].type = (tmp[i].id || tmp[i].id === 0) && m[tmp[i].id] && m[tmp[i].id].type ? m[tmp[i].id].type : "default"; if(options && options.no_id) { delete tmp[i].id; if(tmp[i].li_attr && tmp[i].li_attr.id) { delete tmp[i].li_attr.id; } if(tmp[i].a_attr && tmp[i].a_attr.id) { delete tmp[i].a_attr.id; } } } } else { tmp.type = (tmp.id || tmp.id === 0) && m[tmp.id] && m[tmp.id].type ? m[tmp.id].type : "default"; if(options && options.no_id) { tmp = this._delete_ids(tmp); } } return tmp; }; this._delete_ids = function (tmp) { if($.vakata.is_array(tmp)) { for(var i = 0, j = tmp.length; i < j; i++) { tmp[i] = this._delete_ids(tmp[i]); } return tmp; } delete tmp.id; if(tmp.li_attr && tmp.li_attr.id) { delete tmp.li_attr.id; } if(tmp.a_attr && tmp.a_attr.id) { delete tmp.a_attr.id; } if(tmp.children && $.vakata.is_array(tmp.children)) { tmp.children = this._delete_ids(tmp.children); } return tmp; }; this.check = function (chk, obj, par, pos, more) { if(parent.check.call(this, chk, obj, par, pos, more) === false) { return false; } obj = obj && (obj.id || obj.id === 0) ? obj : this.get_node(obj); par = par && (par.id || par.id === 0) ? par : this.get_node(par); var m = obj && (obj.id || obj.id === 0) ? (more && more.origin ? more.origin : $.jstree.reference(obj.id)) : null, tmp, d, i, j; m = m && m._model && m._model.data ? m._model.data : null; switch(chk) { case "create_node": case "move_node": case "copy_node": if(chk !== 'move_node' || $.inArray(obj.id, par.children) === -1) { tmp = this.get_rules(par); if(tmp.max_children !== undefined && tmp.max_children !== -1 && tmp.max_children === par.children.length) { this._data.core.last_error = { 'error' : 'check', 'plugin' : 'types', 'id' : 'types_01', 'reason' : 'max_children prevents function: ' + chk, 'data' : JSON.stringify({ 'chk' : chk, 'pos' : pos, 'obj' : obj && (obj.id || obj.id === 0) ? obj.id : false, 'par' : par && (par.id || par.id === 0) ? par.id : false }) }; return false; } if(tmp.valid_children !== undefined && tmp.valid_children !== -1 && $.inArray((obj.type || 'default'), tmp.valid_children) === -1) { this._data.core.last_error = { 'error' : 'check', 'plugin' : 'types', 'id' : 'types_02', 'reason' : 'valid_children prevents function: ' + chk, 'data' : JSON.stringify({ 'chk' : chk, 'pos' : pos, 'obj' : obj && (obj.id || obj.id === 0) ? obj.id : false, 'par' : par && (par.id || par.id === 0) ? par.id : false }) }; return false; } if(m && obj.children_d && obj.parents) { d = 0; for(i = 0, j = obj.children_d.length; i < j; i++) { d = Math.max(d, m[obj.children_d[i]].parents.length); } d = d - obj.parents.length + 1; } if(d <= 0 || d === undefined) { d = 1; } do { if(tmp.max_depth !== undefined && tmp.max_depth !== -1 && tmp.max_depth < d) { this._data.core.last_error = { 'error' : 'check', 'plugin' : 'types', 'id' : 'types_03', 'reason' : 'max_depth prevents function: ' + chk, 'data' : JSON.stringify({ 'chk' : chk, 'pos' : pos, 'obj' : obj && (obj.id || obj.id === 0) ? obj.id : false, 'par' : par && (par.id || par.id === 0) ? par.id : false }) }; return false; } par = this.get_node(par.parent); tmp = this.get_rules(par); d++; } while(par); } break; } return true; }; /** * used to retrieve the type settings object for a node * @name get_rules(obj) * @param {mixed} obj the node to find the rules for * @return {Object} * @plugin types */ this.get_rules = function (obj) { obj = this.get_node(obj); if(!obj) { return false; } var tmp = this.get_type(obj, true); if(tmp.max_depth === undefined) { tmp.max_depth = -1; } if(tmp.max_children === undefined) { tmp.max_children = -1; } if(tmp.valid_children === undefined) { tmp.valid_children = -1; } return tmp; }; /** * used to retrieve the type string or settings object for a node * @name get_type(obj [, rules]) * @param {mixed} obj the node to find the rules for * @param {Boolean} rules if set to `true` instead of a string the settings object will be returned * @return {String|Object} * @plugin types */ this.get_type = function (obj, rules) { obj = this.get_node(obj); return (!obj) ? false : ( rules ? $.extend({ 'type' : obj.type }, this.settings.types[obj.type]) : obj.type); }; /** * used to change a node's type * @name set_type(obj, type) * @param {mixed} obj the node to change * @param {String} type the new type * @plugin types */ this.set_type = function (obj, type) { var m = this._model.data, t, t1, t2, old_type, old_icon, k, d, a; if($.vakata.is_array(obj)) { obj = obj.slice(); for(t1 = 0, t2 = obj.length; t1 < t2; t1++) { this.set_type(obj[t1], type); } return true; } t = this.settings.types; obj = this.get_node(obj); if(!t[type] || !obj) { return false; } d = this.get_node(obj, true); if (d && d.length) { a = d.children('.jstree-anchor'); } old_type = obj.type; old_icon = this.get_icon(obj); obj.type = type; if(old_icon === true || !t[old_type] || (t[old_type].icon !== undefined && old_icon === t[old_type].icon)) { this.set_icon(obj, t[type].icon !== undefined ? t[type].icon : true); } // remove old type props if(t[old_type] && t[old_type].li_attr !== undefined && typeof t[old_type].li_attr === 'object') { for (k in t[old_type].li_attr) { if (t[old_type].li_attr.hasOwnProperty(k)) { if (k === 'id') { continue; } else if (k === 'class') { m[obj.id].li_attr['class'] = (m[obj.id].li_attr['class'] || '').replace(t[old_type].li_attr[k], ''); if (d) { d.removeClass(t[old_type].li_attr[k]); } } else if (m[obj.id].li_attr[k] === t[old_type].li_attr[k]) { m[obj.id].li_attr[k] = null; if (d) { d.removeAttr(k); } } } } } if(t[old_type] && t[old_type].a_attr !== undefined && typeof t[old_type].a_attr === 'object') { for (k in t[old_type].a_attr) { if (t[old_type].a_attr.hasOwnProperty(k)) { if (k === 'id') { continue; } else if (k === 'class') { m[obj.id].a_attr['class'] = (m[obj.id].a_attr['class'] || '').replace(t[old_type].a_attr[k], ''); if (a) { a.removeClass(t[old_type].a_attr[k]); } } else if (m[obj.id].a_attr[k] === t[old_type].a_attr[k]) { if (k === 'href') { m[obj.id].a_attr[k] = '#'; if (a) { a.attr('href', '#'); } } else { delete m[obj.id].a_attr[k]; if (a) { a.removeAttr(k); } } } } } } // add new props if(t[type].li_attr !== undefined && typeof t[type].li_attr === 'object') { for (k in t[type].li_attr) { if (t[type].li_attr.hasOwnProperty(k)) { if (k === 'id') { continue; } else if (m[obj.id].li_attr[k] === undefined) { m[obj.id].li_attr[k] = t[type].li_attr[k]; if (d) { if (k === 'class') { d.addClass(t[type].li_attr[k]); } else { d.attr(k, t[type].li_attr[k]); } } } else if (k === 'class') { m[obj.id].li_attr['class'] = t[type].li_attr[k] + ' ' + m[obj.id].li_attr['class']; if (d) { d.addClass(t[type].li_attr[k]); } } } } } if(t[type].a_attr !== undefined && typeof t[type].a_attr === 'object') { for (k in t[type].a_attr) { if (t[type].a_attr.hasOwnProperty(k)) { if (k === 'id') { continue; } else if (m[obj.id].a_attr[k] === undefined) { m[obj.id].a_attr[k] = t[type].a_attr[k]; if (a) { if (k === 'class') { a.addClass(t[type].a_attr[k]); } else { a.attr(k, t[type].a_attr[k]); } } } else if (k === 'href' && m[obj.id].a_attr[k] === '#') { m[obj.id].a_attr['href'] = t[type].a_attr['href']; if (a) { a.attr('href', t[type].a_attr['href']); } } else if (k === 'class') { m[obj.id].a_attr['class'] = t[type].a_attr['class'] + ' ' + m[obj.id].a_attr['class']; if (a) { a.addClass(t[type].a_attr[k]); } } } } } return true; }; }; // include the types plugin by default // $.jstree.defaults.plugins.push("types"); /** * ### Unique plugin * * Enforces that no nodes with the same name can coexist as siblings. */ /** * stores all defaults for the unique plugin * @name $.jstree.defaults.unique * @plugin unique */ $.jstree.defaults.unique = { /** * Indicates if the comparison should be case sensitive. Default is `false`. * @name $.jstree.defaults.unique.case_sensitive * @plugin unique */ case_sensitive : false, /** * Indicates if white space should be trimmed before the comparison. Default is `false`. * @name $.jstree.defaults.unique.trim_whitespace * @plugin unique */ trim_whitespace : false, /** * A callback executed in the instance's scope when a new node is created with no name and a node with the default name already exists, the two arguments are the conflicting name and the counter. The default will produce results like `New node (2)`. * @name $.jstree.defaults.unique.duplicate * @plugin unique */ duplicate : function (name, counter) { return name + ' (' + counter + ')'; } }; $.jstree.plugins.unique = function (options, parent) { this.check = function (chk, obj, par, pos, more) { if(parent.check.call(this, chk, obj, par, pos, more) === false) { return false; } obj = obj && (obj.id || obj.id === 0) ? obj : this.get_node(obj); par = par && (par.id || par.id === 0) ? par : this.get_node(par); if(!par || !par.children) { return true; } var n = chk === "rename_node" ? pos : obj.text, c = [], s = this.settings.unique.case_sensitive, w = this.settings.unique.trim_whitespace, m = this._model.data, i, j, t; for(i = 0, j = par.children.length; i < j; i++) { t = m[par.children[i]].text; if (!s) { t = t.toLowerCase(); } if (w) { t = t.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, ''); } c.push(t); } if(!s) { n = n.toLowerCase(); } if (w) { n = n.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, ''); } switch(chk) { case "delete_node": return true; case "rename_node": t = obj.text || ''; if (!s) { t = t.toLowerCase(); } if (w) { t = t.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, ''); } i = ($.inArray(n, c) === -1 || (obj.text && t === n)); if(!i) { this._data.core.last_error = { 'error' : 'check', 'plugin' : 'unique', 'id' : 'unique_01', 'reason' : 'Child with name ' + n + ' already exists. Preventing: ' + chk, 'data' : JSON.stringify({ 'chk' : chk, 'pos' : pos, 'obj' : obj && (obj.id || obj.id === 0) ? obj.id : false, 'par' : par && (par.id || par.id === 0) ? par.id : false }) }; } return i; case "create_node": i = ($.inArray(n, c) === -1); if(!i) { this._data.core.last_error = { 'error' : 'check', 'plugin' : 'unique', 'id' : 'unique_04', 'reason' : 'Child with name ' + n + ' already exists. Preventing: ' + chk, 'data' : JSON.stringify({ 'chk' : chk, 'pos' : pos, 'obj' : obj && (obj.id || obj.id === 0) ? obj.id : false, 'par' : par && (par.id || par.id === 0) ? par.id : false }) }; } return i; case "copy_node": i = ($.inArray(n, c) === -1); if(!i) { this._data.core.last_error = { 'error' : 'check', 'plugin' : 'unique', 'id' : 'unique_02', 'reason' : 'Child with name ' + n + ' already exists. Preventing: ' + chk, 'data' : JSON.stringify({ 'chk' : chk, 'pos' : pos, 'obj' : obj && (obj.id || obj.id === 0) ? obj.id : false, 'par' : par && (par.id || par.id === 0) ? par.id : false }) }; } return i; case "move_node": i = ( (obj.parent === par.id && (!more || !more.is_multi)) || $.inArray(n, c) === -1); if(!i) { this._data.core.last_error = { 'error' : 'check', 'plugin' : 'unique', 'id' : 'unique_03', 'reason' : 'Child with name ' + n + ' already exists. Preventing: ' + chk, 'data' : JSON.stringify({ 'chk' : chk, 'pos' : pos, 'obj' : obj && (obj.id || obj.id === 0) ? obj.id : false, 'par' : par && (par.id || par.id === 0) ? par.id : false }) }; } return i; } return true; }; this.create_node = function (par, node, pos, callback, is_loaded) { if(!node || (typeof node === 'object' && node.text === undefined)) { if(par === null) { par = $.jstree.root; } par = this.get_node(par); if(!par) { return parent.create_node.call(this, par, node, pos, callback, is_loaded); } pos = pos === undefined ? "last" : pos; if(!pos.toString().match(/^(before|after)$/) && !is_loaded && !this.is_loaded(par)) { return parent.create_node.call(this, par, node, pos, callback, is_loaded); } if(!node) { node = {}; } var tmp, n, dpc, i, j, m = this._model.data, s = this.settings.unique.case_sensitive, w = this.settings.unique.trim_whitespace, cb = this.settings.unique.duplicate, t; n = tmp = this.get_string('New node'); dpc = []; for(i = 0, j = par.children.length; i < j; i++) { t = m[par.children[i]].text; if (!s) { t = t.toLowerCase(); } if (w) { t = t.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, ''); } dpc.push(t); } i = 1; t = n; if (!s) { t = t.toLowerCase(); } if (w) { t = t.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, ''); } while($.inArray(t, dpc) !== -1) { n = cb.call(this, tmp, (++i)).toString(); t = n; if (!s) { t = t.toLowerCase(); } if (w) { t = t.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, ''); } } node.text = n; } return parent.create_node.call(this, par, node, pos, callback, is_loaded); }; }; // include the unique plugin by default // $.jstree.defaults.plugins.push("unique"); /** * ### Wholerow plugin * * Makes each node appear block level. Making selection easier. May cause slow down for large trees in old browsers. */ var div = document.createElement('DIV'); div.setAttribute('unselectable','on'); div.setAttribute('role','presentation'); div.className = 'jstree-wholerow'; div.innerHTML = ' '; $.jstree.plugins.wholerow = function (options, parent) { this.bind = function () { parent.bind.call(this); this.element .on('ready.jstree set_state.jstree', function () { this.hide_dots(); }.bind(this)) .on("init.jstree loading.jstree ready.jstree", function () { //div.style.height = this._data.core.li_height + 'px'; this.get_container_ul().addClass('jstree-wholerow-ul'); }.bind(this)) .on("deselect_all.jstree", function (e, data) { this.element.find('.jstree-wholerow-clicked').removeClass('jstree-wholerow-clicked'); }.bind(this)) .on("changed.jstree", function (e, data) { this.element.find('.jstree-wholerow-clicked').removeClass('jstree-wholerow-clicked'); var tmp = false, i, j; for(i = 0, j = data.selected.length; i < j; i++) { tmp = this.get_node(data.selected[i], true); if(tmp && tmp.length) { tmp.children('.jstree-wholerow').addClass('jstree-wholerow-clicked'); } } }.bind(this)) .on("open_node.jstree", function (e, data) { this.get_node(data.node, true).find('.jstree-clicked').parent().children('.jstree-wholerow').addClass('jstree-wholerow-clicked'); }.bind(this)) .on("hover_node.jstree dehover_node.jstree", function (e, data) { if(e.type === "hover_node" && this.is_disabled(data.node)) { return; } this.get_node(data.node, true).children('.jstree-wholerow')[e.type === "hover_node"?"addClass":"removeClass"]('jstree-wholerow-hovered'); }.bind(this)) .on("contextmenu.jstree", ".jstree-wholerow", function (e) { if (this._data.contextmenu) { e.preventDefault(); var tmp = $.Event('contextmenu', { metaKey : e.metaKey, ctrlKey : e.ctrlKey, altKey : e.altKey, shiftKey : e.shiftKey, pageX : e.pageX, pageY : e.pageY }); $(e.currentTarget).closest(".jstree-node").children(".jstree-anchor").first().trigger(tmp); } }.bind(this)) /*! .on("mousedown.jstree touchstart.jstree", ".jstree-wholerow", function (e) { if(e.target === e.currentTarget) { var a = $(e.currentTarget).closest(".jstree-node").children(".jstree-anchor"); e.target = a[0]; a.trigger(e); } }) */ .on("click.jstree", ".jstree-wholerow", function (e) { e.stopImmediatePropagation(); var tmp = $.Event('click', { metaKey : e.metaKey, ctrlKey : e.ctrlKey, altKey : e.altKey, shiftKey : e.shiftKey }); $(e.currentTarget).closest(".jstree-node").children(".jstree-anchor").first().trigger(tmp).trigger('focus'); }) .on("dblclick.jstree", ".jstree-wholerow", function (e) { e.stopImmediatePropagation(); var tmp = $.Event('dblclick', { metaKey : e.metaKey, ctrlKey : e.ctrlKey, altKey : e.altKey, shiftKey : e.shiftKey }); $(e.currentTarget).closest(".jstree-node").children(".jstree-anchor").first().trigger(tmp).trigger('focus'); }) .on("click.jstree", ".jstree-leaf > .jstree-ocl", function (e) { e.stopImmediatePropagation(); var tmp = $.Event('click', { metaKey : e.metaKey, ctrlKey : e.ctrlKey, altKey : e.altKey, shiftKey : e.shiftKey }); $(e.currentTarget).closest(".jstree-node").children(".jstree-anchor").first().trigger(tmp).trigger('focus'); }.bind(this)) .on("mouseover.jstree", ".jstree-wholerow, .jstree-icon", function (e) { e.stopImmediatePropagation(); if(!this.is_disabled(e.currentTarget)) { this.hover_node(e.currentTarget); } return false; }.bind(this)) .on("mouseleave.jstree", ".jstree-node", function (e) { this.dehover_node(e.currentTarget); }.bind(this)); }; this.teardown = function () { if(this.settings.wholerow) { this.element.find(".jstree-wholerow").remove(); } parent.teardown.call(this); }; this.redraw_node = function(obj, deep, callback, force_render) { obj = parent.redraw_node.apply(this, arguments); if(obj) { var tmp = div.cloneNode(true); //tmp.style.height = this._data.core.li_height + 'px'; if($.inArray(obj.id, this._data.core.selected) !== -1) { tmp.className += ' jstree-wholerow-clicked'; } if(this._data.core.focused && this._data.core.focused === obj.id) { tmp.className += ' jstree-wholerow-hovered'; } obj.insertBefore(tmp, obj.childNodes[0]); } return obj; }; }; // include the wholerow plugin by default // $.jstree.defaults.plugins.push("wholerow"); if(window.customElements && Object && Object.create) { var proto = Object.create(HTMLElement.prototype); proto.createdCallback = function () { var c = { core : {}, plugins : [] }, i; for(i in $.jstree.plugins) { if($.jstree.plugins.hasOwnProperty(i) && this.attributes[i]) { c.plugins.push(i); if(this.getAttribute(i) && JSON.parse(this.getAttribute(i))) { c[i] = JSON.parse(this.getAttribute(i)); } } } for(i in $.jstree.defaults.core) { if($.jstree.defaults.core.hasOwnProperty(i) && this.attributes[i]) { c.core[i] = JSON.parse(this.getAttribute(i)) || this.getAttribute(i); } } $(this).jstree(c); }; // proto.attributeChangedCallback = function (name, previous, value) { }; try { window.customElements.define("vakata-jstree", function() {}, { prototype: proto }); } catch (ignore) { } } }));includes/labelauty/images/input-checked.png000064400000000476152214270100015033 0ustar00PNG  IHDR(-SfPLTE-!tRNS  fIDATx^7@ DQrrΞ_J* .eel@7S`C4z,`%_Mvb=<{fA>Y?=NIENDB`includes/labelauty/images/input-unchecked.png000064400000000232152214270100015364 0ustar00PNG  IHDRRPLTE}VAtRNSwRp&IDATx^c 0 , `[GG2(+&IENDB`includes/labelauty/jquery-labelauty-2-23-7.min.js000064400000005216152214270100015476 0ustar00!function(h){function p(e){var a=e,e=(a=e.clone().attr("style","position: absolute !important; top: -1000 !important; ").appendTo("body")).width(!0);return a.remove(),e}function b(e,a){e&&window.console&&window.console.log&&window.console.log("jQuery-LABELAUTY: "+a)}h.fn.labelauty=function(e){var u=h.extend({development:!1,class:"labelauty",label:!0,separator:"|",checked_label:"Checked",unchecked_label:"Unchecked",force_random_id:!1,minimum_width:!1,same_width:!0},e);return this.each(function(){var e,a=jQuery.migrateDeduplicateWarnings||!1,l=(u.development&&(jQuery.migrateDeduplicateWarnings=!1),h(this)),t=l.is(":checked"),n=l.attr("type"),c=!0,i=l.attr("aria-label");if(l.attr("aria-hidden",!0),!1===l.is(":checkbox")&&!1===l.is(":radio"))return this;if(l.addClass(u.class),d=l.attr("data-labelauty"),!0===(c=u.label)&&(null==d||0===d.length?((e=new Array)[0]=u.unchecked_label,e[1]=u.checked_label):2<(e=d.split(u.separator)).length?(c=!1,b(u.development,"There's more than two labels. LABELAUTY will not use labels.")):1===e.length&&b(u.development,"There's just one label. LABELAUTY will use this one for both cases.")),l.css({display:"none"}),l.removeAttr("data-labelauty"),s=l.attr("id"),u.force_random_id||null==s||""===s.trim()){for(var r=1+Math.floor(1024e3*Math.random()),s="labelauty-"+r;0!==h(s).length;)s="labelauty-"+ ++r,b(u.development,"Holy crap, between 1024 thousand numbers, one raised a conflict. Trying again.");l.attr("id",s)}var d,o=jQuery(function(e,a,l,t,n,c){var i,r,s="";null==n?i=r="":(i=n[0],r=null==n[1]?i:n[1]);s=null==a?"":'tabindex="0" role="'+t+'" aria-checked="'+l+'" aria-label="'+a+'"';n=1==c?'":'';return n}(s,i,t,n,e,c));o.on("click",function(){l.is(":checked")?h(o).attr("aria-checked",!1):h(o).attr("aria-checked",!0)}),o.on("keypress",function(e){e.preventDefault(),32!==e.keyCode&&13!==e.keyCode||(l.is(":checked")?(l.prop("checked",!1),h(o).attr("aria-checked",!1)):(l.prop("checked",!0),h(o).attr("aria-checked",!0)))}),l.after(o),!1!==u.minimum_width&&l.next("label[for="+s+"]").css({"min-width":u.minimum_width}),0!=u.same_width&&1==u.label&&(i=p((d=l.next("label[for="+s+"]")).find("span.labelauty-unchecked")),(t=p(d.find("span.labelauty-checked"))) 2 ) { use_labels = false; debug( settings.development, "There's more than two labels. LABELAUTY will not use labels." ); } else { // If there's just one label (no split by "settings.separator"), it will be used for both cases // Here, we have the possibility of use the same label for both cases if( labels_object.length === 1 ) debug( settings.development, "There's just one label. LABELAUTY will use this one for both cases." ); } } } /* * Let's begin the beauty */ // Start hiding ugly checkboxes // Obviously, we don't need native checkboxes :O $object.css({ display : "none" }); // We don't need more data-labelauty attributes! // Ok, ok, it's just for beauty improvement $object.removeAttr( "data-labelauty" ); // Now, grab checkbox ID Attribute for "label" tag use // If there's no ID Attribute, then generate a new one input_id = $object.attr( "id" ); if( settings.force_random_id || input_id == null || input_id.trim() === "") { var input_id_number = 1 + Math.floor( Math.random() * 1024000 ); input_id = "labelauty-" + input_id_number; // Is there any element with this random ID ? // If exists, then increment until get an unused ID while( $( input_id ).length !== 0 ) { input_id_number++; input_id = "labelauty-" + input_id_number; debug( settings.development, "Holy crap, between 1024 thousand numbers, one raised a conflict. Trying again." ); } $object.attr( "id", input_id ); } // Now, add necessary tags to make this work // Here, we're going to test some control variables and act properly var element = jQuery(create( input_id, aria_label, selected, type, labels_object, use_labels )) element.on('click', function(){ if($object.is(':checked')){ $(element).attr('aria-checked', false); }else{ $(element).attr('aria-checked', true); } }); element.on('keypress', function(event){ event.preventDefault(); if(event.keyCode === 32 || event.keyCode === 13){ if($object.is(':checked')){ $object.prop('checked', false); $(element).attr('aria-checked',false); }else{ $object.prop('checked', true); $(element).attr('aria-checked', true); } } }) $object.after(element); // Now, add "min-width" to label // Let's say the truth, a fixed width is more beautiful than a variable width if( settings.minimum_width !== false ) $object.next( "label[for=" + input_id + "]" ).css({ "min-width": settings.minimum_width }); // Now, add "min-width" to label // Let's say the truth, a fixed width is more beautiful than a variable width if( settings.same_width != false && settings.label == true ) { var label_object = $object.next( "label[for=" + input_id + "]" ); var unchecked_width = getRealWidth(label_object.find( "span.labelauty-unchecked" )); var checked_width = getRealWidth(label_object.find( "span.labelauty-checked" )); if( unchecked_width > checked_width ) label_object.find( "span.labelauty-checked" ).width( unchecked_width ); else label_object.find( "span.labelauty-unchecked" ).width( checked_width ); } if (settings.development) jQuery.migrateDeduplicateWarnings = migrateDeduplicateWarnings; }); }; /* * Tricky code to work with hidden elements, like tabs. * Note: This code is based on jquery.actual plugin. * https://github.com/dreamerslab/jquery.actual */ function getRealWidth( element ) { var width = 0; var $target = element; var style = 'position: absolute !important; top: -1000 !important; '; $target = $target.clone().attr('style', style).appendTo('body'); width = $target.width(true); $target.remove(); return width; } function debug( debug, message ) { if( debug && window.console && window.console.log ) window.console.log( "jQuery-LABELAUTY: " + message ); }; function create( input_id, aria_label, selected, type, messages_object, label ) { var block; var unchecked_message; var checked_message; var aria = ""; if( messages_object == null ) unchecked_message = checked_message = ""; else { unchecked_message = messages_object[0]; // If checked message is null, then put the same text of unchecked message if( messages_object[1] == null ) checked_message = unchecked_message; else checked_message = messages_object[1]; } if(aria_label == null) aria = ""; else aria = 'tabindex="0" role="' + type + '" aria-checked="' + selected + '" aria-label="' + aria_label + '"'; if( label == true ) { block = ''; } else { block = ''; } return block; }; }( jQuery ));includes/labelauty/jquery-labelauty-2-23-7.min.css000064400000014111152214270100015644 0ustar00/* * LABELAUTY jQuery Plugin Styles * * @file: jquery-labelauty.css * @author: Francisco Neves (@fntneves) * @site: www.francisconeves.com * @license: MIT License */input.labelauty+label ::-moz-selection{background-color:rgba(255,255,255,0)}input.labelauty+label ::selection{background-color:rgba(255,255,255,0)}input.labelauty+label ::-moz-selection{background-color:rgba(255,255,255,0)}input.labelauty{display:none !important}input.labelauty+label{display:inline-block;font-size:13px;padding:10px;background-color:#efefef;color:black;cursor:pointer;margin-top:10px;margin-right:10px;width:96%;border-radius:3px 3px 3px 3px;-moz-border-radius:3px 3px 3px 3px;-webkit-border-radius:3px 3px 3px 3px;transition:background-color .25s;-moz-transition:background-color .25s;-webkit-transition:background-color .25s;-o-transition:background-color .25s;-moz-user-select:none;-khtml-user-select:none;-webkit-user-select:none;-o-user-select:none}input.labelauty+label>span.labelauty-unchecked,input.labelauty+label>span.labelauty-checked{display:inline-block;line-height:1.1;vertical-align:middle}input.labelauty+label>span.labelauty-unchecked-image,input.labelauty+label>span.labelauty-checked-image{display:inline-block;width:30px;height:30px;vertical-align:middle;background-repeat:no-repeat;background-position:left center;background-size:contain;transition:background-image .5s linear;-moz-transition:background-image .5s linear;-webkit-transition:background-image .5s linear;-o-transition:background-image .5s linear}input.labelauty+label>span.labelauty-unchecked-image+span.labelauty-unchecked,input.labelauty+label>span.labelauty-checked-image+span.labelauty-checked{margin-left:7px}input.labelauty:not(:checked):not([disabled])+label:hover{background-color:#eaeaea;color:#a7a7a7}input.labelauty:not(:checked)+label>span.labelauty-checked-image{display:none}input.labelauty:not(:checked)+label>span.labelauty-checked{display:none}input.labelauty:checked+label{background-color:#3498db;color:#fff}input.labelauty:checked:not([disabled])+label:hover{background-color:#72c5fd}input.labelauty:checked+label>span.labelauty-unchecked-image{display:none}input.labelauty:checked+label>span.labelauty-unchecked{display:none}input.labelauty:checked+label>span.labelauty-checked{display:inline-block}input.labelauty.no-label:checked+label>span.labelauty-checked{display:block}input.labelauty[disabled]+label{opacity:.5}input.labelauty+label>span.labelauty-unchecked-image{background-image:url(images/icons/folder.png)}input.labelauty+label>span.labelauty-checked-image{background-image:url(images/icons/folder.png)}input.labelauty.email+label>span.labelauty-checked-image,input.labelauty.email+label>span.labelauty-unchecked-image{background-image:url(../../images/icons/email.png)}input.labelauty.cloudfiles+label>span.labelauty-checked-image,input.labelauty.cloudfiles+label>span.labelauty-unchecked-image{background-image:url(../../images/icons/cloudfiles.png)}input.labelauty.dreamobjects+label>span.labelauty-checked-image,input.labelauty.dreamobjects+label>span.labelauty-unchecked-image{background-image:url(../../images/icons/dreamobjects.png)}input.labelauty.dropbox+label>span.labelauty-checked-image,input.labelauty.dropbox+label>span.labelauty-unchecked-image{background-image:url(../../images/icons/dropbox.png)}input.labelauty.pcloud+label>span.labelauty-checked-image,input.labelauty.pcloud+label>span.labelauty-unchecked-image{background-image:url(../../images/icons/pcloud.png)}input.labelauty.ftp+label>span.labelauty-checked-image,input.labelauty.ftp+label>span.labelauty-unchecked-image{background-image:url(../../images/icons/folder.png)}input.labelauty.sftp+label>span.labelauty-checked-image,input.labelauty.sftp+label>span.labelauty-unchecked-image{background-image:url(../../images/icons/folder.png)}input.labelauty.googledrive+label>span.labelauty-checked-image,input.labelauty.googledrive+label>span.labelauty-unchecked-image{background-image:url(../../images/icons/googledrive.png)}input.labelauty.s3generic+label>span.labelauty-checked-image,input.labelauty.s3generic+label>span.labelauty-unchecked-image{background-image:url(../../images/icons/folder.png)}input.labelauty.onedrive+label>span.labelauty-checked-image,input.labelauty.onedrive+label>span.labelauty-unchecked-image{background-image:url(../../images/icons/onedrive.png)}input.labelauty.azure+label>span.labelauty-checked-image,input.labelauty.azure+label>span.labelauty-unchecked-image{background-image:url(../../images/icons/azure.png)}input.labelauty.backblaze+label>span.labelauty-checked-image,input.labelauty.backblaze+label>span.labelauty-unchecked-image{background-image:url(../../images/icons/backblaze.png)}input.labelauty.openstack+label>span.labelauty-checked-image,input.labelauty.openstack+label>span.labelauty-unchecked-image{background-image:url(../../images/icons/openstack.png)}input.labelauty.s3+label>span.labelauty-checked-image,input.labelauty.s3+label>span.labelauty-unchecked-image{background-image:url(../../images/icons/s3.png)}input.labelauty.updraftvault+label>span.labelauty-checked-image,input.labelauty.updraftvault+label>span.labelauty-unchecked-image{background-image:url(../../images/icons/updraftvault.png)}input.labelauty.webdav+label>span.labelauty-checked-image,input.labelauty.webdav+label>span.labelauty-unchecked-image{background-image:url(../../images/icons/webdav.png)}input.labelauty.googlecloud+label>span.labelauty-checked-image,input.labelauty.googlecloud+label>span.labelauty-unchecked-image{background-image:url(../../images/icons/googlecloud.png)}#remote-storage-container{height:auto;width:auto;-moz-column-count:2;-webkit-column-count:2;column-count:2}@media only screen and (min-width:480px){#remote-storage-container{height:auto;width:auto}}@media only screen and (min-width:1000px){#remote-storage-container{-moz-column-count:3;-webkit-column-count:3;column-count:3;height:auto;width:auto}}@media only screen and (max-width:480px){input.labelauty+label{text-align:center}input.labelauty+label>span.labelauty-unchecked-image,input.labelauty+label>span.labelauty-checked-image{display:block;margin:0 auto;margin-bottom:4px}} /*# sourceMappingURL=jquery-labelauty-2-23-7.min.css.map */ includes/labelauty/jquery-labelauty.css000064400000016311152214270100014341 0ustar00/*! * LABELAUTY jQuery Plugin Styles * * @file: jquery-labelauty.css * @author: Francisco Neves (@fntneves) * @site: www.francisconeves.com * @license: MIT License */ /* Prevent text and blocks selection */ input.labelauty + label ::-moz-selection { background-color: rgba(255, 255, 255, 0); } input.labelauty + label ::selection { background-color: rgba(255, 255, 255, 0); } input.labelauty + label ::-moz-selection { background-color: rgba(255, 255, 255, 0); } /* Hide original checkboxes. They are ugly! */ input.labelauty { display: none !important; } /* * Let's style the input * Feel free to work with it as you wish! */ input.labelauty + label { display: inline-block; font-size: 13px; padding: 10px; background-color: #efefef; color: black; cursor: pointer; margin-top: 10px; margin-right: 10px; width: 96%; border-radius: 3px 3px 3px 3px; -moz-border-radius: 3px 3px 3px 3px; -webkit-border-radius: 3px 3px 3px 3px; transition: background-color 0.25s; -moz-transition: background-color 0.25s; -webkit-transition: background-color 0.25s; -o-transition: background-color 0.25s; -moz-user-select: none; -khtml-user-select: none; -webkit-user-select: none; -o-user-select: none; } /* Stylish text inside label */ input.labelauty + label > span.labelauty-unchecked, input.labelauty + label > span.labelauty-checked { display: inline-block; line-height: 1.1; vertical-align: middle; } /* Stylish icons inside label */ input.labelauty + label > span.labelauty-unchecked-image, input.labelauty + label > span.labelauty-checked-image { display: inline-block; width: 30px; height: 30px; vertical-align: middle; background-repeat: no-repeat; background-position: left center; background-size: contain; transition: background-image 0.5s linear; -moz-transition: background-image 0.5s linear; -webkit-transition: background-image 0.5s linear; -o-transition: background-image 0.5s linear; } /* When there's a label, add a little margin to the left */ input.labelauty + label > span.labelauty-unchecked-image + span.labelauty-unchecked, input.labelauty + label > span.labelauty-checked-image + span.labelauty-checked { margin-left: 7px; } /* When not Checked */ input.labelauty:not(:checked):not([disabled]) + label:hover { background-color: #eaeaea; color: #a7a7a7; } input.labelauty:not(:checked) + label > span.labelauty-checked-image { display: none; } input.labelauty:not(:checked) + label > span.labelauty-checked { display: none; } /* When Checked */ input.labelauty:checked + label { background-color: #3498db; color: #ffffff; } input.labelauty:checked:not([disabled]) + label:hover { background-color: #72c5fd; } input.labelauty:checked + label > span.labelauty-unchecked-image { display: none; } input.labelauty:checked + label > span.labelauty-unchecked { display: none; } input.labelauty:checked + label > span.labelauty-checked { display: inline-block; } input.labelauty.no-label:checked + label > span.labelauty-checked { display: block; } /* When Disabled */ input.labelauty[disabled] + label { opacity: 0.5; } /* Add a background to (un)checked images */ input.labelauty + label > span.labelauty-unchecked-image { background-image: url( images/icons/folder.png ); } input.labelauty + label > span.labelauty-checked-image { background-image: url( images/icons/folder.png ); } input.labelauty.email + label > span.labelauty-checked-image, input.labelauty.email + label > span.labelauty-unchecked-image { background-image: url( ../../images/icons/email.png ); } input.labelauty.cloudfiles + label > span.labelauty-checked-image, input.labelauty.cloudfiles + label > span.labelauty-unchecked-image { background-image: url( ../../images/icons/cloudfiles.png ); } input.labelauty.dreamobjects + label > span.labelauty-checked-image, input.labelauty.dreamobjects + label > span.labelauty-unchecked-image { background-image: url( ../../images/icons/dreamobjects.png ); } input.labelauty.dropbox + label > span.labelauty-checked-image, input.labelauty.dropbox + label > span.labelauty-unchecked-image { background-image: url( ../../images/icons/dropbox.png ); } input.labelauty.pcloud + label > span.labelauty-checked-image, input.labelauty.pcloud + label > span.labelauty-unchecked-image { background-image: url( ../../images/icons/pcloud.png ); } input.labelauty.ftp + label > span.labelauty-checked-image, input.labelauty.ftp + label > span.labelauty-unchecked-image { background-image: url( ../../images/icons/folder.png ); } input.labelauty.sftp + label > span.labelauty-checked-image, input.labelauty.sftp + label > span.labelauty-unchecked-image { background-image: url( ../../images/icons/folder.png ); } input.labelauty.googledrive + label > span.labelauty-checked-image, input.labelauty.googledrive + label > span.labelauty-unchecked-image { background-image: url( ../../images/icons/googledrive.png ); } input.labelauty.s3generic + label > span.labelauty-checked-image, input.labelauty.s3generic + label > span.labelauty-unchecked-image { background-image: url( ../../images/icons/folder.png ); } input.labelauty.onedrive + label > span.labelauty-checked-image, input.labelauty.onedrive + label > span.labelauty-unchecked-image { background-image: url( ../../images/icons/onedrive.png ); } input.labelauty.azure + label > span.labelauty-checked-image, input.labelauty.azure + label > span.labelauty-unchecked-image { background-image: url( ../../images/icons/azure.png ); } input.labelauty.backblaze + label > span.labelauty-checked-image, input.labelauty.backblaze + label > span.labelauty-unchecked-image { background-image: url( ../../images/icons/backblaze.png ); } input.labelauty.openstack + label > span.labelauty-checked-image, input.labelauty.openstack + label > span.labelauty-unchecked-image { background-image: url( ../../images/icons/openstack.png ); } input.labelauty.s3 + label > span.labelauty-checked-image, input.labelauty.s3 + label > span.labelauty-unchecked-image { background-image: url( ../../images/icons/s3.png ); } input.labelauty.updraftvault + label > span.labelauty-checked-image, input.labelauty.updraftvault + label > span.labelauty-unchecked-image { background-image: url( ../../images/icons/updraftvault.png ); } input.labelauty.webdav + label > span.labelauty-checked-image, input.labelauty.webdav + label > span.labelauty-unchecked-image { background-image: url( ../../images/icons/webdav.png ); } input.labelauty.googlecloud + label > span.labelauty-checked-image, input.labelauty.googlecloud + label > span.labelauty-unchecked-image { background-image: url( ../../images/icons/googlecloud.png ); } #remote-storage-container { height: auto; width: auto; -moz-column-count: 2; -webkit-column-count: 2; column-count: 2; } @media only screen and (min-width: 480px) { #remote-storage-container { height: auto; width: auto; } } @media only screen and (min-width: 1000px) { #remote-storage-container { -moz-column-count: 3; -webkit-column-count: 3; column-count: 3; height: auto; width: auto; } } @media only screen and (max-width: 480px) { input.labelauty + label { text-align: center; } input.labelauty + label > span.labelauty-unchecked-image, input.labelauty + label > span.labelauty-checked-image { display: block; margin: 0 auto; margin-bottom: 4px; } }includes/labelauty/jquery-labelauty-2-23-7.min.css.map000064400000022507152214270100016430 0ustar00{"version":3,"sources":["includes/labelauty/jquery-labelauty.css"],"names":[],"mappings":"AAAA;;;;;;;EAOE;;AAEF,sCAAsC;AACtC,2CAAsC,wCAAwC,EAAE;AAAhF,sCAAsC,wCAAwC,EAAE;AAChF,2CAA2C,wCAAwC,EAAE;;AAErF,6CAA6C;AAC7C,kBAAkB,wBAAwB,EAAE;;AAE5C;;;EAGE;AACF;;CAEC,qBAAqB;CACrB,eAAe;CACf,aAAa;CACb,yBAAyB;CACzB,YAAY;CACZ,eAAe;CACf,gBAAgB;CAChB,kBAAkB;CAClB,UAAU;;CAEV,8BAA8B;CAC9B,mCAAmC;CACnC,sCAAsC;;;CAGtC,kCAAkC;CAClC,uCAAuC;CACvC,0CAA0C;CAC1C,qCAAqC;;CAErC,sBAAsB;CACtB,wBAAwB;CACxB,yBAAyB;CACzB,oBAAoB;AACrB;;AAEA,8BAA8B;;AAE9B;;;CAGC,qBAAqB;CACrB,gBAAgB;CAChB,sBAAsB;AACvB;;AAEA,+BAA+B;;AAE/B;;;CAGC,qBAAqB;CACrB,WAAW;CACX,YAAY;CACZ,sBAAsB;CACtB,4BAA4B;CAC5B,gCAAgC;CAChC,wBAAwB;;CAExB,wCAAwC;CACxC,6CAA6C;CAC7C,gDAAgD;CAChD,2CAA2C;AAC5C;;AAEA,0DAA0D;AAC1D;;;CAGC,gBAAgB;AACjB;;AAEA,qBAAqB;AACrB;;CAEC,yBAAyB;CACzB,cAAc;AACf;AACA;;CAEC,aAAa;AACd;;AAEA;;CAEC,aAAa;AACd;;AAEA,iBAAiB;AACjB;;CAEC,yBAAyB;CACzB,cAAc;AACf;;AAEA;;CAEC,yBAAyB;AAC1B;AACA;;CAEC,aAAa;AACd;;AAEA;;CAEC,aAAa;AACd;;AAEA;;CAEC,qBAAqB;AACtB;;AAEA;;CAEC,cAAc;AACf;;AAEA,kBAAkB;AAClB;;CAEC,YAAY;AACb;;AAEA,2CAA2C;AAC3C;;CAEC,gDAAgD;AACjD;;AAEA;;CAEC,gDAAgD;AACjD;;AAEA;;CAEC,qDAAqD;AACtD;;AAEA;;CAEC,0DAA0D;AAC3D;;AAEA;;CAEC,4DAA4D;AAC7D;;AAEA;;CAEC,uDAAuD;AACxD;;AAEA;;CAEC,sDAAsD;AACvD;;AAEA;;CAEC,sDAAsD;AACvD;;AAEA;;CAEC,sDAAsD;AACvD;;AAEA;;CAEC,2DAA2D;AAC5D;;AAEA;;CAEC,sDAAsD;AACvD;;AAEA;;CAEC,wDAAwD;AACzD;;AAEA;;CAEC,qDAAqD;AACtD;;AAEA;;CAEC,yDAAyD;AAC1D;;AAEA;;CAEC,yDAAyD;AAC1D;;AAEA;;CAEC,kDAAkD;AACnD;;AAEA;;CAEC,4DAA4D;AAC7D;;AAEA;;CAEC,sDAAsD;AACvD;;AAEA;;CAEC,2DAA2D;AAC5D;;AAEA;IACI,YAAY;IACZ,WAAW;CACd,oBAAoB;CACpB,uBAAuB;CACvB,eAAe;AAChB;;AAEA;;CAEC;EACC,YAAY;EACZ,WAAW;CACZ;;AAED;;AAEA;;CAEC;EACC,oBAAoB;EACpB,uBAAuB;EACvB,eAAe;EACf,YAAY;EACZ,WAAW;CACZ;;AAED;;AAEA;;CAEC;EACC,kBAAkB;CACnB;;CAEA;EACC,cAAc;EACd,cAAc;EACd,kBAAkB;CACnB;;AAED","file":"jquery-labelauty-2-23-7.min.css","sourcesContent":["/*!\n * LABELAUTY jQuery Plugin Styles\n *\n * @file: jquery-labelauty.css\n * @author: Francisco Neves (@fntneves)\n * @site: www.francisconeves.com\n * @license: MIT License\n */\n\n/* Prevent text and blocks selection */\ninput.labelauty + label ::selection { background-color: rgba(255, 255, 255, 0); }\ninput.labelauty + label ::-moz-selection { background-color: rgba(255, 255, 255, 0); }\n\n/* Hide original checkboxes. They are ugly! */\ninput.labelauty { display: none !important; }\n\n/*\n * Let's style the input\n * Feel free to work with it as you wish!\n */\ninput.labelauty + label\n{\n\tdisplay: inline-block;\n\tfont-size: 13px;\n\tpadding: 10px;\n\tbackground-color: #efefef;\n\tcolor: black;\n\tcursor: pointer;\n\tmargin-top: 10px;\n\tmargin-right: 10px;\n\twidth: 96%;\n\n\tborder-radius: 3px 3px 3px 3px;\n\t-moz-border-radius: 3px 3px 3px 3px;\n\t-webkit-border-radius: 3px 3px 3px 3px;\n\n\n\ttransition: background-color 0.25s;\n\t-moz-transition: background-color 0.25s;\n\t-webkit-transition: background-color 0.25s;\n\t-o-transition: background-color 0.25s;\n\n\t-moz-user-select: none;\n\t-khtml-user-select: none;\n\t-webkit-user-select: none;\n\t-o-user-select: none;\n}\n\n/* Stylish text inside label */\n\ninput.labelauty + label > span.labelauty-unchecked,\ninput.labelauty + label > span.labelauty-checked\n{\n\tdisplay: inline-block;\n\tline-height: 1.1;\n\tvertical-align: middle;\n}\n\n/* Stylish icons inside label */\n\ninput.labelauty + label > span.labelauty-unchecked-image,\ninput.labelauty + label > span.labelauty-checked-image\n{\n\tdisplay: inline-block;\n\twidth: 30px;\n\theight: 30px;\n\tvertical-align: middle;\n\tbackground-repeat: no-repeat;\n\tbackground-position: left center;\n\tbackground-size: contain;\n\n\ttransition: background-image 0.5s linear;\n\t-moz-transition: background-image 0.5s linear;\n\t-webkit-transition: background-image 0.5s linear;\n\t-o-transition: background-image 0.5s linear;\n}\n\n/* When there's a label, add a little margin to the left */\ninput.labelauty + label > span.labelauty-unchecked-image + span.labelauty-unchecked,\ninput.labelauty + label > span.labelauty-checked-image + span.labelauty-checked\n{\n\tmargin-left: 7px;\n}\n\n/* When not Checked */\ninput.labelauty:not(:checked):not([disabled]) + label:hover\n{\n\tbackground-color: #eaeaea;\n\tcolor: #a7a7a7;\n}\ninput.labelauty:not(:checked) + label > span.labelauty-checked-image\n{\n\tdisplay: none;\n}\n\ninput.labelauty:not(:checked) + label > span.labelauty-checked\n{\n\tdisplay: none;\n}\n\n/* When Checked */\ninput.labelauty:checked + label\n{\n\tbackground-color: #3498db;\n\tcolor: #ffffff;\n}\n\ninput.labelauty:checked:not([disabled]) + label:hover\n{\n\tbackground-color: #72c5fd;\n}\ninput.labelauty:checked + label > span.labelauty-unchecked-image\n{\n\tdisplay: none;\n}\n\ninput.labelauty:checked + label > span.labelauty-unchecked\n{\n\tdisplay: none;\n}\n\ninput.labelauty:checked + label > span.labelauty-checked\n{\n\tdisplay: inline-block;\n}\n\ninput.labelauty.no-label:checked + label > span.labelauty-checked\n{\n\tdisplay: block;\n}\n\n/* When Disabled */\ninput.labelauty[disabled] + label\n{\n\topacity: 0.5;\n}\n\n/* Add a background to (un)checked images */\ninput.labelauty + label > span.labelauty-unchecked-image\n{\n\tbackground-image: url( images/icons/folder.png );\n}\n\ninput.labelauty + label > span.labelauty-checked-image\n{\n\tbackground-image: url( images/icons/folder.png );\n}\n\ninput.labelauty.email + label > span.labelauty-checked-image,\ninput.labelauty.email + label > span.labelauty-unchecked-image {\n\tbackground-image: url( ../../images/icons/email.png );\n}\n\ninput.labelauty.cloudfiles + label > span.labelauty-checked-image,\ninput.labelauty.cloudfiles + label > span.labelauty-unchecked-image {\n\tbackground-image: url( ../../images/icons/cloudfiles.png );\n}\n\ninput.labelauty.dreamobjects + label > span.labelauty-checked-image,\ninput.labelauty.dreamobjects + label > span.labelauty-unchecked-image {\n\tbackground-image: url( ../../images/icons/dreamobjects.png );\n}\n\ninput.labelauty.dropbox + label > span.labelauty-checked-image,\ninput.labelauty.dropbox + label > span.labelauty-unchecked-image {\n\tbackground-image: url( ../../images/icons/dropbox.png );\n}\n\ninput.labelauty.pcloud + label > span.labelauty-checked-image,\ninput.labelauty.pcloud + label > span.labelauty-unchecked-image {\n\tbackground-image: url( ../../images/icons/pcloud.png );\n}\n\ninput.labelauty.ftp + label > span.labelauty-checked-image,\ninput.labelauty.ftp + label > span.labelauty-unchecked-image {\n\tbackground-image: url( ../../images/icons/folder.png );\n}\n\ninput.labelauty.sftp + label > span.labelauty-checked-image,\ninput.labelauty.sftp + label > span.labelauty-unchecked-image {\n\tbackground-image: url( ../../images/icons/folder.png );\n}\n\ninput.labelauty.googledrive + label > span.labelauty-checked-image,\ninput.labelauty.googledrive + label > span.labelauty-unchecked-image {\n\tbackground-image: url( ../../images/icons/googledrive.png );\n}\n\ninput.labelauty.s3generic + label > span.labelauty-checked-image,\ninput.labelauty.s3generic + label > span.labelauty-unchecked-image {\n\tbackground-image: url( ../../images/icons/folder.png );\n}\n\ninput.labelauty.onedrive + label > span.labelauty-checked-image,\ninput.labelauty.onedrive + label > span.labelauty-unchecked-image {\n\tbackground-image: url( ../../images/icons/onedrive.png );\n}\n\ninput.labelauty.azure + label > span.labelauty-checked-image,\ninput.labelauty.azure + label > span.labelauty-unchecked-image {\n\tbackground-image: url( ../../images/icons/azure.png );\n}\n\ninput.labelauty.backblaze + label > span.labelauty-checked-image,\ninput.labelauty.backblaze + label > span.labelauty-unchecked-image {\n\tbackground-image: url( ../../images/icons/backblaze.png );\n}\n\ninput.labelauty.openstack + label > span.labelauty-checked-image,\ninput.labelauty.openstack + label > span.labelauty-unchecked-image {\n\tbackground-image: url( ../../images/icons/openstack.png );\n}\n\ninput.labelauty.s3 + label > span.labelauty-checked-image,\ninput.labelauty.s3 + label > span.labelauty-unchecked-image {\n\tbackground-image: url( ../../images/icons/s3.png );\n}\n\ninput.labelauty.updraftvault + label > span.labelauty-checked-image,\ninput.labelauty.updraftvault + label > span.labelauty-unchecked-image {\n\tbackground-image: url( ../../images/icons/updraftvault.png );\n}\n\ninput.labelauty.webdav + label > span.labelauty-checked-image,\ninput.labelauty.webdav + label > span.labelauty-unchecked-image {\n\tbackground-image: url( ../../images/icons/webdav.png );\n}\n\ninput.labelauty.googlecloud + label > span.labelauty-checked-image,\ninput.labelauty.googlecloud + label > span.labelauty-unchecked-image {\n\tbackground-image: url( ../../images/icons/googlecloud.png );\n}\n\n#remote-storage-container {\n height: auto;\n width: auto;\n\t-moz-column-count: 2;\n\t-webkit-column-count: 2;\n\tcolumn-count: 2;\n}\n\n@media only screen and (min-width: 480px) {\n\n\t#remote-storage-container {\n\t\theight: auto;\n\t\twidth: auto;\n\t}\n\n}\n\n@media only screen and (min-width: 1000px) {\n\n\t#remote-storage-container {\n\t\t-moz-column-count: 3;\n\t\t-webkit-column-count: 3;\n\t\tcolumn-count: 3;\n\t\theight: auto;\n\t\twidth: auto;\n\t}\n\n}\n\n@media only screen and (max-width: 480px) {\n\n\tinput.labelauty + label {\n\t\ttext-align: center;\n\t}\n\n\tinput.labelauty + label > span.labelauty-unchecked-image, input.labelauty + label > span.labelauty-checked-image {\n\t\tdisplay: block;\n\t\tmargin: 0 auto;\n\t\tmargin-bottom: 4px;\n\t}\n\n}"]}includes/onedrive/client.php000064400000070331152214270100012152 0ustar00 true, CURLOPT_SSL_VERIFYHOST => ($this->_sslVerify ? 2 : false), CURLOPT_SSL_VERIFYPEER => $this->_sslVerify, CURLOPT_AUTOREFERER => true, ); if ($this->_sslVerify && $this->_sslCAPath) { $default_options[CURLOPT_CAINFO] = $this->_sslCAPath; } // Prevent misleading PHP notice if (!$this->safeMode) $default_options[CURLOPT_FOLLOWLOCATION] = true; // See http://php.net/manual/en/function.array-merge.php for a description of the + operator (and why array_merge() would be wrong) $final_options = $options + $default_options; curl_setopt_array($curl, $final_options); return $curl; } /** * Processes a result returned by the OneDrive API call using a cURL object. * * @param (resource) $curl - The cURL object used to perform the call. * @return (object|string) The content returned, as an object instance if * served a JSON, or as a string if served as anything else. */ private function _processResult($curl) { $result = curl_exec($curl); if (false === $result) { throw new \Exception('curl_exec() failed: ' . curl_error($curl)); } $info = curl_getinfo($curl); $this->_httpStatus = array_key_exists('http_code', $info) ? (int) $info['http_code'] : null; $this->_contentType = array_key_exists('content_type', $info) ? (string) $info['content_type'] : null; // Parse nothing but JSON. if (1 !== preg_match('|^application/json|', $this->_contentType)) { return $result; } // Empty JSON string is returned as an empty object. if ('' == $result) { return (object) array(); } $decoded = json_decode($result); $vars = get_object_vars($decoded); if (array_key_exists('error', $vars)) { throw new \Exception($decoded->error->message, (int) $decoded->error->code); } return $decoded; } /** * Constructor. * * @param (array) $options. The options to use while creating this object. * Valid supported keys are: * 'state': When defined, it should contain a valid OneDrive client * state, as returned by getState(). Default: array(). * (boolean)'ssl_verify': whether to verify SSL hosts and peers (default: false) * (boolean|string)'ssl_capath': CA path to use for verifying SSL certificate chain (default: false) */ public function __construct(array $options = array()) { $this->_clientId = array_key_exists('client_id', $options) ? (string) $options['client_id'] : null; $this->_state = array_key_exists('state', $options) ? $options['state'] : (object) array( 'redirect_uri' => null, 'token' => null ); $this->_sslVerify = array_key_exists('ssl_verify', $options) ? $options['ssl_verify'] : false; $this->_sslCAPath = array_key_exists('ssl_capath', $options) ? $options['ssl_capath'] : false; $this->safeMode = (@ini_get('safe_mode') && strtolower(@ini_get('safe_mode')) != "off") ? 1 : 0; $this->use_msgraph_api = array_key_exists('use_msgraph_api', $options) ? $options['use_msgraph_api'] : false; if ($this->use_msgraph_api) { $endpoint_tld = (isset($options['endpoint_tld']) && 'de' == $options['endpoint_tld']) ? $options['endpoint_tld'] : 'com'; $this->api_url = UpdraftPlus_OneDrive_Account::$types[$endpoint_tld]['api_url']; $this->route_prefix = 'me/'; // The base URL for authorization requests. $this->auth_url = UpdraftPlus_OneDrive_Account::$types[$endpoint_tld]['auth_url']; // The base URL for token requests. $this->token_url = UpdraftPlus_OneDrive_Account::$types[$endpoint_tld]['token_url']; } else { // Custom App or old live sdk $this->route_prefix = ''; $this->api_url = 'https://api.onedrive.com/v1.0/'; // The base URL for authorization requests. $this->auth_url = 'https://login.live.com/oauth20_authorize.srf'; // The base URL for token requests. $this->token_url = 'https://login.live.com/oauth20_token.srf'; } } /** * Gets the current state of this Client instance. Typically saved in the * session and passed back to the Client constructor for further requests. * * @return (object) The state of this Client instance. */ public function getState() { return $this->_state; } /** * Gets the URL of the log in form. After login, the browser is redirected to * the redirect URL, and a code is passed as a GET parameter to this URL. * * The browser is also redirected to this URL if the user is already logged * in. * * @param (array) $scopes - The OneDrive scopes requested by the application. * Supported values: 'wl.signin', 'wl.basic', 'wl.contacts_skydrive', * 'wl.skydrive_update'. * @param (string) $redirectUri - The URI to which to redirect to upon * successful log in. * @param (array) $options. Reserved for future use. Default: array(). TODO: * support it. * @param (string) $instance_id - the id of the instance that we are currently trying to authorise * @param string $callback_uri - the current site url where control should redirect after auth server authenticated * @return (string) The login URL. */ public function getLogInUrl(array $scopes, $redirectUri, array $options = array(), $instance_id = '', $callback_uri = '') { if (null === $this->_clientId) { throw new \Exception('The client ID must be set to call getLoginUrl()'); } if ($this->use_msgraph_api) { $imploded = implode(' ', $scopes); } else { $imploded = implode(',', $scopes); } $redirectUri = (string) $redirectUri; $this->_state->redirect_uri = $redirectUri; $prefixed_instance_id = ':' . $instance_id; if ($this->use_msgraph_api) { $token = 'token'.$prefixed_instance_id.$callback_uri; } else { $token = $prefixed_instance_id; } // When using this URL, the browser will eventually be redirected to the // callback URL with a code passed in the URL query string (the name of the // variable is "code"). This is suitable for PHP. $url = $this->auth_url . '?client_id=' . urlencode($this->_clientId) . '&scope=' . urlencode($imploded) . '&response_type=code' . '&redirect_uri=' . urlencode($redirectUri) . '&state=' . urlencode($token) . '&display=popup' . '&locale=en'; return $url; } /** * Gets the access token expiration delay. * * @return (int) The token expiration delay, in seconds. */ public function getTokenExpire() { return $this->_state->token->obtained + $this->_state->token->data->expires_in - time(); } /** * Gets the status of the current access token. * * @return (int) The status of the current access token: * 0 => no access token * -1 => access token will expire soon (1 minute or less) * -2 => access token is expired * 1 => access token is valid */ public function getAccessTokenStatus() { if (null === $this->_state->token) { return 0; } $remaining = $this->getTokenExpire(); if (0 >= $remaining) { return -2; } if (60 >= $remaining) { return -1; } return 1; } /** * Obtains a new access token from OAuth. This token is valid for one hour. * * @param (string) $clientSecret - The OneDrive client secret. * @param (string) $code - The code returned by OneDrive after successful log * in. * @param (string) $redirectUri. Must be the same as the redirect URI passed * to getLoginUrl(). */ public function obtainAccessToken($clientSecret, $code) { if (null === $this->_clientId) { throw new \Exception('The client ID must be set to call obtainAccessToken()'); } if (null === $this->_state->redirect_uri) { throw new \Exception('The state\'s redirect URI must be set to call obtainAccessToken()'); } $url = $this->token_url; $curl = curl_init(); $curl_options = array( CURLOPT_RETURNTRANSFER => true, CURLOPT_SSL_VERIFYHOST => ($this->_sslVerify ? 2 : false), CURLOPT_SSL_VERIFYPEER => $this->_sslVerify, CURLOPT_URL => $url, CURLOPT_AUTOREFERER => true, CURLOPT_POST => 1, // i am sending post data CURLOPT_POSTFIELDS => 'client_id=' . urlencode($this->_clientId) . '&redirect_uri=' . urlencode($this->_state->redirect_uri) . '&client_secret=' . urlencode($clientSecret) . '&grant_type=authorization_code' . '&code=' . urlencode($code), ); // Prevent misleading PHP notice if (!$this->safeMode) $curl_options[CURLOPT_FOLLOWLOCATION] = true; curl_setopt_array($curl, $curl_options); $result = curl_exec($curl); if (false === $result) { if (curl_errno($curl)) { throw new \Exception('Curl error: '.curl_error($curl)); } else { throw new \Exception('Curl error: empty response'); } } $decoded = json_decode($result); if (null === $decoded) { throw new \Exception('json_decode() failed'); } $this->_state->redirect_uri = null; $this->_state->token = (object) array( 'obtained' => time(), 'data' => $decoded ); } /** * Renews the access token from OAuth. This token is valid for one hour. */ /*public function renewAccessToken($clientSecret, $redirectUri) { $url = self::TOKEN_URL . '?client_id=' . $this->_clientId . '&redirect_uri=' . (string) $redirectUri . '&client_secret=' . (string) $clientSecret . '&grant_type=' . 'refresh_token' . '&code=' . (string) $code; }*/ /** * Performs a call to the OneDrive API using the GET method. * * @param (string) $path - The path of the API call (eg. me/skydrive). * @param (array) $options - Further curl options to set. * @return (boolean) Object of result */ public function apiGet($path, $options = array()) { $api = $this->api_url; $url = (strpos($path, 'https://') === 0) ? $path : $api . $path; if (!$this->use_msgraph_api) $url .= '?access_token=' . urlencode($this->_state->token->data->access_token); $curl = $this->_createCurl($path, $options); $curl_options = array( CURLOPT_URL => $url, CURLOPT_HTTPHEADER => array( 'Authorization: Bearer ' . $this->_state->token->data->access_token ), ); curl_setopt_array($curl, $curl_options); //curl_setopt($curl, CURLOPT_URL, $url); return $this->_processResult($curl); } /** * Performs a call to the OneDrive API using the POST method. * * @param (string) $path - The path of the API call (eg. me/skydrive). * @param (array|object) $data - The data to pass in the body of the request. */ public function apiPost($path, $data = null) { $api = $this->api_url; $url = (strpos($path, 'https://') === 0) ? $path : $api . $path; $curl = $this->_createCurl($path); $curl_options = array( CURLOPT_URL => $url, CURLOPT_POST => true, CURLOPT_HTTPHEADER => array( 'Content-Type: application/json', // The data is sent as JSON as per OneDrive documentation 'Authorization: Bearer ' . $this->_state->token->data->access_token ), ); if (null !== $data) { $data = (object) $data; $curl_options[CURLOPT_POSTFIELDS] = json_encode($data); } else { // This doesn't seem to be necessary in my testing, but another user got an error from OneDrive indicating it was needed. Perhaps varies between curl versions? $curl_options[CURLOPT_HTTPHEADER][] = 'Content-Length: 0'; } curl_setopt_array($curl, $curl_options); return $this->_processResult($curl); } /** * Performs a call to the OneDrive API using the PUT method. * * @param (string) $path - The path of the API call (eg. me/skydrive). * @param (resource) $stream - The data stream to upload. * @param (string) $contentType - The MIME type of the data stream, or null * if unknown. Default: null. * @param (int) $size - The number of bytes to send. Default: as many as are left in the stream. * @param (array) $headers - Further headers to send */ public function apiPut($path, $stream, $contentType = null, $size = null, $headers = array()) { $api = $this->api_url; $url = (strpos($path, 'https://') === 0) ? $path : $api . $path; $curl = $this->_createCurl($path); if (null === $size) { $stats = fstat($stream); $size = $stats[7]; } $headers[] = 'Authorization: Bearer ' . $this->_state->token->data->access_token; if (null !== $contentType) { $headers[] = 'Content-Type: ' . $contentType; } $options = array( CURLOPT_URL => $url, CURLOPT_HTTPHEADER => $headers, CURLOPT_PUT => true, CURLOPT_INFILE => $stream, CURLOPT_INFILESIZE => $size ); curl_setopt_array($curl, $options); return $this->_processResult($curl); } /** * Performs a call to the OneDrive API using the DELETE method. * * @param (string) $path - The path of the API call (eg. me/skydrive). */ public function apiDelete($path) { $url = $this->api_url . $path; // . '?access_token=' . urlencode($this->_state->token->data->access_token); $curl = $this->_createCurl($path); curl_setopt_array($curl, array( CURLOPT_URL => $url, CURLOPT_CUSTOMREQUEST => 'DELETE', CURLOPT_HTTPHEADER => array( 'Authorization: Bearer ' . $this->_state->token->data->access_token ) )); return $this->_processResult($curl); } /** * Performs a call to the OneDrive API using the DELETE method. * * @param (string) $path - The path of the API call (eg. me/skydrive). * @param (array) $objectIdArray - An array of unique IDs of the objects to delete. */ public function apiDeleteMulti($path, $objectIdArray) { $multi_curl = curl_multi_init(); $curl_objects = array(); foreach($objectIdArray as $id) { $current_path = $path . $id; $url = $this->api_url . $current_path; $curl = $this->_createCurl($current_path); curl_setopt_array($curl, array( CURLOPT_URL => $url, CURLOPT_CUSTOMREQUEST => 'DELETE', CURLOPT_HTTPHEADER => array( 'Authorization: Bearer ' . $this->_state->token->data->access_token ) )); curl_multi_add_handle($multi_curl, $curl); $curl_objects[] = $curl; } $active = null; do { $status = curl_multi_exec($multi_curl, $active); if ($active) { // Wait a short time for more activity curl_multi_select($multi_curl); } } while ($active && $status == CURLM_OK); $response_array = array(); foreach ($curl_objects as $curl_object) { $response = curl_multi_getcontent($curl_object); // If empty then it's a success other wise we have an error array if (empty($response)) { $response_array[] = 'success'; } else { $response_array[] = json_decode($response, true); } curl_multi_remove_handle($multi_curl, $curl_object); } curl_multi_close($multi_curl); return $response_array; } /** * Performs a call to the OneDrive API using the MOVE method. * * @param (string) $path - The path of the API call (eg. me/skydrive). * @param (array|object) $data - The data to pass in the body of the request. */ public function apiMove($path, $data) { $url = $this->api_url . $path; $data = (object) $data; $curl = $this->_createCurl($path); curl_setopt_array($curl, array( CURLOPT_URL => $url, CURLOPT_CUSTOMREQUEST => 'MOVE', CURLOPT_HTTPHEADER => array( 'Content-Type: application/json', // The data is sent as JSON as per OneDrive documentation 'Authorization: Bearer ' . $this->_state->token->data->access_token ), CURLOPT_POSTFIELDS => json_encode($data) )); return $this->_processResult($curl); } /** * Performs a call to the OneDrive API using the COPY method. * * @param (string) $path - The path of the API call (eg. me/skydrive). * @param (array|object) $data - The data to pass in the body of the request. */ public function apiCopy($path, $data) { $url = $this->api_url . $path; $data = (object) $data; $curl = $this->_createCurl($path); curl_setopt_array($curl, array( CURLOPT_URL => $url, CURLOPT_CUSTOMREQUEST => 'COPY', CURLOPT_HTTPHEADER => array( 'Content-Type: application/json', // The data is sent as JSON as per OneDrive documentation 'Authorization: Bearer ' . $this->_state->token->data->access_token ), CURLOPT_POSTFIELDS => json_encode($data) )); return $this->_processResult($curl); } /** * Creates a folder in the current OneDrive account. * * @param (string) $name - The name of the OneDrive folder to be created. * @param (null|string) $parentId - The ID of the OneDrive folder into which * to create the OneDrive folder, or null to create it in the OneDrive * root folder. Default: null. * @param (null|string) $description - The description of the OneDrive folder to be * created, or null to create it without a description. Default: null. * @return (Folder) The folder created, as a Folder instance referencing to * the OneDrive folder created. */ public function createFolder($name, $parentId = null, $description = null) { if (null === $parentId) { $parent_path = $this->route_prefix.'drive/root/children'; } else{ $parent_path = $this->route_prefix.'drive/items/'.$parentId.'/children'; } $properties = array( 'name' => (string) $name, 'folder' => (object) array() ); //if (null !== $description) { // $properties['description'] = (string) $description; //} $folder_body = (object) $properties; $folder = $this->apiPost($parent_path, $folder_body); return new Folder($this, $folder->id, $folder); } /** * Creates a file in the current OneDrive account. * * @param (string) $name - The name of the OneDrive file to be created. * @param (null|string) $parentId - The ID of the OneDrive folder into which * to create the OneDrive file, or null to create it in the OneDrive * root folder. Default: null. * @param (string|resource) $content - The content of the OneDrive file to be created. * @return (File) The file created, as File instance referencing to the * OneDrive file created. * @throw (\Exception) Thrown on I/O errors. */ public function createFile($name, $parentId = null, $content = '') { if (null === $parentId) { $parent_path = $this->route_prefix.'drive/root'; } else{ $parent_path = $this->route_prefix.'drive/items/'.$parentId; } if (is_resource($content)) { $stream = $content; } else { $stream = fopen('php://temp', 'rw+b'); if (false === $stream) { throw new \Exception('fopen() failed'); } if (false === fwrite($stream, $content)) { fclose($stream); throw new \Exception('fwrite() failed'); } if (!rewind($stream)) { fclose($stream); throw new \Exception('rewind() failed'); } } // TODO: some versions of cURL cannot PUT memory streams? See here for a // workaround: https://bugs.php.net/bug.php?id=43468 $file = $this->apiPut($parent_path . '/children/' . urlencode($name).'/content/', $stream, null, null, array()); if (!is_resource($content)) fclose($stream); return new File($this, $file->id, $file); } /** * Fetches an object from the current OneDrive account. * * @param (null|string) The unique ID of the OneDrive object to fetch, or * null to fetch the OneDrive root folder. Default: null. * @return (Object) The object fetched, as an Object instance referencing to * the OneDrive object fetched. */ public function fetchObject($objectId = null) { $objectId = null !== $objectId ? $objectId : $this->route_prefix.'drive/root'; $result = $this->apiGet($objectId, array()); if (property_exists($result, 'folder')) { return new Folder($this, $objectId, $result); } return new File($this, $objectId, $result); } /** * Fetches the root folder from the current OneDrive account. * * @return (Folder) The root folder, as a Folder instance referencing to the * OneDrive root folder. */ public function fetchRoot() { return $this->fetchObject(); } /** * Fetches the "Camera Roll" folder from the current OneDrive account. * * @return (Folder) The "Camera Roll" folder, as a Folder instance referencing * to the OneDrive "Camera Roll" folder. */ public function fetchCameraRoll() { return $this->fetchObject($this->route_prefix.'drive/special/cameraroll'); } /** * Fetches the "Documents" folder from the current OneDrive account. * * @return (Folder) The "Documents" folder, as a Folder instance referencing * to the OneDrive "Documents" folder. */ public function fetchDocs() { return $this->fetchObject($this->route_prefix.'drive/special/documents'); } /** * Fetches the "Pictures" folder from the current OneDrive account. * * @return (Folder) The "Pictures" folder, as a Folder instance referencing to * the OneDrive "Pictures" folder. */ public function fetchPics() { return $this->fetchObject($this->route_prefix.'drive/special/photos'); } /** * Fetches the "Public" folder from the current OneDrive account. * * @return (Folder) The "Public" folder, as a Folder instance referencing to * the OneDrive "Public" folder. */ public function fetchPublicDocs() { return $this->fetchObject($this->route_prefix.'drive/special/public_documents'); } /** * Fetches the properties of an object in the current OneDrive account. * * @return (array) The properties of the object fetched. */ public function fetchProperties($objectId) { if (null === $objectId) { $object_path = $this->route_prefix.'drive/root'; } else { $object_path = $this->route_prefix.'drive/items/'.$objectId; } return $this->apiGet($objectId, array()); } /** * Fetches the objects in a folder in the current OneDrive account. * * @return (array) The objects in the folder fetched, as Object instances * referencing OneDrive objects. */ public function fetchObjects($objectId) { if (null === $objectId) { $object_path = $this->route_prefix.'drive/root'; } else{ $object_path = $this->route_prefix.'drive/items/'.$objectId; } $fetch_url = $object_path . '/children'; $objects = array(); while ($fetch_url) { $result = $this->apiGet($fetch_url, array()); foreach ($result->value as $data) { $object = property_exists($data, 'folder') ? new Folder($this, $data->id, $data) : new File($this, $data->id, $data); $objects[] = $object; } $next_url_key = '@odata.nextLink'; $fetch_url = !empty($result->$next_url_key) ? $result->$next_url_key : false; } return $objects; } /** * Updates the properties of an object in the current OneDrive account. * * @param (string) $objectId - The unique ID of the object to update. * @param (array|object) $properties - The properties to update. Default: * array(). * @throw (\Exception) Thrown on I/O errors. */ public function updateObject($objectId, $properties = array()) { $objectId = $objectId; $properties = (object) $properties; $encoded = json_encode($properties); $stream = fopen('php://temp', 'w+b'); if (false === $stream) { throw new \Exception('fopen() failed'); } if (false === fwrite($stream, $encoded)) { throw new \Exception('fwrite() failed'); } if (!rewind($stream)) { throw new \Exception('rewind() failed'); } $this->apiPut($objectId, $stream, 'application/json', null, array()); } /** * Moves an object into another folder. * * @param (string) The unique ID of the object to move. * @param (null|string) The unique ID of the folder into which to move the * object, or null to move it to the OneDrive root folder. Default: * null. */ public function moveObject($objectId, $destinationId = null) { if (null === $destinationId) { $destinationId = $this->route_prefix.'drive/root'; } $this->apiMove($objectId, array( 'destination' => $destinationId )); } /** * Copies a file into another folder. OneDrive does not support copying * folders. * * @param (string) The unique ID of the file to copy. * @param (null|string) The unique ID of the folder into which to copy the * file, or null to copy it to the OneDrive root folder. Default: * null. */ public function copyFile($objectId, $destinationId = null) { if (null === $destinationId) { $destinationId = $this->route_prefix.'drive/root'; } $this->apiCopy($objectId, array( 'destination' => $destinationId )); } /** * Deletes an object in the current OneDrive account. * * @param (string) $objectId - The unique ID of the object to delete. */ public function deleteObject($objectId) { $objectId = $objectId; $this->apiDelete($this->route_prefix.'drive/items/'.$objectId); } /** * Deletes an array of objects in the current OneDrive account. * * @param (array) $objectIdArray - An array of unique IDs of the objects to delete. * * @return array - returns an array of responses */ public function deleteObjectMulti($objectIdArray) { if (!is_array($objectIdArray)) return; return $this->apiDeleteMulti($this->route_prefix.'drive/items/', $objectIdArray); } /** * Fetches the quota of the current OneDrive account. * * @return (object) An object with the following properties: * (int) quota - The total space, in bytes. * (int) available - The available space, in bytes. */ public function fetchQuota() { $drive = $this->apiGet($this->route_prefix.'drive', array()); return $drive->quota; } /** * Fetches the account info of the current OneDrive account. * * @return (object) An object with the following properties: * (string) id - OneDrive account ID. * (string) first_name - account owner's first name. * (string) last_name - account owner's last name. * (string) name - account owner's full name. * (string) gender - account owner's gender. * (string) locale - account owner's locale. */ public function fetchAccountInfo() { //$drive = $this->apiGet('drive', array(), true); $drive = $this->apiGet($this->route_prefix.'drive', array()); return $drive->owner; } /** * Fetches the recent documents uploaded to the current OneDrive account. * * @return (object) An object with the following properties: * (array) data - The list of the recent documents uploaded. */ public function fetchRecentDocs() { return $this->apiGet($this->route_prefix.'drive/special/recent_docs', array()); } /** * Fetches the objects shared with the current OneDrive account. * * @return (object) An object with the following properties: * (array) data - The list of the shared objects. */ public function fetchShared() { return $this->apiGet($this->route_prefix.'drive/special/shared', array()); } /** * Give $use_msgraph_api variable * * @return boolean private $use_msgraph_api var */ public function use_msgraph_api() { return $this->use_msgraph_api; } } includes/onedrive/LICENSE000064400000104461152214270100011172 0ustar00GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS 0. Definitions. "This License" refers to version 3 of the GNU General Public License. "Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. "The Program" refers to any copyrightable work licensed under this License. Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals or organizations. To "modify" a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a "modified version" of the earlier work or a work "based on" the earlier work. A "covered work" means either the unmodified Program or a work based on the Program. To "propagate" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. To "convey" a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. An interactive user interface displays "Appropriate Legal Notices" to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. 1. Source Code. The "source code" for a work means the preferred form of the work for making modifications to it. "Object code" means any non-source form of a work. A "Standard Interface" means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. The "System Libraries" of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A "Major Component", in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. The "Corresponding Source" for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. The Corresponding Source for a work in source code form is that same work. 2. Basic Permissions. All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. 3. Protecting Users' Legal Rights From Anti-Circumvention Law. No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. 4. Conveying Verbatim Copies. You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. 5. Conveying Modified Source Versions. You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: a) The work must carry prominent notices stating that you modified it, and giving a relevant date. b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to "keep intact all notices". c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an "aggregate" if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. 6. Conveying Non-Source Forms. You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. A "User Product" is either (1) a "consumer product", which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, "normally used" refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. "Installation Information" for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. 7. Additional Terms. "Additional permissions" are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or d) Limiting the use for publicity purposes of names of licensors or authors of the material; or e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. All other non-permissive additional terms are considered "further restrictions" within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. 8. Termination. You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. 9. Acceptance Not Required for Having Copies. You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. 10. Automatic Licensing of Downstream Recipients. Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. An "entity transaction" is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. 11. Patents. A "contributor" is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's "contributor version". A contributor's "essential patent claims" are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, "control" includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. In the following three paragraphs, a "patent license" is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To "grant" such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. "Knowingly relying" means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. A patent license is "discriminatory" if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. 12. No Surrender of Others' Freedom. If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. 13. Use with the GNU Affero General Public License. Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. 14. Revised Versions of this License. The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. 15. Disclaimer of Warranty. THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. Limitation of Liability. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 17. Interpretation of Sections 15 and 16. If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. {one line to give the program's name and a brief idea of what it does.} Copyright (C) {year} {name of author} This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . Also add information on how to contact you by electronic and paper mail. If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode: {project} Copyright (C) {year} {fullname} This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, your program's commands might be different; for a GUI interface, you would use an "about box". You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see . The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read . includes/onedrive/folder.php000064400000004411152214270100012143 0ustar00_client->fetchObjects($this->_id); } /** * Creates a folder in the OneDrive folder referenced by this Folder instance. * * @param (string) $name - The name of the OneDrive folder to be created. * @param (null|string) $description - The description of the OneDrive folder * to be created, or null to create it without a description. Default: * null. * @return (Folder) The folder created, as a Folder instance. */ public function createFolder($name, $description = null) { return $this->_client->createFolder($name, $this->_id, $description); } /** * Creates a file in the OneDrive folder referenced by this Folder instance. * * @param (string) $name - The name of the OneDrive file to be created. * @param (string) $content - The content of the OneDrive file to be created. * Default: ''. * @return (File) The file created, as a File instance. * @throw (\Exception) Thrown on I/O errors. */ public function createFile($name, $content = '') { return $this->_client->createFile($name, $this->_id, $content); } } includes/onedrive/file.php000064400000004336152214270100011615 0ustar00_client->use_msgraph_api()) { return $this->_client->apiGet('me/drive/items/'.$this->_id . '/content', $options, true); } return $this->_client->apiGet('drive/items/'.$this->_id . '/content', $options, true); } /** * Copies the OneDrive file referenced by this File instance into another * OneDrive folder. * * @param (null|string) The unique ID of the OneDrive folder into which to * copy the OneDrive file referenced by this File instance, or null to * copy it in the OneDrive root folder. Default: null. */ public function copy($destinationId = null) { $this->_client->copyFile($this->_id, $destinationId); } } includes/onedrive/object.php000064400000015026152214270100012142 0ustar00_client = $client; $this->_id = null !== $id ? (string) $id : null; $this->_parentId = property_exists($options, 'parent_id') ? (string) $options->parent_id : null; $this->_name = property_exists($options, 'name') ? (string) $options->name : null; $this->_description = property_exists($options, 'description') ? (string) $options->description : null; $this->_size = property_exists($options, 'size') ? (int) $options->size : null; $this->_createdTime = property_exists($options, 'created_time') ? strtotime($options->created_time) : null; $this->_updatedTime = property_exists($options, 'updated_time') ? strtotime($options->updated_time) : null; } /** * Determines whether the OneDrive object referenced by this Object instance * is a folder. * * @return (bool) true if the OneDrive object referenced by this Object * instance is a folder, false otherwise. */ public function isFolder() { return false; } /** * Fetches the properties of the OneDrive object referenced by this Object * instance. Some properties are cached for faster subsequent access. * * @return (array) The properties of the OneDrive object referenced by this * Object instance. */ public function fetchProperties() { $result = $this->_client->fetchProperties($this->_id); $this->_parentId = '' != $result->parentReference['id'] ? (string) $result->parentReference['id'] : null; $this->_name = $result->name; $this->_description = '' != $result->description ? (string) $result->description : null; $this->_size = (int) $result->size; $this->_createdTime = strtotime($result->createdDateTime); $this->_updatedTime = strtotime($result->lastModifiedDateTime); return $result; } /** * Gets the unique ID of the OneDrive object referenced by this Object * instance. * * @return (string) The unique ID of the OneDrive object referenced by this * Object instance. */ public function getId() { return $this->_id; } /** * Gets the unique ID of the parent folder of the OneDrive object referenced * by this Object instance. * * @return (string) The unique ID of the OneDrive folder containing the object * referenced by this Object instance. */ public function getParentId() { if (null === $this->_parentId) { $this->fetchProperties(); } return $this->_parentId; } /** * Gets the name of the OneDrive object referenced by this Object instance. * * @return (string) The name of the OneDrive object referenced by this Object * instance. */ public function getName() { if (null === $this->_name) { $this->fetchProperties(); } return $this->_name; } /** * Gets the description of the OneDrive object referenced by this Object * instance. * * @return (string) The description of the OneDrive object referenced by this * Object instance. */ public function getDescription() { if (null === $this->_description) { $this->fetchProperties(); } return $this->_description; } /** * Gets the size of the OneDrive object referenced by this Object instance. * * @return (int) The size of the OneDrive object referenced by this Object * instance. */ public function getSize() { if (null === $this->_size) { $this->fetchProperties(); } return $this->_size; } /** * Gets the creation time of the OneDrive object referenced by this Object * instance. * * @return (int) The creation time of the object referenced by this Object * instance, in seconds since UNIX epoch. */ public function getCreatedTime() { if (null === $this->_createdTime) { $this->fetchProperties(); } return $this->_createdTime; } /** * Gets the last modification time of the OneDrive object referenced by this * Object instance. * * @return (int) The last modification time of the object referenced by this * Object instance, in seconds since UNIX epoch. */ public function getUpdatedTime() { if (null === $this->_updatedTime) { $this->fetchProperties(); } return $this->_updatedTime; } /** * Moves the OneDrive object referenced by this Object instance into another * OneDrive folder. * * @param (null|string) The unique ID of the OneDrive folder into which to * move the OneDrive object referenced by this Object instance, or * null to move it to the OneDrive root folder. Default: null. */ public function move($destinationId = null) { $this->_client->moveObject($this->_id, $destinationId); } } includes/onedrive/onedrive.php000064400000000234152214270100012502 0ustar00auth = $auth; } /** * Set location ID * * @param int|string $location Location ID. * * @return void */ public function set_location($location = 1) { if (1 === $location) { $this->apiep = 'https://api.pcloud.com'; } else { $this->apiep = 'https://eapi.pcloud.com'; } } /** * Set backup folder * * @param string $folder - the backup folder * * @return void */ public function set_folder($folder) { $this->folder = $folder; } /** * Retrieves information about the user's account * * @return array|WP_Error - returns the response array or a WP_Error */ public function account_info() { $params = array( 'access_token' => $this->auth ); $args = array( 'method' => 'GET', ); $response = $this->make_request('userinfo', $params, $args); if (is_wp_error($response)) return $response; if (is_array($response) && isset($response['quota'])) { return $response; } else { return new WP_Error('unexpected_response', 'pCloud userinfo request returned an unexpected result: '.json_encode($response)); } } /** * Create base remote directory * * @param string $dir_name - the directory name. * * @return int|WP_Error - returns the int result or a WP_Error */ public function make_directory($dir_name) { $folder_id = 0; $folders = explode("/", $dir_name); foreach ($folders as $folder) { $params = array( 'name' => untrailingslashit($folder), 'folderid' => $folder_id, 'access_token' => $this->auth, ); $args = array( 'method' => 'GET', ); $response = $this->make_request('createfolderifnotexists', $params, $args); if (is_wp_error($response)) return $response; if (is_array($response) && isset($response['metadata']) && isset($response['metadata']['folderid'])) { $folder_id = intval($response['metadata']['folderid']); } else { return new WP_Error('unexpected_response', 'pCloud createfolderifnotexists request returned an unexpected result: '.json_encode($response)); } } return $folder_id; } /** * Get upload Dir ID * * @return int|WP_Error - returns upload folder ID or a WP_Error */ public function get_upload_dir_id() { $backup_dir = $this->get_backup_dir(); $params = array( 'path' => '/' . $backup_dir, 'access_token' => $this->auth, ); $args = array( 'method' => 'GET', ); $response = $this->make_request('listfolder', $params, $args); if (is_wp_error($response)) return $response; if (!isset($response['result']) || 2005 === $response['result']) { return $this->make_directory($backup_dir); } else { if (isset($response['metadata'])) { return $response['metadata']['folderid']; } } return 0; } /** * Prepare to initiate Upload process * * @return array|WP_Error - returns response array or a WP_Error */ public function create_upload() { $params = array( 'access_token' => $this->auth, ); $args = array( 'method' => 'GET', ); $response = $this->make_request('upload_create', $params, $args); if (is_wp_error($response)) return $response; return $response; } /** * Chunked upload * * @param string $path - path/file to be uploaded. * @param int $upload_id - pCloud Upload ID. * @param int $uploadoffset - file offset. * * @return int|WP_Error returns the new offset OR -2 when end of file reached or WP_Error */ public function chunked_upload($path, $upload_id = 0, $uploadoffset = 0) { if (!file_exists($path) || !is_file($path) || !is_readable($path)) { return new WP_Error('invalid_file', 'pCloud chunked upload: Invalid file provided: '.$path); } $filesize = abs(filesize($path)); if ($uploadoffset >= $filesize) { return -2; } $file = fopen($path, 'r'); if (0 < $uploadoffset) { fseek($file, $uploadoffset); } $params = array( 'uploadid' => $upload_id, 'uploadoffset' => $uploadoffset, ); $content = fread($file, $this->part_size); if (!empty($content)) { $result = $this->write($content, $params); if (is_wp_error($result)) { fclose($file); return $result; } $uploadoffset += $this->part_size; } fclose($file); if ($uploadoffset >= $filesize) { return -2; } return $uploadoffset; } /** * Save the uploaded file * * @param int $upload_id - pCloud Upload ID. * @param string $path - File Path. * @param int $folder_id - pCloud Folder ID. * * @return array|WP_Error - returns response array or a WP_Error */ public function save($upload_id, $path, $folder_id) { $path = str_replace(array('\\'), "/", $path); $parts = explode("/", $path); $filename = end($parts); $params = array( 'uploadid' => intval($upload_id), 'name' => rawurlencode($filename), 'folderid' => intval($folder_id), 'access_token' => $this->auth, ); $args = array( 'method' => 'GET', ); $response = $this->make_request('upload_save', $params, $args); if (is_wp_error($response)) return $response; return $response; } /** * Collecting existing backups on pCloud servers * * @return array|WP_Error - returns response array or a WP_Error */ public function list_backups() { $backup_dir = $this->get_backup_dir(); $params = array( 'path' => '/' . $backup_dir, 'access_token' => $this->auth, ); $args = array( 'method' => 'GET', ); $response = $this->make_request('listfolder', $params, $args); if (is_wp_error($response)) return $response; if (is_bool($response) || !isset($response['metadata']) || !isset($response['metadata']['contents'])) { return new WP_Error('unexpected_response', 'pCloud listfolder: returned an unexpected result: '.json_encode($response)); } return $response['metadata']['contents']; } /** * Chunked downloads a file. * * @param int $file_id - pCloud File ID. * @param resource $archive_file - the local file handle. * @param array $options - any extra options to be passed e.g. headers. * @param array $offset - you can create real chunked download using this offset param. * * @return int * @throws Exception Throws standard exception. */ public function download($file_id, $archive_file = null, $options = array(), $offset = 0) { $chunksize = 3 * (1024 * 1024); if (isset($options['Range'])) { // Disabled ! $range_tmp = str_replace('bytes=', '', $options['Range']); $range_arr = explode('-', $range_tmp); if (is_array($range_arr)) { if (isset($range_arr[0]) && is_numeric($range_arr[0]) && isset($range_arr[1]) && is_numeric($range_arr[1])) { $offset = intval($range_arr[0]); $chunksize = intval($range_arr[1]) - $offset; } } } $dwl_url = ''; $params = array( 'fileid' => $file_id, 'access_token' => $this->auth, ); $args = array( 'method' => 'GET', ); $response = $this->make_request('getfilelink', $params, $args); if (is_wp_error($response)) return $response; if (isset($response['hosts']) && isset($response['hosts'][0])) { $dwl_url = $response['hosts'][0] . $response['path']; } if (empty($dwl_url)) { return new WP_Error('unexpected_response', 'pCloud download: Failed to get file download link.'); } $errstr = ''; $args = array( 'headers' => array( 'Range' => 'bytes=' . $offset . '-' . ($offset + ($chunksize - 1)), ), ); $content = false; $api_response = wp_remote_get('https://' . $dwl_url, $args); if (is_array($api_response) && !is_wp_error($api_response)) { $response_body = wp_remote_retrieve_body($api_response); if (is_string($response_body)) { $content = $response_body; } } else { $errstr = $api_response->get_error_message(); } if (!$content) { return new WP_Error('unexpected_response', 'pCloud download: Failed to open connection to the backup file: ' . $dwl_url . ' error:' . $errstr); } else { if (!fwrite($archive_file, $content)) { return new WP_Error('unexpected_response', 'pCloud download: Failed to write content to output file.'); } else { $offset += $chunksize; } } return $offset; } /** * Deletes remote file * * @param string $path - The path to the file to be deleted. * * @return array|WP_Error - returns response array or a WP_Error */ public function delete($path) { $params = array( 'path' => $path, 'access_token' => $this->auth, ); $args = array( 'method' => 'GET', ); $response = $this->make_request('deletefile', $params, $args); if (is_wp_error($response)) return $response; if (is_bool($response)) { return new WP_Error('unexpected_response', 'pCloud deletefile: returned an unexpected result: '.json_encode($response)); } return $response; } /** * Get File info from * * @param string $file - basename, needed file. * * @return array|WP_Error - returns response array or a WP_Error */ public function get_file_info($file) { $path = "/" . $this->get_backup_dir() . "/" . $file; $params = array( 'path' => $path, 'access_token' => $this->auth, ); $args = array( 'method' => 'GET', ); $response = $this->make_request('checksumfile', $params, $args); if (is_wp_error($response)) return $response; if (is_bool($response)) { return new WP_Error('unexpected_response', 'pCloud checksumfile: returned an unexpected result: '.json_encode($response)); } $response = $response['metadata']; return $response; } /** * Get Backup directory * * @return string - the backup directory */ public function get_backup_dir() { return untrailingslashit(apply_filters('updraftplus_pcloud_backup_dir', 'UpdraftPlus').'/'.$this->folder); } /** * Upload - write content chunk * * @param string $content - String content to be written. * @param array $params - Additional request params. * * @return WP_Error - returns a WP_Error if something goes wrong */ private function write($content, $params) { $params['access_token'] = $this->auth; $args = array( 'method' => 'PUT', 'redirection' => 5, 'blocking' => true, 'headers' => array(), 'body' => $content, ); $response = $this->make_request('upload_write', $params, $args); if (is_wp_error($response)) return $response; } /** * This function will make a API request andcheck the response. Returns the response or a WordPress error. * * @param string $endpoint - the API endpoint * @param array $params - the API request parameters * @param array $args - an array of request options * * @return array|WP_Error - returns an array response or WP_Error */ private function make_request($endpoint, $params, $args) { $api_response = wp_remote_request($this->apiep . '/'. $endpoint . '?' . http_build_query($params), $args); if (is_wp_error($api_response)) { return $api_response; } $response_code = wp_remote_retrieve_response_code($api_response); if ($response_code < 200 || $response_code >= 300) { return new WP_Error('unexpected_response_code', 'pCloud ' . $endpoint . ': returned an unexpected response code: '. $response_code . ' response: '.json_encode($api_response)); } $response_body = wp_remote_retrieve_body($api_response); if (empty($response_body) || !is_string($response_body)) { return new WP_Error('no_response_body', 'pCloud ' . $endpoint . ': returned no response body: ' . json_encode($api_response)); } $response_array = json_decode($response_body, true); if (!is_array($response_array)) { return new WP_Error('json_decode_failed', 'pCloud ' . $endpoint . ': Failed to json decode: ' . $response_body); } return $response_array; } } includes/select2/select2.css000064400000044763152214270100011776 0ustar00.select2-container { box-sizing: border-box; display: inline-block; margin: 0; position: relative; vertical-align: middle; } .select2-container .select2-selection--single { box-sizing: border-box; cursor: pointer; display: block; height: 28px; user-select: none; -webkit-user-select: none; } .select2-container .select2-selection--single .select2-selection__rendered { display: block; padding-left: 8px; padding-right: 20px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .select2-container .select2-selection--single .select2-selection__clear { background-color: transparent; border: none; font-size: 1em; } .select2-container[dir="rtl"] .select2-selection--single .select2-selection__rendered { padding-right: 8px; padding-left: 20px; } .select2-container .select2-selection--multiple { box-sizing: border-box; cursor: pointer; display: block; min-height: 32px; user-select: none; -webkit-user-select: none; } .select2-container .select2-selection--multiple .select2-selection__rendered { display: inline; list-style: none; padding: 0; } .select2-container .select2-selection--multiple .select2-selection__clear { background-color: transparent; border: none; font-size: 1em; } .select2-container .select2-search--inline .select2-search__field { box-sizing: border-box; border: none; font-size: 100%; margin-top: 5px; margin-left: 5px; padding: 0; max-width: 100%; resize: none; height: 18px; vertical-align: bottom; font-family: sans-serif; overflow: hidden; word-break: keep-all; } .select2-container .select2-search--inline .select2-search__field::-webkit-search-cancel-button { -webkit-appearance: none; } .select2-dropdown { background-color: white; border: 1px solid #aaa; border-radius: 4px; box-sizing: border-box; display: block; position: absolute; left: -100000px; width: 100%; z-index: 1051; } .select2-results { display: block; } .select2-results__options { list-style: none; margin: 0; padding: 0; } .select2-results__option { padding: 6px; user-select: none; -webkit-user-select: none; } .select2-results__option--selectable { cursor: pointer; } .select2-container--open .select2-dropdown { left: 0; } .select2-container--open .select2-dropdown--above { border-bottom: none; border-bottom-left-radius: 0; border-bottom-right-radius: 0; } .select2-container--open .select2-dropdown--below { border-top: none; border-top-left-radius: 0; border-top-right-radius: 0; } .select2-search--dropdown { display: block; padding: 4px; } .select2-search--dropdown .select2-search__field { padding: 4px; width: 100%; box-sizing: border-box; } .select2-search--dropdown .select2-search__field::-webkit-search-cancel-button { -webkit-appearance: none; } .select2-search--dropdown.select2-search--hide { display: none; } .select2-close-mask { border: 0; margin: 0; padding: 0; display: block; position: fixed; left: 0; top: 0; min-height: 100%; min-width: 100%; height: auto; width: auto; opacity: 0; z-index: 99; background-color: #fff; filter: alpha(opacity=0); } .select2-hidden-accessible { border: 0 !important; clip: rect(0 0 0 0) !important; -webkit-clip-path: inset(50%) !important; clip-path: inset(50%) !important; height: 1px !important; overflow: hidden !important; padding: 0 !important; position: absolute !important; width: 1px !important; white-space: nowrap !important; } .select2-container--default .select2-selection--single { background-color: #fff; border: 1px solid #aaa; border-radius: 4px; } .select2-container--default .select2-selection--single .select2-selection__rendered { color: #444; line-height: 28px; } .select2-container--default .select2-selection--single .select2-selection__clear { cursor: pointer; float: right; font-weight: bold; height: 26px; margin-right: 20px; padding-right: 0px; } .select2-container--default .select2-selection--single .select2-selection__placeholder { color: #999; } .select2-container--default .select2-selection--single .select2-selection__arrow { height: 26px; position: absolute; top: 1px; right: 1px; width: 20px; } .select2-container--default .select2-selection--single .select2-selection__arrow b { border-color: #888 transparent transparent transparent; border-style: solid; border-width: 5px 4px 0 4px; height: 0; left: 50%; margin-left: -4px; margin-top: -2px; position: absolute; top: 50%; width: 0; } .select2-container--default[dir="rtl"] .select2-selection--single .select2-selection__clear { float: left; } .select2-container--default[dir="rtl"] .select2-selection--single .select2-selection__arrow { left: 1px; right: auto; } .select2-container--default.select2-container--disabled .select2-selection--single { background-color: #eee; cursor: default; } .select2-container--default.select2-container--disabled .select2-selection--single .select2-selection__clear { display: none; } .select2-container--default.select2-container--open .select2-selection--single .select2-selection__arrow b { border-color: transparent transparent #888 transparent; border-width: 0 4px 5px 4px; } .select2-container--default .select2-selection--multiple { background-color: white; border: 1px solid #aaa; border-radius: 4px; cursor: text; padding-bottom: 5px; padding-right: 5px; position: relative; } .select2-container--default .select2-selection--multiple.select2-selection--clearable { padding-right: 25px; } .select2-container--default .select2-selection--multiple .select2-selection__clear { cursor: pointer; font-weight: bold; height: 20px; margin-right: 10px; margin-top: 5px; position: absolute; right: 0; padding: 1px; } .select2-container--default .select2-selection--multiple .select2-selection__choice { background-color: #e4e4e4; border: 1px solid #aaa; border-radius: 4px; box-sizing: border-box; display: inline-block; margin-left: 5px; margin-top: 5px; padding: 0; padding-left: 20px; position: relative; max-width: 100%; overflow: hidden; text-overflow: ellipsis; vertical-align: bottom; white-space: nowrap; } .select2-container--default .select2-selection--multiple .select2-selection__choice__display { cursor: default; padding-left: 2px; padding-right: 5px; } .select2-container--default .select2-selection--multiple .select2-selection__choice__remove { background-color: transparent; border: none; border-right: 1px solid #aaa; border-top-left-radius: 4px; border-bottom-left-radius: 4px; color: #999; cursor: pointer; font-size: 1em; font-weight: bold; padding: 0 4px; position: absolute; left: 0; top: 0; } .select2-container--default .select2-selection--multiple .select2-selection__choice__remove:hover, .select2-container--default .select2-selection--multiple .select2-selection__choice__remove:focus { background-color: #f1f1f1; color: #333; outline: none; } .select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice { margin-left: 5px; margin-right: auto; } .select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice__display { padding-left: 5px; padding-right: 2px; } .select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice__remove { border-left: 1px solid #aaa; border-right: none; border-top-left-radius: 0; border-bottom-left-radius: 0; border-top-right-radius: 4px; border-bottom-right-radius: 4px; } .select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__clear { float: left; margin-left: 10px; margin-right: auto; } .select2-container--default.select2-container--focus .select2-selection--multiple { border: solid black 1px; outline: 0; } .select2-container--default.select2-container--disabled .select2-selection--multiple { background-color: #eee; cursor: default; } .select2-container--default.select2-container--disabled .select2-selection__choice__remove { display: none; } .select2-container--default.select2-container--open.select2-container--above .select2-selection--single, .select2-container--default.select2-container--open.select2-container--above .select2-selection--multiple { border-top-left-radius: 0; border-top-right-radius: 0; } .select2-container--default.select2-container--open.select2-container--below .select2-selection--single, .select2-container--default.select2-container--open.select2-container--below .select2-selection--multiple { border-bottom-left-radius: 0; border-bottom-right-radius: 0; } .select2-container--default .select2-search--dropdown .select2-search__field { border: 1px solid #aaa; } .select2-container--default .select2-search--inline .select2-search__field { background: transparent; border: none; outline: 0; box-shadow: none; -webkit-appearance: textfield; } .select2-container--default .select2-results > .select2-results__options { max-height: 200px; overflow-y: auto; } .select2-container--default .select2-results__option .select2-results__option { padding-left: 1em; } .select2-container--default .select2-results__option .select2-results__option .select2-results__group { padding-left: 0; } .select2-container--default .select2-results__option .select2-results__option .select2-results__option { margin-left: -1em; padding-left: 2em; } .select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option { margin-left: -2em; padding-left: 3em; } .select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option { margin-left: -3em; padding-left: 4em; } .select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option { margin-left: -4em; padding-left: 5em; } .select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option { margin-left: -5em; padding-left: 6em; } .select2-container--default .select2-results__option--group { padding: 0; } .select2-container--default .select2-results__option--disabled { color: #999; } .select2-container--default .select2-results__option--selected { background-color: #ddd; } .select2-container--default .select2-results__option--highlighted.select2-results__option--selectable { background-color: #5897fb; color: white; } .select2-container--default .select2-results__group { cursor: default; display: block; padding: 6px; } .select2-container--classic .select2-selection--single { background-color: #f7f7f7; border: 1px solid #aaa; border-radius: 4px; outline: 0; background-image: -webkit-linear-gradient(top, white 50%, #eeeeee 100%); background-image: -o-linear-gradient(top, white 50%, #eeeeee 100%); background-image: linear-gradient(to bottom, white 50%, #eeeeee 100%); background-repeat: repeat-x; filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFFFFFF', endColorstr='#FFEEEEEE', GradientType=0); } .select2-container--classic .select2-selection--single:focus { border: 1px solid #5897fb; } .select2-container--classic .select2-selection--single .select2-selection__rendered { color: #444; line-height: 28px; } .select2-container--classic .select2-selection--single .select2-selection__clear { cursor: pointer; float: right; font-weight: bold; height: 26px; margin-right: 20px; } .select2-container--classic .select2-selection--single .select2-selection__placeholder { color: #999; } .select2-container--classic .select2-selection--single .select2-selection__arrow { background-color: #ddd; border: none; border-left: 1px solid #aaa; border-top-right-radius: 4px; border-bottom-right-radius: 4px; height: 26px; position: absolute; top: 1px; right: 1px; width: 20px; background-image: -webkit-linear-gradient(top, #eeeeee 50%, #cccccc 100%); background-image: -o-linear-gradient(top, #eeeeee 50%, #cccccc 100%); background-image: linear-gradient(to bottom, #eeeeee 50%, #cccccc 100%); background-repeat: repeat-x; filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFEEEEEE', endColorstr='#FFCCCCCC', GradientType=0); } .select2-container--classic .select2-selection--single .select2-selection__arrow b { border-color: #888 transparent transparent transparent; border-style: solid; border-width: 5px 4px 0 4px; height: 0; left: 50%; margin-left: -4px; margin-top: -2px; position: absolute; top: 50%; width: 0; } .select2-container--classic[dir="rtl"] .select2-selection--single .select2-selection__clear { float: left; } .select2-container--classic[dir="rtl"] .select2-selection--single .select2-selection__arrow { border: none; border-right: 1px solid #aaa; border-radius: 0; border-top-left-radius: 4px; border-bottom-left-radius: 4px; left: 1px; right: auto; } .select2-container--classic.select2-container--open .select2-selection--single { border: 1px solid #5897fb; } .select2-container--classic.select2-container--open .select2-selection--single .select2-selection__arrow { background: transparent; border: none; } .select2-container--classic.select2-container--open .select2-selection--single .select2-selection__arrow b { border-color: transparent transparent #888 transparent; border-width: 0 4px 5px 4px; } .select2-container--classic.select2-container--open.select2-container--above .select2-selection--single { border-top: none; border-top-left-radius: 0; border-top-right-radius: 0; background-image: -webkit-linear-gradient(top, white 0%, #eeeeee 50%); background-image: -o-linear-gradient(top, white 0%, #eeeeee 50%); background-image: linear-gradient(to bottom, white 0%, #eeeeee 50%); background-repeat: repeat-x; filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFFFFFF', endColorstr='#FFEEEEEE', GradientType=0); } .select2-container--classic.select2-container--open.select2-container--below .select2-selection--single { border-bottom: none; border-bottom-left-radius: 0; border-bottom-right-radius: 0; background-image: -webkit-linear-gradient(top, #eeeeee 50%, white 100%); background-image: -o-linear-gradient(top, #eeeeee 50%, white 100%); background-image: linear-gradient(to bottom, #eeeeee 50%, white 100%); background-repeat: repeat-x; filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFEEEEEE', endColorstr='#FFFFFFFF', GradientType=0); } .select2-container--classic .select2-selection--multiple { background-color: white; border: 1px solid #aaa; border-radius: 4px; cursor: text; outline: 0; padding-bottom: 5px; padding-right: 5px; } .select2-container--classic .select2-selection--multiple:focus { border: 1px solid #5897fb; } .select2-container--classic .select2-selection--multiple .select2-selection__clear { display: none; } .select2-container--classic .select2-selection--multiple .select2-selection__choice { background-color: #e4e4e4; border: 1px solid #aaa; border-radius: 4px; display: inline-block; margin-left: 5px; margin-top: 5px; padding: 0; } .select2-container--classic .select2-selection--multiple .select2-selection__choice__display { cursor: default; padding-left: 2px; padding-right: 5px; } .select2-container--classic .select2-selection--multiple .select2-selection__choice__remove { background-color: transparent; border: none; border-top-left-radius: 4px; border-bottom-left-radius: 4px; color: #888; cursor: pointer; font-size: 1em; font-weight: bold; padding: 0 4px; } .select2-container--classic .select2-selection--multiple .select2-selection__choice__remove:hover { color: #555; outline: none; } .select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice { margin-left: 5px; margin-right: auto; } .select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice__display { padding-left: 5px; padding-right: 2px; } .select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice__remove { border-top-left-radius: 0; border-bottom-left-radius: 0; border-top-right-radius: 4px; border-bottom-right-radius: 4px; } .select2-container--classic.select2-container--open .select2-selection--multiple { border: 1px solid #5897fb; } .select2-container--classic.select2-container--open.select2-container--above .select2-selection--multiple { border-top: none; border-top-left-radius: 0; border-top-right-radius: 0; } .select2-container--classic.select2-container--open.select2-container--below .select2-selection--multiple { border-bottom: none; border-bottom-left-radius: 0; border-bottom-right-radius: 0; } .select2-container--classic .select2-search--dropdown .select2-search__field { border: 1px solid #aaa; outline: 0; } .select2-container--classic .select2-search--inline .select2-search__field { outline: 0; box-shadow: none; } .select2-container--classic .select2-dropdown { background-color: white; border: 1px solid transparent; } .select2-container--classic .select2-dropdown--above { border-bottom: none; } .select2-container--classic .select2-dropdown--below { border-top: none; } .select2-container--classic .select2-results > .select2-results__options { max-height: 200px; overflow-y: auto; } .select2-container--classic .select2-results__option--group { padding: 0; } .select2-container--classic .select2-results__option--disabled { color: grey; } .select2-container--classic .select2-results__option--highlighted.select2-results__option--selectable { background-color: #3875d7; color: white; } .select2-container--classic .select2-results__group { cursor: default; display: block; padding: 6px; } .select2-container--classic.select2-container--open .select2-dropdown { border-color: #5897fb; } includes/select2/select2.js000064400000462433152214270100011620 0ustar00/*! * Select2 4.1.0-rc.0 * https://select2.github.io * * Released under the MIT license * https://github.com/select2/select2/blob/master/LICENSE.md */ ;(function (factory) { if (typeof define === 'function' && define.amd) { // AMD. Register as an anonymous module. define(['jquery'], factory); } else if (typeof module === 'object' && module.exports) { // Node/CommonJS module.exports = function (root, jQuery) { if (jQuery === undefined) { // require('jQuery') returns a factory that requires window to // build a jQuery instance, we normalize how we use modules // that require this pattern but the window provided is a noop // if it's defined (how jquery works) if (typeof window !== 'undefined') { jQuery = require('jquery'); } else { jQuery = require('jquery')(root); } } factory(jQuery); return jQuery; }; } else { // Browser globals factory(jQuery); } } (function (jQuery) { // This is needed so we can catch the AMD loader configuration and use it // The inner file should be wrapped (by `banner.start.js`) in a function that // returns the AMD loader references. var S2 =(function () { // Restore the Select2 AMD loader so it can be used // Needed mostly in the language files, where the loader is not inserted if (jQuery && jQuery.fn && jQuery.fn.select2 && jQuery.fn.select2.amd) { var S2 = jQuery.fn.select2.amd; } var S2;(function () { if (!S2 || !S2.requirejs) { if (!S2) { S2 = {}; } else { require = S2; } /** * @license almond 0.3.3 Copyright jQuery Foundation and other contributors. * Released under MIT license, http://github.com/requirejs/almond/LICENSE */ //Going sloppy to avoid 'use strict' string cost, but strict practices should //be followed. /*global setTimeout: false */ var requirejs, require, define; (function (undef) { var main, req, makeMap, handlers, defined = {}, waiting = {}, config = {}, defining = {}, hasOwn = Object.prototype.hasOwnProperty, aps = [].slice, jsSuffixRegExp = /\.js$/; function hasProp(obj, prop) { return hasOwn.call(obj, prop); } /** * Given a relative module name, like ./something, normalize it to * a real name that can be mapped to a path. * @param {String} name the relative name * @param {String} baseName a real name that the name arg is relative * to. * @returns {String} normalized name */ function normalize(name, baseName) { var nameParts, nameSegment, mapValue, foundMap, lastIndex, foundI, foundStarMap, starI, i, j, part, normalizedBaseParts, baseParts = baseName && baseName.split("/"), map = config.map, starMap = (map && map['*']) || {}; //Adjust any relative paths. if (name) { name = name.split('/'); lastIndex = name.length - 1; // If wanting node ID compatibility, strip .js from end // of IDs. Have to do this here, and not in nameToUrl // because node allows either .js or non .js to map // to same file. if (config.nodeIdCompat && jsSuffixRegExp.test(name[lastIndex])) { name[lastIndex] = name[lastIndex].replace(jsSuffixRegExp, ''); } // Starts with a '.' so need the baseName if (name[0].charAt(0) === '.' && baseParts) { //Convert baseName to array, and lop off the last part, //so that . matches that 'directory' and not name of the baseName's //module. For instance, baseName of 'one/two/three', maps to //'one/two/three.js', but we want the directory, 'one/two' for //this normalization. normalizedBaseParts = baseParts.slice(0, baseParts.length - 1); name = normalizedBaseParts.concat(name); } //start trimDots for (i = 0; i < name.length; i++) { part = name[i]; if (part === '.') { name.splice(i, 1); i -= 1; } else if (part === '..') { // If at the start, or previous value is still .., // keep them so that when converted to a path it may // still work when converted to a path, even though // as an ID it is less than ideal. In larger point // releases, may be better to just kick out an error. if (i === 0 || (i === 1 && name[2] === '..') || name[i - 1] === '..') { continue; } else if (i > 0) { name.splice(i - 1, 2); i -= 2; } } } //end trimDots name = name.join('/'); } //Apply map config if available. if ((baseParts || starMap) && map) { nameParts = name.split('/'); for (i = nameParts.length; i > 0; i -= 1) { nameSegment = nameParts.slice(0, i).join("/"); if (baseParts) { //Find the longest baseName segment match in the config. //So, do joins on the biggest to smallest lengths of baseParts. for (j = baseParts.length; j > 0; j -= 1) { mapValue = map[baseParts.slice(0, j).join('/')]; //baseName segment has config, find if it has one for //this name. if (mapValue) { mapValue = mapValue[nameSegment]; if (mapValue) { //Match, update name to the new value. foundMap = mapValue; foundI = i; break; } } } } if (foundMap) { break; } //Check for a star map match, but just hold on to it, //if there is a shorter segment match later in a matching //config, then favor over this star map. if (!foundStarMap && starMap && starMap[nameSegment]) { foundStarMap = starMap[nameSegment]; starI = i; } } if (!foundMap && foundStarMap) { foundMap = foundStarMap; foundI = starI; } if (foundMap) { nameParts.splice(0, foundI, foundMap); name = nameParts.join('/'); } } return name; } function makeRequire(relName, forceSync) { return function () { //A version of a require function that passes a moduleName //value for items that may need to //look up paths relative to the moduleName var args = aps.call(arguments, 0); //If first arg is not require('string'), and there is only //one arg, it is the array form without a callback. Insert //a null so that the following concat is correct. if (typeof args[0] !== 'string' && args.length === 1) { args.push(null); } return req.apply(undef, args.concat([relName, forceSync])); }; } function makeNormalize(relName) { return function (name) { return normalize(name, relName); }; } function makeLoad(depName) { return function (value) { defined[depName] = value; }; } function callDep(name) { if (hasProp(waiting, name)) { var args = waiting[name]; delete waiting[name]; defining[name] = true; main.apply(undef, args); } if (!hasProp(defined, name) && !hasProp(defining, name)) { throw new Error('No ' + name); } return defined[name]; } //Turns a plugin!resource to [plugin, resource] //with the plugin being undefined if the name //did not have a plugin prefix. function splitPrefix(name) { var prefix, index = name ? name.indexOf('!') : -1; if (index > -1) { prefix = name.substring(0, index); name = name.substring(index + 1, name.length); } return [prefix, name]; } //Creates a parts array for a relName where first part is plugin ID, //second part is resource ID. Assumes relName has already been normalized. function makeRelParts(relName) { return relName ? splitPrefix(relName) : []; } /** * Makes a name map, normalizing the name, and using a plugin * for normalization if necessary. Grabs a ref to plugin * too, as an optimization. */ makeMap = function (name, relParts) { var plugin, parts = splitPrefix(name), prefix = parts[0], relResourceName = relParts[1]; name = parts[1]; if (prefix) { prefix = normalize(prefix, relResourceName); plugin = callDep(prefix); } //Normalize according if (prefix) { if (plugin && plugin.normalize) { name = plugin.normalize(name, makeNormalize(relResourceName)); } else { name = normalize(name, relResourceName); } } else { name = normalize(name, relResourceName); parts = splitPrefix(name); prefix = parts[0]; name = parts[1]; if (prefix) { plugin = callDep(prefix); } } //Using ridiculous property names for space reasons return { f: prefix ? prefix + '!' + name : name, //fullName n: name, pr: prefix, p: plugin }; }; function makeConfig(name) { return function () { return (config && config.config && config.config[name]) || {}; }; } handlers = { require: function (name) { return makeRequire(name); }, exports: function (name) { var e = defined[name]; if (typeof e !== 'undefined') { return e; } else { return (defined[name] = {}); } }, module: function (name) { return { id: name, uri: '', exports: defined[name], config: makeConfig(name) }; } }; main = function (name, deps, callback, relName) { var cjsModule, depName, ret, map, i, relParts, args = [], callbackType = typeof callback, usingExports; //Use name if no relName relName = relName || name; relParts = makeRelParts(relName); //Call the callback to define the module, if necessary. if (callbackType === 'undefined' || callbackType === 'function') { //Pull out the defined dependencies and pass the ordered //values to the callback. //Default to [require, exports, module] if no deps deps = !deps.length && callback.length ? ['require', 'exports', 'module'] : deps; for (i = 0; i < deps.length; i += 1) { map = makeMap(deps[i], relParts); depName = map.f; //Fast path CommonJS standard dependencies. if (depName === "require") { args[i] = handlers.require(name); } else if (depName === "exports") { //CommonJS module spec 1.1 args[i] = handlers.exports(name); usingExports = true; } else if (depName === "module") { //CommonJS module spec 1.1 cjsModule = args[i] = handlers.module(name); } else if (hasProp(defined, depName) || hasProp(waiting, depName) || hasProp(defining, depName)) { args[i] = callDep(depName); } else if (map.p) { map.p.load(map.n, makeRequire(relName, true), makeLoad(depName), {}); args[i] = defined[depName]; } else { throw new Error(name + ' missing ' + depName); } } ret = callback ? callback.apply(defined[name], args) : undefined; if (name) { //If setting exports via "module" is in play, //favor that over return value and exports. After that, //favor a non-undefined return value over exports use. if (cjsModule && cjsModule.exports !== undef && cjsModule.exports !== defined[name]) { defined[name] = cjsModule.exports; } else if (ret !== undef || !usingExports) { //Use the return value from the function. defined[name] = ret; } } } else if (name) { //May just be an object definition for the module. Only //worry about defining if have a module name. defined[name] = callback; } }; requirejs = require = req = function (deps, callback, relName, forceSync, alt) { if (typeof deps === "string") { if (handlers[deps]) { //callback in this case is really relName return handlers[deps](callback); } //Just return the module wanted. In this scenario, the //deps arg is the module name, and second arg (if passed) //is just the relName. //Normalize module name, if it contains . or .. return callDep(makeMap(deps, makeRelParts(callback)).f); } else if (!deps.splice) { //deps is a config object, not an array. config = deps; if (config.deps) { req(config.deps, config.callback); } if (!callback) { return; } if (callback.splice) { //callback is an array, which means it is a dependency list. //Adjust args if there are dependencies deps = callback; callback = relName; relName = null; } else { deps = undef; } } //Support require(['a']) callback = callback || function () {}; //If relName is a function, it is an errback handler, //so remove it. if (typeof relName === 'function') { relName = forceSync; forceSync = alt; } //Simulate async callback; if (forceSync) { main(undef, deps, callback, relName); } else { //Using a non-zero value because of concern for what old browsers //do, and latest browsers "upgrade" to 4 if lower value is used: //http://www.whatwg.org/specs/web-apps/current-work/multipage/timers.html#dom-windowtimers-settimeout: //If want a value immediately, use require('id') instead -- something //that works in almond on the global level, but not guaranteed and //unlikely to work in other AMD implementations. setTimeout(function () { main(undef, deps, callback, relName); }, 4); } return req; }; /** * Just drops the config on the floor, but returns req in case * the config return value is used. */ req.config = function (cfg) { return req(cfg); }; /** * Expose module registry for debugging and tooling */ requirejs._defined = defined; define = function (name, deps, callback) { if (typeof name !== 'string') { throw new Error('See almond README: incorrect module build, no module name'); } //This module may not have dependencies if (!deps.splice) { //deps is not an array, so probably means //an object literal or factory function for //the value. Adjust args. callback = deps; deps = []; } if (!hasProp(defined, name) && !hasProp(waiting, name)) { waiting[name] = [name, deps, callback]; } }; define.amd = { jQuery: true }; }()); S2.requirejs = requirejs;S2.require = require;S2.define = define; } }()); S2.define("almond", function(){}); /* global jQuery:false, $:false */ S2.define('jquery',[],function () { var _$ = jQuery || $; if (_$ == null && console && console.error) { console.error( 'Select2: An instance of jQuery or a jQuery-compatible library was not ' + 'found. Make sure that you are including jQuery before Select2 on your ' + 'web page.' ); } return _$; }); S2.define('select2/utils',[ 'jquery' ], function ($) { var Utils = {}; Utils.Extend = function (ChildClass, SuperClass) { var __hasProp = {}.hasOwnProperty; function BaseConstructor () { this.constructor = ChildClass; } for (var key in SuperClass) { if (__hasProp.call(SuperClass, key)) { ChildClass[key] = SuperClass[key]; } } BaseConstructor.prototype = SuperClass.prototype; ChildClass.prototype = new BaseConstructor(); ChildClass.__super__ = SuperClass.prototype; return ChildClass; }; function getMethods (theClass) { var proto = theClass.prototype; var methods = []; for (var methodName in proto) { var m = proto[methodName]; if (typeof m !== 'function') { continue; } if (methodName === 'constructor') { continue; } methods.push(methodName); } return methods; } Utils.Decorate = function (SuperClass, DecoratorClass) { var decoratedMethods = getMethods(DecoratorClass); var superMethods = getMethods(SuperClass); function DecoratedClass () { var unshift = Array.prototype.unshift; var argCount = DecoratorClass.prototype.constructor.length; var calledConstructor = SuperClass.prototype.constructor; if (argCount > 0) { unshift.call(arguments, SuperClass.prototype.constructor); calledConstructor = DecoratorClass.prototype.constructor; } calledConstructor.apply(this, arguments); } DecoratorClass.displayName = SuperClass.displayName; function ctr () { this.constructor = DecoratedClass; } DecoratedClass.prototype = new ctr(); for (var m = 0; m < superMethods.length; m++) { var superMethod = superMethods[m]; DecoratedClass.prototype[superMethod] = SuperClass.prototype[superMethod]; } var calledMethod = function (methodName) { // Stub out the original method if it's not decorating an actual method var originalMethod = function () {}; if (methodName in DecoratedClass.prototype) { originalMethod = DecoratedClass.prototype[methodName]; } var decoratedMethod = DecoratorClass.prototype[methodName]; return function () { var unshift = Array.prototype.unshift; unshift.call(arguments, originalMethod); return decoratedMethod.apply(this, arguments); }; }; for (var d = 0; d < decoratedMethods.length; d++) { var decoratedMethod = decoratedMethods[d]; DecoratedClass.prototype[decoratedMethod] = calledMethod(decoratedMethod); } return DecoratedClass; }; var Observable = function () { this.listeners = {}; }; Observable.prototype.on = function (event, callback) { this.listeners = this.listeners || {}; if (event in this.listeners) { this.listeners[event].push(callback); } else { this.listeners[event] = [callback]; } }; Observable.prototype.trigger = function (event) { var slice = Array.prototype.slice; var params = slice.call(arguments, 1); this.listeners = this.listeners || {}; // Params should always come in as an array if (params == null) { params = []; } // If there are no arguments to the event, use a temporary object if (params.length === 0) { params.push({}); } // Set the `_type` of the first object to the event params[0]._type = event; if (event in this.listeners) { this.invoke(this.listeners[event], slice.call(arguments, 1)); } if ('*' in this.listeners) { this.invoke(this.listeners['*'], arguments); } }; Observable.prototype.invoke = function (listeners, params) { for (var i = 0, len = listeners.length; i < len; i++) { listeners[i].apply(this, params); } }; Utils.Observable = Observable; Utils.generateChars = function (length) { var chars = ''; for (var i = 0; i < length; i++) { var randomChar = Math.floor(Math.random() * 36); chars += randomChar.toString(36); } return chars; }; Utils.bind = function (func, context) { return function () { func.apply(context, arguments); }; }; Utils._convertData = function (data) { for (var originalKey in data) { var keys = originalKey.split('-'); var dataLevel = data; if (keys.length === 1) { continue; } for (var k = 0; k < keys.length; k++) { var key = keys[k]; // Lowercase the first letter // By default, dash-separated becomes camelCase key = key.substring(0, 1).toLowerCase() + key.substring(1); if (!(key in dataLevel)) { dataLevel[key] = {}; } if (k == keys.length - 1) { dataLevel[key] = data[originalKey]; } dataLevel = dataLevel[key]; } delete data[originalKey]; } return data; }; Utils.hasScroll = function (index, el) { // Adapted from the function created by @ShadowScripter // and adapted by @BillBarry on the Stack Exchange Code Review website. // The original code can be found at // http://codereview.stackexchange.com/q/13338 // and was designed to be used with the Sizzle selector engine. var $el = $(el); var overflowX = el.style.overflowX; var overflowY = el.style.overflowY; //Check both x and y declarations if (overflowX === overflowY && (overflowY === 'hidden' || overflowY === 'visible')) { return false; } if (overflowX === 'scroll' || overflowY === 'scroll') { return true; } return ($el.innerHeight() < el.scrollHeight || $el.innerWidth() < el.scrollWidth); }; Utils.escapeMarkup = function (markup) { var replaceMap = { '\\': '\', '&': '&', '<': '<', '>': '>', '"': '"', '\'': ''', '/': '/' }; // Do not try to escape the markup if it's not a string if (typeof markup !== 'string') { return markup; } return String(markup).replace(/[&<>"'\/\\]/g, function (match) { return replaceMap[match]; }); }; // Cache objects in Utils.__cache instead of $.data (see #4346) Utils.__cache = {}; var id = 0; Utils.GetUniqueElementId = function (element) { // Get a unique element Id. If element has no id, // creates a new unique number, stores it in the id // attribute and returns the new id with a prefix. // If an id already exists, it simply returns it with a prefix. var select2Id = element.getAttribute('data-select2-id'); if (select2Id != null) { return select2Id; } // If element has id, use it. if (element.id) { select2Id = 'select2-data-' + element.id; } else { select2Id = 'select2-data-' + (++id).toString() + '-' + Utils.generateChars(4); } element.setAttribute('data-select2-id', select2Id); return select2Id; }; Utils.StoreData = function (element, name, value) { // Stores an item in the cache for a specified element. // name is the cache key. var id = Utils.GetUniqueElementId(element); if (!Utils.__cache[id]) { Utils.__cache[id] = {}; } Utils.__cache[id][name] = value; }; Utils.GetData = function (element, name) { // Retrieves a value from the cache by its key (name) // name is optional. If no name specified, return // all cache items for the specified element. // and for a specified element. var id = Utils.GetUniqueElementId(element); if (name) { if (Utils.__cache[id]) { if (Utils.__cache[id][name] != null) { return Utils.__cache[id][name]; } return $(element).data(name); // Fallback to HTML5 data attribs. } return $(element).data(name); // Fallback to HTML5 data attribs. } else { return Utils.__cache[id]; } }; Utils.RemoveData = function (element) { // Removes all cached items for a specified element. var id = Utils.GetUniqueElementId(element); if (Utils.__cache[id] != null) { delete Utils.__cache[id]; } element.removeAttribute('data-select2-id'); }; Utils.copyNonInternalCssClasses = function (dest, src) { var classes; var destinationClasses = dest.getAttribute('class').trim().split(/\s+/); destinationClasses = destinationClasses.filter(function (clazz) { // Save all Select2 classes return clazz.indexOf('select2-') === 0; }); var sourceClasses = src.getAttribute('class').trim().split(/\s+/); sourceClasses = sourceClasses.filter(function (clazz) { // Only copy non-Select2 classes return clazz.indexOf('select2-') !== 0; }); var replacements = destinationClasses.concat(sourceClasses); dest.setAttribute('class', replacements.join(' ')); }; return Utils; }); S2.define('select2/results',[ 'jquery', './utils' ], function ($, Utils) { function Results ($element, options, dataAdapter) { this.$element = $element; this.data = dataAdapter; this.options = options; Results.__super__.constructor.call(this); } Utils.Extend(Results, Utils.Observable); Results.prototype.render = function () { var $results = $( '
        ' ); if (this.options.get('multiple')) { $results.attr('aria-multiselectable', 'true'); } this.$results = $results; return $results; }; Results.prototype.clear = function () { this.$results.empty(); }; Results.prototype.displayMessage = function (params) { var escapeMarkup = this.options.get('escapeMarkup'); this.clear(); this.hideLoading(); var $message = $( '
      • ' ); var message = this.options.get('translations').get(params.message); $message.append( escapeMarkup( message(params.args) ) ); $message[0].className += ' select2-results__message'; this.$results.append($message); }; Results.prototype.hideMessages = function () { this.$results.find('.select2-results__message').remove(); }; Results.prototype.append = function (data) { this.hideLoading(); var $options = []; if (data.results == null || data.results.length === 0) { if (this.$results.children().length === 0) { this.trigger('results:message', { message: 'noResults' }); } return; } data.results = this.sort(data.results); for (var d = 0; d < data.results.length; d++) { var item = data.results[d]; var $option = this.option(item); $options.push($option); } this.$results.append($options); }; Results.prototype.position = function ($results, $dropdown) { var $resultsContainer = $dropdown.find('.select2-results'); $resultsContainer.append($results); }; Results.prototype.sort = function (data) { var sorter = this.options.get('sorter'); return sorter(data); }; Results.prototype.highlightFirstItem = function () { var $options = this.$results .find('.select2-results__option--selectable'); var $selected = $options.filter('.select2-results__option--selected'); // Check if there are any selected options if ($selected.length > 0) { // If there are selected options, highlight the first $selected.first().trigger('mouseenter'); } else { // If there are no selected options, highlight the first option // in the dropdown $options.first().trigger('mouseenter'); } this.ensureHighlightVisible(); }; Results.prototype.setClasses = function () { var self = this; this.data.current(function (selected) { var selectedIds = selected.map(function (s) { return s.id.toString(); }); var $options = self.$results .find('.select2-results__option--selectable'); $options.each(function () { var $option = $(this); var item = Utils.GetData(this, 'data'); // id needs to be converted to a string when comparing var id = '' + item.id; if ((item.element != null && item.element.selected) || (item.element == null && selectedIds.indexOf(id) > -1)) { this.classList.add('select2-results__option--selected'); $option.attr('aria-selected', 'true'); } else { this.classList.remove('select2-results__option--selected'); $option.attr('aria-selected', 'false'); } }); }); }; Results.prototype.showLoading = function (params) { this.hideLoading(); var loadingMore = this.options.get('translations').get('searching'); var loading = { disabled: true, loading: true, text: loadingMore(params) }; var $loading = this.option(loading); $loading.className += ' loading-results'; this.$results.prepend($loading); }; Results.prototype.hideLoading = function () { this.$results.find('.loading-results').remove(); }; Results.prototype.option = function (data) { var option = document.createElement('li'); option.classList.add('select2-results__option'); option.classList.add('select2-results__option--selectable'); var attrs = { 'role': 'option' }; var matches = window.Element.prototype.matches || window.Element.prototype.msMatchesSelector || window.Element.prototype.webkitMatchesSelector; if ((data.element != null && matches.call(data.element, ':disabled')) || (data.element == null && data.disabled)) { attrs['aria-disabled'] = 'true'; option.classList.remove('select2-results__option--selectable'); option.classList.add('select2-results__option--disabled'); } if (data.id == null) { option.classList.remove('select2-results__option--selectable'); } if (data._resultId != null) { option.id = data._resultId; } if (data.title) { option.title = data.title; } if (data.children) { attrs.role = 'group'; attrs['aria-label'] = data.text; option.classList.remove('select2-results__option--selectable'); option.classList.add('select2-results__option--group'); } for (var attr in attrs) { var val = attrs[attr]; option.setAttribute(attr, val); } if (data.children) { var $option = $(option); var label = document.createElement('strong'); label.className = 'select2-results__group'; this.template(data, label); var $children = []; for (var c = 0; c < data.children.length; c++) { var child = data.children[c]; var $child = this.option(child); $children.push($child); } var $childrenContainer = $('
          ', { 'class': 'select2-results__options select2-results__options--nested', 'role': 'none' }); $childrenContainer.append($children); $option.append(label); $option.append($childrenContainer); } else { this.template(data, option); } Utils.StoreData(option, 'data', data); return option; }; Results.prototype.bind = function (container, $container) { var self = this; var id = container.id + '-results'; this.$results.attr('id', id); container.on('results:all', function (params) { self.clear(); self.append(params.data); if (container.isOpen()) { self.setClasses(); self.highlightFirstItem(); } }); container.on('results:append', function (params) { self.append(params.data); if (container.isOpen()) { self.setClasses(); } }); container.on('query', function (params) { self.hideMessages(); self.showLoading(params); }); container.on('select', function () { if (!container.isOpen()) { return; } self.setClasses(); if (self.options.get('scrollAfterSelect')) { self.highlightFirstItem(); } }); container.on('unselect', function () { if (!container.isOpen()) { return; } self.setClasses(); if (self.options.get('scrollAfterSelect')) { self.highlightFirstItem(); } }); container.on('open', function () { // When the dropdown is open, aria-expended="true" self.$results.attr('aria-expanded', 'true'); self.$results.attr('aria-hidden', 'false'); self.setClasses(); self.ensureHighlightVisible(); }); container.on('close', function () { // When the dropdown is closed, aria-expended="false" self.$results.attr('aria-expanded', 'false'); self.$results.attr('aria-hidden', 'true'); self.$results.removeAttr('aria-activedescendant'); }); container.on('results:toggle', function () { var $highlighted = self.getHighlightedResults(); if ($highlighted.length === 0) { return; } $highlighted.trigger('mouseup'); }); container.on('results:select', function () { var $highlighted = self.getHighlightedResults(); if ($highlighted.length === 0) { return; } var data = Utils.GetData($highlighted[0], 'data'); if ($highlighted.hasClass('select2-results__option--selected')) { self.trigger('close', {}); } else { self.trigger('select', { data: data }); } }); container.on('results:previous', function () { var $highlighted = self.getHighlightedResults(); var $options = self.$results.find('.select2-results__option--selectable'); var currentIndex = $options.index($highlighted); // If we are already at the top, don't move further // If no options, currentIndex will be -1 if (currentIndex <= 0) { return; } var nextIndex = currentIndex - 1; // If none are highlighted, highlight the first if ($highlighted.length === 0) { nextIndex = 0; } var $next = $options.eq(nextIndex); $next.trigger('mouseenter'); var currentOffset = self.$results.offset().top; var nextTop = $next.offset().top; var nextOffset = self.$results.scrollTop() + (nextTop - currentOffset); if (nextIndex === 0) { self.$results.scrollTop(0); } else if (nextTop - currentOffset < 0) { self.$results.scrollTop(nextOffset); } }); container.on('results:next', function () { var $highlighted = self.getHighlightedResults(); var $options = self.$results.find('.select2-results__option--selectable'); var currentIndex = $options.index($highlighted); var nextIndex = currentIndex + 1; // If we are at the last option, stay there if (nextIndex >= $options.length) { return; } var $next = $options.eq(nextIndex); $next.trigger('mouseenter'); var currentOffset = self.$results.offset().top + self.$results.outerHeight(false); var nextBottom = $next.offset().top + $next.outerHeight(false); var nextOffset = self.$results.scrollTop() + nextBottom - currentOffset; if (nextIndex === 0) { self.$results.scrollTop(0); } else if (nextBottom > currentOffset) { self.$results.scrollTop(nextOffset); } }); container.on('results:focus', function (params) { params.element[0].classList.add('select2-results__option--highlighted'); params.element[0].setAttribute('aria-selected', 'true'); }); container.on('results:message', function (params) { self.displayMessage(params); }); if ($.fn.mousewheel) { this.$results.on('mousewheel', function (e) { var top = self.$results.scrollTop(); var bottom = self.$results.get(0).scrollHeight - top + e.deltaY; var isAtTop = e.deltaY > 0 && top - e.deltaY <= 0; var isAtBottom = e.deltaY < 0 && bottom <= self.$results.height(); if (isAtTop) { self.$results.scrollTop(0); e.preventDefault(); e.stopPropagation(); } else if (isAtBottom) { self.$results.scrollTop( self.$results.get(0).scrollHeight - self.$results.height() ); e.preventDefault(); e.stopPropagation(); } }); } this.$results.on('mouseup', '.select2-results__option--selectable', function (evt) { var $this = $(this); var data = Utils.GetData(this, 'data'); if ($this.hasClass('select2-results__option--selected')) { if (self.options.get('multiple')) { self.trigger('unselect', { originalEvent: evt, data: data }); } else { self.trigger('close', {}); } return; } self.trigger('select', { originalEvent: evt, data: data }); }); this.$results.on('mouseenter', '.select2-results__option--selectable', function (evt) { var data = Utils.GetData(this, 'data'); self.getHighlightedResults() .removeClass('select2-results__option--highlighted') .attr('aria-selected', 'false'); self.trigger('results:focus', { data: data, element: $(this) }); }); }; Results.prototype.getHighlightedResults = function () { var $highlighted = this.$results .find('.select2-results__option--highlighted'); return $highlighted; }; Results.prototype.destroy = function () { this.$results.remove(); }; Results.prototype.ensureHighlightVisible = function () { var $highlighted = this.getHighlightedResults(); if ($highlighted.length === 0) { return; } var $options = this.$results.find('.select2-results__option--selectable'); var currentIndex = $options.index($highlighted); var currentOffset = this.$results.offset().top; var nextTop = $highlighted.offset().top; var nextOffset = this.$results.scrollTop() + (nextTop - currentOffset); var offsetDelta = nextTop - currentOffset; nextOffset -= $highlighted.outerHeight(false) * 2; if (currentIndex <= 2) { this.$results.scrollTop(0); } else if (offsetDelta > this.$results.outerHeight() || offsetDelta < 0) { this.$results.scrollTop(nextOffset); } }; Results.prototype.template = function (result, container) { var template = this.options.get('templateResult'); var escapeMarkup = this.options.get('escapeMarkup'); var content = template(result, container); if (content == null) { container.style.display = 'none'; } else if (typeof content === 'string') { container.innerHTML = escapeMarkup(content); } else { $(container).append(content); } }; return Results; }); S2.define('select2/keys',[ ], function () { var KEYS = { BACKSPACE: 8, TAB: 9, ENTER: 13, SHIFT: 16, CTRL: 17, ALT: 18, ESC: 27, SPACE: 32, PAGE_UP: 33, PAGE_DOWN: 34, END: 35, HOME: 36, LEFT: 37, UP: 38, RIGHT: 39, DOWN: 40, DELETE: 46 }; return KEYS; }); S2.define('select2/selection/base',[ 'jquery', '../utils', '../keys' ], function ($, Utils, KEYS) { function BaseSelection ($element, options) { this.$element = $element; this.options = options; BaseSelection.__super__.constructor.call(this); } Utils.Extend(BaseSelection, Utils.Observable); BaseSelection.prototype.render = function () { var $selection = $( '' ); this._tabindex = 0; if (Utils.GetData(this.$element[0], 'old-tabindex') != null) { this._tabindex = Utils.GetData(this.$element[0], 'old-tabindex'); } else if (this.$element.attr('tabindex') != null) { this._tabindex = this.$element.attr('tabindex'); } $selection.attr('title', this.$element.attr('title')); $selection.attr('tabindex', this._tabindex); $selection.attr('aria-disabled', 'false'); this.$selection = $selection; return $selection; }; BaseSelection.prototype.bind = function (container, $container) { var self = this; var resultsId = container.id + '-results'; this.container = container; this.$selection.on('focus', function (evt) { self.trigger('focus', evt); }); this.$selection.on('blur', function (evt) { self._handleBlur(evt); }); this.$selection.on('keydown', function (evt) { self.trigger('keypress', evt); if (evt.which === KEYS.SPACE) { evt.preventDefault(); } }); container.on('results:focus', function (params) { self.$selection.attr('aria-activedescendant', params.data._resultId); }); container.on('selection:update', function (params) { self.update(params.data); }); container.on('open', function () { // When the dropdown is open, aria-expanded="true" self.$selection.attr('aria-expanded', 'true'); self.$selection.attr('aria-owns', resultsId); self._attachCloseHandler(container); }); container.on('close', function () { // When the dropdown is closed, aria-expanded="false" self.$selection.attr('aria-expanded', 'false'); self.$selection.removeAttr('aria-activedescendant'); self.$selection.removeAttr('aria-owns'); self.$selection.trigger('focus'); self._detachCloseHandler(container); }); container.on('enable', function () { self.$selection.attr('tabindex', self._tabindex); self.$selection.attr('aria-disabled', 'false'); }); container.on('disable', function () { self.$selection.attr('tabindex', '-1'); self.$selection.attr('aria-disabled', 'true'); }); }; BaseSelection.prototype._handleBlur = function (evt) { var self = this; // This needs to be delayed as the active element is the body when the tab // key is pressed, possibly along with others. window.setTimeout(function () { // Don't trigger `blur` if the focus is still in the selection if ( (document.activeElement == self.$selection[0]) || ($.contains(self.$selection[0], document.activeElement)) ) { return; } self.trigger('blur', evt); }, 1); }; BaseSelection.prototype._attachCloseHandler = function (container) { $(document.body).on('mousedown.select2.' + container.id, function (e) { var $target = $(e.target); var $select = $target.closest('.select2'); var $all = $('.select2.select2-container--open'); $all.each(function () { if (this == $select[0]) { return; } var $element = Utils.GetData(this, 'element'); $element.select2('close'); }); }); }; BaseSelection.prototype._detachCloseHandler = function (container) { $(document.body).off('mousedown.select2.' + container.id); }; BaseSelection.prototype.position = function ($selection, $container) { var $selectionContainer = $container.find('.selection'); $selectionContainer.append($selection); }; BaseSelection.prototype.destroy = function () { this._detachCloseHandler(this.container); }; BaseSelection.prototype.update = function (data) { throw new Error('The `update` method must be defined in child classes.'); }; /** * Helper method to abstract the "enabled" (not "disabled") state of this * object. * * @return {true} if the instance is not disabled. * @return {false} if the instance is disabled. */ BaseSelection.prototype.isEnabled = function () { return !this.isDisabled(); }; /** * Helper method to abstract the "disabled" state of this object. * * @return {true} if the disabled option is true. * @return {false} if the disabled option is false. */ BaseSelection.prototype.isDisabled = function () { return this.options.get('disabled'); }; return BaseSelection; }); S2.define('select2/selection/single',[ 'jquery', './base', '../utils', '../keys' ], function ($, BaseSelection, Utils, KEYS) { function SingleSelection () { SingleSelection.__super__.constructor.apply(this, arguments); } Utils.Extend(SingleSelection, BaseSelection); SingleSelection.prototype.render = function () { var $selection = SingleSelection.__super__.render.call(this); $selection[0].classList.add('select2-selection--single'); $selection.html( '' + '' + '' + '' ); return $selection; }; SingleSelection.prototype.bind = function (container, $container) { var self = this; SingleSelection.__super__.bind.apply(this, arguments); var id = container.id + '-container'; this.$selection.find('.select2-selection__rendered') .attr('id', id) .attr('role', 'textbox') .attr('aria-readonly', 'true'); this.$selection.attr('aria-labelledby', id); this.$selection.attr('aria-controls', id); this.$selection.on('mousedown', function (evt) { // Only respond to left clicks if (evt.which !== 1) { return; } self.trigger('toggle', { originalEvent: evt }); }); this.$selection.on('focus', function (evt) { // User focuses on the container }); this.$selection.on('blur', function (evt) { // User exits the container }); container.on('focus', function (evt) { if (!container.isOpen()) { self.$selection.trigger('focus'); } }); }; SingleSelection.prototype.clear = function () { var $rendered = this.$selection.find('.select2-selection__rendered'); $rendered.empty(); $rendered.removeAttr('title'); // clear tooltip on empty }; SingleSelection.prototype.display = function (data, container) { var template = this.options.get('templateSelection'); var escapeMarkup = this.options.get('escapeMarkup'); return escapeMarkup(template(data, container)); }; SingleSelection.prototype.selectionContainer = function () { return $(''); }; SingleSelection.prototype.update = function (data) { if (data.length === 0) { this.clear(); return; } var selection = data[0]; var $rendered = this.$selection.find('.select2-selection__rendered'); var formatted = this.display(selection, $rendered); $rendered.empty().append(formatted); var title = selection.title || selection.text; if (title) { $rendered.attr('title', title); } else { $rendered.removeAttr('title'); } }; return SingleSelection; }); S2.define('select2/selection/multiple',[ 'jquery', './base', '../utils' ], function ($, BaseSelection, Utils) { function MultipleSelection ($element, options) { MultipleSelection.__super__.constructor.apply(this, arguments); } Utils.Extend(MultipleSelection, BaseSelection); MultipleSelection.prototype.render = function () { var $selection = MultipleSelection.__super__.render.call(this); $selection[0].classList.add('select2-selection--multiple'); $selection.html( '
            ' ); return $selection; }; MultipleSelection.prototype.bind = function (container, $container) { var self = this; MultipleSelection.__super__.bind.apply(this, arguments); var id = container.id + '-container'; this.$selection.find('.select2-selection__rendered').attr('id', id); this.$selection.on('click', function (evt) { self.trigger('toggle', { originalEvent: evt }); }); this.$selection.on( 'click', '.select2-selection__choice__remove', function (evt) { // Ignore the event if it is disabled if (self.isDisabled()) { return; } var $remove = $(this); var $selection = $remove.parent(); var data = Utils.GetData($selection[0], 'data'); self.trigger('unselect', { originalEvent: evt, data: data }); } ); this.$selection.on( 'keydown', '.select2-selection__choice__remove', function (evt) { // Ignore the event if it is disabled if (self.isDisabled()) { return; } evt.stopPropagation(); } ); }; MultipleSelection.prototype.clear = function () { var $rendered = this.$selection.find('.select2-selection__rendered'); $rendered.empty(); $rendered.removeAttr('title'); }; MultipleSelection.prototype.display = function (data, container) { var template = this.options.get('templateSelection'); var escapeMarkup = this.options.get('escapeMarkup'); return escapeMarkup(template(data, container)); }; MultipleSelection.prototype.selectionContainer = function () { var $container = $( '
          • ' + '' + '' + '
          • ' ); return $container; }; MultipleSelection.prototype.update = function (data) { this.clear(); if (data.length === 0) { return; } var $selections = []; var selectionIdPrefix = this.$selection.find('.select2-selection__rendered') .attr('id') + '-choice-'; for (var d = 0; d < data.length; d++) { var selection = data[d]; var $selection = this.selectionContainer(); var formatted = this.display(selection, $selection); var selectionId = selectionIdPrefix + Utils.generateChars(4) + '-'; if (selection.id) { selectionId += selection.id; } else { selectionId += Utils.generateChars(4); } $selection.find('.select2-selection__choice__display') .append(formatted) .attr('id', selectionId); var title = selection.title || selection.text; if (title) { $selection.attr('title', title); } var removeItem = this.options.get('translations').get('removeItem'); var $remove = $selection.find('.select2-selection__choice__remove'); $remove.attr('title', removeItem()); $remove.attr('aria-label', removeItem()); $remove.attr('aria-describedby', selectionId); Utils.StoreData($selection[0], 'data', selection); $selections.push($selection); } var $rendered = this.$selection.find('.select2-selection__rendered'); $rendered.append($selections); }; return MultipleSelection; }); S2.define('select2/selection/placeholder',[ ], function () { function Placeholder (decorated, $element, options) { this.placeholder = this.normalizePlaceholder(options.get('placeholder')); decorated.call(this, $element, options); } Placeholder.prototype.normalizePlaceholder = function (_, placeholder) { if (typeof placeholder === 'string') { placeholder = { id: '', text: placeholder }; } return placeholder; }; Placeholder.prototype.createPlaceholder = function (decorated, placeholder) { var $placeholder = this.selectionContainer(); $placeholder.html(this.display(placeholder)); $placeholder[0].classList.add('select2-selection__placeholder'); $placeholder[0].classList.remove('select2-selection__choice'); var placeholderTitle = placeholder.title || placeholder.text || $placeholder.text(); this.$selection.find('.select2-selection__rendered').attr( 'title', placeholderTitle ); return $placeholder; }; Placeholder.prototype.update = function (decorated, data) { var singlePlaceholder = ( data.length == 1 && data[0].id != this.placeholder.id ); var multipleSelections = data.length > 1; if (multipleSelections || singlePlaceholder) { return decorated.call(this, data); } this.clear(); var $placeholder = this.createPlaceholder(this.placeholder); this.$selection.find('.select2-selection__rendered').append($placeholder); }; return Placeholder; }); S2.define('select2/selection/allowClear',[ 'jquery', '../keys', '../utils' ], function ($, KEYS, Utils) { function AllowClear () { } AllowClear.prototype.bind = function (decorated, container, $container) { var self = this; decorated.call(this, container, $container); if (this.placeholder == null) { if (this.options.get('debug') && window.console && console.error) { console.error( 'Select2: The `allowClear` option should be used in combination ' + 'with the `placeholder` option.' ); } } this.$selection.on('mousedown', '.select2-selection__clear', function (evt) { self._handleClear(evt); }); container.on('keypress', function (evt) { self._handleKeyboardClear(evt, container); }); }; AllowClear.prototype._handleClear = function (_, evt) { // Ignore the event if it is disabled if (this.isDisabled()) { return; } var $clear = this.$selection.find('.select2-selection__clear'); // Ignore the event if nothing has been selected if ($clear.length === 0) { return; } evt.stopPropagation(); var data = Utils.GetData($clear[0], 'data'); var previousVal = this.$element.val(); this.$element.val(this.placeholder.id); var unselectData = { data: data }; this.trigger('clear', unselectData); if (unselectData.prevented) { this.$element.val(previousVal); return; } for (var d = 0; d < data.length; d++) { unselectData = { data: data[d] }; // Trigger the `unselect` event, so people can prevent it from being // cleared. this.trigger('unselect', unselectData); // If the event was prevented, don't clear it out. if (unselectData.prevented) { this.$element.val(previousVal); return; } } this.$element.trigger('input').trigger('change'); this.trigger('toggle', {}); }; AllowClear.prototype._handleKeyboardClear = function (_, evt, container) { if (container.isOpen()) { return; } if (evt.which == KEYS.DELETE || evt.which == KEYS.BACKSPACE) { this._handleClear(evt); } }; AllowClear.prototype.update = function (decorated, data) { decorated.call(this, data); this.$selection.find('.select2-selection__clear').remove(); this.$selection[0].classList.remove('select2-selection--clearable'); if (this.$selection.find('.select2-selection__placeholder').length > 0 || data.length === 0) { return; } var selectionId = this.$selection.find('.select2-selection__rendered') .attr('id'); var removeAll = this.options.get('translations').get('removeAllItems'); var $remove = $( '' ); $remove.attr('title', removeAll()); $remove.attr('aria-label', removeAll()); $remove.attr('aria-describedby', selectionId); Utils.StoreData($remove[0], 'data', data); this.$selection.prepend($remove); this.$selection[0].classList.add('select2-selection--clearable'); }; return AllowClear; }); S2.define('select2/selection/search',[ 'jquery', '../utils', '../keys' ], function ($, Utils, KEYS) { function Search (decorated, $element, options) { decorated.call(this, $element, options); } Search.prototype.render = function (decorated) { var searchLabel = this.options.get('translations').get('search'); var $search = $( '' + '' + '' ); this.$searchContainer = $search; this.$search = $search.find('textarea'); this.$search.prop('autocomplete', this.options.get('autocomplete')); this.$search.attr('aria-label', searchLabel()); var $rendered = decorated.call(this); this._transferTabIndex(); $rendered.append(this.$searchContainer); return $rendered; }; Search.prototype.bind = function (decorated, container, $container) { var self = this; var resultsId = container.id + '-results'; var selectionId = container.id + '-container'; decorated.call(this, container, $container); self.$search.attr('aria-describedby', selectionId); container.on('open', function () { self.$search.attr('aria-controls', resultsId); self.$search.trigger('focus'); }); container.on('close', function () { self.$search.val(''); self.resizeSearch(); self.$search.removeAttr('aria-controls'); self.$search.removeAttr('aria-activedescendant'); self.$search.trigger('focus'); }); container.on('enable', function () { self.$search.prop('disabled', false); self._transferTabIndex(); }); container.on('disable', function () { self.$search.prop('disabled', true); }); container.on('focus', function (evt) { self.$search.trigger('focus'); }); container.on('results:focus', function (params) { if (params.data._resultId) { self.$search.attr('aria-activedescendant', params.data._resultId); } else { self.$search.removeAttr('aria-activedescendant'); } }); this.$selection.on('focusin', '.select2-search--inline', function (evt) { self.trigger('focus', evt); }); this.$selection.on('focusout', '.select2-search--inline', function (evt) { self._handleBlur(evt); }); this.$selection.on('keydown', '.select2-search--inline', function (evt) { evt.stopPropagation(); self.trigger('keypress', evt); self._keyUpPrevented = evt.isDefaultPrevented(); var key = evt.which; if (key === KEYS.BACKSPACE && self.$search.val() === '') { var $previousChoice = self.$selection .find('.select2-selection__choice').last(); if ($previousChoice.length > 0) { var item = Utils.GetData($previousChoice[0], 'data'); self.searchRemoveChoice(item); evt.preventDefault(); } } }); this.$selection.on('click', '.select2-search--inline', function (evt) { if (self.$search.val()) { evt.stopPropagation(); } }); // Try to detect the IE version should the `documentMode` property that // is stored on the document. This is only implemented in IE and is // slightly cleaner than doing a user agent check. // This property is not available in Edge, but Edge also doesn't have // this bug. var msie = document.documentMode; var disableInputEvents = msie && msie <= 11; // Workaround for browsers which do not support the `input` event // This will prevent double-triggering of events for browsers which support // both the `keyup` and `input` events. this.$selection.on( 'input.searchcheck', '.select2-search--inline', function (evt) { // IE will trigger the `input` event when a placeholder is used on a // search box. To get around this issue, we are forced to ignore all // `input` events in IE and keep using `keyup`. if (disableInputEvents) { self.$selection.off('input.search input.searchcheck'); return; } // Unbind the duplicated `keyup` event self.$selection.off('keyup.search'); } ); this.$selection.on( 'keyup.search input.search', '.select2-search--inline', function (evt) { // IE will trigger the `input` event when a placeholder is used on a // search box. To get around this issue, we are forced to ignore all // `input` events in IE and keep using `keyup`. if (disableInputEvents && evt.type === 'input') { self.$selection.off('input.search input.searchcheck'); return; } var key = evt.which; // We can freely ignore events from modifier keys if (key == KEYS.SHIFT || key == KEYS.CTRL || key == KEYS.ALT) { return; } // Tabbing will be handled during the `keydown` phase if (key == KEYS.TAB) { return; } self.handleSearch(evt); } ); }; /** * This method will transfer the tabindex attribute from the rendered * selection to the search box. This allows for the search box to be used as * the primary focus instead of the selection container. * * @private */ Search.prototype._transferTabIndex = function (decorated) { this.$search.attr('tabindex', this.$selection.attr('tabindex')); this.$selection.attr('tabindex', '-1'); }; Search.prototype.createPlaceholder = function (decorated, placeholder) { this.$search.attr('placeholder', placeholder.text); }; Search.prototype.update = function (decorated, data) { var searchHadFocus = this.$search[0] == document.activeElement; this.$search.attr('placeholder', ''); decorated.call(this, data); this.resizeSearch(); if (searchHadFocus) { this.$search.trigger('focus'); } }; Search.prototype.handleSearch = function () { this.resizeSearch(); if (!this._keyUpPrevented) { var input = this.$search.val(); this.trigger('query', { term: input }); } this._keyUpPrevented = false; }; Search.prototype.searchRemoveChoice = function (decorated, item) { this.trigger('unselect', { data: item }); this.$search.val(item.text); this.handleSearch(); }; Search.prototype.resizeSearch = function () { this.$search.css('width', '25px'); var width = '100%'; if (this.$search.attr('placeholder') === '') { var minimumWidth = this.$search.val().length + 1; width = (minimumWidth * 0.75) + 'em'; } this.$search.css('width', width); }; return Search; }); S2.define('select2/selection/selectionCss',[ '../utils' ], function (Utils) { function SelectionCSS () { } SelectionCSS.prototype.render = function (decorated) { var $selection = decorated.call(this); var selectionCssClass = this.options.get('selectionCssClass') || ''; if (selectionCssClass.indexOf(':all:') !== -1) { selectionCssClass = selectionCssClass.replace(':all:', ''); Utils.copyNonInternalCssClasses($selection[0], this.$element[0]); } $selection.addClass(selectionCssClass); return $selection; }; return SelectionCSS; }); S2.define('select2/selection/eventRelay',[ 'jquery' ], function ($) { function EventRelay () { } EventRelay.prototype.bind = function (decorated, container, $container) { var self = this; var relayEvents = [ 'open', 'opening', 'close', 'closing', 'select', 'selecting', 'unselect', 'unselecting', 'clear', 'clearing' ]; var preventableEvents = [ 'opening', 'closing', 'selecting', 'unselecting', 'clearing' ]; decorated.call(this, container, $container); container.on('*', function (name, params) { // Ignore events that should not be relayed if (relayEvents.indexOf(name) === -1) { return; } // The parameters should always be an object params = params || {}; // Generate the jQuery event for the Select2 event var evt = $.Event('select2:' + name, { params: params }); self.$element.trigger(evt); // Only handle preventable events if it was one if (preventableEvents.indexOf(name) === -1) { return; } params.prevented = evt.isDefaultPrevented(); }); }; return EventRelay; }); S2.define('select2/translation',[ 'jquery', 'require' ], function ($, require) { function Translation (dict) { this.dict = dict || {}; } Translation.prototype.all = function () { return this.dict; }; Translation.prototype.get = function (key) { return this.dict[key]; }; Translation.prototype.extend = function (translation) { this.dict = $.extend({}, translation.all(), this.dict); }; // Static functions Translation._cache = {}; Translation.loadPath = function (path) { if (!(path in Translation._cache)) { var translations = require(path); Translation._cache[path] = translations; } return new Translation(Translation._cache[path]); }; return Translation; }); S2.define('select2/diacritics',[ ], function () { var diacritics = { '\u24B6': 'A', '\uFF21': 'A', '\u00C0': 'A', '\u00C1': 'A', '\u00C2': 'A', '\u1EA6': 'A', '\u1EA4': 'A', '\u1EAA': 'A', '\u1EA8': 'A', '\u00C3': 'A', '\u0100': 'A', '\u0102': 'A', '\u1EB0': 'A', '\u1EAE': 'A', '\u1EB4': 'A', '\u1EB2': 'A', '\u0226': 'A', '\u01E0': 'A', '\u00C4': 'A', '\u01DE': 'A', '\u1EA2': 'A', '\u00C5': 'A', '\u01FA': 'A', '\u01CD': 'A', '\u0200': 'A', '\u0202': 'A', '\u1EA0': 'A', '\u1EAC': 'A', '\u1EB6': 'A', '\u1E00': 'A', '\u0104': 'A', '\u023A': 'A', '\u2C6F': 'A', '\uA732': 'AA', '\u00C6': 'AE', '\u01FC': 'AE', '\u01E2': 'AE', '\uA734': 'AO', '\uA736': 'AU', '\uA738': 'AV', '\uA73A': 'AV', '\uA73C': 'AY', '\u24B7': 'B', '\uFF22': 'B', '\u1E02': 'B', '\u1E04': 'B', '\u1E06': 'B', '\u0243': 'B', '\u0182': 'B', '\u0181': 'B', '\u24B8': 'C', '\uFF23': 'C', '\u0106': 'C', '\u0108': 'C', '\u010A': 'C', '\u010C': 'C', '\u00C7': 'C', '\u1E08': 'C', '\u0187': 'C', '\u023B': 'C', '\uA73E': 'C', '\u24B9': 'D', '\uFF24': 'D', '\u1E0A': 'D', '\u010E': 'D', '\u1E0C': 'D', '\u1E10': 'D', '\u1E12': 'D', '\u1E0E': 'D', '\u0110': 'D', '\u018B': 'D', '\u018A': 'D', '\u0189': 'D', '\uA779': 'D', '\u01F1': 'DZ', '\u01C4': 'DZ', '\u01F2': 'Dz', '\u01C5': 'Dz', '\u24BA': 'E', '\uFF25': 'E', '\u00C8': 'E', '\u00C9': 'E', '\u00CA': 'E', '\u1EC0': 'E', '\u1EBE': 'E', '\u1EC4': 'E', '\u1EC2': 'E', '\u1EBC': 'E', '\u0112': 'E', '\u1E14': 'E', '\u1E16': 'E', '\u0114': 'E', '\u0116': 'E', '\u00CB': 'E', '\u1EBA': 'E', '\u011A': 'E', '\u0204': 'E', '\u0206': 'E', '\u1EB8': 'E', '\u1EC6': 'E', '\u0228': 'E', '\u1E1C': 'E', '\u0118': 'E', '\u1E18': 'E', '\u1E1A': 'E', '\u0190': 'E', '\u018E': 'E', '\u24BB': 'F', '\uFF26': 'F', '\u1E1E': 'F', '\u0191': 'F', '\uA77B': 'F', '\u24BC': 'G', '\uFF27': 'G', '\u01F4': 'G', '\u011C': 'G', '\u1E20': 'G', '\u011E': 'G', '\u0120': 'G', '\u01E6': 'G', '\u0122': 'G', '\u01E4': 'G', '\u0193': 'G', '\uA7A0': 'G', '\uA77D': 'G', '\uA77E': 'G', '\u24BD': 'H', '\uFF28': 'H', '\u0124': 'H', '\u1E22': 'H', '\u1E26': 'H', '\u021E': 'H', '\u1E24': 'H', '\u1E28': 'H', '\u1E2A': 'H', '\u0126': 'H', '\u2C67': 'H', '\u2C75': 'H', '\uA78D': 'H', '\u24BE': 'I', '\uFF29': 'I', '\u00CC': 'I', '\u00CD': 'I', '\u00CE': 'I', '\u0128': 'I', '\u012A': 'I', '\u012C': 'I', '\u0130': 'I', '\u00CF': 'I', '\u1E2E': 'I', '\u1EC8': 'I', '\u01CF': 'I', '\u0208': 'I', '\u020A': 'I', '\u1ECA': 'I', '\u012E': 'I', '\u1E2C': 'I', '\u0197': 'I', '\u24BF': 'J', '\uFF2A': 'J', '\u0134': 'J', '\u0248': 'J', '\u24C0': 'K', '\uFF2B': 'K', '\u1E30': 'K', '\u01E8': 'K', '\u1E32': 'K', '\u0136': 'K', '\u1E34': 'K', '\u0198': 'K', '\u2C69': 'K', '\uA740': 'K', '\uA742': 'K', '\uA744': 'K', '\uA7A2': 'K', '\u24C1': 'L', '\uFF2C': 'L', '\u013F': 'L', '\u0139': 'L', '\u013D': 'L', '\u1E36': 'L', '\u1E38': 'L', '\u013B': 'L', '\u1E3C': 'L', '\u1E3A': 'L', '\u0141': 'L', '\u023D': 'L', '\u2C62': 'L', '\u2C60': 'L', '\uA748': 'L', '\uA746': 'L', '\uA780': 'L', '\u01C7': 'LJ', '\u01C8': 'Lj', '\u24C2': 'M', '\uFF2D': 'M', '\u1E3E': 'M', '\u1E40': 'M', '\u1E42': 'M', '\u2C6E': 'M', '\u019C': 'M', '\u24C3': 'N', '\uFF2E': 'N', '\u01F8': 'N', '\u0143': 'N', '\u00D1': 'N', '\u1E44': 'N', '\u0147': 'N', '\u1E46': 'N', '\u0145': 'N', '\u1E4A': 'N', '\u1E48': 'N', '\u0220': 'N', '\u019D': 'N', '\uA790': 'N', '\uA7A4': 'N', '\u01CA': 'NJ', '\u01CB': 'Nj', '\u24C4': 'O', '\uFF2F': 'O', '\u00D2': 'O', '\u00D3': 'O', '\u00D4': 'O', '\u1ED2': 'O', '\u1ED0': 'O', '\u1ED6': 'O', '\u1ED4': 'O', '\u00D5': 'O', '\u1E4C': 'O', '\u022C': 'O', '\u1E4E': 'O', '\u014C': 'O', '\u1E50': 'O', '\u1E52': 'O', '\u014E': 'O', '\u022E': 'O', '\u0230': 'O', '\u00D6': 'O', '\u022A': 'O', '\u1ECE': 'O', '\u0150': 'O', '\u01D1': 'O', '\u020C': 'O', '\u020E': 'O', '\u01A0': 'O', '\u1EDC': 'O', '\u1EDA': 'O', '\u1EE0': 'O', '\u1EDE': 'O', '\u1EE2': 'O', '\u1ECC': 'O', '\u1ED8': 'O', '\u01EA': 'O', '\u01EC': 'O', '\u00D8': 'O', '\u01FE': 'O', '\u0186': 'O', '\u019F': 'O', '\uA74A': 'O', '\uA74C': 'O', '\u0152': 'OE', '\u01A2': 'OI', '\uA74E': 'OO', '\u0222': 'OU', '\u24C5': 'P', '\uFF30': 'P', '\u1E54': 'P', '\u1E56': 'P', '\u01A4': 'P', '\u2C63': 'P', '\uA750': 'P', '\uA752': 'P', '\uA754': 'P', '\u24C6': 'Q', '\uFF31': 'Q', '\uA756': 'Q', '\uA758': 'Q', '\u024A': 'Q', '\u24C7': 'R', '\uFF32': 'R', '\u0154': 'R', '\u1E58': 'R', '\u0158': 'R', '\u0210': 'R', '\u0212': 'R', '\u1E5A': 'R', '\u1E5C': 'R', '\u0156': 'R', '\u1E5E': 'R', '\u024C': 'R', '\u2C64': 'R', '\uA75A': 'R', '\uA7A6': 'R', '\uA782': 'R', '\u24C8': 'S', '\uFF33': 'S', '\u1E9E': 'S', '\u015A': 'S', '\u1E64': 'S', '\u015C': 'S', '\u1E60': 'S', '\u0160': 'S', '\u1E66': 'S', '\u1E62': 'S', '\u1E68': 'S', '\u0218': 'S', '\u015E': 'S', '\u2C7E': 'S', '\uA7A8': 'S', '\uA784': 'S', '\u24C9': 'T', '\uFF34': 'T', '\u1E6A': 'T', '\u0164': 'T', '\u1E6C': 'T', '\u021A': 'T', '\u0162': 'T', '\u1E70': 'T', '\u1E6E': 'T', '\u0166': 'T', '\u01AC': 'T', '\u01AE': 'T', '\u023E': 'T', '\uA786': 'T', '\uA728': 'TZ', '\u24CA': 'U', '\uFF35': 'U', '\u00D9': 'U', '\u00DA': 'U', '\u00DB': 'U', '\u0168': 'U', '\u1E78': 'U', '\u016A': 'U', '\u1E7A': 'U', '\u016C': 'U', '\u00DC': 'U', '\u01DB': 'U', '\u01D7': 'U', '\u01D5': 'U', '\u01D9': 'U', '\u1EE6': 'U', '\u016E': 'U', '\u0170': 'U', '\u01D3': 'U', '\u0214': 'U', '\u0216': 'U', '\u01AF': 'U', '\u1EEA': 'U', '\u1EE8': 'U', '\u1EEE': 'U', '\u1EEC': 'U', '\u1EF0': 'U', '\u1EE4': 'U', '\u1E72': 'U', '\u0172': 'U', '\u1E76': 'U', '\u1E74': 'U', '\u0244': 'U', '\u24CB': 'V', '\uFF36': 'V', '\u1E7C': 'V', '\u1E7E': 'V', '\u01B2': 'V', '\uA75E': 'V', '\u0245': 'V', '\uA760': 'VY', '\u24CC': 'W', '\uFF37': 'W', '\u1E80': 'W', '\u1E82': 'W', '\u0174': 'W', '\u1E86': 'W', '\u1E84': 'W', '\u1E88': 'W', '\u2C72': 'W', '\u24CD': 'X', '\uFF38': 'X', '\u1E8A': 'X', '\u1E8C': 'X', '\u24CE': 'Y', '\uFF39': 'Y', '\u1EF2': 'Y', '\u00DD': 'Y', '\u0176': 'Y', '\u1EF8': 'Y', '\u0232': 'Y', '\u1E8E': 'Y', '\u0178': 'Y', '\u1EF6': 'Y', '\u1EF4': 'Y', '\u01B3': 'Y', '\u024E': 'Y', '\u1EFE': 'Y', '\u24CF': 'Z', '\uFF3A': 'Z', '\u0179': 'Z', '\u1E90': 'Z', '\u017B': 'Z', '\u017D': 'Z', '\u1E92': 'Z', '\u1E94': 'Z', '\u01B5': 'Z', '\u0224': 'Z', '\u2C7F': 'Z', '\u2C6B': 'Z', '\uA762': 'Z', '\u24D0': 'a', '\uFF41': 'a', '\u1E9A': 'a', '\u00E0': 'a', '\u00E1': 'a', '\u00E2': 'a', '\u1EA7': 'a', '\u1EA5': 'a', '\u1EAB': 'a', '\u1EA9': 'a', '\u00E3': 'a', '\u0101': 'a', '\u0103': 'a', '\u1EB1': 'a', '\u1EAF': 'a', '\u1EB5': 'a', '\u1EB3': 'a', '\u0227': 'a', '\u01E1': 'a', '\u00E4': 'a', '\u01DF': 'a', '\u1EA3': 'a', '\u00E5': 'a', '\u01FB': 'a', '\u01CE': 'a', '\u0201': 'a', '\u0203': 'a', '\u1EA1': 'a', '\u1EAD': 'a', '\u1EB7': 'a', '\u1E01': 'a', '\u0105': 'a', '\u2C65': 'a', '\u0250': 'a', '\uA733': 'aa', '\u00E6': 'ae', '\u01FD': 'ae', '\u01E3': 'ae', '\uA735': 'ao', '\uA737': 'au', '\uA739': 'av', '\uA73B': 'av', '\uA73D': 'ay', '\u24D1': 'b', '\uFF42': 'b', '\u1E03': 'b', '\u1E05': 'b', '\u1E07': 'b', '\u0180': 'b', '\u0183': 'b', '\u0253': 'b', '\u24D2': 'c', '\uFF43': 'c', '\u0107': 'c', '\u0109': 'c', '\u010B': 'c', '\u010D': 'c', '\u00E7': 'c', '\u1E09': 'c', '\u0188': 'c', '\u023C': 'c', '\uA73F': 'c', '\u2184': 'c', '\u24D3': 'd', '\uFF44': 'd', '\u1E0B': 'd', '\u010F': 'd', '\u1E0D': 'd', '\u1E11': 'd', '\u1E13': 'd', '\u1E0F': 'd', '\u0111': 'd', '\u018C': 'd', '\u0256': 'd', '\u0257': 'd', '\uA77A': 'd', '\u01F3': 'dz', '\u01C6': 'dz', '\u24D4': 'e', '\uFF45': 'e', '\u00E8': 'e', '\u00E9': 'e', '\u00EA': 'e', '\u1EC1': 'e', '\u1EBF': 'e', '\u1EC5': 'e', '\u1EC3': 'e', '\u1EBD': 'e', '\u0113': 'e', '\u1E15': 'e', '\u1E17': 'e', '\u0115': 'e', '\u0117': 'e', '\u00EB': 'e', '\u1EBB': 'e', '\u011B': 'e', '\u0205': 'e', '\u0207': 'e', '\u1EB9': 'e', '\u1EC7': 'e', '\u0229': 'e', '\u1E1D': 'e', '\u0119': 'e', '\u1E19': 'e', '\u1E1B': 'e', '\u0247': 'e', '\u025B': 'e', '\u01DD': 'e', '\u24D5': 'f', '\uFF46': 'f', '\u1E1F': 'f', '\u0192': 'f', '\uA77C': 'f', '\u24D6': 'g', '\uFF47': 'g', '\u01F5': 'g', '\u011D': 'g', '\u1E21': 'g', '\u011F': 'g', '\u0121': 'g', '\u01E7': 'g', '\u0123': 'g', '\u01E5': 'g', '\u0260': 'g', '\uA7A1': 'g', '\u1D79': 'g', '\uA77F': 'g', '\u24D7': 'h', '\uFF48': 'h', '\u0125': 'h', '\u1E23': 'h', '\u1E27': 'h', '\u021F': 'h', '\u1E25': 'h', '\u1E29': 'h', '\u1E2B': 'h', '\u1E96': 'h', '\u0127': 'h', '\u2C68': 'h', '\u2C76': 'h', '\u0265': 'h', '\u0195': 'hv', '\u24D8': 'i', '\uFF49': 'i', '\u00EC': 'i', '\u00ED': 'i', '\u00EE': 'i', '\u0129': 'i', '\u012B': 'i', '\u012D': 'i', '\u00EF': 'i', '\u1E2F': 'i', '\u1EC9': 'i', '\u01D0': 'i', '\u0209': 'i', '\u020B': 'i', '\u1ECB': 'i', '\u012F': 'i', '\u1E2D': 'i', '\u0268': 'i', '\u0131': 'i', '\u24D9': 'j', '\uFF4A': 'j', '\u0135': 'j', '\u01F0': 'j', '\u0249': 'j', '\u24DA': 'k', '\uFF4B': 'k', '\u1E31': 'k', '\u01E9': 'k', '\u1E33': 'k', '\u0137': 'k', '\u1E35': 'k', '\u0199': 'k', '\u2C6A': 'k', '\uA741': 'k', '\uA743': 'k', '\uA745': 'k', '\uA7A3': 'k', '\u24DB': 'l', '\uFF4C': 'l', '\u0140': 'l', '\u013A': 'l', '\u013E': 'l', '\u1E37': 'l', '\u1E39': 'l', '\u013C': 'l', '\u1E3D': 'l', '\u1E3B': 'l', '\u017F': 'l', '\u0142': 'l', '\u019A': 'l', '\u026B': 'l', '\u2C61': 'l', '\uA749': 'l', '\uA781': 'l', '\uA747': 'l', '\u01C9': 'lj', '\u24DC': 'm', '\uFF4D': 'm', '\u1E3F': 'm', '\u1E41': 'm', '\u1E43': 'm', '\u0271': 'm', '\u026F': 'm', '\u24DD': 'n', '\uFF4E': 'n', '\u01F9': 'n', '\u0144': 'n', '\u00F1': 'n', '\u1E45': 'n', '\u0148': 'n', '\u1E47': 'n', '\u0146': 'n', '\u1E4B': 'n', '\u1E49': 'n', '\u019E': 'n', '\u0272': 'n', '\u0149': 'n', '\uA791': 'n', '\uA7A5': 'n', '\u01CC': 'nj', '\u24DE': 'o', '\uFF4F': 'o', '\u00F2': 'o', '\u00F3': 'o', '\u00F4': 'o', '\u1ED3': 'o', '\u1ED1': 'o', '\u1ED7': 'o', '\u1ED5': 'o', '\u00F5': 'o', '\u1E4D': 'o', '\u022D': 'o', '\u1E4F': 'o', '\u014D': 'o', '\u1E51': 'o', '\u1E53': 'o', '\u014F': 'o', '\u022F': 'o', '\u0231': 'o', '\u00F6': 'o', '\u022B': 'o', '\u1ECF': 'o', '\u0151': 'o', '\u01D2': 'o', '\u020D': 'o', '\u020F': 'o', '\u01A1': 'o', '\u1EDD': 'o', '\u1EDB': 'o', '\u1EE1': 'o', '\u1EDF': 'o', '\u1EE3': 'o', '\u1ECD': 'o', '\u1ED9': 'o', '\u01EB': 'o', '\u01ED': 'o', '\u00F8': 'o', '\u01FF': 'o', '\u0254': 'o', '\uA74B': 'o', '\uA74D': 'o', '\u0275': 'o', '\u0153': 'oe', '\u01A3': 'oi', '\u0223': 'ou', '\uA74F': 'oo', '\u24DF': 'p', '\uFF50': 'p', '\u1E55': 'p', '\u1E57': 'p', '\u01A5': 'p', '\u1D7D': 'p', '\uA751': 'p', '\uA753': 'p', '\uA755': 'p', '\u24E0': 'q', '\uFF51': 'q', '\u024B': 'q', '\uA757': 'q', '\uA759': 'q', '\u24E1': 'r', '\uFF52': 'r', '\u0155': 'r', '\u1E59': 'r', '\u0159': 'r', '\u0211': 'r', '\u0213': 'r', '\u1E5B': 'r', '\u1E5D': 'r', '\u0157': 'r', '\u1E5F': 'r', '\u024D': 'r', '\u027D': 'r', '\uA75B': 'r', '\uA7A7': 'r', '\uA783': 'r', '\u24E2': 's', '\uFF53': 's', '\u00DF': 's', '\u015B': 's', '\u1E65': 's', '\u015D': 's', '\u1E61': 's', '\u0161': 's', '\u1E67': 's', '\u1E63': 's', '\u1E69': 's', '\u0219': 's', '\u015F': 's', '\u023F': 's', '\uA7A9': 's', '\uA785': 's', '\u1E9B': 's', '\u24E3': 't', '\uFF54': 't', '\u1E6B': 't', '\u1E97': 't', '\u0165': 't', '\u1E6D': 't', '\u021B': 't', '\u0163': 't', '\u1E71': 't', '\u1E6F': 't', '\u0167': 't', '\u01AD': 't', '\u0288': 't', '\u2C66': 't', '\uA787': 't', '\uA729': 'tz', '\u24E4': 'u', '\uFF55': 'u', '\u00F9': 'u', '\u00FA': 'u', '\u00FB': 'u', '\u0169': 'u', '\u1E79': 'u', '\u016B': 'u', '\u1E7B': 'u', '\u016D': 'u', '\u00FC': 'u', '\u01DC': 'u', '\u01D8': 'u', '\u01D6': 'u', '\u01DA': 'u', '\u1EE7': 'u', '\u016F': 'u', '\u0171': 'u', '\u01D4': 'u', '\u0215': 'u', '\u0217': 'u', '\u01B0': 'u', '\u1EEB': 'u', '\u1EE9': 'u', '\u1EEF': 'u', '\u1EED': 'u', '\u1EF1': 'u', '\u1EE5': 'u', '\u1E73': 'u', '\u0173': 'u', '\u1E77': 'u', '\u1E75': 'u', '\u0289': 'u', '\u24E5': 'v', '\uFF56': 'v', '\u1E7D': 'v', '\u1E7F': 'v', '\u028B': 'v', '\uA75F': 'v', '\u028C': 'v', '\uA761': 'vy', '\u24E6': 'w', '\uFF57': 'w', '\u1E81': 'w', '\u1E83': 'w', '\u0175': 'w', '\u1E87': 'w', '\u1E85': 'w', '\u1E98': 'w', '\u1E89': 'w', '\u2C73': 'w', '\u24E7': 'x', '\uFF58': 'x', '\u1E8B': 'x', '\u1E8D': 'x', '\u24E8': 'y', '\uFF59': 'y', '\u1EF3': 'y', '\u00FD': 'y', '\u0177': 'y', '\u1EF9': 'y', '\u0233': 'y', '\u1E8F': 'y', '\u00FF': 'y', '\u1EF7': 'y', '\u1E99': 'y', '\u1EF5': 'y', '\u01B4': 'y', '\u024F': 'y', '\u1EFF': 'y', '\u24E9': 'z', '\uFF5A': 'z', '\u017A': 'z', '\u1E91': 'z', '\u017C': 'z', '\u017E': 'z', '\u1E93': 'z', '\u1E95': 'z', '\u01B6': 'z', '\u0225': 'z', '\u0240': 'z', '\u2C6C': 'z', '\uA763': 'z', '\u0386': '\u0391', '\u0388': '\u0395', '\u0389': '\u0397', '\u038A': '\u0399', '\u03AA': '\u0399', '\u038C': '\u039F', '\u038E': '\u03A5', '\u03AB': '\u03A5', '\u038F': '\u03A9', '\u03AC': '\u03B1', '\u03AD': '\u03B5', '\u03AE': '\u03B7', '\u03AF': '\u03B9', '\u03CA': '\u03B9', '\u0390': '\u03B9', '\u03CC': '\u03BF', '\u03CD': '\u03C5', '\u03CB': '\u03C5', '\u03B0': '\u03C5', '\u03CE': '\u03C9', '\u03C2': '\u03C3', '\u2019': '\'' }; return diacritics; }); S2.define('select2/data/base',[ '../utils' ], function (Utils) { function BaseAdapter ($element, options) { BaseAdapter.__super__.constructor.call(this); } Utils.Extend(BaseAdapter, Utils.Observable); BaseAdapter.prototype.current = function (callback) { throw new Error('The `current` method must be defined in child classes.'); }; BaseAdapter.prototype.query = function (params, callback) { throw new Error('The `query` method must be defined in child classes.'); }; BaseAdapter.prototype.bind = function (container, $container) { // Can be implemented in subclasses }; BaseAdapter.prototype.destroy = function () { // Can be implemented in subclasses }; BaseAdapter.prototype.generateResultId = function (container, data) { var id = container.id + '-result-'; id += Utils.generateChars(4); if (data.id != null) { id += '-' + data.id.toString(); } else { id += '-' + Utils.generateChars(4); } return id; }; return BaseAdapter; }); S2.define('select2/data/select',[ './base', '../utils', 'jquery' ], function (BaseAdapter, Utils, $) { function SelectAdapter ($element, options) { this.$element = $element; this.options = options; SelectAdapter.__super__.constructor.call(this); } Utils.Extend(SelectAdapter, BaseAdapter); SelectAdapter.prototype.current = function (callback) { var self = this; var data = Array.prototype.map.call( this.$element[0].querySelectorAll(':checked'), function (selectedElement) { return self.item($(selectedElement)); } ); callback(data); }; SelectAdapter.prototype.select = function (data) { var self = this; data.selected = true; // If data.element is a DOM node, use it instead if ( data.element != null && data.element.tagName.toLowerCase() === 'option' ) { data.element.selected = true; this.$element.trigger('input').trigger('change'); return; } if (this.$element.prop('multiple')) { this.current(function (currentData) { var val = []; data = [data]; data.push.apply(data, currentData); for (var d = 0; d < data.length; d++) { var id = data[d].id; if (val.indexOf(id) === -1) { val.push(id); } } self.$element.val(val); self.$element.trigger('input').trigger('change'); }); } else { var val = data.id; this.$element.val(val); this.$element.trigger('input').trigger('change'); } }; SelectAdapter.prototype.unselect = function (data) { var self = this; if (!this.$element.prop('multiple')) { return; } data.selected = false; if ( data.element != null && data.element.tagName.toLowerCase() === 'option' ) { data.element.selected = false; this.$element.trigger('input').trigger('change'); return; } this.current(function (currentData) { var val = []; for (var d = 0; d < currentData.length; d++) { var id = currentData[d].id; if (id !== data.id && val.indexOf(id) === -1) { val.push(id); } } self.$element.val(val); self.$element.trigger('input').trigger('change'); }); }; SelectAdapter.prototype.bind = function (container, $container) { var self = this; this.container = container; container.on('select', function (params) { self.select(params.data); }); container.on('unselect', function (params) { self.unselect(params.data); }); }; SelectAdapter.prototype.destroy = function () { // Remove anything added to child elements this.$element.find('*').each(function () { // Remove any custom data set by Select2 Utils.RemoveData(this); }); }; SelectAdapter.prototype.query = function (params, callback) { var data = []; var self = this; var $options = this.$element.children(); $options.each(function () { if ( this.tagName.toLowerCase() !== 'option' && this.tagName.toLowerCase() !== 'optgroup' ) { return; } var $option = $(this); var option = self.item($option); var matches = self.matches(params, option); if (matches !== null) { data.push(matches); } }); callback({ results: data }); }; SelectAdapter.prototype.addOptions = function ($options) { this.$element.append($options); }; SelectAdapter.prototype.option = function (data) { var option; if (data.children) { option = document.createElement('optgroup'); option.label = data.text; } else { option = document.createElement('option'); if (option.textContent !== undefined) { option.textContent = data.text; } else { option.innerText = data.text; } } if (data.id !== undefined) { option.value = data.id; } if (data.disabled) { option.disabled = true; } if (data.selected) { option.selected = true; } if (data.title) { option.title = data.title; } var normalizedData = this._normalizeItem(data); normalizedData.element = option; // Override the option's data with the combined data Utils.StoreData(option, 'data', normalizedData); return $(option); }; SelectAdapter.prototype.item = function ($option) { var data = {}; data = Utils.GetData($option[0], 'data'); if (data != null) { return data; } var option = $option[0]; if (option.tagName.toLowerCase() === 'option') { data = { id: $option.val(), text: $option.text(), disabled: $option.prop('disabled'), selected: $option.prop('selected'), title: $option.prop('title') }; } else if (option.tagName.toLowerCase() === 'optgroup') { data = { text: $option.prop('label'), children: [], title: $option.prop('title') }; var $children = $option.children('option'); var children = []; for (var c = 0; c < $children.length; c++) { var $child = $($children[c]); var child = this.item($child); children.push(child); } data.children = children; } data = this._normalizeItem(data); data.element = $option[0]; Utils.StoreData($option[0], 'data', data); return data; }; SelectAdapter.prototype._normalizeItem = function (item) { if (item !== Object(item)) { item = { id: item, text: item }; } item = $.extend({}, { text: '' }, item); var defaults = { selected: false, disabled: false }; if (item.id != null) { item.id = item.id.toString(); } if (item.text != null) { item.text = item.text.toString(); } if (item._resultId == null && item.id && this.container != null) { item._resultId = this.generateResultId(this.container, item); } return $.extend({}, defaults, item); }; SelectAdapter.prototype.matches = function (params, data) { var matcher = this.options.get('matcher'); return matcher(params, data); }; return SelectAdapter; }); S2.define('select2/data/array',[ './select', '../utils', 'jquery' ], function (SelectAdapter, Utils, $) { function ArrayAdapter ($element, options) { this._dataToConvert = options.get('data') || []; ArrayAdapter.__super__.constructor.call(this, $element, options); } Utils.Extend(ArrayAdapter, SelectAdapter); ArrayAdapter.prototype.bind = function (container, $container) { ArrayAdapter.__super__.bind.call(this, container, $container); this.addOptions(this.convertToOptions(this._dataToConvert)); }; ArrayAdapter.prototype.select = function (data) { var $option = this.$element.find('option').filter(function (i, elm) { return elm.value == data.id.toString(); }); if ($option.length === 0) { $option = this.option(data); this.addOptions($option); } ArrayAdapter.__super__.select.call(this, data); }; ArrayAdapter.prototype.convertToOptions = function (data) { var self = this; var $existing = this.$element.find('option'); var existingIds = $existing.map(function () { return self.item($(this)).id; }).get(); var $options = []; // Filter out all items except for the one passed in the argument function onlyItem (item) { return function () { return $(this).val() == item.id; }; } for (var d = 0; d < data.length; d++) { var item = this._normalizeItem(data[d]); // Skip items which were pre-loaded, only merge the data if (existingIds.indexOf(item.id) >= 0) { var $existingOption = $existing.filter(onlyItem(item)); var existingData = this.item($existingOption); var newData = $.extend(true, {}, item, existingData); var $newOption = this.option(newData); $existingOption.replaceWith($newOption); continue; } var $option = this.option(item); if (item.children) { var $children = this.convertToOptions(item.children); $option.append($children); } $options.push($option); } return $options; }; return ArrayAdapter; }); S2.define('select2/data/ajax',[ './array', '../utils', 'jquery' ], function (ArrayAdapter, Utils, $) { function AjaxAdapter ($element, options) { this.ajaxOptions = this._applyDefaults(options.get('ajax')); if (this.ajaxOptions.processResults != null) { this.processResults = this.ajaxOptions.processResults; } AjaxAdapter.__super__.constructor.call(this, $element, options); } Utils.Extend(AjaxAdapter, ArrayAdapter); AjaxAdapter.prototype._applyDefaults = function (options) { var defaults = { data: function (params) { return $.extend({}, params, { q: params.term }); }, transport: function (params, success, failure) { var $request = $.ajax(params); $request.then(success); $request.fail(failure); return $request; } }; return $.extend({}, defaults, options, true); }; AjaxAdapter.prototype.processResults = function (results) { return results; }; AjaxAdapter.prototype.query = function (params, callback) { var matches = []; var self = this; if (this._request != null) { // JSONP requests cannot always be aborted if (typeof this._request.abort === 'function') { this._request.abort(); } this._request = null; } var options = $.extend({ type: 'GET' }, this.ajaxOptions); if (typeof options.url === 'function') { options.url = options.url.call(this.$element, params); } if (typeof options.data === 'function') { options.data = options.data.call(this.$element, params); } function request () { var $request = options.transport(options, function (data) { var results = self.processResults(data, params); if (self.options.get('debug') && window.console && console.error) { // Check to make sure that the response included a `results` key. if (!results || !results.results || !Array.isArray(results.results)) { console.error( 'Select2: The AJAX results did not return an array in the ' + '`results` key of the response.' ); } } callback(results); }, function () { // Attempt to detect if a request was aborted // Only works if the transport exposes a status property if ('status' in $request && ($request.status === 0 || $request.status === '0')) { return; } self.trigger('results:message', { message: 'errorLoading' }); }); self._request = $request; } if (this.ajaxOptions.delay && params.term != null) { if (this._queryTimeout) { window.clearTimeout(this._queryTimeout); } this._queryTimeout = window.setTimeout(request, this.ajaxOptions.delay); } else { request(); } }; return AjaxAdapter; }); S2.define('select2/data/tags',[ 'jquery' ], function ($) { function Tags (decorated, $element, options) { var tags = options.get('tags'); var createTag = options.get('createTag'); if (createTag !== undefined) { this.createTag = createTag; } var insertTag = options.get('insertTag'); if (insertTag !== undefined) { this.insertTag = insertTag; } decorated.call(this, $element, options); if (Array.isArray(tags)) { for (var t = 0; t < tags.length; t++) { var tag = tags[t]; var item = this._normalizeItem(tag); var $option = this.option(item); this.$element.append($option); } } } Tags.prototype.query = function (decorated, params, callback) { var self = this; this._removeOldTags(); if (params.term == null || params.page != null) { decorated.call(this, params, callback); return; } function wrapper (obj, child) { var data = obj.results; for (var i = 0; i < data.length; i++) { var option = data[i]; var checkChildren = ( option.children != null && !wrapper({ results: option.children }, true) ); var optionText = (option.text || '').toUpperCase(); var paramsTerm = (params.term || '').toUpperCase(); var checkText = optionText === paramsTerm; if (checkText || checkChildren) { if (child) { return false; } obj.data = data; callback(obj); return; } } if (child) { return true; } var tag = self.createTag(params); if (tag != null) { var $option = self.option(tag); $option.attr('data-select2-tag', 'true'); self.addOptions([$option]); self.insertTag(data, tag); } obj.results = data; callback(obj); } decorated.call(this, params, wrapper); }; Tags.prototype.createTag = function (decorated, params) { if (params.term == null) { return null; } var term = params.term.trim(); if (term === '') { return null; } return { id: term, text: term }; }; Tags.prototype.insertTag = function (_, data, tag) { data.unshift(tag); }; Tags.prototype._removeOldTags = function (_) { var $options = this.$element.find('option[data-select2-tag]'); $options.each(function () { if (this.selected) { return; } $(this).remove(); }); }; return Tags; }); S2.define('select2/data/tokenizer',[ 'jquery' ], function ($) { function Tokenizer (decorated, $element, options) { var tokenizer = options.get('tokenizer'); if (tokenizer !== undefined) { this.tokenizer = tokenizer; } decorated.call(this, $element, options); } Tokenizer.prototype.bind = function (decorated, container, $container) { decorated.call(this, container, $container); this.$search = container.dropdown.$search || container.selection.$search || $container.find('.select2-search__field'); }; Tokenizer.prototype.query = function (decorated, params, callback) { var self = this; function createAndSelect (data) { // Normalize the data object so we can use it for checks var item = self._normalizeItem(data); // Check if the data object already exists as a tag // Select it if it doesn't var $existingOptions = self.$element.find('option').filter(function () { return $(this).val() === item.id; }); // If an existing option wasn't found for it, create the option if (!$existingOptions.length) { var $option = self.option(item); $option.attr('data-select2-tag', true); self._removeOldTags(); self.addOptions([$option]); } // Select the item, now that we know there is an option for it select(item); } function select (data) { self.trigger('select', { data: data }); } params.term = params.term || ''; var tokenData = this.tokenizer(params, this.options, createAndSelect); if (tokenData.term !== params.term) { // Replace the search term if we have the search box if (this.$search.length) { this.$search.val(tokenData.term); this.$search.trigger('focus'); } params.term = tokenData.term; } decorated.call(this, params, callback); }; Tokenizer.prototype.tokenizer = function (_, params, options, callback) { var separators = options.get('tokenSeparators') || []; var term = params.term; var i = 0; var createTag = this.createTag || function (params) { return { id: params.term, text: params.term }; }; while (i < term.length) { var termChar = term[i]; if (separators.indexOf(termChar) === -1) { i++; continue; } var part = term.substr(0, i); var partParams = $.extend({}, params, { term: part }); var data = createTag(partParams); if (data == null) { i++; continue; } callback(data); // Reset the term to not include the tokenized portion term = term.substr(i + 1) || ''; i = 0; } return { term: term }; }; return Tokenizer; }); S2.define('select2/data/minimumInputLength',[ ], function () { function MinimumInputLength (decorated, $e, options) { this.minimumInputLength = options.get('minimumInputLength'); decorated.call(this, $e, options); } MinimumInputLength.prototype.query = function (decorated, params, callback) { params.term = params.term || ''; if (params.term.length < this.minimumInputLength) { this.trigger('results:message', { message: 'inputTooShort', args: { minimum: this.minimumInputLength, input: params.term, params: params } }); return; } decorated.call(this, params, callback); }; return MinimumInputLength; }); S2.define('select2/data/maximumInputLength',[ ], function () { function MaximumInputLength (decorated, $e, options) { this.maximumInputLength = options.get('maximumInputLength'); decorated.call(this, $e, options); } MaximumInputLength.prototype.query = function (decorated, params, callback) { params.term = params.term || ''; if (this.maximumInputLength > 0 && params.term.length > this.maximumInputLength) { this.trigger('results:message', { message: 'inputTooLong', args: { maximum: this.maximumInputLength, input: params.term, params: params } }); return; } decorated.call(this, params, callback); }; return MaximumInputLength; }); S2.define('select2/data/maximumSelectionLength',[ ], function (){ function MaximumSelectionLength (decorated, $e, options) { this.maximumSelectionLength = options.get('maximumSelectionLength'); decorated.call(this, $e, options); } MaximumSelectionLength.prototype.bind = function (decorated, container, $container) { var self = this; decorated.call(this, container, $container); container.on('select', function () { self._checkIfMaximumSelected(); }); }; MaximumSelectionLength.prototype.query = function (decorated, params, callback) { var self = this; this._checkIfMaximumSelected(function () { decorated.call(self, params, callback); }); }; MaximumSelectionLength.prototype._checkIfMaximumSelected = function (_, successCallback) { var self = this; this.current(function (currentData) { var count = currentData != null ? currentData.length : 0; if (self.maximumSelectionLength > 0 && count >= self.maximumSelectionLength) { self.trigger('results:message', { message: 'maximumSelected', args: { maximum: self.maximumSelectionLength } }); return; } if (successCallback) { successCallback(); } }); }; return MaximumSelectionLength; }); S2.define('select2/dropdown',[ 'jquery', './utils' ], function ($, Utils) { function Dropdown ($element, options) { this.$element = $element; this.options = options; Dropdown.__super__.constructor.call(this); } Utils.Extend(Dropdown, Utils.Observable); Dropdown.prototype.render = function () { var $dropdown = $( '' + '' + '' ); $dropdown.attr('dir', this.options.get('dir')); this.$dropdown = $dropdown; return $dropdown; }; Dropdown.prototype.bind = function () { // Should be implemented in subclasses }; Dropdown.prototype.position = function ($dropdown, $container) { // Should be implemented in subclasses }; Dropdown.prototype.destroy = function () { // Remove the dropdown from the DOM this.$dropdown.remove(); }; return Dropdown; }); S2.define('select2/dropdown/search',[ 'jquery' ], function ($) { function Search () { } Search.prototype.render = function (decorated) { var $rendered = decorated.call(this); var searchLabel = this.options.get('translations').get('search'); var $search = $( '' + '' + '' ); this.$searchContainer = $search; this.$search = $search.find('input'); this.$search.prop('autocomplete', this.options.get('autocomplete')); this.$search.attr('aria-label', searchLabel()); $rendered.prepend($search); return $rendered; }; Search.prototype.bind = function (decorated, container, $container) { var self = this; var resultsId = container.id + '-results'; decorated.call(this, container, $container); this.$search.on('keydown', function (evt) { self.trigger('keypress', evt); self._keyUpPrevented = evt.isDefaultPrevented(); }); // Workaround for browsers which do not support the `input` event // This will prevent double-triggering of events for browsers which support // both the `keyup` and `input` events. this.$search.on('input', function (evt) { // Unbind the duplicated `keyup` event $(this).off('keyup'); }); this.$search.on('keyup input', function (evt) { self.handleSearch(evt); }); container.on('open', function () { self.$search.attr('tabindex', 0); self.$search.attr('aria-controls', resultsId); self.$search.trigger('focus'); window.setTimeout(function () { self.$search.trigger('focus'); }, 0); }); container.on('close', function () { self.$search.attr('tabindex', -1); self.$search.removeAttr('aria-controls'); self.$search.removeAttr('aria-activedescendant'); self.$search.val(''); self.$search.trigger('blur'); }); container.on('focus', function () { if (!container.isOpen()) { self.$search.trigger('focus'); } }); container.on('results:all', function (params) { if (params.query.term == null || params.query.term === '') { var showSearch = self.showSearch(params); if (showSearch) { self.$searchContainer[0].classList.remove('select2-search--hide'); } else { self.$searchContainer[0].classList.add('select2-search--hide'); } } }); container.on('results:focus', function (params) { if (params.data._resultId) { self.$search.attr('aria-activedescendant', params.data._resultId); } else { self.$search.removeAttr('aria-activedescendant'); } }); }; Search.prototype.handleSearch = function (evt) { if (!this._keyUpPrevented) { var input = this.$search.val(); this.trigger('query', { term: input }); } this._keyUpPrevented = false; }; Search.prototype.showSearch = function (_, params) { return true; }; return Search; }); S2.define('select2/dropdown/hidePlaceholder',[ ], function () { function HidePlaceholder (decorated, $element, options, dataAdapter) { this.placeholder = this.normalizePlaceholder(options.get('placeholder')); decorated.call(this, $element, options, dataAdapter); } HidePlaceholder.prototype.append = function (decorated, data) { data.results = this.removePlaceholder(data.results); decorated.call(this, data); }; HidePlaceholder.prototype.normalizePlaceholder = function (_, placeholder) { if (typeof placeholder === 'string') { placeholder = { id: '', text: placeholder }; } return placeholder; }; HidePlaceholder.prototype.removePlaceholder = function (_, data) { var modifiedData = data.slice(0); for (var d = data.length - 1; d >= 0; d--) { var item = data[d]; if (this.placeholder.id === item.id) { modifiedData.splice(d, 1); } } return modifiedData; }; return HidePlaceholder; }); S2.define('select2/dropdown/infiniteScroll',[ 'jquery' ], function ($) { function InfiniteScroll (decorated, $element, options, dataAdapter) { this.lastParams = {}; decorated.call(this, $element, options, dataAdapter); this.$loadingMore = this.createLoadingMore(); this.loading = false; } InfiniteScroll.prototype.append = function (decorated, data) { this.$loadingMore.remove(); this.loading = false; decorated.call(this, data); if (this.showLoadingMore(data)) { this.$results.append(this.$loadingMore); this.loadMoreIfNeeded(); } }; InfiniteScroll.prototype.bind = function (decorated, container, $container) { var self = this; decorated.call(this, container, $container); container.on('query', function (params) { self.lastParams = params; self.loading = true; }); container.on('query:append', function (params) { self.lastParams = params; self.loading = true; }); this.$results.on('scroll', this.loadMoreIfNeeded.bind(this)); }; InfiniteScroll.prototype.loadMoreIfNeeded = function () { var isLoadMoreVisible = $.contains( document.documentElement, this.$loadingMore[0] ); if (this.loading || !isLoadMoreVisible) { return; } var currentOffset = this.$results.offset().top + this.$results.outerHeight(false); var loadingMoreOffset = this.$loadingMore.offset().top + this.$loadingMore.outerHeight(false); if (currentOffset + 50 >= loadingMoreOffset) { this.loadMore(); } }; InfiniteScroll.prototype.loadMore = function () { this.loading = true; var params = $.extend({}, {page: 1}, this.lastParams); params.page++; this.trigger('query:append', params); }; InfiniteScroll.prototype.showLoadingMore = function (_, data) { return data.pagination && data.pagination.more; }; InfiniteScroll.prototype.createLoadingMore = function () { var $option = $( '
          • ' ); var message = this.options.get('translations').get('loadingMore'); $option.html(message(this.lastParams)); return $option; }; return InfiniteScroll; }); S2.define('select2/dropdown/attachBody',[ 'jquery', '../utils' ], function ($, Utils) { function AttachBody (decorated, $element, options) { this.$dropdownParent = $(options.get('dropdownParent') || document.body); decorated.call(this, $element, options); } AttachBody.prototype.bind = function (decorated, container, $container) { var self = this; decorated.call(this, container, $container); container.on('open', function () { self._showDropdown(); self._attachPositioningHandler(container); // Must bind after the results handlers to ensure correct sizing self._bindContainerResultHandlers(container); }); container.on('close', function () { self._hideDropdown(); self._detachPositioningHandler(container); }); this.$dropdownContainer.on('mousedown', function (evt) { evt.stopPropagation(); }); }; AttachBody.prototype.destroy = function (decorated) { decorated.call(this); this.$dropdownContainer.remove(); }; AttachBody.prototype.position = function (decorated, $dropdown, $container) { // Clone all of the container classes $dropdown.attr('class', $container.attr('class')); $dropdown[0].classList.remove('select2'); $dropdown[0].classList.add('select2-container--open'); $dropdown.css({ position: 'absolute', top: -999999 }); this.$container = $container; }; AttachBody.prototype.render = function (decorated) { var $container = $(''); var $dropdown = decorated.call(this); $container.append($dropdown); this.$dropdownContainer = $container; return $container; }; AttachBody.prototype._hideDropdown = function (decorated) { this.$dropdownContainer.detach(); }; AttachBody.prototype._bindContainerResultHandlers = function (decorated, container) { // These should only be bound once if (this._containerResultsHandlersBound) { return; } var self = this; container.on('results:all', function () { self._positionDropdown(); self._resizeDropdown(); }); container.on('results:append', function () { self._positionDropdown(); self._resizeDropdown(); }); container.on('results:message', function () { self._positionDropdown(); self._resizeDropdown(); }); container.on('select', function () { self._positionDropdown(); self._resizeDropdown(); }); container.on('unselect', function () { self._positionDropdown(); self._resizeDropdown(); }); this._containerResultsHandlersBound = true; }; AttachBody.prototype._attachPositioningHandler = function (decorated, container) { var self = this; var scrollEvent = 'scroll.select2.' + container.id; var resizeEvent = 'resize.select2.' + container.id; var orientationEvent = 'orientationchange.select2.' + container.id; var $watchers = this.$container.parents().filter(Utils.hasScroll); $watchers.each(function () { Utils.StoreData(this, 'select2-scroll-position', { x: $(this).scrollLeft(), y: $(this).scrollTop() }); }); $watchers.on(scrollEvent, function (ev) { var position = Utils.GetData(this, 'select2-scroll-position'); $(this).scrollTop(position.y); }); $(window).on(scrollEvent + ' ' + resizeEvent + ' ' + orientationEvent, function (e) { self._positionDropdown(); self._resizeDropdown(); }); }; AttachBody.prototype._detachPositioningHandler = function (decorated, container) { var scrollEvent = 'scroll.select2.' + container.id; var resizeEvent = 'resize.select2.' + container.id; var orientationEvent = 'orientationchange.select2.' + container.id; var $watchers = this.$container.parents().filter(Utils.hasScroll); $watchers.off(scrollEvent); $(window).off(scrollEvent + ' ' + resizeEvent + ' ' + orientationEvent); }; AttachBody.prototype._positionDropdown = function () { var $window = $(window); var isCurrentlyAbove = this.$dropdown[0].classList .contains('select2-dropdown--above'); var isCurrentlyBelow = this.$dropdown[0].classList .contains('select2-dropdown--below'); var newDirection = null; var offset = this.$container.offset(); offset.bottom = offset.top + this.$container.outerHeight(false); var container = { height: this.$container.outerHeight(false) }; container.top = offset.top; container.bottom = offset.top + container.height; var dropdown = { height: this.$dropdown.outerHeight(false) }; var viewport = { top: $window.scrollTop(), bottom: $window.scrollTop() + $window.height() }; var enoughRoomAbove = viewport.top < (offset.top - dropdown.height); var enoughRoomBelow = viewport.bottom > (offset.bottom + dropdown.height); var css = { left: offset.left, top: container.bottom }; // Determine what the parent element is to use for calculating the offset var $offsetParent = this.$dropdownParent; // For statically positioned elements, we need to get the element // that is determining the offset if ($offsetParent.css('position') === 'static') { $offsetParent = $offsetParent.offsetParent(); } var parentOffset = { top: 0, left: 0 }; if ( $.contains(document.body, $offsetParent[0]) || $offsetParent[0].isConnected ) { parentOffset = $offsetParent.offset(); } css.top -= parentOffset.top; css.left -= parentOffset.left; if (!isCurrentlyAbove && !isCurrentlyBelow) { newDirection = 'below'; } if (!enoughRoomBelow && enoughRoomAbove && !isCurrentlyAbove) { newDirection = 'above'; } else if (!enoughRoomAbove && enoughRoomBelow && isCurrentlyAbove) { newDirection = 'below'; } if (newDirection == 'above' || (isCurrentlyAbove && newDirection !== 'below')) { css.top = container.top - parentOffset.top - dropdown.height; } if (newDirection != null) { this.$dropdown[0].classList.remove('select2-dropdown--below'); this.$dropdown[0].classList.remove('select2-dropdown--above'); this.$dropdown[0].classList.add('select2-dropdown--' + newDirection); this.$container[0].classList.remove('select2-container--below'); this.$container[0].classList.remove('select2-container--above'); this.$container[0].classList.add('select2-container--' + newDirection); } this.$dropdownContainer.css(css); }; AttachBody.prototype._resizeDropdown = function () { var css = { width: this.$container.outerWidth(false) + 'px' }; if (this.options.get('dropdownAutoWidth')) { css.minWidth = css.width; css.position = 'relative'; css.width = 'auto'; } this.$dropdown.css(css); }; AttachBody.prototype._showDropdown = function (decorated) { this.$dropdownContainer.appendTo(this.$dropdownParent); this._positionDropdown(); this._resizeDropdown(); }; return AttachBody; }); S2.define('select2/dropdown/minimumResultsForSearch',[ ], function () { function countResults (data) { var count = 0; for (var d = 0; d < data.length; d++) { var item = data[d]; if (item.children) { count += countResults(item.children); } else { count++; } } return count; } function MinimumResultsForSearch (decorated, $element, options, dataAdapter) { this.minimumResultsForSearch = options.get('minimumResultsForSearch'); if (this.minimumResultsForSearch < 0) { this.minimumResultsForSearch = Infinity; } decorated.call(this, $element, options, dataAdapter); } MinimumResultsForSearch.prototype.showSearch = function (decorated, params) { if (countResults(params.data.results) < this.minimumResultsForSearch) { return false; } return decorated.call(this, params); }; return MinimumResultsForSearch; }); S2.define('select2/dropdown/selectOnClose',[ '../utils' ], function (Utils) { function SelectOnClose () { } SelectOnClose.prototype.bind = function (decorated, container, $container) { var self = this; decorated.call(this, container, $container); container.on('close', function (params) { self._handleSelectOnClose(params); }); }; SelectOnClose.prototype._handleSelectOnClose = function (_, params) { if (params && params.originalSelect2Event != null) { var event = params.originalSelect2Event; // Don't select an item if the close event was triggered from a select or // unselect event if (event._type === 'select' || event._type === 'unselect') { return; } } var $highlightedResults = this.getHighlightedResults(); // Only select highlighted results if ($highlightedResults.length < 1) { return; } var data = Utils.GetData($highlightedResults[0], 'data'); // Don't re-select already selected resulte if ( (data.element != null && data.element.selected) || (data.element == null && data.selected) ) { return; } this.trigger('select', { data: data }); }; return SelectOnClose; }); S2.define('select2/dropdown/closeOnSelect',[ ], function () { function CloseOnSelect () { } CloseOnSelect.prototype.bind = function (decorated, container, $container) { var self = this; decorated.call(this, container, $container); container.on('select', function (evt) { self._selectTriggered(evt); }); container.on('unselect', function (evt) { self._selectTriggered(evt); }); }; CloseOnSelect.prototype._selectTriggered = function (_, evt) { var originalEvent = evt.originalEvent; // Don't close if the control key is being held if (originalEvent && (originalEvent.ctrlKey || originalEvent.metaKey)) { return; } this.trigger('close', { originalEvent: originalEvent, originalSelect2Event: evt }); }; return CloseOnSelect; }); S2.define('select2/dropdown/dropdownCss',[ '../utils' ], function (Utils) { function DropdownCSS () { } DropdownCSS.prototype.render = function (decorated) { var $dropdown = decorated.call(this); var dropdownCssClass = this.options.get('dropdownCssClass') || ''; if (dropdownCssClass.indexOf(':all:') !== -1) { dropdownCssClass = dropdownCssClass.replace(':all:', ''); Utils.copyNonInternalCssClasses($dropdown[0], this.$element[0]); } $dropdown.addClass(dropdownCssClass); return $dropdown; }; return DropdownCSS; }); S2.define('select2/dropdown/tagsSearchHighlight',[ '../utils' ], function (Utils) { function TagsSearchHighlight () { } TagsSearchHighlight.prototype.highlightFirstItem = function (decorated) { var $options = this.$results .find( '.select2-results__option--selectable' + ':not(.select2-results__option--selected)' ); if ($options.length > 0) { var $firstOption = $options.first(); var data = Utils.GetData($firstOption[0], 'data'); var firstElement = data.element; if (firstElement && firstElement.getAttribute) { if (firstElement.getAttribute('data-select2-tag') === 'true') { $firstOption.trigger('mouseenter'); return; } } } decorated.call(this); }; return TagsSearchHighlight; }); S2.define('select2/i18n/en',[],function () { // English return { errorLoading: function () { return 'The results could not be loaded.'; }, inputTooLong: function (args) { var overChars = args.input.length - args.maximum; var message = 'Please delete ' + overChars + ' character'; if (overChars != 1) { message += 's'; } return message; }, inputTooShort: function (args) { var remainingChars = args.minimum - args.input.length; var message = 'Please enter ' + remainingChars + ' or more characters'; return message; }, loadingMore: function () { return 'Loading more results…'; }, maximumSelected: function (args) { var message = 'You can only select ' + args.maximum + ' item'; if (args.maximum != 1) { message += 's'; } return message; }, noResults: function () { return 'No results found'; }, searching: function () { return 'Searching…'; }, removeAllItems: function () { return 'Remove all items'; }, removeItem: function () { return 'Remove item'; }, search: function() { return 'Search'; } }; }); S2.define('select2/defaults',[ 'jquery', './results', './selection/single', './selection/multiple', './selection/placeholder', './selection/allowClear', './selection/search', './selection/selectionCss', './selection/eventRelay', './utils', './translation', './diacritics', './data/select', './data/array', './data/ajax', './data/tags', './data/tokenizer', './data/minimumInputLength', './data/maximumInputLength', './data/maximumSelectionLength', './dropdown', './dropdown/search', './dropdown/hidePlaceholder', './dropdown/infiniteScroll', './dropdown/attachBody', './dropdown/minimumResultsForSearch', './dropdown/selectOnClose', './dropdown/closeOnSelect', './dropdown/dropdownCss', './dropdown/tagsSearchHighlight', './i18n/en' ], function ($, ResultsList, SingleSelection, MultipleSelection, Placeholder, AllowClear, SelectionSearch, SelectionCSS, EventRelay, Utils, Translation, DIACRITICS, SelectData, ArrayData, AjaxData, Tags, Tokenizer, MinimumInputLength, MaximumInputLength, MaximumSelectionLength, Dropdown, DropdownSearch, HidePlaceholder, InfiniteScroll, AttachBody, MinimumResultsForSearch, SelectOnClose, CloseOnSelect, DropdownCSS, TagsSearchHighlight, EnglishTranslation) { function Defaults () { this.reset(); } Defaults.prototype.apply = function (options) { options = $.extend(true, {}, this.defaults, options); if (options.dataAdapter == null) { if (options.ajax != null) { options.dataAdapter = AjaxData; } else if (options.data != null) { options.dataAdapter = ArrayData; } else { options.dataAdapter = SelectData; } if (options.minimumInputLength > 0) { options.dataAdapter = Utils.Decorate( options.dataAdapter, MinimumInputLength ); } if (options.maximumInputLength > 0) { options.dataAdapter = Utils.Decorate( options.dataAdapter, MaximumInputLength ); } if (options.maximumSelectionLength > 0) { options.dataAdapter = Utils.Decorate( options.dataAdapter, MaximumSelectionLength ); } if (options.tags) { options.dataAdapter = Utils.Decorate(options.dataAdapter, Tags); } if (options.tokenSeparators != null || options.tokenizer != null) { options.dataAdapter = Utils.Decorate( options.dataAdapter, Tokenizer ); } } if (options.resultsAdapter == null) { options.resultsAdapter = ResultsList; if (options.ajax != null) { options.resultsAdapter = Utils.Decorate( options.resultsAdapter, InfiniteScroll ); } if (options.placeholder != null) { options.resultsAdapter = Utils.Decorate( options.resultsAdapter, HidePlaceholder ); } if (options.selectOnClose) { options.resultsAdapter = Utils.Decorate( options.resultsAdapter, SelectOnClose ); } if (options.tags) { options.resultsAdapter = Utils.Decorate( options.resultsAdapter, TagsSearchHighlight ); } } if (options.dropdownAdapter == null) { if (options.multiple) { options.dropdownAdapter = Dropdown; } else { var SearchableDropdown = Utils.Decorate(Dropdown, DropdownSearch); options.dropdownAdapter = SearchableDropdown; } if (options.minimumResultsForSearch !== 0) { options.dropdownAdapter = Utils.Decorate( options.dropdownAdapter, MinimumResultsForSearch ); } if (options.closeOnSelect) { options.dropdownAdapter = Utils.Decorate( options.dropdownAdapter, CloseOnSelect ); } if (options.dropdownCssClass != null) { options.dropdownAdapter = Utils.Decorate( options.dropdownAdapter, DropdownCSS ); } options.dropdownAdapter = Utils.Decorate( options.dropdownAdapter, AttachBody ); } if (options.selectionAdapter == null) { if (options.multiple) { options.selectionAdapter = MultipleSelection; } else { options.selectionAdapter = SingleSelection; } // Add the placeholder mixin if a placeholder was specified if (options.placeholder != null) { options.selectionAdapter = Utils.Decorate( options.selectionAdapter, Placeholder ); } if (options.allowClear) { options.selectionAdapter = Utils.Decorate( options.selectionAdapter, AllowClear ); } if (options.multiple) { options.selectionAdapter = Utils.Decorate( options.selectionAdapter, SelectionSearch ); } if (options.selectionCssClass != null) { options.selectionAdapter = Utils.Decorate( options.selectionAdapter, SelectionCSS ); } options.selectionAdapter = Utils.Decorate( options.selectionAdapter, EventRelay ); } // If the defaults were not previously applied from an element, it is // possible for the language option to have not been resolved options.language = this._resolveLanguage(options.language); // Always fall back to English since it will always be complete options.language.push('en'); var uniqueLanguages = []; for (var l = 0; l < options.language.length; l++) { var language = options.language[l]; if (uniqueLanguages.indexOf(language) === -1) { uniqueLanguages.push(language); } } options.language = uniqueLanguages; options.translations = this._processTranslations( options.language, options.debug ); return options; }; Defaults.prototype.reset = function () { function stripDiacritics (text) { // Used 'uni range + named function' from http://jsperf.com/diacritics/18 function match(a) { return DIACRITICS[a] || a; } return text.replace(/[^\u0000-\u007E]/g, match); } function matcher (params, data) { // Always return the object if there is nothing to compare if (params.term == null || params.term.trim() === '') { return data; } // Do a recursive check for options with children if (data.children && data.children.length > 0) { // Clone the data object if there are children // This is required as we modify the object to remove any non-matches var match = $.extend(true, {}, data); // Check each child of the option for (var c = data.children.length - 1; c >= 0; c--) { var child = data.children[c]; var matches = matcher(params, child); // If there wasn't a match, remove the object in the array if (matches == null) { match.children.splice(c, 1); } } // If any children matched, return the new object if (match.children.length > 0) { return match; } // If there were no matching children, check just the plain object return matcher(params, match); } var original = stripDiacritics(data.text).toUpperCase(); var term = stripDiacritics(params.term).toUpperCase(); // Check if the text contains the term if (original.indexOf(term) > -1) { return data; } // If it doesn't contain the term, don't return anything return null; } this.defaults = { amdLanguageBase: './i18n/', autocomplete: 'off', closeOnSelect: true, debug: false, dropdownAutoWidth: false, escapeMarkup: Utils.escapeMarkup, language: {}, matcher: matcher, minimumInputLength: 0, maximumInputLength: 0, maximumSelectionLength: 0, minimumResultsForSearch: 0, selectOnClose: false, scrollAfterSelect: false, sorter: function (data) { return data; }, templateResult: function (result) { return result.text; }, templateSelection: function (selection) { return selection.text; }, theme: 'default', width: 'resolve' }; }; Defaults.prototype.applyFromElement = function (options, $element) { var optionLanguage = options.language; var defaultLanguage = this.defaults.language; var elementLanguage = $element.prop('lang'); var parentLanguage = $element.closest('[lang]').prop('lang'); var languages = Array.prototype.concat.call( this._resolveLanguage(elementLanguage), this._resolveLanguage(optionLanguage), this._resolveLanguage(defaultLanguage), this._resolveLanguage(parentLanguage) ); options.language = languages; return options; }; Defaults.prototype._resolveLanguage = function (language) { if (!language) { return []; } if ($.isEmptyObject(language)) { return []; } if ($.isPlainObject(language)) { return [language]; } var languages; if (!Array.isArray(language)) { languages = [language]; } else { languages = language; } var resolvedLanguages = []; for (var l = 0; l < languages.length; l++) { resolvedLanguages.push(languages[l]); if (typeof languages[l] === 'string' && languages[l].indexOf('-') > 0) { // Extract the region information if it is included var languageParts = languages[l].split('-'); var baseLanguage = languageParts[0]; resolvedLanguages.push(baseLanguage); } } return resolvedLanguages; }; Defaults.prototype._processTranslations = function (languages, debug) { var translations = new Translation(); for (var l = 0; l < languages.length; l++) { var languageData = new Translation(); var language = languages[l]; if (typeof language === 'string') { try { // Try to load it with the original name languageData = Translation.loadPath(language); } catch (e) { try { // If we couldn't load it, check if it wasn't the full path language = this.defaults.amdLanguageBase + language; languageData = Translation.loadPath(language); } catch (ex) { // The translation could not be loaded at all. Sometimes this is // because of a configuration problem, other times this can be // because of how Select2 helps load all possible translation files if (debug && window.console && console.warn) { console.warn( 'Select2: The language file for "' + language + '" could ' + 'not be automatically loaded. A fallback will be used instead.' ); } } } } else if ($.isPlainObject(language)) { languageData = new Translation(language); } else { languageData = language; } translations.extend(languageData); } return translations; }; Defaults.prototype.set = function (key, value) { var camelKey = $.camelCase(key); var data = {}; data[camelKey] = value; var convertedData = Utils._convertData(data); $.extend(true, this.defaults, convertedData); }; var defaults = new Defaults(); return defaults; }); S2.define('select2/options',[ 'jquery', './defaults', './utils' ], function ($, Defaults, Utils) { function Options (options, $element) { this.options = options; if ($element != null) { this.fromElement($element); } if ($element != null) { this.options = Defaults.applyFromElement(this.options, $element); } this.options = Defaults.apply(this.options); } Options.prototype.fromElement = function ($e) { var excludedData = ['select2']; if (this.options.multiple == null) { this.options.multiple = $e.prop('multiple'); } if (this.options.disabled == null) { this.options.disabled = $e.prop('disabled'); } if (this.options.autocomplete == null && $e.prop('autocomplete')) { this.options.autocomplete = $e.prop('autocomplete'); } if (this.options.dir == null) { if ($e.prop('dir')) { this.options.dir = $e.prop('dir'); } else if ($e.closest('[dir]').prop('dir')) { this.options.dir = $e.closest('[dir]').prop('dir'); } else { this.options.dir = 'ltr'; } } $e.prop('disabled', this.options.disabled); $e.prop('multiple', this.options.multiple); if (Utils.GetData($e[0], 'select2Tags')) { if (this.options.debug && window.console && console.warn) { console.warn( 'Select2: The `data-select2-tags` attribute has been changed to ' + 'use the `data-data` and `data-tags="true"` attributes and will be ' + 'removed in future versions of Select2.' ); } Utils.StoreData($e[0], 'data', Utils.GetData($e[0], 'select2Tags')); Utils.StoreData($e[0], 'tags', true); } if (Utils.GetData($e[0], 'ajaxUrl')) { if (this.options.debug && window.console && console.warn) { console.warn( 'Select2: The `data-ajax-url` attribute has been changed to ' + '`data-ajax--url` and support for the old attribute will be removed' + ' in future versions of Select2.' ); } $e.attr('ajax--url', Utils.GetData($e[0], 'ajaxUrl')); Utils.StoreData($e[0], 'ajax-Url', Utils.GetData($e[0], 'ajaxUrl')); } var dataset = {}; function upperCaseLetter(_, letter) { return letter.toUpperCase(); } // Pre-load all of the attributes which are prefixed with `data-` for (var attr = 0; attr < $e[0].attributes.length; attr++) { var attributeName = $e[0].attributes[attr].name; var prefix = 'data-'; if (attributeName.substr(0, prefix.length) == prefix) { // Get the contents of the attribute after `data-` var dataName = attributeName.substring(prefix.length); // Get the data contents from the consistent source // This is more than likely the jQuery data helper var dataValue = Utils.GetData($e[0], dataName); // camelCase the attribute name to match the spec var camelDataName = dataName.replace(/-([a-z])/g, upperCaseLetter); // Store the data attribute contents into the dataset since dataset[camelDataName] = dataValue; } } // Prefer the element's `dataset` attribute if it exists // jQuery 1.x does not correctly handle data attributes with multiple dashes if ($.fn.jquery && $.fn.jquery.substr(0, 2) == '1.' && $e[0].dataset) { dataset = $.extend(true, {}, $e[0].dataset, dataset); } // Prefer our internal data cache if it exists var data = $.extend(true, {}, Utils.GetData($e[0]), dataset); data = Utils._convertData(data); for (var key in data) { if (excludedData.indexOf(key) > -1) { continue; } if ($.isPlainObject(this.options[key])) { $.extend(this.options[key], data[key]); } else { this.options[key] = data[key]; } } return this; }; Options.prototype.get = function (key) { return this.options[key]; }; Options.prototype.set = function (key, val) { this.options[key] = val; }; return Options; }); S2.define('select2/core',[ 'jquery', './options', './utils', './keys' ], function ($, Options, Utils, KEYS) { var Select2 = function ($element, options) { if (Utils.GetData($element[0], 'select2') != null) { Utils.GetData($element[0], 'select2').destroy(); } this.$element = $element; this.id = this._generateId($element); options = options || {}; this.options = new Options(options, $element); Select2.__super__.constructor.call(this); // Set up the tabindex var tabindex = $element.attr('tabindex') || 0; Utils.StoreData($element[0], 'old-tabindex', tabindex); $element.attr('tabindex', '-1'); // Set up containers and adapters var DataAdapter = this.options.get('dataAdapter'); this.dataAdapter = new DataAdapter($element, this.options); var $container = this.render(); this._placeContainer($container); var SelectionAdapter = this.options.get('selectionAdapter'); this.selection = new SelectionAdapter($element, this.options); this.$selection = this.selection.render(); this.selection.position(this.$selection, $container); var DropdownAdapter = this.options.get('dropdownAdapter'); this.dropdown = new DropdownAdapter($element, this.options); this.$dropdown = this.dropdown.render(); this.dropdown.position(this.$dropdown, $container); var ResultsAdapter = this.options.get('resultsAdapter'); this.results = new ResultsAdapter($element, this.options, this.dataAdapter); this.$results = this.results.render(); this.results.position(this.$results, this.$dropdown); // Bind events var self = this; // Bind the container to all of the adapters this._bindAdapters(); // Register any DOM event handlers this._registerDomEvents(); // Register any internal event handlers this._registerDataEvents(); this._registerSelectionEvents(); this._registerDropdownEvents(); this._registerResultsEvents(); this._registerEvents(); // Set the initial state this.dataAdapter.current(function (initialData) { self.trigger('selection:update', { data: initialData }); }); // Hide the original select $element[0].classList.add('select2-hidden-accessible'); $element.attr('aria-hidden', 'true'); // Synchronize any monitored attributes this._syncAttributes(); Utils.StoreData($element[0], 'select2', this); // Ensure backwards compatibility with $element.data('select2'). $element.data('select2', this); }; Utils.Extend(Select2, Utils.Observable); Select2.prototype._generateId = function ($element) { var id = ''; if ($element.attr('id') != null) { id = $element.attr('id'); } else if ($element.attr('name') != null) { id = $element.attr('name') + '-' + Utils.generateChars(2); } else { id = Utils.generateChars(4); } id = id.replace(/(:|\.|\[|\]|,)/g, ''); id = 'select2-' + id; return id; }; Select2.prototype._placeContainer = function ($container) { $container.insertAfter(this.$element); var width = this._resolveWidth(this.$element, this.options.get('width')); if (width != null) { $container.css('width', width); } }; Select2.prototype._resolveWidth = function ($element, method) { var WIDTH = /^width:(([-+]?([0-9]*\.)?[0-9]+)(px|em|ex|%|in|cm|mm|pt|pc))/i; if (method == 'resolve') { var styleWidth = this._resolveWidth($element, 'style'); if (styleWidth != null) { return styleWidth; } return this._resolveWidth($element, 'element'); } if (method == 'element') { var elementWidth = $element.outerWidth(false); if (elementWidth <= 0) { return 'auto'; } return elementWidth + 'px'; } if (method == 'style') { var style = $element.attr('style'); if (typeof(style) !== 'string') { return null; } var attrs = style.split(';'); for (var i = 0, l = attrs.length; i < l; i = i + 1) { var attr = attrs[i].replace(/\s/g, ''); var matches = attr.match(WIDTH); if (matches !== null && matches.length >= 1) { return matches[1]; } } return null; } if (method == 'computedstyle') { var computedStyle = window.getComputedStyle($element[0]); return computedStyle.width; } return method; }; Select2.prototype._bindAdapters = function () { this.dataAdapter.bind(this, this.$container); this.selection.bind(this, this.$container); this.dropdown.bind(this, this.$container); this.results.bind(this, this.$container); }; Select2.prototype._registerDomEvents = function () { var self = this; this.$element.on('change.select2', function () { self.dataAdapter.current(function (data) { self.trigger('selection:update', { data: data }); }); }); this.$element.on('focus.select2', function (evt) { self.trigger('focus', evt); }); this._syncA = Utils.bind(this._syncAttributes, this); this._syncS = Utils.bind(this._syncSubtree, this); this._observer = new window.MutationObserver(function (mutations) { self._syncA(); self._syncS(mutations); }); this._observer.observe(this.$element[0], { attributes: true, childList: true, subtree: false }); }; Select2.prototype._registerDataEvents = function () { var self = this; this.dataAdapter.on('*', function (name, params) { self.trigger(name, params); }); }; Select2.prototype._registerSelectionEvents = function () { var self = this; var nonRelayEvents = ['toggle', 'focus']; this.selection.on('toggle', function () { self.toggleDropdown(); }); this.selection.on('focus', function (params) { self.focus(params); }); this.selection.on('*', function (name, params) { if (nonRelayEvents.indexOf(name) !== -1) { return; } self.trigger(name, params); }); }; Select2.prototype._registerDropdownEvents = function () { var self = this; this.dropdown.on('*', function (name, params) { self.trigger(name, params); }); }; Select2.prototype._registerResultsEvents = function () { var self = this; this.results.on('*', function (name, params) { self.trigger(name, params); }); }; Select2.prototype._registerEvents = function () { var self = this; this.on('open', function () { self.$container[0].classList.add('select2-container--open'); }); this.on('close', function () { self.$container[0].classList.remove('select2-container--open'); }); this.on('enable', function () { self.$container[0].classList.remove('select2-container--disabled'); }); this.on('disable', function () { self.$container[0].classList.add('select2-container--disabled'); }); this.on('blur', function () { self.$container[0].classList.remove('select2-container--focus'); }); this.on('query', function (params) { if (!self.isOpen()) { self.trigger('open', {}); } this.dataAdapter.query(params, function (data) { self.trigger('results:all', { data: data, query: params }); }); }); this.on('query:append', function (params) { this.dataAdapter.query(params, function (data) { self.trigger('results:append', { data: data, query: params }); }); }); this.on('keypress', function (evt) { var key = evt.which; if (self.isOpen()) { if (key === KEYS.ESC || (key === KEYS.UP && evt.altKey)) { self.close(evt); evt.preventDefault(); } else if (key === KEYS.ENTER || key === KEYS.TAB) { self.trigger('results:select', {}); evt.preventDefault(); } else if ((key === KEYS.SPACE && evt.ctrlKey)) { self.trigger('results:toggle', {}); evt.preventDefault(); } else if (key === KEYS.UP) { self.trigger('results:previous', {}); evt.preventDefault(); } else if (key === KEYS.DOWN) { self.trigger('results:next', {}); evt.preventDefault(); } } else { if (key === KEYS.ENTER || key === KEYS.SPACE || (key === KEYS.DOWN && evt.altKey)) { self.open(); evt.preventDefault(); } } }); }; Select2.prototype._syncAttributes = function () { this.options.set('disabled', this.$element.prop('disabled')); if (this.isDisabled()) { if (this.isOpen()) { this.close(); } this.trigger('disable', {}); } else { this.trigger('enable', {}); } }; Select2.prototype._isChangeMutation = function (mutations) { var self = this; if (mutations.addedNodes && mutations.addedNodes.length > 0) { for (var n = 0; n < mutations.addedNodes.length; n++) { var node = mutations.addedNodes[n]; if (node.selected) { return true; } } } else if (mutations.removedNodes && mutations.removedNodes.length > 0) { return true; } else if (Array.isArray(mutations)) { return mutations.some(function (mutation) { return self._isChangeMutation(mutation); }); } return false; }; Select2.prototype._syncSubtree = function (mutations) { var changed = this._isChangeMutation(mutations); var self = this; // Only re-pull the data if we think there is a change if (changed) { this.dataAdapter.current(function (currentData) { self.trigger('selection:update', { data: currentData }); }); } }; /** * Override the trigger method to automatically trigger pre-events when * there are events that can be prevented. */ Select2.prototype.trigger = function (name, args) { var actualTrigger = Select2.__super__.trigger; var preTriggerMap = { 'open': 'opening', 'close': 'closing', 'select': 'selecting', 'unselect': 'unselecting', 'clear': 'clearing' }; if (args === undefined) { args = {}; } if (name in preTriggerMap) { var preTriggerName = preTriggerMap[name]; var preTriggerArgs = { prevented: false, name: name, args: args }; actualTrigger.call(this, preTriggerName, preTriggerArgs); if (preTriggerArgs.prevented) { args.prevented = true; return; } } actualTrigger.call(this, name, args); }; Select2.prototype.toggleDropdown = function () { if (this.isDisabled()) { return; } if (this.isOpen()) { this.close(); } else { this.open(); } }; Select2.prototype.open = function () { if (this.isOpen()) { return; } if (this.isDisabled()) { return; } this.trigger('query', {}); }; Select2.prototype.close = function (evt) { if (!this.isOpen()) { return; } this.trigger('close', { originalEvent : evt }); }; /** * Helper method to abstract the "enabled" (not "disabled") state of this * object. * * @return {true} if the instance is not disabled. * @return {false} if the instance is disabled. */ Select2.prototype.isEnabled = function () { return !this.isDisabled(); }; /** * Helper method to abstract the "disabled" state of this object. * * @return {true} if the disabled option is true. * @return {false} if the disabled option is false. */ Select2.prototype.isDisabled = function () { return this.options.get('disabled'); }; Select2.prototype.isOpen = function () { return this.$container[0].classList.contains('select2-container--open'); }; Select2.prototype.hasFocus = function () { return this.$container[0].classList.contains('select2-container--focus'); }; Select2.prototype.focus = function (data) { // No need to re-trigger focus events if we are already focused if (this.hasFocus()) { return; } this.$container[0].classList.add('select2-container--focus'); this.trigger('focus', {}); }; Select2.prototype.enable = function (args) { if (this.options.get('debug') && window.console && console.warn) { console.warn( 'Select2: The `select2("enable")` method has been deprecated and will' + ' be removed in later Select2 versions. Use $element.prop("disabled")' + ' instead.' ); } if (args == null || args.length === 0) { args = [true]; } var disabled = !args[0]; this.$element.prop('disabled', disabled); }; Select2.prototype.data = function () { if (this.options.get('debug') && arguments.length > 0 && window.console && console.warn) { console.warn( 'Select2: Data can no longer be set using `select2("data")`. You ' + 'should consider setting the value instead using `$element.val()`.' ); } var data = []; this.dataAdapter.current(function (currentData) { data = currentData; }); return data; }; Select2.prototype.val = function (args) { if (this.options.get('debug') && window.console && console.warn) { console.warn( 'Select2: The `select2("val")` method has been deprecated and will be' + ' removed in later Select2 versions. Use $element.val() instead.' ); } if (args == null || args.length === 0) { return this.$element.val(); } var newVal = args[0]; if (Array.isArray(newVal)) { newVal = newVal.map(function (obj) { return obj.toString(); }); } this.$element.val(newVal).trigger('input').trigger('change'); }; Select2.prototype.destroy = function () { Utils.RemoveData(this.$container[0]); this.$container.remove(); this._observer.disconnect(); this._observer = null; this._syncA = null; this._syncS = null; this.$element.off('.select2'); this.$element.attr('tabindex', Utils.GetData(this.$element[0], 'old-tabindex')); this.$element[0].classList.remove('select2-hidden-accessible'); this.$element.attr('aria-hidden', 'false'); Utils.RemoveData(this.$element[0]); this.$element.removeData('select2'); this.dataAdapter.destroy(); this.selection.destroy(); this.dropdown.destroy(); this.results.destroy(); this.dataAdapter = null; this.selection = null; this.dropdown = null; this.results = null; }; Select2.prototype.render = function () { var $container = $( '' + '' + '' + '' ); $container.attr('dir', this.options.get('dir')); this.$container = $container; this.$container[0].classList .add('select2-container--' + this.options.get('theme')); Utils.StoreData($container[0], 'element', this.$element); return $container; }; return Select2; }); S2.define('jquery-mousewheel',[ 'jquery' ], function ($) { // Used to shim jQuery.mousewheel for non-full builds. return $; }); S2.define('jquery.select2',[ 'jquery', 'jquery-mousewheel', './select2/core', './select2/defaults', './select2/utils' ], function ($, _, Select2, Defaults, Utils) { if ($.fn.select2 == null) { // All methods that should return the element var thisMethods = ['open', 'close', 'destroy']; $.fn.select2 = function (options) { options = options || {}; if (typeof options === 'object') { this.each(function () { var instanceOptions = $.extend(true, {}, options); var instance = new Select2($(this), instanceOptions); }); return this; } else if (typeof options === 'string') { var ret; var args = Array.prototype.slice.call(arguments, 1); this.each(function () { var instance = Utils.GetData(this, 'select2'); if (instance == null && window.console && console.error) { console.error( 'The select2(\'' + options + '\') method was called on an ' + 'element that is not using Select2.' ); } ret = instance[options].apply(instance, args); }); // Check if we should be returning `this` if (thisMethods.indexOf(options) > -1) { return this; } return ret; } else { throw new Error('Invalid arguments for Select2: ' + options); } }; } if ($.fn.select2.defaults == null) { $.fn.select2.defaults = Defaults; } return Select2; }); // Return the AMD loader configuration so it can be used outside of this file return { define: S2.define, require: S2.require }; }()); // Autoload the jQuery bindings // We know that all of the modules exist above this, so we're safe var select2 = S2.require('jquery.select2'); // Hold the AMD module references on the jQuery function that was just loaded // This allows Select2 to use the internal loader outside of this file, such // as in the language files. jQuery.fn.select2.amd = S2; // Return the Select2 instance for anyone who is importing it. return select2; })); includes/select2/select2.min.css000064400000037610152214270100012551 0ustar00.select2-container{box-sizing:border-box;display:inline-block;margin:0;position:relative;vertical-align:middle}.select2-container .select2-selection--single{box-sizing:border-box;cursor:pointer;display:block;height:28px;user-select:none;-webkit-user-select:none}.select2-container .select2-selection--single .select2-selection__rendered{display:block;padding-left:8px;padding-right:20px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.select2-container .select2-selection--single .select2-selection__clear{background-color:transparent;border:none;font-size:1em}.select2-container[dir="rtl"] .select2-selection--single .select2-selection__rendered{padding-right:8px;padding-left:20px}.select2-container .select2-selection--multiple{box-sizing:border-box;cursor:pointer;display:block;min-height:32px;user-select:none;-webkit-user-select:none}.select2-container .select2-selection--multiple .select2-selection__rendered{display:inline;list-style:none;padding:0}.select2-container .select2-selection--multiple .select2-selection__clear{background-color:transparent;border:none;font-size:1em}.select2-container .select2-search--inline .select2-search__field{box-sizing:border-box;border:none;font-size:100%;margin-top:5px;margin-left:5px;padding:0;max-width:100%;resize:none;height:18px;vertical-align:bottom;font-family:sans-serif;overflow:hidden;word-break:keep-all}.select2-container .select2-search--inline .select2-search__field::-webkit-search-cancel-button{-webkit-appearance:none}.select2-dropdown{background-color:white;border:1px solid #aaa;border-radius:4px;box-sizing:border-box;display:block;position:absolute;left:-100000px;width:100%;z-index:1051}.select2-results{display:block}.select2-results__options{list-style:none;margin:0;padding:0}.select2-results__option{padding:6px;user-select:none;-webkit-user-select:none}.select2-results__option--selectable{cursor:pointer}.select2-container--open .select2-dropdown{left:0}.select2-container--open .select2-dropdown--above{border-bottom:none;border-bottom-left-radius:0;border-bottom-right-radius:0}.select2-container--open .select2-dropdown--below{border-top:none;border-top-left-radius:0;border-top-right-radius:0}.select2-search--dropdown{display:block;padding:4px}.select2-search--dropdown .select2-search__field{padding:4px;width:100%;box-sizing:border-box}.select2-search--dropdown .select2-search__field::-webkit-search-cancel-button{-webkit-appearance:none}.select2-search--dropdown.select2-search--hide{display:none}.select2-close-mask{border:0;margin:0;padding:0;display:block;position:fixed;left:0;top:0;min-height:100%;min-width:100%;height:auto;width:auto;opacity:0;z-index:99;background-color:#fff;filter:alpha(opacity=0)}.select2-hidden-accessible{border:0 !important;clip:rect(0 0 0 0) !important;-webkit-clip-path:inset(50%) !important;clip-path:inset(50%) !important;height:1px !important;overflow:hidden !important;padding:0 !important;position:absolute !important;width:1px !important;white-space:nowrap !important}.select2-container--default .select2-selection--single{background-color:#fff;border:1px solid #aaa;border-radius:4px}.select2-container--default .select2-selection--single .select2-selection__rendered{color:#444;line-height:28px}.select2-container--default .select2-selection--single .select2-selection__clear{cursor:pointer;float:right;font-weight:bold;height:26px;margin-right:20px;padding-right:0px}.select2-container--default .select2-selection--single .select2-selection__placeholder{color:#999}.select2-container--default .select2-selection--single .select2-selection__arrow{height:26px;position:absolute;top:1px;right:1px;width:20px}.select2-container--default .select2-selection--single .select2-selection__arrow b{border-color:#888 transparent transparent transparent;border-style:solid;border-width:5px 4px 0 4px;height:0;left:50%;margin-left:-4px;margin-top:-2px;position:absolute;top:50%;width:0}.select2-container--default[dir="rtl"] .select2-selection--single .select2-selection__clear{float:left}.select2-container--default[dir="rtl"] .select2-selection--single .select2-selection__arrow{left:1px;right:auto}.select2-container--default.select2-container--disabled .select2-selection--single{background-color:#eee;cursor:default}.select2-container--default.select2-container--disabled .select2-selection--single .select2-selection__clear{display:none}.select2-container--default.select2-container--open .select2-selection--single .select2-selection__arrow b{border-color:transparent transparent #888 transparent;border-width:0 4px 5px 4px}.select2-container--default .select2-selection--multiple{background-color:white;border:1px solid #aaa;border-radius:4px;cursor:text;padding-bottom:5px;padding-right:5px;position:relative}.select2-container--default .select2-selection--multiple.select2-selection--clearable{padding-right:25px}.select2-container--default .select2-selection--multiple .select2-selection__clear{cursor:pointer;font-weight:bold;height:20px;margin-right:10px;margin-top:5px;position:absolute;right:0;padding:1px}.select2-container--default .select2-selection--multiple .select2-selection__choice{background-color:#e4e4e4;border:1px solid #aaa;border-radius:4px;box-sizing:border-box;display:inline-block;margin-left:5px;margin-top:5px;padding:0;padding-left:20px;position:relative;max-width:100%;overflow:hidden;text-overflow:ellipsis;vertical-align:bottom;white-space:nowrap}.select2-container--default .select2-selection--multiple .select2-selection__choice__display{cursor:default;padding-left:2px;padding-right:5px}.select2-container--default .select2-selection--multiple .select2-selection__choice__remove{background-color:transparent;border:none;border-right:1px solid #aaa;border-top-left-radius:4px;border-bottom-left-radius:4px;color:#999;cursor:pointer;font-size:1em;font-weight:bold;padding:0 4px;position:absolute;left:0;top:0}.select2-container--default .select2-selection--multiple .select2-selection__choice__remove:hover,.select2-container--default .select2-selection--multiple .select2-selection__choice__remove:focus{background-color:#f1f1f1;color:#333;outline:none}.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice{margin-left:5px;margin-right:auto}.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice__display{padding-left:5px;padding-right:2px}.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice__remove{border-left:1px solid #aaa;border-right:none;border-top-left-radius:0;border-bottom-left-radius:0;border-top-right-radius:4px;border-bottom-right-radius:4px}.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__clear{float:left;margin-left:10px;margin-right:auto}.select2-container--default.select2-container--focus .select2-selection--multiple{border:solid black 1px;outline:0}.select2-container--default.select2-container--disabled .select2-selection--multiple{background-color:#eee;cursor:default}.select2-container--default.select2-container--disabled .select2-selection__choice__remove{display:none}.select2-container--default.select2-container--open.select2-container--above .select2-selection--single,.select2-container--default.select2-container--open.select2-container--above .select2-selection--multiple{border-top-left-radius:0;border-top-right-radius:0}.select2-container--default.select2-container--open.select2-container--below .select2-selection--single,.select2-container--default.select2-container--open.select2-container--below .select2-selection--multiple{border-bottom-left-radius:0;border-bottom-right-radius:0}.select2-container--default .select2-search--dropdown .select2-search__field{border:1px solid #aaa}.select2-container--default .select2-search--inline .select2-search__field{background:transparent;border:none;outline:0;box-shadow:none;-webkit-appearance:textfield}.select2-container--default .select2-results>.select2-results__options{max-height:200px;overflow-y:auto}.select2-container--default .select2-results__option .select2-results__option{padding-left:1em}.select2-container--default .select2-results__option .select2-results__option .select2-results__group{padding-left:0}.select2-container--default .select2-results__option .select2-results__option .select2-results__option{margin-left:-1em;padding-left:2em}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-2em;padding-left:3em}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-3em;padding-left:4em}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-4em;padding-left:5em}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-5em;padding-left:6em}.select2-container--default .select2-results__option--group{padding:0}.select2-container--default .select2-results__option--disabled{color:#999}.select2-container--default .select2-results__option--selected{background-color:#ddd}.select2-container--default .select2-results__option--highlighted.select2-results__option--selectable{background-color:#5897fb;color:white}.select2-container--default .select2-results__group{cursor:default;display:block;padding:6px}.select2-container--classic .select2-selection--single{background-color:#f7f7f7;border:1px solid #aaa;border-radius:4px;outline:0;background-image:-webkit-linear-gradient(top, #fff 50%, #eee 100%);background-image:-o-linear-gradient(top, #fff 50%, #eee 100%);background-image:linear-gradient(to bottom, #fff 50%, #eee 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFFFFFF', endColorstr='#FFEEEEEE', GradientType=0)}.select2-container--classic .select2-selection--single:focus{border:1px solid #5897fb}.select2-container--classic .select2-selection--single .select2-selection__rendered{color:#444;line-height:28px}.select2-container--classic .select2-selection--single .select2-selection__clear{cursor:pointer;float:right;font-weight:bold;height:26px;margin-right:20px}.select2-container--classic .select2-selection--single .select2-selection__placeholder{color:#999}.select2-container--classic .select2-selection--single .select2-selection__arrow{background-color:#ddd;border:none;border-left:1px solid #aaa;border-top-right-radius:4px;border-bottom-right-radius:4px;height:26px;position:absolute;top:1px;right:1px;width:20px;background-image:-webkit-linear-gradient(top, #eee 50%, #ccc 100%);background-image:-o-linear-gradient(top, #eee 50%, #ccc 100%);background-image:linear-gradient(to bottom, #eee 50%, #ccc 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFEEEEEE', endColorstr='#FFCCCCCC', GradientType=0)}.select2-container--classic .select2-selection--single .select2-selection__arrow b{border-color:#888 transparent transparent transparent;border-style:solid;border-width:5px 4px 0 4px;height:0;left:50%;margin-left:-4px;margin-top:-2px;position:absolute;top:50%;width:0}.select2-container--classic[dir="rtl"] .select2-selection--single .select2-selection__clear{float:left}.select2-container--classic[dir="rtl"] .select2-selection--single .select2-selection__arrow{border:none;border-right:1px solid #aaa;border-radius:0;border-top-left-radius:4px;border-bottom-left-radius:4px;left:1px;right:auto}.select2-container--classic.select2-container--open .select2-selection--single{border:1px solid #5897fb}.select2-container--classic.select2-container--open .select2-selection--single .select2-selection__arrow{background:transparent;border:none}.select2-container--classic.select2-container--open .select2-selection--single .select2-selection__arrow b{border-color:transparent transparent #888 transparent;border-width:0 4px 5px 4px}.select2-container--classic.select2-container--open.select2-container--above .select2-selection--single{border-top:none;border-top-left-radius:0;border-top-right-radius:0;background-image:-webkit-linear-gradient(top, #fff 0%, #eee 50%);background-image:-o-linear-gradient(top, #fff 0%, #eee 50%);background-image:linear-gradient(to bottom, #fff 0%, #eee 50%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFFFFFF', endColorstr='#FFEEEEEE', GradientType=0)}.select2-container--classic.select2-container--open.select2-container--below .select2-selection--single{border-bottom:none;border-bottom-left-radius:0;border-bottom-right-radius:0;background-image:-webkit-linear-gradient(top, #eee 50%, #fff 100%);background-image:-o-linear-gradient(top, #eee 50%, #fff 100%);background-image:linear-gradient(to bottom, #eee 50%, #fff 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFEEEEEE', endColorstr='#FFFFFFFF', GradientType=0)}.select2-container--classic .select2-selection--multiple{background-color:white;border:1px solid #aaa;border-radius:4px;cursor:text;outline:0;padding-bottom:5px;padding-right:5px}.select2-container--classic .select2-selection--multiple:focus{border:1px solid #5897fb}.select2-container--classic .select2-selection--multiple .select2-selection__clear{display:none}.select2-container--classic .select2-selection--multiple .select2-selection__choice{background-color:#e4e4e4;border:1px solid #aaa;border-radius:4px;display:inline-block;margin-left:5px;margin-top:5px;padding:0}.select2-container--classic .select2-selection--multiple .select2-selection__choice__display{cursor:default;padding-left:2px;padding-right:5px}.select2-container--classic .select2-selection--multiple .select2-selection__choice__remove{background-color:transparent;border:none;border-top-left-radius:4px;border-bottom-left-radius:4px;color:#888;cursor:pointer;font-size:1em;font-weight:bold;padding:0 4px}.select2-container--classic .select2-selection--multiple .select2-selection__choice__remove:hover{color:#555;outline:none}.select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice{margin-left:5px;margin-right:auto}.select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice__display{padding-left:5px;padding-right:2px}.select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice__remove{border-top-left-radius:0;border-bottom-left-radius:0;border-top-right-radius:4px;border-bottom-right-radius:4px}.select2-container--classic.select2-container--open .select2-selection--multiple{border:1px solid #5897fb}.select2-container--classic.select2-container--open.select2-container--above .select2-selection--multiple{border-top:none;border-top-left-radius:0;border-top-right-radius:0}.select2-container--classic.select2-container--open.select2-container--below .select2-selection--multiple{border-bottom:none;border-bottom-left-radius:0;border-bottom-right-radius:0}.select2-container--classic .select2-search--dropdown .select2-search__field{border:1px solid #aaa;outline:0}.select2-container--classic .select2-search--inline .select2-search__field{outline:0;box-shadow:none}.select2-container--classic .select2-dropdown{background-color:#fff;border:1px solid transparent}.select2-container--classic .select2-dropdown--above{border-bottom:none}.select2-container--classic .select2-dropdown--below{border-top:none}.select2-container--classic .select2-results>.select2-results__options{max-height:200px;overflow-y:auto}.select2-container--classic .select2-results__option--group{padding:0}.select2-container--classic .select2-results__option--disabled{color:grey}.select2-container--classic .select2-results__option--highlighted.select2-results__option--selectable{background-color:#3875d7;color:#fff}.select2-container--classic .select2-results__group{cursor:default;display:block;padding:6px}.select2-container--classic.select2-container--open .select2-dropdown{border-color:#5897fb} includes/select2/select2.min.js000064400000216713152214270100012400 0ustar00/*! Select2 4.1.0-rc.0 | https://github.com/select2/select2/blob/master/LICENSE.md */ !function(n){"function"==typeof define&&define.amd?define(["jquery"],n):"object"==typeof module&&module.exports?module.exports=function(e,t){return void 0===t&&(t="undefined"!=typeof window?require("jquery"):require("jquery")(e)),n(t),t}:n(jQuery)}(function(t){var e,n,s,p,r,o,h,f,g,m,y,v,i,a,_,s=((u=t&&t.fn&&t.fn.select2&&t.fn.select2.amd?t.fn.select2.amd:u)&&u.requirejs||(u?n=u:u={},g={},m={},y={},v={},i=Object.prototype.hasOwnProperty,a=[].slice,_=/\.js$/,h=function(e,t){var n,s,i=c(e),r=i[0],t=t[1];return e=i[1],r&&(n=x(r=l(r,t))),r?e=n&&n.normalize?n.normalize(e,(s=t,function(e){return l(e,s)})):l(e,t):(r=(i=c(e=l(e,t)))[0],e=i[1],r&&(n=x(r))),{f:r?r+"!"+e:e,n:e,pr:r,p:n}},f={require:function(e){return w(e)},exports:function(e){var t=g[e];return void 0!==t?t:g[e]={}},module:function(e){return{id:e,uri:"",exports:g[e],config:(t=e,function(){return y&&y.config&&y.config[t]||{}})};var t}},r=function(e,t,n,s){var i,r,o,a,l,c=[],u=typeof n,d=A(s=s||e);if("undefined"==u||"function"==u){for(t=!t.length&&n.length?["require","exports","module"]:t,a=0;a":">",'"':""","'":"'","/":"/"};return"string"!=typeof e?e:String(e).replace(/[&<>"'\/\\]/g,function(e){return t[e]})},s.__cache={};var n=0;return s.GetUniqueElementId=function(e){var t=e.getAttribute("data-select2-id");return null!=t||(t=e.id?"select2-data-"+e.id:"select2-data-"+(++n).toString()+"-"+s.generateChars(4),e.setAttribute("data-select2-id",t)),t},s.StoreData=function(e,t,n){e=s.GetUniqueElementId(e);s.__cache[e]||(s.__cache[e]={}),s.__cache[e][t]=n},s.GetData=function(e,t){var n=s.GetUniqueElementId(e);return t?s.__cache[n]&&null!=s.__cache[n][t]?s.__cache[n][t]:r(e).data(t):s.__cache[n]},s.RemoveData=function(e){var t=s.GetUniqueElementId(e);null!=s.__cache[t]&&delete s.__cache[t],e.removeAttribute("data-select2-id")},s.copyNonInternalCssClasses=function(e,t){var n=(n=e.getAttribute("class").trim().split(/\s+/)).filter(function(e){return 0===e.indexOf("select2-")}),t=(t=t.getAttribute("class").trim().split(/\s+/)).filter(function(e){return 0!==e.indexOf("select2-")}),t=n.concat(t);e.setAttribute("class",t.join(" "))},s}),u.define("select2/results",["jquery","./utils"],function(d,p){function s(e,t,n){this.$element=e,this.data=n,this.options=t,s.__super__.constructor.call(this)}return p.Extend(s,p.Observable),s.prototype.render=function(){var e=d('
              ');return this.options.get("multiple")&&e.attr("aria-multiselectable","true"),this.$results=e},s.prototype.clear=function(){this.$results.empty()},s.prototype.displayMessage=function(e){var t=this.options.get("escapeMarkup");this.clear(),this.hideLoading();var n=d(''),s=this.options.get("translations").get(e.message);n.append(t(s(e.args))),n[0].className+=" select2-results__message",this.$results.append(n)},s.prototype.hideMessages=function(){this.$results.find(".select2-results__message").remove()},s.prototype.append=function(e){this.hideLoading();var t=[];if(null!=e.results&&0!==e.results.length){e.results=this.sort(e.results);for(var n=0;n",{class:"select2-results__options select2-results__options--nested",role:"none"});i.append(l),o.append(a),o.append(i)}else this.template(e,t);return p.StoreData(t,"data",e),t},s.prototype.bind=function(t,e){var i=this,n=t.id+"-results";this.$results.attr("id",n),t.on("results:all",function(e){i.clear(),i.append(e.data),t.isOpen()&&(i.setClasses(),i.highlightFirstItem())}),t.on("results:append",function(e){i.append(e.data),t.isOpen()&&i.setClasses()}),t.on("query",function(e){i.hideMessages(),i.showLoading(e)}),t.on("select",function(){t.isOpen()&&(i.setClasses(),i.options.get("scrollAfterSelect")&&i.highlightFirstItem())}),t.on("unselect",function(){t.isOpen()&&(i.setClasses(),i.options.get("scrollAfterSelect")&&i.highlightFirstItem())}),t.on("open",function(){i.$results.attr("aria-expanded","true"),i.$results.attr("aria-hidden","false"),i.setClasses(),i.ensureHighlightVisible()}),t.on("close",function(){i.$results.attr("aria-expanded","false"),i.$results.attr("aria-hidden","true"),i.$results.removeAttr("aria-activedescendant")}),t.on("results:toggle",function(){var e=i.getHighlightedResults();0!==e.length&&e.trigger("mouseup")}),t.on("results:select",function(){var e,t=i.getHighlightedResults();0!==t.length&&(e=p.GetData(t[0],"data"),t.hasClass("select2-results__option--selected")?i.trigger("close",{}):i.trigger("select",{data:e}))}),t.on("results:previous",function(){var e,t=i.getHighlightedResults(),n=i.$results.find(".select2-results__option--selectable"),s=n.index(t);s<=0||(e=s-1,0===t.length&&(e=0),(s=n.eq(e)).trigger("mouseenter"),t=i.$results.offset().top,n=s.offset().top,s=i.$results.scrollTop()+(n-t),0===e?i.$results.scrollTop(0):n-t<0&&i.$results.scrollTop(s))}),t.on("results:next",function(){var e,t=i.getHighlightedResults(),n=i.$results.find(".select2-results__option--selectable"),s=n.index(t)+1;s>=n.length||((e=n.eq(s)).trigger("mouseenter"),t=i.$results.offset().top+i.$results.outerHeight(!1),n=e.offset().top+e.outerHeight(!1),e=i.$results.scrollTop()+n-t,0===s?i.$results.scrollTop(0):tthis.$results.outerHeight()||s<0)&&this.$results.scrollTop(n))},s.prototype.template=function(e,t){var n=this.options.get("templateResult"),s=this.options.get("escapeMarkup"),e=n(e,t);null==e?t.style.display="none":"string"==typeof e?t.innerHTML=s(e):d(t).append(e)},s}),u.define("select2/keys",[],function(){return{BACKSPACE:8,TAB:9,ENTER:13,SHIFT:16,CTRL:17,ALT:18,ESC:27,SPACE:32,PAGE_UP:33,PAGE_DOWN:34,END:35,HOME:36,LEFT:37,UP:38,RIGHT:39,DOWN:40,DELETE:46}}),u.define("select2/selection/base",["jquery","../utils","../keys"],function(n,s,i){function r(e,t){this.$element=e,this.options=t,r.__super__.constructor.call(this)}return s.Extend(r,s.Observable),r.prototype.render=function(){var e=n('');return this._tabindex=0,null!=s.GetData(this.$element[0],"old-tabindex")?this._tabindex=s.GetData(this.$element[0],"old-tabindex"):null!=this.$element.attr("tabindex")&&(this._tabindex=this.$element.attr("tabindex")),e.attr("title",this.$element.attr("title")),e.attr("tabindex",this._tabindex),e.attr("aria-disabled","false"),this.$selection=e},r.prototype.bind=function(e,t){var n=this,s=e.id+"-results";this.container=e,this.$selection.on("focus",function(e){n.trigger("focus",e)}),this.$selection.on("blur",function(e){n._handleBlur(e)}),this.$selection.on("keydown",function(e){n.trigger("keypress",e),e.which===i.SPACE&&e.preventDefault()}),e.on("results:focus",function(e){n.$selection.attr("aria-activedescendant",e.data._resultId)}),e.on("selection:update",function(e){n.update(e.data)}),e.on("open",function(){n.$selection.attr("aria-expanded","true"),n.$selection.attr("aria-owns",s),n._attachCloseHandler(e)}),e.on("close",function(){n.$selection.attr("aria-expanded","false"),n.$selection.removeAttr("aria-activedescendant"),n.$selection.removeAttr("aria-owns"),n.$selection.trigger("focus"),n._detachCloseHandler(e)}),e.on("enable",function(){n.$selection.attr("tabindex",n._tabindex),n.$selection.attr("aria-disabled","false")}),e.on("disable",function(){n.$selection.attr("tabindex","-1"),n.$selection.attr("aria-disabled","true")})},r.prototype._handleBlur=function(e){var t=this;window.setTimeout(function(){document.activeElement==t.$selection[0]||n.contains(t.$selection[0],document.activeElement)||t.trigger("blur",e)},1)},r.prototype._attachCloseHandler=function(e){n(document.body).on("mousedown.select2."+e.id,function(e){var t=n(e.target).closest(".select2");n(".select2.select2-container--open").each(function(){this!=t[0]&&s.GetData(this,"element").select2("close")})})},r.prototype._detachCloseHandler=function(e){n(document.body).off("mousedown.select2."+e.id)},r.prototype.position=function(e,t){t.find(".selection").append(e)},r.prototype.destroy=function(){this._detachCloseHandler(this.container)},r.prototype.update=function(e){throw new Error("The `update` method must be defined in child classes.")},r.prototype.isEnabled=function(){return!this.isDisabled()},r.prototype.isDisabled=function(){return this.options.get("disabled")},r}),u.define("select2/selection/single",["jquery","./base","../utils","../keys"],function(e,t,n,s){function i(){i.__super__.constructor.apply(this,arguments)}return n.Extend(i,t),i.prototype.render=function(){var e=i.__super__.render.call(this);return e[0].classList.add("select2-selection--single"),e.html(''),e},i.prototype.bind=function(t,e){var n=this;i.__super__.bind.apply(this,arguments);var s=t.id+"-container";this.$selection.find(".select2-selection__rendered").attr("id",s).attr("role","textbox").attr("aria-readonly","true"),this.$selection.attr("aria-labelledby",s),this.$selection.attr("aria-controls",s),this.$selection.on("mousedown",function(e){1===e.which&&n.trigger("toggle",{originalEvent:e})}),this.$selection.on("focus",function(e){}),this.$selection.on("blur",function(e){}),t.on("focus",function(e){t.isOpen()||n.$selection.trigger("focus")})},i.prototype.clear=function(){var e=this.$selection.find(".select2-selection__rendered");e.empty(),e.removeAttr("title")},i.prototype.display=function(e,t){var n=this.options.get("templateSelection");return this.options.get("escapeMarkup")(n(e,t))},i.prototype.selectionContainer=function(){return e("")},i.prototype.update=function(e){var t,n;0!==e.length?(n=e[0],t=this.$selection.find(".select2-selection__rendered"),e=this.display(n,t),t.empty().append(e),(n=n.title||n.text)?t.attr("title",n):t.removeAttr("title")):this.clear()},i}),u.define("select2/selection/multiple",["jquery","./base","../utils"],function(i,e,c){function r(e,t){r.__super__.constructor.apply(this,arguments)}return c.Extend(r,e),r.prototype.render=function(){var e=r.__super__.render.call(this);return e[0].classList.add("select2-selection--multiple"),e.html('
                '),e},r.prototype.bind=function(e,t){var n=this;r.__super__.bind.apply(this,arguments);var s=e.id+"-container";this.$selection.find(".select2-selection__rendered").attr("id",s),this.$selection.on("click",function(e){n.trigger("toggle",{originalEvent:e})}),this.$selection.on("click",".select2-selection__choice__remove",function(e){var t;n.isDisabled()||(t=i(this).parent(),t=c.GetData(t[0],"data"),n.trigger("unselect",{originalEvent:e,data:t}))}),this.$selection.on("keydown",".select2-selection__choice__remove",function(e){n.isDisabled()||e.stopPropagation()})},r.prototype.clear=function(){var e=this.$selection.find(".select2-selection__rendered");e.empty(),e.removeAttr("title")},r.prototype.display=function(e,t){var n=this.options.get("templateSelection");return this.options.get("escapeMarkup")(n(e,t))},r.prototype.selectionContainer=function(){return i('
              • ')},r.prototype.update=function(e){if(this.clear(),0!==e.length){for(var t=[],n=this.$selection.find(".select2-selection__rendered").attr("id")+"-choice-",s=0;s')).attr("title",s()),e.attr("aria-label",s()),e.attr("aria-describedby",n),a.StoreData(e[0],"data",t),this.$selection.prepend(e),this.$selection[0].classList.add("select2-selection--clearable"))},e}),u.define("select2/selection/search",["jquery","../utils","../keys"],function(s,a,l){function e(e,t,n){e.call(this,t,n)}return e.prototype.render=function(e){var t=this.options.get("translations").get("search"),n=s('');this.$searchContainer=n,this.$search=n.find("textarea"),this.$search.prop("autocomplete",this.options.get("autocomplete")),this.$search.attr("aria-label",t());e=e.call(this);return this._transferTabIndex(),e.append(this.$searchContainer),e},e.prototype.bind=function(e,t,n){var s=this,i=t.id+"-results",r=t.id+"-container";e.call(this,t,n),s.$search.attr("aria-describedby",r),t.on("open",function(){s.$search.attr("aria-controls",i),s.$search.trigger("focus")}),t.on("close",function(){s.$search.val(""),s.resizeSearch(),s.$search.removeAttr("aria-controls"),s.$search.removeAttr("aria-activedescendant"),s.$search.trigger("focus")}),t.on("enable",function(){s.$search.prop("disabled",!1),s._transferTabIndex()}),t.on("disable",function(){s.$search.prop("disabled",!0)}),t.on("focus",function(e){s.$search.trigger("focus")}),t.on("results:focus",function(e){e.data._resultId?s.$search.attr("aria-activedescendant",e.data._resultId):s.$search.removeAttr("aria-activedescendant")}),this.$selection.on("focusin",".select2-search--inline",function(e){s.trigger("focus",e)}),this.$selection.on("focusout",".select2-search--inline",function(e){s._handleBlur(e)}),this.$selection.on("keydown",".select2-search--inline",function(e){var t;e.stopPropagation(),s.trigger("keypress",e),s._keyUpPrevented=e.isDefaultPrevented(),e.which!==l.BACKSPACE||""!==s.$search.val()||0<(t=s.$selection.find(".select2-selection__choice").last()).length&&(t=a.GetData(t[0],"data"),s.searchRemoveChoice(t),e.preventDefault())}),this.$selection.on("click",".select2-search--inline",function(e){s.$search.val()&&e.stopPropagation()});var t=document.documentMode,o=t&&t<=11;this.$selection.on("input.searchcheck",".select2-search--inline",function(e){o?s.$selection.off("input.search input.searchcheck"):s.$selection.off("keyup.search")}),this.$selection.on("keyup.search input.search",".select2-search--inline",function(e){var t;o&&"input"===e.type?s.$selection.off("input.search input.searchcheck"):(t=e.which)!=l.SHIFT&&t!=l.CTRL&&t!=l.ALT&&t!=l.TAB&&s.handleSearch(e)})},e.prototype._transferTabIndex=function(e){this.$search.attr("tabindex",this.$selection.attr("tabindex")),this.$selection.attr("tabindex","-1")},e.prototype.createPlaceholder=function(e,t){this.$search.attr("placeholder",t.text)},e.prototype.update=function(e,t){var n=this.$search[0]==document.activeElement;this.$search.attr("placeholder",""),e.call(this,t),this.resizeSearch(),n&&this.$search.trigger("focus")},e.prototype.handleSearch=function(){var e;this.resizeSearch(),this._keyUpPrevented||(e=this.$search.val(),this.trigger("query",{term:e})),this._keyUpPrevented=!1},e.prototype.searchRemoveChoice=function(e,t){this.trigger("unselect",{data:t}),this.$search.val(t.text),this.handleSearch()},e.prototype.resizeSearch=function(){this.$search.css("width","25px");var e="100%";""===this.$search.attr("placeholder")&&(e=.75*(this.$search.val().length+1)+"em"),this.$search.css("width",e)},e}),u.define("select2/selection/selectionCss",["../utils"],function(n){function e(){}return e.prototype.render=function(e){var t=e.call(this),e=this.options.get("selectionCssClass")||"";return-1!==e.indexOf(":all:")&&(e=e.replace(":all:",""),n.copyNonInternalCssClasses(t[0],this.$element[0])),t.addClass(e),t},e}),u.define("select2/selection/eventRelay",["jquery"],function(o){function e(){}return e.prototype.bind=function(e,t,n){var s=this,i=["open","opening","close","closing","select","selecting","unselect","unselecting","clear","clearing"],r=["opening","closing","selecting","unselecting","clearing"];e.call(this,t,n),t.on("*",function(e,t){var n;-1!==i.indexOf(e)&&(t=t||{},n=o.Event("select2:"+e,{params:t}),s.$element.trigger(n),-1!==r.indexOf(e)&&(t.prevented=n.isDefaultPrevented()))})},e}),u.define("select2/translation",["jquery","require"],function(t,n){function s(e){this.dict=e||{}}return s.prototype.all=function(){return this.dict},s.prototype.get=function(e){return this.dict[e]},s.prototype.extend=function(e){this.dict=t.extend({},e.all(),this.dict)},s._cache={},s.loadPath=function(e){var t;return e in s._cache||(t=n(e),s._cache[e]=t),new s(s._cache[e])},s}),u.define("select2/diacritics",[],function(){return{"Ⓐ":"A","A":"A","À":"A","Á":"A","Â":"A","Ầ":"A","Ấ":"A","Ẫ":"A","Ẩ":"A","Ã":"A","Ā":"A","Ă":"A","Ằ":"A","Ắ":"A","Ẵ":"A","Ẳ":"A","Ȧ":"A","Ǡ":"A","Ä":"A","Ǟ":"A","Ả":"A","Å":"A","Ǻ":"A","Ǎ":"A","Ȁ":"A","Ȃ":"A","Ạ":"A","Ậ":"A","Ặ":"A","Ḁ":"A","Ą":"A","Ⱥ":"A","Ɐ":"A","Ꜳ":"AA","Æ":"AE","Ǽ":"AE","Ǣ":"AE","Ꜵ":"AO","Ꜷ":"AU","Ꜹ":"AV","Ꜻ":"AV","Ꜽ":"AY","Ⓑ":"B","B":"B","Ḃ":"B","Ḅ":"B","Ḇ":"B","Ƀ":"B","Ƃ":"B","Ɓ":"B","Ⓒ":"C","C":"C","Ć":"C","Ĉ":"C","Ċ":"C","Č":"C","Ç":"C","Ḉ":"C","Ƈ":"C","Ȼ":"C","Ꜿ":"C","Ⓓ":"D","D":"D","Ḋ":"D","Ď":"D","Ḍ":"D","Ḑ":"D","Ḓ":"D","Ḏ":"D","Đ":"D","Ƌ":"D","Ɗ":"D","Ɖ":"D","Ꝺ":"D","DZ":"DZ","DŽ":"DZ","Dz":"Dz","Dž":"Dz","Ⓔ":"E","E":"E","È":"E","É":"E","Ê":"E","Ề":"E","Ế":"E","Ễ":"E","Ể":"E","Ẽ":"E","Ē":"E","Ḕ":"E","Ḗ":"E","Ĕ":"E","Ė":"E","Ë":"E","Ẻ":"E","Ě":"E","Ȅ":"E","Ȇ":"E","Ẹ":"E","Ệ":"E","Ȩ":"E","Ḝ":"E","Ę":"E","Ḙ":"E","Ḛ":"E","Ɛ":"E","Ǝ":"E","Ⓕ":"F","F":"F","Ḟ":"F","Ƒ":"F","Ꝼ":"F","Ⓖ":"G","G":"G","Ǵ":"G","Ĝ":"G","Ḡ":"G","Ğ":"G","Ġ":"G","Ǧ":"G","Ģ":"G","Ǥ":"G","Ɠ":"G","Ꞡ":"G","Ᵹ":"G","Ꝿ":"G","Ⓗ":"H","H":"H","Ĥ":"H","Ḣ":"H","Ḧ":"H","Ȟ":"H","Ḥ":"H","Ḩ":"H","Ḫ":"H","Ħ":"H","Ⱨ":"H","Ⱶ":"H","Ɥ":"H","Ⓘ":"I","I":"I","Ì":"I","Í":"I","Î":"I","Ĩ":"I","Ī":"I","Ĭ":"I","İ":"I","Ï":"I","Ḯ":"I","Ỉ":"I","Ǐ":"I","Ȉ":"I","Ȋ":"I","Ị":"I","Į":"I","Ḭ":"I","Ɨ":"I","Ⓙ":"J","J":"J","Ĵ":"J","Ɉ":"J","Ⓚ":"K","K":"K","Ḱ":"K","Ǩ":"K","Ḳ":"K","Ķ":"K","Ḵ":"K","Ƙ":"K","Ⱪ":"K","Ꝁ":"K","Ꝃ":"K","Ꝅ":"K","Ꞣ":"K","Ⓛ":"L","L":"L","Ŀ":"L","Ĺ":"L","Ľ":"L","Ḷ":"L","Ḹ":"L","Ļ":"L","Ḽ":"L","Ḻ":"L","Ł":"L","Ƚ":"L","Ɫ":"L","Ⱡ":"L","Ꝉ":"L","Ꝇ":"L","Ꞁ":"L","LJ":"LJ","Lj":"Lj","Ⓜ":"M","M":"M","Ḿ":"M","Ṁ":"M","Ṃ":"M","Ɱ":"M","Ɯ":"M","Ⓝ":"N","N":"N","Ǹ":"N","Ń":"N","Ñ":"N","Ṅ":"N","Ň":"N","Ṇ":"N","Ņ":"N","Ṋ":"N","Ṉ":"N","Ƞ":"N","Ɲ":"N","Ꞑ":"N","Ꞥ":"N","NJ":"NJ","Nj":"Nj","Ⓞ":"O","O":"O","Ò":"O","Ó":"O","Ô":"O","Ồ":"O","Ố":"O","Ỗ":"O","Ổ":"O","Õ":"O","Ṍ":"O","Ȭ":"O","Ṏ":"O","Ō":"O","Ṑ":"O","Ṓ":"O","Ŏ":"O","Ȯ":"O","Ȱ":"O","Ö":"O","Ȫ":"O","Ỏ":"O","Ő":"O","Ǒ":"O","Ȍ":"O","Ȏ":"O","Ơ":"O","Ờ":"O","Ớ":"O","Ỡ":"O","Ở":"O","Ợ":"O","Ọ":"O","Ộ":"O","Ǫ":"O","Ǭ":"O","Ø":"O","Ǿ":"O","Ɔ":"O","Ɵ":"O","Ꝋ":"O","Ꝍ":"O","Œ":"OE","Ƣ":"OI","Ꝏ":"OO","Ȣ":"OU","Ⓟ":"P","P":"P","Ṕ":"P","Ṗ":"P","Ƥ":"P","Ᵽ":"P","Ꝑ":"P","Ꝓ":"P","Ꝕ":"P","Ⓠ":"Q","Q":"Q","Ꝗ":"Q","Ꝙ":"Q","Ɋ":"Q","Ⓡ":"R","R":"R","Ŕ":"R","Ṙ":"R","Ř":"R","Ȑ":"R","Ȓ":"R","Ṛ":"R","Ṝ":"R","Ŗ":"R","Ṟ":"R","Ɍ":"R","Ɽ":"R","Ꝛ":"R","Ꞧ":"R","Ꞃ":"R","Ⓢ":"S","S":"S","ẞ":"S","Ś":"S","Ṥ":"S","Ŝ":"S","Ṡ":"S","Š":"S","Ṧ":"S","Ṣ":"S","Ṩ":"S","Ș":"S","Ş":"S","Ȿ":"S","Ꞩ":"S","Ꞅ":"S","Ⓣ":"T","T":"T","Ṫ":"T","Ť":"T","Ṭ":"T","Ț":"T","Ţ":"T","Ṱ":"T","Ṯ":"T","Ŧ":"T","Ƭ":"T","Ʈ":"T","Ⱦ":"T","Ꞇ":"T","Ꜩ":"TZ","Ⓤ":"U","U":"U","Ù":"U","Ú":"U","Û":"U","Ũ":"U","Ṹ":"U","Ū":"U","Ṻ":"U","Ŭ":"U","Ü":"U","Ǜ":"U","Ǘ":"U","Ǖ":"U","Ǚ":"U","Ủ":"U","Ů":"U","Ű":"U","Ǔ":"U","Ȕ":"U","Ȗ":"U","Ư":"U","Ừ":"U","Ứ":"U","Ữ":"U","Ử":"U","Ự":"U","Ụ":"U","Ṳ":"U","Ų":"U","Ṷ":"U","Ṵ":"U","Ʉ":"U","Ⓥ":"V","V":"V","Ṽ":"V","Ṿ":"V","Ʋ":"V","Ꝟ":"V","Ʌ":"V","Ꝡ":"VY","Ⓦ":"W","W":"W","Ẁ":"W","Ẃ":"W","Ŵ":"W","Ẇ":"W","Ẅ":"W","Ẉ":"W","Ⱳ":"W","Ⓧ":"X","X":"X","Ẋ":"X","Ẍ":"X","Ⓨ":"Y","Y":"Y","Ỳ":"Y","Ý":"Y","Ŷ":"Y","Ỹ":"Y","Ȳ":"Y","Ẏ":"Y","Ÿ":"Y","Ỷ":"Y","Ỵ":"Y","Ƴ":"Y","Ɏ":"Y","Ỿ":"Y","Ⓩ":"Z","Z":"Z","Ź":"Z","Ẑ":"Z","Ż":"Z","Ž":"Z","Ẓ":"Z","Ẕ":"Z","Ƶ":"Z","Ȥ":"Z","Ɀ":"Z","Ⱬ":"Z","Ꝣ":"Z","ⓐ":"a","a":"a","ẚ":"a","à":"a","á":"a","â":"a","ầ":"a","ấ":"a","ẫ":"a","ẩ":"a","ã":"a","ā":"a","ă":"a","ằ":"a","ắ":"a","ẵ":"a","ẳ":"a","ȧ":"a","ǡ":"a","ä":"a","ǟ":"a","ả":"a","å":"a","ǻ":"a","ǎ":"a","ȁ":"a","ȃ":"a","ạ":"a","ậ":"a","ặ":"a","ḁ":"a","ą":"a","ⱥ":"a","ɐ":"a","ꜳ":"aa","æ":"ae","ǽ":"ae","ǣ":"ae","ꜵ":"ao","ꜷ":"au","ꜹ":"av","ꜻ":"av","ꜽ":"ay","ⓑ":"b","b":"b","ḃ":"b","ḅ":"b","ḇ":"b","ƀ":"b","ƃ":"b","ɓ":"b","ⓒ":"c","c":"c","ć":"c","ĉ":"c","ċ":"c","č":"c","ç":"c","ḉ":"c","ƈ":"c","ȼ":"c","ꜿ":"c","ↄ":"c","ⓓ":"d","d":"d","ḋ":"d","ď":"d","ḍ":"d","ḑ":"d","ḓ":"d","ḏ":"d","đ":"d","ƌ":"d","ɖ":"d","ɗ":"d","ꝺ":"d","dz":"dz","dž":"dz","ⓔ":"e","e":"e","è":"e","é":"e","ê":"e","ề":"e","ế":"e","ễ":"e","ể":"e","ẽ":"e","ē":"e","ḕ":"e","ḗ":"e","ĕ":"e","ė":"e","ë":"e","ẻ":"e","ě":"e","ȅ":"e","ȇ":"e","ẹ":"e","ệ":"e","ȩ":"e","ḝ":"e","ę":"e","ḙ":"e","ḛ":"e","ɇ":"e","ɛ":"e","ǝ":"e","ⓕ":"f","f":"f","ḟ":"f","ƒ":"f","ꝼ":"f","ⓖ":"g","g":"g","ǵ":"g","ĝ":"g","ḡ":"g","ğ":"g","ġ":"g","ǧ":"g","ģ":"g","ǥ":"g","ɠ":"g","ꞡ":"g","ᵹ":"g","ꝿ":"g","ⓗ":"h","h":"h","ĥ":"h","ḣ":"h","ḧ":"h","ȟ":"h","ḥ":"h","ḩ":"h","ḫ":"h","ẖ":"h","ħ":"h","ⱨ":"h","ⱶ":"h","ɥ":"h","ƕ":"hv","ⓘ":"i","i":"i","ì":"i","í":"i","î":"i","ĩ":"i","ī":"i","ĭ":"i","ï":"i","ḯ":"i","ỉ":"i","ǐ":"i","ȉ":"i","ȋ":"i","ị":"i","į":"i","ḭ":"i","ɨ":"i","ı":"i","ⓙ":"j","j":"j","ĵ":"j","ǰ":"j","ɉ":"j","ⓚ":"k","k":"k","ḱ":"k","ǩ":"k","ḳ":"k","ķ":"k","ḵ":"k","ƙ":"k","ⱪ":"k","ꝁ":"k","ꝃ":"k","ꝅ":"k","ꞣ":"k","ⓛ":"l","l":"l","ŀ":"l","ĺ":"l","ľ":"l","ḷ":"l","ḹ":"l","ļ":"l","ḽ":"l","ḻ":"l","ſ":"l","ł":"l","ƚ":"l","ɫ":"l","ⱡ":"l","ꝉ":"l","ꞁ":"l","ꝇ":"l","lj":"lj","ⓜ":"m","m":"m","ḿ":"m","ṁ":"m","ṃ":"m","ɱ":"m","ɯ":"m","ⓝ":"n","n":"n","ǹ":"n","ń":"n","ñ":"n","ṅ":"n","ň":"n","ṇ":"n","ņ":"n","ṋ":"n","ṉ":"n","ƞ":"n","ɲ":"n","ʼn":"n","ꞑ":"n","ꞥ":"n","nj":"nj","ⓞ":"o","o":"o","ò":"o","ó":"o","ô":"o","ồ":"o","ố":"o","ỗ":"o","ổ":"o","õ":"o","ṍ":"o","ȭ":"o","ṏ":"o","ō":"o","ṑ":"o","ṓ":"o","ŏ":"o","ȯ":"o","ȱ":"o","ö":"o","ȫ":"o","ỏ":"o","ő":"o","ǒ":"o","ȍ":"o","ȏ":"o","ơ":"o","ờ":"o","ớ":"o","ỡ":"o","ở":"o","ợ":"o","ọ":"o","ộ":"o","ǫ":"o","ǭ":"o","ø":"o","ǿ":"o","ɔ":"o","ꝋ":"o","ꝍ":"o","ɵ":"o","œ":"oe","ƣ":"oi","ȣ":"ou","ꝏ":"oo","ⓟ":"p","p":"p","ṕ":"p","ṗ":"p","ƥ":"p","ᵽ":"p","ꝑ":"p","ꝓ":"p","ꝕ":"p","ⓠ":"q","q":"q","ɋ":"q","ꝗ":"q","ꝙ":"q","ⓡ":"r","r":"r","ŕ":"r","ṙ":"r","ř":"r","ȑ":"r","ȓ":"r","ṛ":"r","ṝ":"r","ŗ":"r","ṟ":"r","ɍ":"r","ɽ":"r","ꝛ":"r","ꞧ":"r","ꞃ":"r","ⓢ":"s","s":"s","ß":"s","ś":"s","ṥ":"s","ŝ":"s","ṡ":"s","š":"s","ṧ":"s","ṣ":"s","ṩ":"s","ș":"s","ş":"s","ȿ":"s","ꞩ":"s","ꞅ":"s","ẛ":"s","ⓣ":"t","t":"t","ṫ":"t","ẗ":"t","ť":"t","ṭ":"t","ț":"t","ţ":"t","ṱ":"t","ṯ":"t","ŧ":"t","ƭ":"t","ʈ":"t","ⱦ":"t","ꞇ":"t","ꜩ":"tz","ⓤ":"u","u":"u","ù":"u","ú":"u","û":"u","ũ":"u","ṹ":"u","ū":"u","ṻ":"u","ŭ":"u","ü":"u","ǜ":"u","ǘ":"u","ǖ":"u","ǚ":"u","ủ":"u","ů":"u","ű":"u","ǔ":"u","ȕ":"u","ȗ":"u","ư":"u","ừ":"u","ứ":"u","ữ":"u","ử":"u","ự":"u","ụ":"u","ṳ":"u","ų":"u","ṷ":"u","ṵ":"u","ʉ":"u","ⓥ":"v","v":"v","ṽ":"v","ṿ":"v","ʋ":"v","ꝟ":"v","ʌ":"v","ꝡ":"vy","ⓦ":"w","w":"w","ẁ":"w","ẃ":"w","ŵ":"w","ẇ":"w","ẅ":"w","ẘ":"w","ẉ":"w","ⱳ":"w","ⓧ":"x","x":"x","ẋ":"x","ẍ":"x","ⓨ":"y","y":"y","ỳ":"y","ý":"y","ŷ":"y","ỹ":"y","ȳ":"y","ẏ":"y","ÿ":"y","ỷ":"y","ẙ":"y","ỵ":"y","ƴ":"y","ɏ":"y","ỿ":"y","ⓩ":"z","z":"z","ź":"z","ẑ":"z","ż":"z","ž":"z","ẓ":"z","ẕ":"z","ƶ":"z","ȥ":"z","ɀ":"z","ⱬ":"z","ꝣ":"z","Ά":"Α","Έ":"Ε","Ή":"Η","Ί":"Ι","Ϊ":"Ι","Ό":"Ο","Ύ":"Υ","Ϋ":"Υ","Ώ":"Ω","ά":"α","έ":"ε","ή":"η","ί":"ι","ϊ":"ι","ΐ":"ι","ό":"ο","ύ":"υ","ϋ":"υ","ΰ":"υ","ώ":"ω","ς":"σ","’":"'"}}),u.define("select2/data/base",["../utils"],function(n){function s(e,t){s.__super__.constructor.call(this)}return n.Extend(s,n.Observable),s.prototype.current=function(e){throw new Error("The `current` method must be defined in child classes.")},s.prototype.query=function(e,t){throw new Error("The `query` method must be defined in child classes.")},s.prototype.bind=function(e,t){},s.prototype.destroy=function(){},s.prototype.generateResultId=function(e,t){e=e.id+"-result-";return e+=n.generateChars(4),null!=t.id?e+="-"+t.id.toString():e+="-"+n.generateChars(4),e},s}),u.define("select2/data/select",["./base","../utils","jquery"],function(e,a,l){function n(e,t){this.$element=e,this.options=t,n.__super__.constructor.call(this)}return a.Extend(n,e),n.prototype.current=function(e){var t=this;e(Array.prototype.map.call(this.$element[0].querySelectorAll(":checked"),function(e){return t.item(l(e))}))},n.prototype.select=function(i){var e,r=this;if(i.selected=!0,null!=i.element&&"option"===i.element.tagName.toLowerCase())return i.element.selected=!0,void this.$element.trigger("input").trigger("change");this.$element.prop("multiple")?this.current(function(e){var t=[];(i=[i]).push.apply(i,e);for(var n=0;nthis.maximumInputLength?this.trigger("results:message",{message:"inputTooLong",args:{maximum:this.maximumInputLength,input:t.term,params:t}}):e.call(this,t,n)},e}),u.define("select2/data/maximumSelectionLength",[],function(){function e(e,t,n){this.maximumSelectionLength=n.get("maximumSelectionLength"),e.call(this,t,n)}return e.prototype.bind=function(e,t,n){var s=this;e.call(this,t,n),t.on("select",function(){s._checkIfMaximumSelected()})},e.prototype.query=function(e,t,n){var s=this;this._checkIfMaximumSelected(function(){e.call(s,t,n)})},e.prototype._checkIfMaximumSelected=function(e,t){var n=this;this.current(function(e){e=null!=e?e.length:0;0=n.maximumSelectionLength?n.trigger("results:message",{message:"maximumSelected",args:{maximum:n.maximumSelectionLength}}):t&&t()})},e}),u.define("select2/dropdown",["jquery","./utils"],function(t,e){function n(e,t){this.$element=e,this.options=t,n.__super__.constructor.call(this)}return e.Extend(n,e.Observable),n.prototype.render=function(){var e=t('');return e.attr("dir",this.options.get("dir")),this.$dropdown=e},n.prototype.bind=function(){},n.prototype.position=function(e,t){},n.prototype.destroy=function(){this.$dropdown.remove()},n}),u.define("select2/dropdown/search",["jquery"],function(r){function e(){}return e.prototype.render=function(e){var t=e.call(this),n=this.options.get("translations").get("search"),e=r('');return this.$searchContainer=e,this.$search=e.find("input"),this.$search.prop("autocomplete",this.options.get("autocomplete")),this.$search.attr("aria-label",n()),t.prepend(e),t},e.prototype.bind=function(e,t,n){var s=this,i=t.id+"-results";e.call(this,t,n),this.$search.on("keydown",function(e){s.trigger("keypress",e),s._keyUpPrevented=e.isDefaultPrevented()}),this.$search.on("input",function(e){r(this).off("keyup")}),this.$search.on("keyup input",function(e){s.handleSearch(e)}),t.on("open",function(){s.$search.attr("tabindex",0),s.$search.attr("aria-controls",i),s.$search.trigger("focus"),window.setTimeout(function(){s.$search.trigger("focus")},0)}),t.on("close",function(){s.$search.attr("tabindex",-1),s.$search.removeAttr("aria-controls"),s.$search.removeAttr("aria-activedescendant"),s.$search.val(""),s.$search.trigger("blur")}),t.on("focus",function(){t.isOpen()||s.$search.trigger("focus")}),t.on("results:all",function(e){null!=e.query.term&&""!==e.query.term||(s.showSearch(e)?s.$searchContainer[0].classList.remove("select2-search--hide"):s.$searchContainer[0].classList.add("select2-search--hide"))}),t.on("results:focus",function(e){e.data._resultId?s.$search.attr("aria-activedescendant",e.data._resultId):s.$search.removeAttr("aria-activedescendant")})},e.prototype.handleSearch=function(e){var t;this._keyUpPrevented||(t=this.$search.val(),this.trigger("query",{term:t})),this._keyUpPrevented=!1},e.prototype.showSearch=function(e,t){return!0},e}),u.define("select2/dropdown/hidePlaceholder",[],function(){function e(e,t,n,s){this.placeholder=this.normalizePlaceholder(n.get("placeholder")),e.call(this,t,n,s)}return e.prototype.append=function(e,t){t.results=this.removePlaceholder(t.results),e.call(this,t)},e.prototype.normalizePlaceholder=function(e,t){return t="string"==typeof t?{id:"",text:t}:t},e.prototype.removePlaceholder=function(e,t){for(var n=t.slice(0),s=t.length-1;0<=s;s--){var i=t[s];this.placeholder.id===i.id&&n.splice(s,1)}return n},e}),u.define("select2/dropdown/infiniteScroll",["jquery"],function(n){function e(e,t,n,s){this.lastParams={},e.call(this,t,n,s),this.$loadingMore=this.createLoadingMore(),this.loading=!1}return e.prototype.append=function(e,t){this.$loadingMore.remove(),this.loading=!1,e.call(this,t),this.showLoadingMore(t)&&(this.$results.append(this.$loadingMore),this.loadMoreIfNeeded())},e.prototype.bind=function(e,t,n){var s=this;e.call(this,t,n),t.on("query",function(e){s.lastParams=e,s.loading=!0}),t.on("query:append",function(e){s.lastParams=e,s.loading=!0}),this.$results.on("scroll",this.loadMoreIfNeeded.bind(this))},e.prototype.loadMoreIfNeeded=function(){var e=n.contains(document.documentElement,this.$loadingMore[0]);!this.loading&&e&&(e=this.$results.offset().top+this.$results.outerHeight(!1),this.$loadingMore.offset().top+this.$loadingMore.outerHeight(!1)<=e+50&&this.loadMore())},e.prototype.loadMore=function(){this.loading=!0;var e=n.extend({},{page:1},this.lastParams);e.page++,this.trigger("query:append",e)},e.prototype.showLoadingMore=function(e,t){return t.pagination&&t.pagination.more},e.prototype.createLoadingMore=function(){var e=n('
              • '),t=this.options.get("translations").get("loadingMore");return e.html(t(this.lastParams)),e},e}),u.define("select2/dropdown/attachBody",["jquery","../utils"],function(u,o){function e(e,t,n){this.$dropdownParent=u(n.get("dropdownParent")||document.body),e.call(this,t,n)}return e.prototype.bind=function(e,t,n){var s=this;e.call(this,t,n),t.on("open",function(){s._showDropdown(),s._attachPositioningHandler(t),s._bindContainerResultHandlers(t)}),t.on("close",function(){s._hideDropdown(),s._detachPositioningHandler(t)}),this.$dropdownContainer.on("mousedown",function(e){e.stopPropagation()})},e.prototype.destroy=function(e){e.call(this),this.$dropdownContainer.remove()},e.prototype.position=function(e,t,n){t.attr("class",n.attr("class")),t[0].classList.remove("select2"),t[0].classList.add("select2-container--open"),t.css({position:"absolute",top:-999999}),this.$container=n},e.prototype.render=function(e){var t=u(""),e=e.call(this);return t.append(e),this.$dropdownContainer=t},e.prototype._hideDropdown=function(e){this.$dropdownContainer.detach()},e.prototype._bindContainerResultHandlers=function(e,t){var n;this._containerResultsHandlersBound||(n=this,t.on("results:all",function(){n._positionDropdown(),n._resizeDropdown()}),t.on("results:append",function(){n._positionDropdown(),n._resizeDropdown()}),t.on("results:message",function(){n._positionDropdown(),n._resizeDropdown()}),t.on("select",function(){n._positionDropdown(),n._resizeDropdown()}),t.on("unselect",function(){n._positionDropdown(),n._resizeDropdown()}),this._containerResultsHandlersBound=!0)},e.prototype._attachPositioningHandler=function(e,t){var n=this,s="scroll.select2."+t.id,i="resize.select2."+t.id,r="orientationchange.select2."+t.id,t=this.$container.parents().filter(o.hasScroll);t.each(function(){o.StoreData(this,"select2-scroll-position",{x:u(this).scrollLeft(),y:u(this).scrollTop()})}),t.on(s,function(e){var t=o.GetData(this,"select2-scroll-position");u(this).scrollTop(t.y)}),u(window).on(s+" "+i+" "+r,function(e){n._positionDropdown(),n._resizeDropdown()})},e.prototype._detachPositioningHandler=function(e,t){var n="scroll.select2."+t.id,s="resize.select2."+t.id,t="orientationchange.select2."+t.id;this.$container.parents().filter(o.hasScroll).off(n),u(window).off(n+" "+s+" "+t)},e.prototype._positionDropdown=function(){var e=u(window),t=this.$dropdown[0].classList.contains("select2-dropdown--above"),n=this.$dropdown[0].classList.contains("select2-dropdown--below"),s=null,i=this.$container.offset();i.bottom=i.top+this.$container.outerHeight(!1);var r={height:this.$container.outerHeight(!1)};r.top=i.top,r.bottom=i.top+r.height;var o=this.$dropdown.outerHeight(!1),a=e.scrollTop(),l=e.scrollTop()+e.height(),c=ai.bottom+o,a={left:i.left,top:r.bottom},l=this.$dropdownParent;"static"===l.css("position")&&(l=l.offsetParent());i={top:0,left:0};(u.contains(document.body,l[0])||l[0].isConnected)&&(i=l.offset()),a.top-=i.top,a.left-=i.left,t||n||(s="below"),e||!c||t?!c&&e&&t&&(s="below"):s="above",("above"==s||t&&"below"!==s)&&(a.top=r.top-i.top-o),null!=s&&(this.$dropdown[0].classList.remove("select2-dropdown--below"),this.$dropdown[0].classList.remove("select2-dropdown--above"),this.$dropdown[0].classList.add("select2-dropdown--"+s),this.$container[0].classList.remove("select2-container--below"),this.$container[0].classList.remove("select2-container--above"),this.$container[0].classList.add("select2-container--"+s)),this.$dropdownContainer.css(a)},e.prototype._resizeDropdown=function(){var e={width:this.$container.outerWidth(!1)+"px"};this.options.get("dropdownAutoWidth")&&(e.minWidth=e.width,e.position="relative",e.width="auto"),this.$dropdown.css(e)},e.prototype._showDropdown=function(e){this.$dropdownContainer.appendTo(this.$dropdownParent),this._positionDropdown(),this._resizeDropdown()},e}),u.define("select2/dropdown/minimumResultsForSearch",[],function(){function e(e,t,n,s){this.minimumResultsForSearch=n.get("minimumResultsForSearch"),this.minimumResultsForSearch<0&&(this.minimumResultsForSearch=1/0),e.call(this,t,n,s)}return e.prototype.showSearch=function(e,t){return!(function e(t){for(var n=0,s=0;s');return e.attr("dir",this.options.get("dir")),this.$container=e,this.$container[0].classList.add("select2-container--"+this.options.get("theme")),r.StoreData(e[0],"element",this.$element),e},o}),u.define("jquery-mousewheel",["jquery"],function(e){return e}),u.define("jquery.select2",["jquery","jquery-mousewheel","./select2/core","./select2/defaults","./select2/utils"],function(i,e,r,t,o){var a;return null==i.fn.select2&&(a=["open","close","destroy"],i.fn.select2=function(t){if("object"==typeof(t=t||{}))return this.each(function(){var e=i.extend(!0,{},t);new r(i(this),e)}),this;if("string"!=typeof t)throw new Error("Invalid arguments for Select2: "+t);var n,s=Array.prototype.slice.call(arguments,1);return this.each(function(){var e=o.GetData(this,"select2");null==e&&window.console&&console.error&&console.error("The select2('"+t+"') method was called on an element that is not using Select2."),n=e[t].apply(e,s)}),-1=0)&&i.push(n)}return i.push(t.ownerDocument.body),t.ownerDocument!==document&&i.push(t.ownerDocument.defaultView),i}function i(){O&&document.body.removeChild(O),O=null}function n(t){var o=void 0;t===document?(o=document,t=document.documentElement):o=t.ownerDocument;var i=o.documentElement,n=e(t),r=A();return n.top-=r.top,n.left-=r.left,"undefined"==typeof n.width&&(n.width=document.body.scrollWidth-n.left-n.right),"undefined"==typeof n.height&&(n.height=document.body.scrollHeight-n.top-n.bottom),n.top=n.top-i.clientTop,n.left=n.left-i.clientLeft,n.right=o.body.clientWidth-n.width-n.left,n.bottom=o.body.clientHeight-n.height-n.top,n}function r(t){return t.offsetParent||document.documentElement}function s(){if(T)return T;var t=document.createElement("div");t.style.width="100%",t.style.height="200px";var e=document.createElement("div");a(e.style,{position:"absolute",top:0,left:0,pointerEvents:"none",visibility:"hidden",width:"200px",height:"150px",overflow:"hidden"}),e.appendChild(t),document.body.appendChild(e);var o=t.offsetWidth;e.style.overflow="scroll";var i=t.offsetWidth;o===i&&(i=e.clientWidth),document.body.removeChild(e);var n=o-i;return T={width:n,height:n}}function a(){var t=arguments.length<=0||void 0===arguments[0]?{}:arguments[0],e=[];return Array.prototype.push.apply(e,arguments),e.slice(1).forEach(function(e){if(e)for(var o in e)({}).hasOwnProperty.call(e,o)&&(t[o]=e[o])}),t}function f(t,e){if("undefined"!=typeof t.classList)e.split(" ").forEach(function(e){e.trim()&&t.classList.remove(e)});else{var o=new RegExp("(^| )"+e.split(" ").join("|")+"( |$)","gi"),i=d(t).replace(o," ");u(t,i)}}function l(t,e){if("undefined"!=typeof t.classList)e.split(" ").forEach(function(e){e.trim()&&t.classList.add(e)});else{f(t,e);var o=d(t)+(" "+e);u(t,o)}}function h(t,e){if("undefined"!=typeof t.classList)return t.classList.contains(e);var o=d(t);return new RegExp("(^| )"+e+"( |$)","gi").test(o)}function d(t){return t.className instanceof t.ownerDocument.defaultView.SVGAnimatedString?t.className.baseVal:t.className}function u(t,e){t.setAttribute("class",e)}function p(t,e,o){o.forEach(function(o){e.indexOf(o)===-1&&h(t,o)&&f(t,o)}),e.forEach(function(e){h(t,e)||l(t,e)})}function t(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function c(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function, not "+typeof e);t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}),e&&(Object.setPrototypeOf?Object.setPrototypeOf(t,e):t.__proto__=e)}function g(t,e){var o=arguments.length<=2||void 0===arguments[2]?1:arguments[2];return t+o>=e&&e>=t-o}function m(){return"object"==typeof performance&&"function"==typeof performance.now?performance.now():+new Date}function v(){for(var t={top:0,left:0},e=arguments.length,o=Array(e),i=0;i1?o-1:0),n=1;n16?(e=Math.min(e-16,250),void(o=setTimeout(n,250))):void("undefined"!=typeof t&&m()-t<10||(null!=o&&(clearTimeout(o),o=null),t=m(),F(),e=m()-t))};"undefined"!=typeof window&&"undefined"!=typeof window.addEventListener&&["resize","scroll","touchmove"].forEach(function(t){window.addEventListener(t,i)})}();var Y={center:"center",left:"right",right:"left"},D={middle:"middle",top:"bottom",bottom:"top"},L={top:0,left:0,middle:"50%",center:"50%",bottom:"100%",right:"100%"},X=function(t,e){var o=t.left,i=t.top;return"auto"===o&&(o=Y[e.left]),"auto"===i&&(i=D[e.top]),{left:o,top:i}},H=function(t){var e=t.left,o=t.top;return"undefined"!=typeof L[t.left]&&(e=L[t.left]),"undefined"!=typeof L[t.top]&&(o=L[t.top]),{left:e,top:o}},N=function(t){var e=t.split(" "),o=k(e,2),i=o[0],n=o[1];return{top:i,left:n}},R=N,U=function(e){function h(e){var o=this;t(this,h),_(Object.getPrototypeOf(h.prototype),"constructor",this).call(this),this.position=this.position.bind(this),j.push(this),this.history=[],this.setOptions(e,!1),C.modules.forEach(function(t){"undefined"!=typeof t.initialize&&t.initialize.call(o)}),this.position()}return c(h,e),w(h,[{key:"getClass",value:function(){var t=arguments.length<=0||void 0===arguments[0]?"":arguments[0],e=this.options.classes;return"undefined"!=typeof e&&e[t]?this.options.classes[t]:this.options.classPrefix?this.options.classPrefix+"-"+t:t}},{key:"setOptions",value:function(t){var e=this,i=arguments.length<=1||void 0===arguments[1]||arguments[1],n={offset:"0 0",targetOffset:"0 0",targetAttachment:"auto auto",classPrefix:"tether"};this.options=a(n,t);var r=this.options,s=r.element,f=r.target,h=r.targetModifier;if(this.element=s,this.target=f,this.targetModifier=h,"viewport"===this.target?(this.target=document.body,this.targetModifier="visible"):"scroll-handle"===this.target&&(this.target=document.body,this.targetModifier="scroll-handle"),["element","target"].forEach(function(t){if("undefined"==typeof e[t])throw new Error("Tether Error: Both element and target must be defined");"undefined"!=typeof e[t].jquery?e[t]=e[t][0]:"string"==typeof e[t]&&(e[t]=document.querySelector(e[t]))}),l(this.element,this.getClass("element")),this.options.addTargetClasses!==!1&&l(this.target,this.getClass("target")),!this.options.attachment)throw new Error("Tether Error: You must provide an attachment");this.targetAttachment=R(this.options.targetAttachment),this.attachment=R(this.options.attachment),this.offset=N(this.options.offset),this.targetOffset=N(this.options.targetOffset),"undefined"!=typeof this.scrollParents&&this.disable(),"scroll-handle"===this.targetModifier?this.scrollParents=[this.target]:this.scrollParents=o(this.target),this.options.enabled!==!1&&this.enable(i)}},{key:"getTargetBounds",value:function(){if("undefined"==typeof this.targetModifier)return n(this.target);if("visible"===this.targetModifier){if(this.target===document.body)return{top:pageYOffset,left:pageXOffset,height:innerHeight,width:innerWidth};var t=n(this.target),e={height:t.height,width:t.width,top:t.top,left:t.left};return e.height=Math.min(e.height,t.height-(pageYOffset-t.top)),e.height=Math.min(e.height,t.height-(t.top+t.height-(pageYOffset+innerHeight))),e.height=Math.min(innerHeight,e.height),e.height-=2,e.width=Math.min(e.width,t.width-(pageXOffset-t.left)),e.width=Math.min(e.width,t.width-(t.left+t.width-(pageXOffset+innerWidth))),e.width=Math.min(innerWidth,e.width),e.width-=2,e.topo.clientWidth||[i.overflow,i.overflowX].indexOf("scroll")>=0||this.target!==document.body,s=0;r&&(s=15);var a=t.height-parseFloat(i.borderTopWidth)-parseFloat(i.borderBottomWidth)-s,e={width:15,height:.975*a*(a/o.scrollHeight),left:t.left+t.width-parseFloat(i.borderLeftWidth)-15},f=0;a<408&&this.target===document.body&&(f=-11e-5*Math.pow(a,2)-.00727*a+22.58),this.target!==document.body&&(e.height=Math.max(e.height,24));var l=this.target.scrollTop/(o.scrollHeight-a);return e.top=l*(a-e.height-f)+t.top+parseFloat(i.borderTopWidth),this.target===document.body&&(e.height=Math.max(e.height,24)),e}}},{key:"clearCache",value:function(){this._cache={}}},{key:"cache",value:function(t,e){return"undefined"==typeof this._cache&&(this._cache={}),"undefined"==typeof this._cache[t]&&(this._cache[t]=e.call(this)),this._cache[t]}},{key:"enable",value:function(){var t=this,e=arguments.length<=0||void 0===arguments[0]||arguments[0];this.options.addTargetClasses!==!1&&l(this.target,this.getClass("enabled")),l(this.element,this.getClass("enabled")),this.enabled=!0,this.scrollParents.forEach(function(e){e!==t.target.ownerDocument&&e.addEventListener("scroll",t.position)}),e&&this.position()}},{key:"disable",value:function(){var t=this;f(this.target,this.getClass("enabled")),f(this.element,this.getClass("enabled")),this.enabled=!1,"undefined"!=typeof this.scrollParents&&this.scrollParents.forEach(function(e){e.removeEventListener("scroll",t.position)})}},{key:"destroy",value:function(){var t=this;this.disable(),j.forEach(function(e,o){e===t&&j.splice(o,1)}),0===j.length&&i()}},{key:"updateAttachClasses",value:function(t,e){var o=this;t=t||this.attachment,e=e||this.targetAttachment;var i=["left","top","bottom","right","middle","center"];"undefined"!=typeof this._addAttachClasses&&this._addAttachClasses.length&&this._addAttachClasses.splice(0,this._addAttachClasses.length),"undefined"==typeof this._addAttachClasses&&(this._addAttachClasses=[]);var n=this._addAttachClasses;t.top&&n.push(this.getClass("element-attached")+"-"+t.top),t.left&&n.push(this.getClass("element-attached")+"-"+t.left),e.top&&n.push(this.getClass("target-attached")+"-"+e.top),e.left&&n.push(this.getClass("target-attached")+"-"+e.left);var r=[];i.forEach(function(t){r.push(o.getClass("element-attached")+"-"+t),r.push(o.getClass("target-attached")+"-"+t)}),S(function(){"undefined"!=typeof o._addAttachClasses&&(p(o.element,o._addAttachClasses,r),o.options.addTargetClasses!==!1&&p(o.target,o._addAttachClasses,r),delete o._addAttachClasses)})}},{key:"position",value:function(){var t=this,e=arguments.length<=0||void 0===arguments[0]||arguments[0];if(this.enabled){this.clearCache();var o=X(this.targetAttachment,this.attachment);this.updateAttachClasses(this.attachment,o);var i=this.cache("element-bounds",function(){return n(t.element)}),a=i.width,f=i.height;if(0===a&&0===f&&"undefined"!=typeof this.lastSize){var l=this.lastSize;a=l.width,f=l.height}else this.lastSize={width:a,height:f};var h=this.cache("target-bounds",function(){return t.getTargetBounds()}),d=h,u=y(H(this.attachment),{width:a,height:f}),p=y(H(o),d),c=y(this.offset,{width:a,height:f}),g=y(this.targetOffset,d);u=v(u,c),p=v(p,g);for(var m=h.left+p.left-u.left,b=h.top+p.top-u.top,w=0;wA.documentElement.clientHeight&&(P=this.cache("scrollbar-size",s),x.viewport.bottom-=P.height),T.innerWidth>A.documentElement.clientWidth&&(P=this.cache("scrollbar-size",s),x.viewport.right-=P.width),["","static"].indexOf(A.body.style.position)!==-1&&["","static"].indexOf(A.body.parentElement.style.position)!==-1||(x.page.bottom=A.body.scrollHeight-b-f,x.page.right=A.body.scrollWidth-m-a),"undefined"!=typeof this.options.optimizations&&this.options.optimizations.moveElement!==!1&&"undefined"==typeof this.targetModifier&&!function(){var e=t.cache("target-offsetparent",function(){return r(t.target)}),o=t.cache("target-offsetparent-bounds",function(){return n(e)}),i=getComputedStyle(e),s=o,a={};if(["Top","Left","Bottom","Right"].forEach(function(t){a[t.toLowerCase()]=parseFloat(i["border"+t+"Width"])}),o.right=A.body.scrollWidth-o.left-s.width+a.right,o.bottom=A.body.scrollHeight-o.top-s.height+a.bottom,x.page.top>=o.top+a.top&&x.page.bottom>=o.bottom&&x.page.left>=o.left+a.left&&x.page.right>=o.right){var f=e.scrollTop,l=e.scrollLeft;x.offset={top:x.page.top-o.top+f-a.top,left:x.page.left-o.left+l-a.left}}}(),this.move(x),this.history.unshift(x),this.history.length>3&&this.history.pop(),e&&W(),!0}}},{key:"move",value:function(t){var e=this;if("undefined"!=typeof this.element.parentNode){var o={};for(var i in t){o[i]={};for(var n in t[i]){for(var s=!1,f=0;f=0){var p=s.split(" "),g=k(p,2);d=g[0],h=g[1]}else h=d=s;var w=b(e,n);"target"!==d&&"both"!==d||(ow[3]&&"bottom"===v.top&&(o-=u,v.top="top")),"together"===d&&("top"===v.top&&("bottom"===y.top&&ow[3]&&o-(f-u)>=w[1]&&(o-=f-u,v.top="bottom",y.top="bottom")),"bottom"===v.top&&("top"===y.top&&o+f>w[3]?(o-=u,v.top="top",o-=f,y.top="bottom"):"bottom"===y.top&&ow[3]&&"top"===y.top?(o-=f,y.top="bottom"):ow[2]&&"right"===v.left&&(i-=c,v.left="left")),"together"===h&&(iw[2]&&"right"===v.left?"left"===y.left?(i-=c,v.left="left",i-=l,y.left="right"):"right"===y.left&&(i-=c,v.left="left",i+=l,y.left="left"):"center"===v.left&&(i+l>w[2]&&"left"===y.left?(i-=l,y.left="right"):iw[3]&&"top"===y.top&&(o-=f,y.top="bottom")),"element"!==h&&"both"!==h||(iw[2]&&("left"===y.left?(i-=l,y.left="right"):"center"===y.left&&(i-=l/2,y.left="right"))),"string"==typeof a?a=a.split(",").map(function(t){return t.trim()}):a===!0&&(a=["top","left","right","bottom"]),a=a||[];var C=[],O=[];o=0?(o=w[1],C.push("top")):O.push("top")),o+f>w[3]&&(a.indexOf("bottom")>=0?(o=w[3]-f,C.push("bottom")):O.push("bottom")),i=0?(i=w[0],C.push("left")):O.push("left")),i+l>w[2]&&(a.indexOf("right")>=0?(i=w[2]-l,C.push("right")):O.push("right")),C.length&&!function(){var t=void 0;t="undefined"!=typeof e.options.pinnedClass?e.options.pinnedClass:e.getClass("pinned"),m.push(t),C.forEach(function(e){m.push(t+"-"+e)})}(),O.length&&!function(){var t=void 0;t="undefined"!=typeof e.options.outOfBoundsClass?e.options.outOfBoundsClass:e.getClass("out-of-bounds"),m.push(t),O.forEach(function(e){m.push(t+"-"+e)})}(),(C.indexOf("left")>=0||C.indexOf("right")>=0)&&(y.left=v.left=!1),(C.indexOf("top")>=0||C.indexOf("bottom")>=0)&&(y.top=v.top=!1),v.top===r.top&&v.left===r.left&&y.top===e.attachment.top&&y.left===e.attachment.left||(e.updateAttachClasses(y,v),e.trigger("update",{attachment:y,targetAttachment:v}))}),S(function(){e.options.addTargetClasses!==!1&&p(e.target,m,g),p(e.element,m,g)}),{top:o,left:i}}});var z=C.Utils,n=z.getBounds,p=z.updateClasses,S=z.defer;C.modules.push({position:function(t){var e=this,o=t.top,i=t.left,r=this.cache("element-bounds",function(){return n(e.element)}),s=r.height,a=r.width,f=this.getTargetBounds(),l=o+s,h=i+a,d=[];o<=f.bottom&&l>=f.top&&["left","right"].forEach(function(t){var e=f[t];e!==i&&e!==h||d.push(t)}),i<=f.right&&h>=f.left&&["top","bottom"].forEach(function(t){var e=f[t];e!==o&&e!==l||d.push(t)});var u=[],c=[],g=["left","top","right","bottom"];return u.push(this.getClass("abutted")),g.forEach(function(t){u.push(e.getClass("abutted")+"-"+t)}),d.length&&c.push(this.getClass("abutted")),d.forEach(function(t){c.push(e.getClass("abutted")+"-"+t)}),S(function(){e.options.addTargetClasses!==!1&&p(e.target,c,u),p(e.element,c,u)}),!0}});var k=function(){function t(t,e){var o=[],i=!0,n=!1,r=void 0;try{for(var s,a=t[Symbol.iterator]();!(i=(s=a.next()).done)&&(o.push(s.value),!e||o.length!==e);i=!0);}catch(f){n=!0,r=f}finally{try{!i&&a["return"]&&a["return"]()}finally{if(n)throw r}}return o}return function(e,o){if(Array.isArray(e))return e;if(Symbol.iterator in Object(e))return t(e,o);throw new TypeError("Invalid attempt to destructure non-iterable instance")}}();return C.modules.push({position:function(t){var e=t.top,o=t.left;if(this.options.shift){var i=this.options.shift;"function"==typeof this.options.shift&&(i=this.options.shift.call(this,{top:e,left:o}));var n=void 0,r=void 0;if("string"==typeof i){i=i.split(" "),i[1]=i[1]||i[0];var s=i,a=k(s,2);n=a[0],r=a[1],n=parseFloat(n,10),r=parseFloat(r,10)}else n=i.top,r=i.left;return e+=n,o+=r,{top:e,left:o}}}}),V});includes/tether/tether.js000064400000156554152214270100011510 0ustar00/*! tether 1.4.7 */ (function(root, factory) { if (typeof define === 'function' && define.amd) { define([], factory); } else if (typeof exports === 'object') { module.exports = factory(); } else { root.Tether = factory(); } }(this, function() { 'use strict'; var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } var TetherBase = undefined; if (typeof TetherBase === 'undefined') { TetherBase = { modules: [] }; } var zeroElement = null; // Same as native getBoundingClientRect, except it takes into account parent offsets // if the element lies within a nested document ( or '); jQuery('#updraft-iframe-modal').dialog({ title: title, resizeOnWindowResize: true, scrollWithViewport: true, resizeAccordingToViewport: true, useContentSize: false, open: function(event, ui) { jQuery(this).dialog('option', 'width', width), jQuery(this).dialog('option', 'minHeight', 260); if (jQuery(window).height() > height) { jQuery(this).dialog('option', 'height', height); } else { jQuery(this).dialog('option', 'height', jQuery(window).height()-30); } } }).dialog('open'); } function updraft_html_modal(showwhat, title, width, height) { jQuery('#updraft-iframe-modal-innards').html(showwhat); var updraft_html_modal_buttons = {}; if (width < 450) { updraft_html_modal_buttons[updraftlion.close] = function() { jQuery(this).dialog("close"); }; } jQuery('#updraft-iframe-modal').dialog({ title: title, buttons: updraft_html_modal_buttons, resizeOnWindowResize: true, scrollWithViewport: true, resizeAccordingToViewport: true, useContentSize: false, open: function(event, ui) { jQuery(this).dialog('option', 'width', width), jQuery(this).dialog('option', 'minHeight', 260); if (jQuery(window).height() > height) { jQuery(this).dialog('option', 'height', height); } else { jQuery(this).dialog('option', 'height', jQuery(window).height()-30); } } }).dialog('open'); } function updraftplus_diskspace() { jQuery('#updraft-navtab-backups-content .updraft_diskspaceused').html(''+updraftlion.calculating+''); updraft_send_command('get_fragment', { fragment: 'disk_usage', data: 'updraft' }, function(response) { jQuery('#updraft-navtab-backups-content .updraft_diskspaceused').html(response.output); }, { type: 'GET' }); } var lastlog_lastmessage = ""; function updraftplus_deletefromserver(timestamp, type, findex) { if (!findex) findex=0; var pdata = { stage: 'delete', timestamp: timestamp, type: type, findex: findex }; updraft_send_command('updraft_download_backup', pdata, null, { action: 'updraft_download_backup', nonce: updraft_download_nonce, nonce_key: '_wpnonce' }); } function updraftplus_downloadstage2(timestamp, type, findex) { location.href =ajaxurl+'?_wpnonce='+updraft_download_nonce+'×tamp='+timestamp+'&type='+type+'&stage=2&findex='+findex+'&action=updraft_download_backup'; } function updraftplus_show_contents(timestamp, type, findex) { var modal_content = '

                ' + updraftlion.zip_file_contents_info + ' -

                '+updraftlion.browse_download_link+'
                '; updraft_html_modal(modal_content, updraftlion.zip_file_contents, 780, 500); zip_files_jstree('zipbrowser', timestamp, type, findex); } /** * Creates the jstree and makes a call to the backend to dynamically get the tree nodes * * @param {string} entity Entity for the jstree * @param {integer} timestamp Timestamp of the jstree * @param {string} type Type of file to display in the JS tree * @param {array} findex Index of Zip */ function zip_files_jstree(entity, timestamp, type, findex) { jQuery('#updraft_zip_files_jstree').jstree({ "core": { "multiple": false, "data": function (nodeid, callback) { updraft_send_command('get_jstree_directory_nodes', {entity:entity, node:nodeid, timestamp:timestamp, type:type, findex:findex}, function(response) { if (response.hasOwnProperty('error')) { alert(response.error); } else { callback.call(this, response.nodes); } }, { error_callback: function(response, status, error_code, resp) { if (typeof resp !== 'undefined' && resp.hasOwnProperty('fatal_error')) { console.error(resp.fatal_error_message); jQuery('#updraft_zip_files_jstree').html('

                '+resp.fatal_error_message+'

                '); alert(resp.fatal_error_message); } else { var error_message = "updraft_send_command: error: "+status+" ("+error_code+")"; jQuery('#updraft_zip_files_jstree').html('

                '+error_message+'

                '); console.log(error_message); alert(error_message); console.log(response); } } }); }, "error": function(error) { alert(error); console.log(error); }, }, "search": { "show_only_matches": true }, "plugins": ["search", "sort"], }); // Update modal title once tree loads jQuery('#updraft_zip_files_jstree').on('ready.jstree', function(e, data) { jQuery('#updraft-iframe-modal').dialog('option', 'title', updraftlion.zip_file_contents + ': ' + data.instance.get_node('#').children[0]) }); // Search function for jstree, this will hide nodes that don't match the search var timeout = false; jQuery('#zip_files_jstree_search').on('keyup', function () { if (timeout) { clearTimeout(timeout); } timeout = setTimeout(function () { var value = jQuery('#zip_files_jstree_search').val(); jQuery('#updraft_zip_files_jstree').jstree(true).search(value); }, 250); }); // Detect change on the tree and update the input that has been marked as editing jQuery('#updraft_zip_files_jstree').on("changed.jstree", function (e, data) { jQuery('#updraft_zip_path_text').text(data.node.li_attr.path); if (data.node.li_attr.size) { jQuery('#updraft_zip_size_text').text(data.node.li_attr.size); jQuery('#updraft_zip_download_item').show(); } else { jQuery('#updraft_zip_size_text').text(''); jQuery('#updraft_zip_download_item').hide(); } }); jQuery('#updraft_zip_download_item').on('click', function(event) { event.preventDefault(); var path = jQuery('#updraft_zip_path_text').text(); updraft_send_command('get_zipfile_download', {path:path, timestamp:timestamp, type:type, findex:findex}, function(response) { if (response.hasOwnProperty('error')) { alert(response.error); } else if (response.hasOwnProperty('path')) { location.href =ajaxurl+'?_wpnonce='+updraft_download_nonce+'×tamp='+timestamp+'&type='+type+'&stage=2&findex='+findex+'&filepath='+response.path+'&action=updraft_download_backup'; } else { alert(updraftlion.download_timeout); } }, { error_callback: function(response, status, error_code, resp) { if (typeof resp !== 'undefined' && resp.hasOwnProperty('fatal_error')) { console.error(resp.fatal_error_message); alert(resp.fatal_error_message); } else { var error_message = "updraft_send_command: error: "+status+" ("+error_code+")"; console.log(error_message); alert(error_message); console.log(response); } } }); }); } /** * This function will clean up the updraft downloader UI * * @param {object} item - the object pressed in the UI * @param {string} what - the file entity */ function remove_updraft_downloader(item, what) { jQuery(item).closest('.updraftplus_downloader').fadeOut().remove(); if (0 == jQuery('.updraftplus_downloader_container_'+what+' .updraftplus_downloader').length) jQuery('.updraftplus_downloader_container_'+what).remove(); } /** * This function will prepare the downloader UI and kick of the request to download the file entities. * * @param {string} base - the base string for the id * @param {integer} backup_timestamp - the backup timestamp * @param {string} what - the file entity * @param {string} whicharea - the area we want to append the downloader * @param {string} set_contents - the contents we want to download * @param {string} prettydate - the pretty backup date * @param {boolean} async - boolean to indicate if this is a async request or not */ function updraft_downloader(base, backup_timestamp, what, whicharea, set_contents, prettydate, async) { if (typeof set_contents !== "string") set_contents = set_contents.toString(); jQuery('.ud_downloadstatus').show(); var set_contents = set_contents.split(','); var prdate = (prettydate) ? prettydate : backup_timestamp; // Old-style, from when it was a form // var data = jQuery('#updraft-navtab-backups-content .uddownloadform_'+what+'_'+backup_timestamp+'_'+set_contents[i]).serialize(); var nonce = jQuery('#updraft-navtab-backups-content .uddownloadform_'+what+'_'+backup_timestamp+'_'+set_contents[0]).data('wp_nonce').toString(); if (!jQuery('.updraftplus_downloader_container_'+what).length) { jQuery(whicharea).append('
                '); jQuery('.updraftplus_downloader_container_' + what).append('' + updraftlion.download + ' ' + what + ' (' + prdate + '):'); } for (var i = 0; i < set_contents.length; i++) { // Create somewhere for the status to be found var stid = base+backup_timestamp+'_'+what+'_'+set_contents[i]; var stid_selector = '.'+stid; var show_index = parseInt(set_contents[i]); show_index++; var itext = (0 == set_contents[i]) ? '' : ' ('+show_index+')'; if (!jQuery(stid_selector).length) { jQuery('.updraftplus_downloader_container_'+what).append('
                '+what+itext+':
                '+updraftlion.begunlooking+'
                '); jQuery(stid_selector).data('downloaderfor', { base: base, nonce: backup_timestamp, what: what, index: set_contents[i] }); setTimeout(function() { updraft_activejobs_update(true); }, 1500); } jQuery(stid_selector).data('lasttimebegan', (new Date).getTime()); } // Now send the actual request to kick it all off async = async ? true : false; var data = { type: what, timestamp: backup_timestamp, findex: set_contents }; var options = { action: 'updraft_download_backup', nonce_key: '_wpnonce', nonce: nonce, timeout: 10000, async: async } updraft_send_command('updraft_download_backup', data, function (response) {}, options); // We don't want the form to submit as that replaces the document return false; } /** * Parse JSON string, including automatically detecting unwanted extra input and skipping it * * @param {string} json_mix_str - JSON string which need to parse and convert to object * @param {boolean} analyse - if true, then the return format will contain information on the parsing, and parsing will skip attempting to JSON.parse() the entire string (will begin with trying to locate the actual JSON) * * @throws SyntaxError|String (including passing on what JSON.parse may throw) if a parsing error occurs. * * @returns Mixed parsed JSON object. Will only return if parsing is successful (otherwise, will throw). If analyse is true, then will rather return an object with properties (mixed)parsed, (integer)json_start_pos and (integer)json_end_pos */ function ud_parse_json(json_mix_str, analyse) { analyse = ('undefined' === typeof analyse) ? false : true; // Just try it - i.e. the 'default' case where things work (which can include extra whitespace/line-feeds, and simple strings, etc.). if (!analyse) { try { var result = JSON.parse(json_mix_str); return result; } catch (e) { console.log('UpdraftPlus: Exception when trying to parse JSON (1) - will attempt to fix/re-parse based upon first/last curly brackets'); console.log(json_mix_str); } } var json_start_pos = json_mix_str.indexOf('{'); var json_last_pos = json_mix_str.lastIndexOf('}'); // Case where some php notice may be added after or before json string if (json_start_pos > -1 && json_last_pos > -1) { var json_str = json_mix_str.slice(json_start_pos, json_last_pos + 1); try { var parsed = JSON.parse(json_str); if (!analyse) { console.log('UpdraftPlus: JSON re-parse successful'); } return analyse ? { parsed: parsed, json_start_pos: json_start_pos, json_last_pos: json_last_pos + 1 } : parsed; } catch (e) { console.log('UpdraftPlus: Exception when trying to parse JSON (2) - will attempt to fix/re-parse based upon bracket counting'); var cursor = json_start_pos; var open_count = 0; var last_character = ''; var inside_string = false; // Don't mistake this for a real JSON parser. Its aim is to improve the odds in real-world cases seen, not to arrive at universal perfection. while ((open_count > 0 || cursor == json_start_pos) && cursor <= json_last_pos) { var current_character = json_mix_str.charAt(cursor); if (!inside_string && '{' == current_character) { open_count++; } else if (!inside_string && '}' == current_character) { open_count--; } else if ('"' == current_character && '\\' != last_character) { inside_string = inside_string ? false : true; } last_character = current_character; cursor++; } console.log("Started at cursor="+json_start_pos+", ended at cursor="+cursor+" with result following:"); console.log(json_mix_str.substring(json_start_pos, cursor)); try { var parsed = JSON.parse(json_mix_str.substring(json_start_pos, cursor)); console.log('UpdraftPlus: JSON re-parse successful'); return analyse ? { parsed: parsed, json_start_pos: json_start_pos, json_last_pos: cursor } : parsed; } catch (e) { // Throw it again, so that our function works just like JSON.parse() in its behaviour. throw e; } } } throw "UpdraftPlus: could not parse the JSON"; } // Catch HTTP errors if the download status check returns them jQuery(document).ajaxError(function(event, jqxhr, settings, exception) { if (exception == null || exception == '') return; if (jqxhr.responseText == null || jqxhr.responseText == '') return; console.log("Error caught by UpdraftPlus ajaxError handler (follows) for "+settings.url); console.log(exception); if (settings.url.search(ajaxurl) == 0) { // TODO subaction=downloadstatus is no longer used. This should be adjusted to the current set-up. if (settings.url.search('subaction=downloadstatus') >= 0) { var timestamp = settings.url.match(/timestamp=\d+/); var type = settings.url.match(/type=[a-z]+/); var findex = settings.url.match(/findex=\d+/); var base = settings.url.match(/base=[a-z_]+/); findex = (findex instanceof Array) ? parseInt(findex[0].substr(7)) : 0; type = (type instanceof Array) ? type[0].substr(5) : ''; base = (base instanceof Array) ? base[0].substr(5) : ''; timestamp = (timestamp instanceof Array) ? parseInt(timestamp[0].substr(10)) : 0; if ('' != base && '' != type && timestamp >0) { var stid = base+timestamp+'_'+type+'_'+findex; jQuery('.'+stid+' .raw').html(''+updraftlion.error+' '+updraftlion.servererrorcode); } } else if (settings.url.search('subaction=restore_alldownloaded') >= 0) { // var timestamp = settings.url.match(/timestamp=\d+/); jQuery('#updraft-restore-modal-stage2a').append('
                '+updraftlion.error+' '+updraftlion.servererrorcode+': '+exception); } } }); function updraft_restorer_checkstage2(doalert) { // How many left? var stilldownloading = jQuery('#ud_downloadstatus2 .file').length; if (stilldownloading > 0) { if (doalert) { alert(updraftlion.stilldownloading); } return; } // Allow pressing 'Restore' to proceed jQuery('.updraft-restore--next-step').prop('disabled', true); jQuery('#updraft-restore-modal-stage2a').html(' '+updraftlion.preparing_backup_files); updraft_send_command('restore_alldownloaded', { timestamp: jQuery('#updraft_restore_timestamp').val(), restoreopts: jQuery('#updraft_restore_form').serialize() }, function(resp, status, data) { var info = null; jQuery('#updraft_restorer_restore_options').val(''); jQuery('.updraft-restore--next-step').prop('disabled', false); try { // var resp = ud_parse_json(data); if (null == resp) { jQuery('#updraft-restore-modal-stage2a').html(updraftlion.emptyresponse); return; } var report = resp.m; if (resp.w != '') { report = report + '

                ' + updraftlion.warnings +'

                ' + resp.w + '
                '; } if (resp.e != '') { report = report + '

                ' + updraftlion.errors+'

                ' + resp.e + '
                '; } else { updraft_restore_stage = 3; } if (resp.hasOwnProperty('i')) { // Store the information passed back from the backup scan try { info = ud_parse_json(resp.i); // if (info.hasOwnProperty('multisite') && info.multisite && info.hasOwnProperty('same_url') && info.same_url) { if (info.hasOwnProperty('addui')) { console.log("Further UI options are being displayed"); var addui = info.addui; report += '
                '+addui+'
                '; if (typeof JSON == 'object' && typeof JSON.stringify == 'function') { // If possible, remove from the stored info, to prevent passing back potentially large amounts of unwanted data delete info.addui; resp.i = JSON.stringify(info); } } if (info.hasOwnProperty('php_max_input_vars')) { php_max_input_vars = parseInt(info.php_max_input_vars); } if (info.hasOwnProperty('skipped_db_scan')) { skipped_db_scan = parseInt(info.skipped_db_scan); } } catch (err) { console.log(err); console.log(resp); } jQuery('#updraft_restorer_backup_info').val(resp.i); } else { jQuery('#updraft_restorer_backup_info').val(); } jQuery('#updraft-restore-modal-stage2a').html(report); jQuery('.updraft-restore--next-step').text(updraftlion.restore); if (jQuery('#updraft-restore-modal-stage2a .updraft_select2').length > 0) { jQuery('#updraft-restore-modal-stage2a .updraft_select2').select2(); } } catch (err) { console.log(data); console.log(err); jQuery('#updraft-restore-modal-stage2a').text(updraftlion.jsonnotunderstood+' '+updraftlion.errordata+": "+data).html(); } }, { error_callback: function(response, status, error_code, resp) { if (typeof resp !== 'undefined' && resp.hasOwnProperty('fatal_error')) { console.error(resp.fatal_error_message); jQuery('#updraft-restore-modal-stage2a').html('

                '+resp.fatal_error_message+'

                '); alert(resp.fatal_error_message); } else { var error_message = "updraft_send_command: error: "+status+" ("+error_code+")"; jQuery('#updraft-restore-modal-stage2a').html('

                '+error_message+'

                '); console.log(error_message); alert(error_message); console.log(response); } } }); } function updraft_downloader_status(base, nonce, what, findex) { // Short-circuit. See previous versions for the old code. return; } function updraft_downloader_status_update(download_status, response_raw) { var cancel_repeat = 0; jQuery(download_status).each(function (x, dstatus) { if (dstatus.base == '') return; var stid = dstatus.base + dstatus.timestamp + '_' + dstatus.what + '_' + dstatus.findex; var stid_selector = '.' + stid; if (dstatus.e != null) { jQuery(stid_selector + ' .raw').html('' + updraftlion.error + ' ' + dstatus.e); console.log(dstatus); } else if (dstatus.p != null) { jQuery(stid_selector + '_st .dlfileprogress').width(dstatus.p + '%'); // jQuery(stid_selector+'_st .dlsofar').html(Math.round(dstatus.s/1024)); // jQuery(stid_selector+'_st .dlsize').html(Math.round(dstatus.t/1024)); // Is a restart appropriate? // dstatus.a, if set, indicates that a) the download is incomplete and b) the value is the number of seconds since the file was last modified... if (dstatus.a != null && dstatus.a > 0) { var timenow = (new Date).getTime(); var lasttimebegan = jQuery(stid_selector).data('lasttimebegan'); // Remember that this is in milliseconds var sincelastrestart = timenow - lasttimebegan; if (dstatus.a > 90 && sincelastrestart > 60000) { console.log(dstatus.timestamp + " " + dstatus.what + " " + dstatus.findex + ": restarting download: file_age=" + dstatus.a + ", sincelastrestart_ms=" + sincelastrestart); jQuery(stid_selector).data('lasttimebegan', (new Date).getTime()); var $original_button = jQuery('#updraft-navtab-backups-content .uddownloadform_' + dstatus.what + '_' + dstatus.timestamp + '_' + dstatus.findex); var data = { type: dstatus.what, timestamp: dstatus.timestamp, findex: dstatus.findex }; var options = { action: 'updraft_download_backup', nonce_key: '_wpnonce', nonce: $original_button.data('wp_nonce').toString(), timeout: 10000 }; updraft_send_command('updraft_download_backup', data, function (response) {}, options); jQuery(stid_selector).data('lasttimebegan', (new Date).getTime()); } } if (dstatus.m != null) { if (dstatus.p >= 100 && 'udrestoredlstatus_' == dstatus.base) { jQuery(stid_selector + ' .raw').html(dstatus.m); jQuery(stid_selector).fadeOut('slow', function () { remove_updraft_downloader(this, dstatus.what); updraft_restorer_checkstage2(0); }); } else if (dstatus.p >= 100 && dstatus.base == 'udclonedlstatus_') { jQuery(stid_selector + ' .raw').html(dstatus.m); jQuery(stid_selector).fadeOut('slow', function () { remove_updraft_downloader(this, dstatus.what); }); } else if (dstatus.p < 100 || dstatus.base != 'uddlstatus_') { jQuery(stid_selector + ' .raw').html(dstatus.m); } else { var file_ready_actions = updraftlion.fileready + ' ' + updraftlion.actions + ': \ \ '; if (dstatus.hasOwnProperty('can_show_contents') && dstatus.can_show_contents) { file_ready_actions += ' '; } jQuery(stid_selector + ' .raw').html(file_ready_actions); jQuery(stid_selector + '_st').remove(); } } // dlstatus_lastlog = response_raw; } else if (dstatus.m != null) { jQuery(stid_selector + ' .raw').html(dstatus.m); } else { jQuery(stid_selector + ' .raw').html(updraftlion.jsonnotunderstood + ' (' + response_raw + ')'); cancel_repeat = 1; } }); return cancel_repeat; } /** * Function that sets up a ajax call to start a backup * * @param {Integer} backupnow_nodb Indicate whether the database should be backed up: valid values are 0, 1 * @param {Integer} backupnow_nofiles Indicate whether any files should be backed up: valid values are 0, 1 * @param {Integer} backupnow_nocloud Indicate whether the backup should be uploaded to cloud storage: valid values are 0, 1 * @param {String} onlythesefileentities A csv list of file entities to be backed up * @param {String} onlythesetableentities A csv list of table entities to be backed up * @param {Array} extradata any extra data to be added * @param {String} label A optional label to be added to a backup * @param {String} only_these_cloud_services An array of remote sorage locations to be backed up to */ function updraft_backupnow_go(backupnow_nodb, backupnow_nofiles, backupnow_nocloud, onlythesefileentities, extradata, label, onlythesetableentities, only_these_cloud_services) { var params = { backupnow_nodb: backupnow_nodb, backupnow_nofiles: backupnow_nofiles, backupnow_nocloud: backupnow_nocloud, backupnow_label: label, extradata: extradata }; if ('' != onlythesefileentities) { params.onlythisfileentity = onlythesefileentities; } if ('' != onlythesetableentities) { params.onlythesetableentities = onlythesetableentities; } if ('' != only_these_cloud_services) { params.only_these_cloud_services = only_these_cloud_services; } params.always_keep = (typeof extradata.always_keep !== 'undefined') ? extradata.always_keep : 0; delete extradata.always_keep; params.incremental = (typeof extradata.incremental !== 'undefined') ? extradata.incremental : 0; delete extradata.incremental; params.db_anon_all = (typeof extradata.db_anon !== 'undefined' && typeof extradata.db_anon.all !== 'undefined') ? extradata.db_anon.all : 0; params.db_anon_non_staff = (typeof extradata.db_anon !== 'undefined' && typeof extradata.db_anon.non_staff !== 'undefined') ? extradata.db_anon.non_staff : 0; params.db_anon_wc_orders = (typeof extradata.db_anon !== 'undefined' && typeof extradata.db_anon.wc_orders !== 'undefined') ? extradata.db_anon.wc_orders : 0; if ('undefined' !== typeof extradata.db_anon) { delete extradata.db_anon.all; delete extradata.db_anon.non_staff; delete extradata.db_anon.wc_orders; } // Display Request start message if (!jQuery('.updraft_requeststart').length) { var requeststart_el = jQuery('
                ').html(''+updraftlion.requeststart); requeststart_el.data('remove', false); setTimeout( function() { requeststart_el.data('remove', true); }, 3000 ); setTimeout( function() { requeststart_el.remove(); }, 75000 ); jQuery('#updraft_activejobsrow').before(requeststart_el); } updraft_activejobslist_backupnownonce_only = 1; updraft_send_command('backupnow', params, function(resp) { if (resp.hasOwnProperty('error')) { jQuery('.updraft_requeststart').remove(); alert(resp.error); return; } jQuery('#updraft_backup_started').html(resp.m); if (resp.hasOwnProperty('nonce')) { // Can't return it from this context updraft_backupnow_nonce = resp.nonce; console.log("UpdraftPlus: ID of started job: "+updraft_backupnow_nonce); } setTimeout(function() { updraft_activejobs_update(true);}, 500); }); } jQuery(function($) { // actioned When the checkout embed is complete $(document).on('udp/checkout/done', function(e, data) { if (data.hasOwnProperty('product') && 'updraftpremium' === data.product && 'complete' === data.status) { $('.premium-upgrade-purchase-success').show(); $('.updraft_feat_table').closest('section').hide(); $('.updraft_premium_cta__action').hide(); } }); // Advanced settings new menu button listeners $('.expertmode .advanced_settings_container .advanced_tools_button').on('click', function() { advanced_tool_hide($(this).attr("id")); }); function advanced_tool_hide(show_tool) { $('.expertmode .advanced_settings_container .advanced_tools:not(".'+show_tool+'")').hide(); $('.expertmode .advanced_settings_container .advanced_tools.'+show_tool).fadeIn('slow'); $('.expertmode .advanced_settings_container .advanced_tools_button:not(#'+show_tool+')').removeClass('active'); $('.expertmode .advanced_settings_container .advanced_tools_button#'+show_tool).addClass('active'); } // https://github.com/select2/select2/issues/1246#issuecomment-71710835 if (jQuery.ui && jQuery.ui.dialog && jQuery.ui.dialog.prototype._allowInteraction) { var ui_dialog_interaction = jQuery.ui.dialog.prototype._allowInteraction; jQuery.ui.dialog.prototype._allowInteraction = function(e) { if (jQuery(e.target).closest('.select2-dropdown').length) return true; return ui_dialog_interaction.apply(this, arguments); }; } // Update WebDAV URL as user edits $('#updraft-navtab-settings-content #remote-storage-holder').on('change keyup paste', '.updraft_webdav_settings', function() { var updraft_webdav_settings = []; $('.updraft_webdav_settings').each(function(index, item) { var id = $(item).attr('id'); if (id && 'updraft_webdav_' == id.substring(0, 15)) { var which_one = id.substring(15); id_split = which_one.split('_'); which_one = id_split[0]; var instance_id = id_split[1]; if ('undefined' == typeof updraft_webdav_settings[instance_id]) updraft_webdav_settings[instance_id] = []; updraft_webdav_settings[instance_id][which_one] = this.value; } }); var updraft_webdav_url = ""; var host = "@"; var slash = "/"; var colon = ":"; var colon_port = ":"; for (var instance_id in updraft_webdav_settings) { if (updraft_webdav_settings[instance_id]['host'].indexOf("@") >= 0 || "" === updraft_webdav_settings[instance_id]['host']) { host = ""; } if (updraft_webdav_settings[instance_id]['host'].indexOf("/") >= 0) { $('.webdav-'+instance_id+' .updraft_webdav_host_error').show(); } else { $('.webdav-'+instance_id+' .updraft_webdav_host_error').hide(); } if (0 == updraft_webdav_settings[instance_id]['path'].indexOf("/") || "" === updraft_webdav_settings[instance_id]['path']) { slash = ""; } if ("" === updraft_webdav_settings[instance_id]['user'] || "" === updraft_webdav_settings[instance_id]['pass']) { colon = ""; } if ("" === updraft_webdav_settings[instance_id]['host'] || "" === updraft_webdav_settings[instance_id]['port']) { colon_port = ""; } updraft_webdav_url = updraft_webdav_settings[instance_id]['webdav'] + updraft_webdav_settings[instance_id]['user'] + colon + updraft_webdav_settings[instance_id]['pass'] + host +encodeURIComponent(updraft_webdav_settings[instance_id]['host']) + colon_port + updraft_webdav_settings[instance_id]['port'] + slash + updraft_webdav_settings[instance_id]['path']; masked_webdav_url = updraft_webdav_settings[instance_id]['webdav'] + updraft_webdav_settings[instance_id]['user'] + colon + updraft_webdav_settings[instance_id]['pass'].replace(/./gi,'*') + host +encodeURIComponent(updraft_webdav_settings[instance_id]['host']) + colon_port + updraft_webdav_settings[instance_id]['port'] + slash + updraft_webdav_settings[instance_id]['path']; $('#updraft_webdav_url_' + instance_id).val(updraft_webdav_url); $('#updraft_webdav_masked_url_' + instance_id).val(masked_webdav_url); } }); $('div.ud-phpseclib-notice').on('click', 'button.notice-dismiss', function (event) { event.stopImmediatePropagation(); updraft_send_command('dismiss_phpseclib_notice', null, function(resp, status, response) { if (!resp.hasOwnProperty('success') || 1 !== resp.success) { console.log(resp); alert(updraftlion.unexpectedresponse+' '+response); } }); }); // Delete button $('#updraft-navtab-backups-content').on('click', '.js--delete-selected-backups', function(e) { e.preventDefault(); updraft_deleteallselected(); }); $('#updraft-navtab-backups-content').on('click', '.updraft_existing_backups .backup-select input', function(e) { // e.preventDefault(); updraft_backups_selection.toggle($(this).closest('.updraft_existing_backups_row')); }); $('#updraft-navtab-backups-content').on('click', '#cb-select-all', function(e) { if ($(this).is(':checked')) { updraft_backups_selection.selectAll(); } else { updraft_backups_selection.deselectAll(); } }); $('#updraft-wrap').on('click', '[id^=updraftplus_manual_authorisation_submit_]', function(e) { e.preventDefault(); var method = $(this).data('method'); var auth_data = $('#updraftplus_manual_authentication_data_'+method).val(); $('#updraftplus_manual_authentication_error_'+method).text(); $('#updraft-wrap #updraftplus_manual_authorisation_template_'+method+' .updraftplus_spinner.spinner').addClass('visible'); $('#updraftplus_manual_authorisation_submit_'+method).prop('disabled', true); manual_remote_storage_auth(method, auth_data); }); /** * This method will send the ajax request to manually authenticate the remote storage method and then update the page with the response * * @param {string} method - the remote storage method * @param {string} auth_data - the auth data as a base64 json encoded string */ function manual_remote_storage_auth(method, auth_data) { updraft_send_command('manual_remote_storage_authentication', {method: method, auth_data: auth_data}, function(response) { $('#updraft-wrap #updraftplus_manual_authorisation_template_'+method+' .updraftplus_spinner.spinner').removeClass('visible'); if (response.hasOwnProperty('result') && 'success' === response.result) { $('#updraft-wrap .updraftplus-top-menu').before(response.data); $('#updraft-wrap #updraftplus_manual_authorisation_template_'+method).parent().remove(); $('#updraft-wrap .updraft_authenticate_'+method).remove(); } else if (response.hasOwnProperty('result') && 'error' === response.result) { $('#updraftplus_manual_authentication_error_'+method).text(response.data); $('#updraftplus_manual_authorisation_submit_'+method).prop('disabled', false); } }); } $('#updraft-navtab-backups-content').on('click', '.js--select-all-backups', function(e) { updraft_backups_selection.selectAll(); }); $('#updraft-navtab-backups-content').on('click', '.js--deselect-all-backups', function(e) { updraft_backups_selection.deselectAll(); }); $('#updraft-navtab-backups-content').on('click', '.updraft_existing_backups .updraft_existing_backups_row', function(e) { if (!e.ctrlKey && !e.metaKey) return; if (e.shiftKey) { // it's multiple range selection, it requires the user to hold shift+ctrl buttons during the range selection, the initial and the new starting index is saved in firstMultipleSelectionIndex variable if ("undefined" == typeof updraft_backups_selection.firstMultipleSelectionIndex) { // if all the above conditions are fulfilled then we need to set up the keyup event handler only for range selection operation. By doing it, we also ignore the Apple Command (metaKey) keycode checking which varies among the browser https://unixpapa.com/js/key.html $(document).on('keyup.MultipleSelection', function(e) { // multiple range selection operation requires the user to hold ctrl/cmd + shift buttons all the time during the selections, the range selection operation will be canceled if the user releases one of the held buttons (shitf or ctrl/cmd) and if that happens the highlight mode will stop working updraft_backups_selection.unregister_highlight_mode(); // once this event handler has been triggered and the highlight mode has been turned off, this event handler needs to be removed by using its namespace .MultipleSelection $(document).off('.MultipleSelection'); }); updraft_backups_selection.select(this); $(this).addClass('range-selection-start'); updraft_backups_selection.register_highlight_mode(); } else { updraft_backups_selection.selectAllInBetween(this); jQuery('#updraft-navtab-backups-content .updraft_existing_backups .updraft_existing_backups_row').removeClass('range-selection'); } // set the new starting index to the ending range index updraft_backups_selection.firstMultipleSelectionIndex = this.rowIndex - 1; } else { updraft_backups_selection.toggle(this); } }); updraft_backups_selection.checkSelectionStatus(); $('#updraft-navtab-addons-content .wrap').on('click', '.updraftplus_com_login .ud_connectsubmit', function (e) { e.preventDefault(); var email = $('#updraft-navtab-addons-content .wrap .updraftplus_com_login #updraftplus-addons_options_email').val(); var password = $('#updraft-navtab-addons-content .wrap .updraftplus_com_login #updraftplus-addons_options_password').val(); var auto_update = $('#updraft-navtab-addons-content .wrap .updraftplus_com_login #updraftplus-addons_options_auto_updates').is(':checked') ? 1: 0; var auto_udc_connect = $('#updraft-navtab-addons-content .wrap .updraftplus_com_login #updraftplus-addons_options_auto_udc_connect').is(':checked') ? 1: 0; var options = { email: email, password: password, auto_update: auto_update, auto_udc_connect: auto_udc_connect }; updraftplus_com_login.submit(options); }); $('#updraft-navtab-addons-content .wrap').on('keydown', '.updraftplus_com_login input', function (e) { if (13 == e.which) { e.preventDefault(); var email = $('#updraft-navtab-addons-content .wrap .updraftplus_com_login #updraftplus-addons_options_email').val(); var password = $('#updraft-navtab-addons-content .wrap .updraftplus_com_login #updraftplus-addons_options_password').val(); var auto_update = $('#updraft-navtab-addons-content .wrap .updraftplus_com_login #updraftplus-addons_options_auto_updates').is(':checked') ? 1: 0; var auto_udc_connect = $('#updraft-navtab-addons-content .wrap .updraftplus_com_login #updraftplus-addons_options_auto_udc_connect').is(':checked') ? 1: 0; var options = { email: email, password: password, auto_update: auto_update, auto_udc_connect: auto_udc_connect }; updraftplus_com_login.submit(options); } }); $('#updraft-navtab-migrate-content').on('click', '.updraftclone_show_step_1', function (e) { $('.updraftplus-clone').addClass('opened'); $('.updraftclone_show_step_1').hide(); $('.updraft_migrate_widget_temporary_clone_stage1').show(); $('.updraft_migrate_widget_temporary_clone_stage0').hide(); }); $('#updraft-navtab-migrate-content').on('click', '.updraft_migrate_widget_temporary_clone_show_stage0', function(e) { e.preventDefault(); $('.updraft_migrate_widget_temporary_clone_stage0').toggle(); }); // First tab setup setup_migrate_tabs(); // hide section when clicking the close button $('#updraft-navtab-migrate-content').on('click', '.updraft_migrate_widget_module_content .close', function (e) { $('.updraft_migrate_intro').show(); $(this).closest('.updraft_migrate_widget_module_content').hide(); }); $('#updraft-navtab-migrate-content').on('click', '#updraft_migrate_tab_alt .close', function (e) { e.preventDefault(); $('.updraft_migrate_intro').show(); $('#updraft_migrate_tab_alt').html('').hide(); }); // Migrate show Add site button $('#updraft-navtab-migrate-content').on('click', '.updraft_migrate_add_site--trigger', function (e) { e.preventDefault(); $('.updraft_migrate_add_site').toggle(); }); $('#updraft-navtab-migrate-content').on('click', '.updraft_migrate_widget_module_content .updraftplus_com_login .ud_connectsubmit', function (e) { e.preventDefault(); var email = $('#updraft-navtab-migrate-content .updraft_migrate_widget_module_content .updraftplus_com_login #temporary_clone_options_email').val(); var password = $('#updraft-navtab-migrate-content .updraft_migrate_widget_module_content .updraftplus_com_login #temporary_clone_options_password').val(); var tfa = $('#updraft-navtab-migrate-content .updraft_migrate_widget_module_content .updraftplus_com_login #temporary_clone_options_two_factor_code').val(); var consent = $('#updraft-navtab-migrate-content .updraft_migrate_widget_module_content .updraftplus_com_login .temporary_clone_terms_and_conditions').is(':checked') ? 1 : 0; var options = { form_data: { email: email, password: password, two_factor_code: tfa, consent: consent } }; if (!email || !password) { $('#updraft-navtab-migrate-content .updraft_migrate_widget_module_content .updraftplus_com_login_status').html('' + updraftlion.error + ' ' + updraftlion.username_password_required).show(); } else { temporary_clone_submit(options); } }); $('#updraft-navtab-migrate-content').on('keydown', '.updraft_migrate_widget_module_content .updraftplus_com_login input', function (e) { if (13 == e.which) { e.preventDefault(); var email = $('#updraft-navtab-migrate-content .updraft_migrate_widget_module_content .updraftplus_com_login #temporary_clone_options_email').val(); var password = $('#updraft-navtab-migrate-content .updraft_migrate_widget_module_content .updraftplus_com_login #temporary_clone_options_password').val(); var tfa = $('#updraft-navtab-migrate-content .updraft_migrate_widget_module_content .updraftplus_com_login #temporary_clone_options_two_factor_code').val(); var consent = $('#updraft-navtab-migrate-content .updraft_migrate_widget_module_content .updraftplus_com_login .temporary_clone_terms_and_conditions').is(':checked') ? 1 : 0; var options = { form_data: { email: email, password: password, two_factor_code: tfa, consent: consent } }; if (!email || !password) { $('#updraft-navtab-migrate-content .updraft_migrate_widget_module_content .updraftplus_com_login_status').html('' + updraftlion.error + ' ' + updraftlion.username_password_required).show(); } else { temporary_clone_submit(options); } } }); $('#updraft-navtab-migrate-content').on('click', '.updraft_migrate_widget_module_content .updraftplus_com_key .ud_key_connectsubmit', function (e) { e.preventDefault(); var clone_key = $('#updraft-navtab-migrate-content .updraft_migrate_widget_module_content .updraftplus_com_key #temporary_clone_options_key').val(); var consent = $('#updraft-navtab-migrate-content .updraft_migrate_widget_module_content .updraftplus_com_key .temporary_clone_terms_and_conditions').is(':checked') ? 1 : 0; var options = { form_data: { clone_key: clone_key, consent: consent } }; if (!clone_key) { $('#updraft-navtab-migrate-content .updraft_migrate_widget_module_content .updraftplus_com_key_status').html('' + updraftlion.error + ' ' + updraftlion.clone_key_required).show(); } else { temporary_clone_key_submit(options); } }); $('#updraft-navtab-migrate-content').on('keydown', '.updraft_migrate_widget_module_content .updraftplus_com_key input', function (e) { if (13 == e.which) { e.preventDefault(); var clone_key = $('#updraft-navtab-migrate-content .updraft_migrate_widget_module_content .updraftplus_com_key #temporary_clone_options_key').val(); var consent = $('#updraft-navtab-migrate-content .updraft_migrate_widget_module_content .updraftplus_com_key .temporary_clone_terms_and_conditions').is(':checked') ? 1 : 0; var options = { form_data: { clone_key: clone_key, consent: consent } }; if (!clone_key) { $('#updraft-navtab-migrate-content .updraft_migrate_widget_module_content .updraftplus_com_key_status').html('' + updraftlion.error + ' ' + updraftlion.clone_key_required).show(); } else { temporary_clone_key_submit(options); } } }); $('#updraft-navtab-migrate-content').on('change', '.updraft_migrate_widget_module_content #updraftplus_clone_php_options', function () { var php_version = $(this).data('php_version'); var selected_version = $(this).val(); if (selected_version < php_version) { $('#updraft-navtab-migrate-content .updraft_migrate_widget_module_content .updraftplus_clone_status').html(updraftlion.clone_version_warning); } else { $('#updraft-navtab-migrate-content .updraft_migrate_widget_module_content .updraftplus_clone_status').html(''); } }); $('#updraft-navtab-migrate-content').on('change', '.updraft_migrate_widget_module_content #updraftplus_clone_wp_options', function () { var wp_version = $(this).data('wp_version'); var selected_version = $(this).val(); if (selected_version < wp_version) { $('#updraft-navtab-migrate-content .updraft_migrate_widget_module_content .updraftplus_clone_status').html(updraftlion.clone_version_warning); } else { $('#updraft-navtab-migrate-content .updraft_migrate_widget_module_content .updraftplus_clone_status').html(''); } }); $('#updraft-navtab-migrate-content').on('change', '.updraft_migrate_widget_module_content #updraftplus_clone_backup_options', function() { // reset the package list $('#updraft-navtab-migrate-content .updraft_migrate_widget_module_content #updraftplus_clone_package_options > option').each(function() { var value = $(this).val(); if ('starter' == value) $('#updraft-navtab-migrate-content .updraft_migrate_widget_module_content #updraftplus_clone_package_options option[value="'+value+'"]').prop('selected', true); $('#updraft-navtab-migrate-content .updraft_migrate_widget_module_content #updraftplus_clone_package_options option[value="'+value+'"]').prop("disabled", false); }); var clone_backup_select = $(this).find('option:selected'); if ('current' == $(clone_backup_select).data('nonce') || 'wp_only' == $(clone_backup_select).data('nonce')) return; var total_size = $(clone_backup_select).data('size'); // Disable packages that are to small for this backup set, then set the first available package as the selected option $('#updraft-navtab-migrate-content .updraft_migrate_widget_module_content #updraftplus_clone_package_options > option').each(function() { var size = $(this).data('size'); var value = $(this).val(); if (total_size >= size) { $('#updraft-navtab-migrate-content .updraft_migrate_widget_module_content #updraftplus_clone_package_options option[value="'+value+'"]').prop("disabled", true); } else { $('#updraft-navtab-migrate-content .updraft_migrate_widget_module_content #updraftplus_clone_package_options option[value="'+value+'"]').prop('selected', true); return false; } }); }); $('#updraft-navtab-migrate-content').on('click', '.updraft_migrate_widget_module_content #updraft_migrate_createclone', function (e) { e.preventDefault(); $('#updraft-navtab-migrate-content .updraft_migrate_widget_module_content #updraft_migrate_createclone').prop('disabled', true); $('#updraft-navtab-migrate-content .updraft_migrate_widget_module_content .updraftplus_clone_status').html(''); $('#updraft-navtab-migrate-content .updraft_migrate_widget_module_content .updraftplus_spinner.spinner').addClass('visible'); var clone_id = $(this).data('clone_id'); var secret_token = $(this).data('secret_token'); var php_version = $('#updraft-navtab-migrate-content .updraft_migrate_widget_module_content #updraftplus_clone_php_options').val(); var wp_version = $('#updraft-navtab-migrate-content .updraft_migrate_widget_module_content #updraftplus_clone_wp_options').val(); var region = $('#updraft-navtab-migrate-content .updraft_migrate_widget_module_content #updraftplus_clone_region_options').val(); var package = $('#updraft-navtab-migrate-content .updraft_migrate_widget_module_content #updraftplus_clone_package_options').val(); var updraftclone_branch = $('#updraft-navtab-migrate-content .updraft_migrate_widget_module_content #updraftplus_clone_updraftclone_branch').val(); var updraftplus_branch = $('#updraft-navtab-migrate-content .updraft_migrate_widget_module_content #updraftplus_clone_updraftplus_branch').val(); var admin_only = $('#updraft-navtab-migrate-content .updraft_migrate_widget_module_content .updraftplus_clone_admin_login_options').is(':checked'); var use_queue = $('#updraftplus_clone_use_queue').is(':checked') ? 1 : 0; var db_anon_all = $('#updraft-navtab-migrate-content .updraft_migrate_widget_module_content #updraftplus_clone_backupnow_db_anon_all').is(':checked') ? 1 : 0; var db_anon_non_staff = $('#updraft-navtab-migrate-content .updraft_migrate_widget_module_content #updraftplus_clone_backupnow_db_anon_non_staff').is(':checked') ? 1 : 0; var db_anon_wc_orders = $('#updraft-navtab-migrate-content .updraft_migrate_widget_module_content #updraftplus_clone_backupnow_db_anon_wc_order_data').is(':checked') ? 1 : 0; var backup_nonce = 'current'; var backup_timestamp = 'current'; var clone_backup_select_length = $('#updraft-navtab-migrate-content .updraft_migrate_widget_module_content #updraftplus_clone_backup_options').length; var clone_backup_select = $('#updraft-navtab-migrate-content .updraft_migrate_widget_module_content #updraftplus_clone_backup_options').find('option:selected'); if (0 !== clone_backup_select_length && 'undefined' !== typeof clone_backup_select) { backup_nonce = clone_backup_select.data('nonce'); backup_timestamp = clone_backup_select.data('timestamp'); } var options = { form_data: { clone_id: clone_id, secret_token: secret_token, install_info: { php_version: php_version, wp_version: wp_version, region: region, package: package, admin_only: admin_only, updraftclone_branch: ('undefined' === typeof updraftclone_branch) ? '' : updraftclone_branch, updraftplus_branch: ('undefined' === typeof updraftplus_branch) ? '' : updraftplus_branch, use_queue: ('undefined' === typeof use_queue) ? 1 : use_queue } } }; var backup_options = { db_anon_all: db_anon_all, db_anon_non_staff: db_anon_non_staff, db_anon_wc_orders: db_anon_wc_orders, clone_region: region } if ('wp_only' === backup_nonce) { options['form_data']['install_info']['wp_only'] = 1; } temporary_clone_process_create(options, backup_timestamp, backup_nonce, backup_options); }); // Create a updraftplus_com_login object, to store functions and variables var updraftplus_com_login = {}; updraftplus_com_login.set_status = function(status) { $('#updraft-navtab-addons-content .wrap').find('.updraftplus_spinner.spinner').text(status); } updraftplus_com_login.show_loader = function() { $('#updraft-navtab-addons-content .wrap').find('.updraftplus_spinner.spinner').addClass('visible'); $('#updraft-navtab-addons-content .wrap').find('.ud_connectsubmit').prop('disabled', 'disabled'); } updraftplus_com_login.hide_loader = function() { $('#updraft-navtab-addons-content .wrap').find('.updraftplus_spinner.spinner').removeClass('visible').text(updraftlion.processing); $('#updraft-navtab-addons-content .wrap').find('.ud_connectsubmit').prop('disabled', false); } /* This function will send an AJAX request to the backend to check the users credentials, then it will either inform the user of any errors or if there are none it will submit the form. @param {array} options - an array that includes the users email and password */ updraftplus_com_login.submit = function(options) { $('#updraft-navtab-addons-content .wrap .updraftplus_com_login_status').html('').hide(); if (this.stage) { switch (this.stage) { case 'connect_udc': case 'connect_udc_TFA': // update data in object var email = $('#updraftplus-addons_options_email').val(); var password = $('#updraftplus-addons_options_password').val(); this.login_data.email = email; this.login_data.password = password; // connect_udc again this.connect_udc(); break; case 'create_key': this.create_key(); break; default: this.stage = null; updraftplus_com_login.submit(); break; } return; } this.set_status(updraftlion.connecting); this.show_loader(); updraft_send_command('updraftplus_com_login_submit', { data: options, }, function (response) { if (response.hasOwnProperty('success')) { // logged in was successful, so create a key if the checkbox was checked. if ($('#updraftplus-addons_options_auto_udc_connect').is(':checked')) { this.login_data = { email: options.email, password: options.password, i_consent: 1, two_factor_code: '' }; // CREATE KEY updraftplus_com_login.create_key(); } else { updraftplus_com_login.hide_loader(); $('#updraft-navtab-addons-content .wrap .updraftplus_com_login').trigger('submit'); } } else if (response.hasOwnProperty('error')) { updraftplus_com_login.hide_loader(); $('#updraft-navtab-addons-content .wrap .updraftplus_com_login_status').html(response.message).show(); } }.bind(this)); } updraftplus_com_login.create_key = function() { this.stage = 'create_key'; this.set_status(updraftlion.udc_cloud_connected); this.show_loader(); var command_data = { where_send: '__updraftpluscom', key_description: '', key_size: null, mothership_firewalled: 0 }; // updraftcentral_cloud_show_spinner(modal); updraft_send_command('updraftcentral_create_key', command_data, function(response) { // updraftcentral_cloud_hide_spinner(modal); try { var data = ud_parse_json(response); if (data.hasOwnProperty('error')) { console.log(data); return; } if (data.hasOwnProperty('bundle')) { console.log('bundle', data.bundle); this.login_data.key = data.bundle, this.stage = 'connect_udc'; updraftplus_com_login.connect_udc(); } else { if (data.hasOwnProperty('r')) { $('#updraft-navtab-addons-content .wrap .updraftplus_com_login_status').html(updraftlion.trouble_connecting).show(); alert(data.r); } else { $('#updraft-navtab-addons-content .wrap .updraftplus_com_login_status').html(updraftlion.trouble_connecting).show(); console.log(data); } updraftplus_com_login.hide_loader(); } } catch (err) { console.log(err); updraftplus_com_login.hide_loader(); } }.bind(this), { json_parse: false }); } updraftplus_com_login.connect_udc = function() { var container = $('#updraft-navtab-addons-content .wrap'); updraftplus_com_login.set_status(updraftlion.udc_cloud_key_created); updraftplus_com_login.show_loader(); if ('connect_udc_TFA' == this.stage) { this.login_data.two_factor_code = container.find('input#updraftplus-addons_options_two_factor_code').val(); updraftplus_com_login.set_status(updraftlion.checking_tfa_code); } var login_data = { form_data: this.login_data }; login_data.form_data.addons_options_connect = 1; // Final step, connect UDC with the Key and all. updraft_send_command('process_updraftcentral_login', login_data, function(login_response) { try { var data = ud_parse_json(login_response); if (data.hasOwnProperty('error')) { if ('incorrect_password' === data.code) { container.find('.tfa_fields').hide(); container.find('.non_tfa_fields').show(); container.find('input#updraftplus-addons_options_two_factor_code').val(''); container.find('input#updraftplus-addons_options_password').val('').trigger('focus'); } if ('no_key_found' === data.code) { this.stage = 'create_key'; } // Continue with UpdraftPlus account even if the user has used all UpdraftCentral licences if ('no_licences_available' === data.code) { $('#updraft-navtab-addons-content .wrap .updraftplus_com_login_status').html(updraftlion.login_udc_no_licences_short).show(); data.status = 'authenticated'; container.find('input[name="_wp_http_referer"]').val(function(index, val) { return val + '&udc_connect=0'; }); } else { $('#updraft-navtab-addons-content .wrap .updraftplus_com_login_status').html(data.message).show(); $('#updraft-navtab-addons-content .wrap .updraftplus_com_login_status').find('a').attr('target', '_blank'); console.log(data); updraftplus_com_login.hide_loader(); return; } } if (data.hasOwnProperty('tfa_enabled') && true == data.tfa_enabled) { $('#updraft-navtab-addons-content .wrap .updraftplus_com_login_status').html('').hide(); container.find('.non_tfa_fields').hide(); container.find('.tfa_fields').show(); container.find('input#updraftplus-addons_options_two_factor_code').trigger('focus'); this.stage = 'connect_udc_TFA'; } if ('authenticated' === data.status) { container.find('.non_tfa_fields').hide(); container.find('.tfa_fields').hide(); container.find('.updraft-after-form-table').hide(); this.stage = null; $('#updraft-navtab-addons-content .wrap .updraftplus_com_login_status').html(updraftlion.login_successful_short).show().addClass('success'); // submit the form (to reload the page). setTimeout(function() { $('#updraft-navtab-addons-content .wrap form.updraftplus_com_login').trigger('submit'); }, 1000); } } catch (err) { console.log(err); } updraftplus_com_login.hide_loader(); }.bind(this), { json_parse: false }); } /** * This function will send an AJAX request to the backend to check the users credentials, then it will either inform the user of any errors or display UI elements that include their token count and a way to create new clones. * * @param {array} options - an array that includes the users email and password */ function temporary_clone_submit(options) { $('#updraft-navtab-migrate-content .updraft_migrate_widget_module_content .updraftplus_com_login_status').html('').hide(); $('#updraft-navtab-migrate-content .updraft_migrate_widget_module_content .updraftplus_com_login .updraftplus_spinner.spinner').addClass('visible'); updraft_send_command('process_updraftplus_clone_login', options, function (response) { try { $('#updraft-navtab-migrate-content .updraft_migrate_widget_module_content .updraftplus_com_login .updraftplus_spinner.spinner').removeClass('visible'); if (response.hasOwnProperty('status') && 'error' == response.status) { $('#updraft-navtab-migrate-content .updraft_migrate_widget_module_content .updraftplus_com_login_status').html(response.message).show(); $('#updraft-navtab-migrate-content .updraft_migrate_widget_module_content .updraft_migrate_widget_temporary_clone_stage1 .tfa_fields').hide(); $('#updraft-navtab-migrate-content .updraft_migrate_widget_module_content .updraft_migrate_widget_temporary_clone_stage1 .non_tfa_fields').show(); $('#updraft-navtab-migrate-content .updraft_migrate_widget_module_content .updraftplus_com_login #temporary_clone_options_two_factor_code').val(''); return; } if (response.hasOwnProperty('tfa_enabled') && true == response.tfa_enabled) { $('#updraft-navtab-migrate-content .updraft_migrate_widget_module_content .updraft_migrate_widget_temporary_clone_stage1 .non_tfa_fields').hide(); $('#updraft-navtab-migrate-content .updraft_migrate_widget_module_content .updraft_migrate_widget_temporary_clone_stage1 .tfa_fields').show(); $('#updraft-navtab-migrate-content .updraft_migrate_widget_module_content .updraft_migrate_widget_temporary_clone_stage1 input#temporary_clone_options_two_factor_code').trigger('focus'); } if ('authenticated' === response.status) { $('#updraft-navtab-migrate-content .updraft_migrate_widget_module_content .updraft_migrate_widget_temporary_clone_stage1').hide(); $('#updraft-navtab-migrate-content .updraft_migrate_widget_module_content .updraft_migrate_widget_temporary_clone_stage1 .non_tfa_fields').show(); $('#updraft-navtab-migrate-content .updraft_migrate_widget_module_content .updraft_migrate_widget_temporary_clone_stage1 .tfa_fields').hide(); $('#updraft-navtab-migrate-content .updraft_migrate_widget_module_content .updraft_migrate_widget_temporary_clone_stage1 input#temporary_clone_options_two_factor_code').val(''); $('#updraft-navtab-migrate-content .updraft_migrate_widget_module_content .updraft_migrate_widget_temporary_clone_stage2').show(); $('#updraft-navtab-migrate-content .updraft_migrate_widget_module_content .updraft_migrate_widget_temporary_clone_stage2').html(response.html); if (response.hasOwnProperty('clone_info') && response.clone_info.hasOwnProperty('expires_after')) temporary_clone_timer(response.clone_info.expires_after); } } catch (err) { console.log(err); } }); } /** * This function will send an AJAX request to the backend to check the clone key, then it will either inform the user of any errors or display UI elements that include their token count and a way to create new clones. * * @param {array} options - an array that includes the clone key */ function temporary_clone_key_submit(options) { $('#updraft-navtab-migrate-content .updraft_migrate_widget_module_content .updraftplus_com_key_status').html('').hide(); $('#updraft-navtab-migrate-content .updraft_migrate_widget_module_content .updraftplus_com_key .updraftplus_spinner.spinner').addClass('visible'); updraft_send_command('process_updraftplus_clone_login', options, function (response) { try { $('#updraft-navtab-migrate-content .updraft_migrate_widget_module_content .updraftplus_com_key .updraftplus_spinner.spinner').removeClass('visible'); if (response.hasOwnProperty('status') && 'error' == response.status) { $('#updraft-navtab-migrate-content .updraft_migrate_widget_module_content .updraftplus_com_key_status').html(response.message).show(); return; } if ('authenticated' === response.status) { $('#updraft-navtab-migrate-content .updraft_migrate_widget_module_content .updraft_migrate_widget_temporary_clone_stage1').hide(); $('#updraft-navtab-migrate-content .updraft_migrate_widget_module_content .updraft_migrate_widget_temporary_clone_stage2').show(); $('#updraft-navtab-migrate-content .updraft_migrate_widget_module_content .updraft_migrate_widget_temporary_clone_stage2').html(response.html); if (response.hasOwnProperty('clone_info') && response.clone_info.hasOwnProperty('expires_after')) temporary_clone_timer(response.clone_info.expires_after); } } catch (err) { console.log(err); } }); } /** * This function will add a timer to reset the UI if the user does not create the clone before it expires * * @param {integer} expires_after - the clone expires time in seconds */ function temporary_clone_timer(expires_after) { // the expires_after time is in seconds we need it in milliseconds for the setTimeout function var timeout = expires_after * 1000; temporary_clone_timeout = setTimeout(function () { $('#updraft-navtab-migrate-content .updraft_migrate_widget_module_content .updraft_migrate_widget_temporary_clone_stage2').hide(); $('#updraft-navtab-migrate-content .updraft_migrate_widget_module_content .updraft_migrate_widget_temporary_clone_stage2').html(''); $('#updraft-navtab-migrate-content .updraft_migrate_widget_module_content .updraft_migrate_widget_temporary_clone_stage1').show(); }, timeout); } /** * This function will check if we are using an existing backup and if anything needs downloading before proceeding to process the clone create command * * @param {array} options - an array of options to create the clone * @param {string} backup_timestamp - the timestamp of the backup we want to use or 'current' to create a new backup * @param {string} backup_nonce - the backup nonce of the backup we want to use or 'current' to create a new backup * @param {array} backup_options - an array of options for the backup */ function temporary_clone_process_create(options, backup_timestamp, backup_nonce, backup_options) { var which_to_download = ''; if ('current' != backup_timestamp) { updraft_send_command('whichdownloadsneeded', { updraftplus_clone: true, timestamp: backup_timestamp }, function (response) { if (response.hasOwnProperty('downloads')) { console.log('UpdraftPlus: items which still require downloading follow'); which_to_download = response.downloads; console.log(which_to_download); } // Kick off any downloads, if needed if (0 == which_to_download.length) return; for (var i = 0; i < which_to_download.length; i++) { // updraft_downloader(base, backup_timestamp, what, whicharea, set_contents, prettydate, async) updraft_downloader('udclonedlstatus_', backup_timestamp, which_to_download[i][0], '#ud_downloadstatus3', which_to_download[i][1], '', false); } }, { alert_on_error: false, error_callback: function (response, status, error_code, resp) { if (typeof resp !== 'undefined' && resp.hasOwnProperty('fatal_error')) { console.error(resp.fatal_error_message); $('#updraft-navtab-migrate-content .updraft_migrate_widget_module_content .updraftplus_clone_status').html('

                ' + resp.fatal_error_message + '

                '); } else { var error_message = "updraft_send_command: error: " + status + " (" + error_code + ")"; $('#updraft-navtab-migrate-content .updraft_migrate_widget_module_content .updraftplus_clone_status').html('

                ' + error_message + '

                '); console.log(error_message); console.log(response); } } }); } setTimeout(function () { if (0 != which_to_download.length) { temporary_clone_process_create(options, backup_timestamp, backup_nonce, backup_options); return; } var clone_id = options['form_data']['clone_id']; var secret_token = options['form_data']['secret_token']; updraft_send_command('process_updraftplus_clone_create', options, function (response) { try { $('#updraft-navtab-migrate-content .updraft_migrate_widget_module_content #updraft_migrate_createclone').prop('disabled', false); $('#updraft-navtab-migrate-content .updraft_migrate_widget_module_content .updraftplus_spinner.spinner').removeClass('visible'); if (response.hasOwnProperty('status') && 'error' == response.status) { $('#updraft-navtab-migrate-content .updraft_migrate_widget_module_content .updraftplus_clone_status').html(updraftlion.error + ' ' + response.message).show(); return; } if ('success' === response.status) { $('#updraft-navtab-migrate-content .updraft_migrate_widget_module_content .updraft_migrate_widget_temporary_clone_stage2').hide(); $('#updraft-navtab-migrate-content .updraft_migrate_widget_module_content .updraft_migrate_widget_temporary_clone_stage3').show(); $('#updraft-navtab-migrate-content .updraft_migrate_widget_module_content .updraft_migrate_widget_temporary_clone_stage3').html(response.html); // remove the clone timeout as the clone has now been created if (temporary_clone_timeout) clearTimeout(temporary_clone_timeout); // check if the response includes a secret token, if it does we have claimed a clone from the queue and need to update our current secret token to the one that belongs to the claimed clone if (response.hasOwnProperty('secret_token')) { secret_token = response.secret_token; } if ('wp_only' === backup_nonce) { jQuery('#updraft_clone_progress .updraftplus_spinner.spinner').addClass('visible'); temporary_clone_poll(clone_id, secret_token); } else { jQuery('#updraft_clone_progress .updraftplus_spinner.spinner').addClass('visible'); temporary_clone_boot_backup(clone_id, secret_token, response.url, response.key, backup_nonce, backup_timestamp, backup_options); } } } catch (err) { $('#updraft-navtab-migrate-content .updraft_migrate_widget_module_content #updraft_migrate_createclone').prop('disabled', false); console.log("Error when processing the response of process_updraftplus_clone_create (as follows)"); console.log(err); } }); }, 5000); } /** * This function will send an AJAX request to the backend to start a clone backup job * * @param {string} clone_id - the clone id * @param {string} secret_token - the clone secret * @param {string} clone_url - the clone url * @param {string} key - the migration key * @param {string} backup_nonce - the nonce for the backup we want to use or 'current' for a fresh backup * @param {string} backup_timestamp - the timestamp for the backup we want to use or 'current' for a fresh backup * @param {array} backup_options - an array of options for the backup */ function temporary_clone_boot_backup(clone_id, secret_token, clone_url, key, backup_nonce, backup_timestamp, backup_options) { var params = { updraftplus_clone_backup: 1, backupnow_nodb: 0, backupnow_nofiles: 0, backupnow_nocloud: 0, backupnow_label: 'UpdraftClone', extradata: '', onlythisfileentity: 'plugins,themes,uploads,others', clone_id: clone_id, secret_token: secret_token, clone_url: clone_url, key: key, backup_nonce: backup_nonce, backup_timestamp: backup_timestamp, db_anon_all: backup_options['db_anon_all'], db_anon_non_staff: backup_options['db_anon_non_staff'], db_anon_wc_orders: backup_options['db_anon_wc_orders'], clone_region: backup_options['clone_region'] }; updraft_activejobslist_backupnownonce_only = 1; updraft_send_command('backupnow', params, function (response) { jQuery('#updraft_clone_progress .updraftplus_spinner.spinner').removeClass('visible'); jQuery('#updraft_backup_started').html(response.m); if (response.hasOwnProperty('nonce')) { // Can't return it from this context updraft_backupnow_nonce = response.nonce; updraft_clone_jobs.push(updraft_backupnow_nonce); updraft_inpage_success_callback = function () { jQuery('#updraft_clone_activejobsrow').hide(); // If user aborts the job if (updraft_aborted_jobs[updraft_backupnow_nonce]) { jQuery('#updraft_clone_progress').html(updraftlion.clone_backup_aborted); } else { jQuery('#updraft_clone_progress').html(updraftlion.clone_backup_complete); } }; console.log("UpdraftPlus: ID of started job: " + updraft_backupnow_nonce); } updraft_activejobs_update(true); }); } /** * This function will send an AJAX request to the backend to poll for the clones install information * * @param {string} clone_id - the clone id * @param {string} secret_token - the clone secret */ function temporary_clone_poll(clone_id, secret_token) { var options = { clone_id: clone_id, secret_token: secret_token, }; setTimeout(function () { updraft_send_command('process_updraftplus_clone_poll', options, function (response) { if (response.hasOwnProperty('status')) { if ('error' == response.status) { $('#updraft-navtab-migrate-content .updraft_migrate_widget_module_content .updraftplus_clone_status').html(updraftlion.error + ' ' + response.message).show(); return; } if ('success' === response.status) { if (response.hasOwnProperty('data') && response.data.hasOwnProperty('wordpress_credentials')) { $('#updraft-navtab-migrate-content .updraft_migrate_widget_module_content .updraftplus_spinner.spinner').removeClass('visible'); $('#updraft-navtab-migrate-content .updraft_migrate_widget_module_content #updraft_clone_progress').append('
                WordPress ' + updraftlion.credentials + ':
                ' + updraftlion.username + ': ' + response.data.wordpress_credentials.username + '
                ' + updraftlion.password + ': ' + response.data.wordpress_credentials.password); return; } } } else { console.log(response); } temporary_clone_poll(clone_id, secret_token); }); }, 60000); } $('#updraft-navtab-settings-content #remote-storage-holder').on('click', '.updraftplusmethod a.updraft_add_instance', function(e) { e.preventDefault(); updraft_settings_form_changed = true; var method = $(this).data('method'); add_new_instance(method); }); $('#updraft-navtab-settings-content #remote-storage-holder').on('click', '.updraftplusmethod a.updraft_delete_instance', function(e) { e.preventDefault(); updraft_settings_form_changed = true; var method = $(this).data('method'); var instance_id = $(this).data('instance_id'); if (1 === $('.' + method + '_updraft_remote_storage_border').length) { add_new_instance(method); } $('.' + method + '-' + instance_id).hide('slow', function() { $(this).remove(); }); }); $('#updraft-navtab-settings-content #remote-storage-holder').on('click', '.updraftplusmethod .updraft_edit_label_instance', function(e) { $(this).find('span').hide(); $(this).attr('contentEditable', true).trigger('focus'); }); $('#updraft-navtab-settings-content #remote-storage-holder').on('keyup', '.updraftplusmethod .updraft_edit_label_instance', function(e) { var method = jQuery(this).data('method'); var instance_id = jQuery(this).data('instance_id'); var content = jQuery(this).text(); $('#updraft_' + method + '_instance_label_' + instance_id).val(content); }); $('#updraft-navtab-settings-content #remote-storage-holder').on('blur', '.updraftplusmethod .updraft_edit_label_instance', function(e) { $(this).attr('contentEditable', false); $(this).find('span').show(); }); $('#updraft-navtab-settings-content #remote-storage-holder').on('keypress', '.updraftplusmethod .updraft_edit_label_instance', function(e) { if (13 === e.which) { $(this).attr('contentEditable', false); $(this).find('span').show(); $(this).trigger('blur'); } }); /** * This method will get the default options and compile a template with them * * @param {string} method - the remote storage name * @param {boolean} first_instance - indicates if this is the first instance of this type */ function add_new_instance(method) { var template = Handlebars.compile(updraftlion.remote_storage_templates[method]); var context = {}; // Initiate a reference by assigning an empty object to a variable (in this case the context variable) so that it can be used as a target of merging one or more other objects. Unlike basic values (boolean, string, integer, etc.), in Javascript objects and arrays are passed by reference // copy what are in the template properties to the context overwriting the same object properties, and then copy what are in the default instance settings to the context overwriting all the same properties from the previous merging operation (if any). The context properties are overwritten by other objects that have the same properties later in the parameters order Object.assign(context, updraftlion.remote_storage_options[method]['template_properties'], updraftlion.remote_storage_options[method]['default']); var method_name = updraftlion.remote_storage_methods[method]; context['instance_id'] = 's-' + generate_instance_id(32); context['instance_enabled'] = 1; context['instance_label'] = method_name + ' (' + (jQuery('.' + method + '_updraft_remote_storage_border').length + 1) + ')'; context['instance_conditional_logic'] = { type: '', // always by default rules: [], day_of_the_week_options: updraftlion.conditional_logic.day_of_the_week_options, logic_options: updraftlion.conditional_logic.logic_options, operand_options: updraftlion.conditional_logic.operand_options, operator_options: updraftlion.conditional_logic.operator_options, }; var html = template(context); jQuery(html).hide().insertAfter(jQuery('.' + method + '_add_instance_container').first()).show('slow'); } /** * This method will return a random instance id string * * @param {integer} length - the length of the string to be generated * * @return string - the instance id */ function generate_instance_id(length) { var uuid = ''; var characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; for (var i = 0; i < length; i++) { uuid += characters.charAt(Math.floor(Math.random() * characters.length)); } return uuid; } jQuery('#updraft-navtab-settings-content #remote-storage-holder').on("change", "input[class='updraft_instance_toggle']", function () { updraft_settings_form_changed = true; if (jQuery(this).is(':checked')) { jQuery(this).siblings('label').html(updraftlion.instance_enabled); } else { jQuery(this).siblings('label').html(updraftlion.instance_disabled); } }); jQuery('#updraft-navtab-settings-content #remote-storage-holder').on("change", "select[class='logic_type']", function () { updraft_settings_form_changed = true; if ('' !== this.value) { jQuery('div.logic', jQuery(this).parents('tr.updraftplusmethod')).show(); jQuery(this).parents('tr.updraftplusmethod').find('div.logic ul.rules > li').each(function() { jQuery(this).find('select').each(function() { jQuery(this).prop('disabled', false); }) }); } else { jQuery(this).parents('tr.updraftplusmethod').find('div.logic ul.rules > li').each(function() { jQuery(this).find('select').each(function() { jQuery(this).prop('disabled', true); }) }); jQuery(this).parents('tr.updraftplusmethod').find('div.logic').hide(); } }); jQuery('#updraft-navtab-settings-content #remote-storage-holder').on("change", "select[class='conditional_logic_operand']", function () { updraft_settings_form_changed = true; jQuery(this).parent().find('select:nth(2)').empty(); if ('day_of_the_week' === jQuery(this).val()) { for (var i=0; i').text(updraftlion.conditional_logic.day_of_the_week_options[i].value)); } } else if ('day_of_the_month' === jQuery(this).val()) { for (var i=1; i<=31; i++) { jQuery(this).parent().find('select:nth(2)').append(jQuery('').text(i)); } } }); jQuery('#updraft-navtab-settings-content #remote-storage-holder').on("click", "div.conditional_remote_backup ul.rules li span", function () { updraft_settings_form_changed = true; var $ul = jQuery(this).parents('ul.rules'); if (jQuery(this).hasClass('remove-rule')) { jQuery(this).parent().slideUp(function() { jQuery(this).remove(); if (jQuery($ul).find('> li').length < 2) { jQuery('li:nth(0) span.remove-rule', $ul).remove(); } }); } }); jQuery('#updraft-navtab-settings-content #remote-storage-holder').on("click", "div.conditional_remote_backup input.add-new-rule", function () { var $ul = jQuery(this).parent().find('ul.rules'); if (jQuery($ul).find('> li').length < 2) { jQuery($ul).find('li:nth(0)').append(''); } $cloned_item = jQuery($ul).find('> li').last().clone(); jQuery($cloned_item).find('> select').each(function() { jQuery(this).prop('name', jQuery(this).prop('name').replace(/\[instance_conditional_logic\]\[rules\]\[[0-9]+\]/gi, '[instance_conditional_logic][rules]['+jQuery($ul).data('rules')+']')); }); jQuery($ul).append($cloned_item); jQuery($ul).data('rules', parseInt(jQuery($ul).data('rules')) + 1); jQuery($cloned_item).find('select[name*="[operand]"]').trigger('change'); }); jQuery('#updraft-navtab-settings-content #remote-storage-holder').on('click', '.updraftplusmethod button.updraft-test-button', function() { var method = jQuery(this).data('method'); var instance_id = jQuery(this).data('instance_id'); updraft_remote_storage_test(method, function(response, status, data) { if ('sftp' != method) { return false; } if (data.hasOwnProperty('scp') && data.scp) { alert(updraftlion.settings_test_result.replace('%s', 'SCP')+' '+response.output); } else { alert(updraftlion.settings_test_result.replace('%s', 'SFTP')+' '+response.output); } if (response.hasOwnProperty('data') && response.data) { if (response.data.hasOwnProperty('valid_md5_fingerprint') && response.data.valid_md5_fingerprint) { $('#updraft_sftp_fingerprint_'+instance_id).val(response.data.valid_md5_fingerprint); } } return true; }, instance_id); }); $('#updraft-navtab-settings-content select.updraft_interval, #updraft-navtab-settings-content select.updraft_interval_database').on('change', function() { updraft_check_same_times(); }); $('#backupnow_includefiles_showmoreoptions').on('click', function(e) { e.preventDefault(); $('#backupnow_includefiles_moreoptions').toggle(); }); $('#backupnow_database_showmoreoptions').on('click', function(e) { e.preventDefault(); $('#backupnow_database_moreoptions').toggle(); }); $('#updraft-navtab-migrate-content').on('click', '#backupnow_database_showmoreoptions', function (e) { e.preventDefault(); $('#updraft-navtab-migrate-content #backupnow_database_moreoptions').toggle(); }); $('#backupnow_db_anon_all').on('click', function(e) { if ($('#backupnow_db_anon_non_staff').prop('checked')) $('#backupnow_db_anon_non_staff').prop("checked", false); }); $('#backupnow_db_anon_non_staff').on('click', function(e) { if ($('#backupnow_db_anon_all').prop('checked')) $('#backupnow_db_anon_all').prop("checked", false); }); $('#updraft-navtab-migrate-content').on('click', '#updraftplus_migration_backupnow_db_anon_all', function() { if ($('#updraftplus_migration_backupnow_db_anon_non_staff').prop('checked')) $('#updraftplus_migration_backupnow_db_anon_non_staff').prop("checked", false); }); $('#updraft-navtab-migrate-content').on('click', '#updraftplus_migration_backupnow_db_anon_non_staff', function() { if ($('#updraftplus_migration_backupnow_db_anon_all').prop('checked')) $('#updraftplus_migration_backupnow_db_anon_all').prop("checked", false); }); $('#updraft-navtab-migrate-content').on('click', '#updraftplus_clone_backupnow_db_anon_all', function() { if ($('#updraftplus_clone_backupnow_db_anon_non_staff').prop('checked')) $('#updraftplus_clone_backupnow_db_anon_non_staff').prop("checked", false); }); $('#updraft-navtab-migrate-content').on('click', '#updraftplus_clone_backupnow_db_anon_non_staff', function() { if ($('#updraftplus_clone_backupnow_db_anon_all').prop('checked')) $('#updraftplus_clone_backupnow_db_anon_all').prop("checked", false); }); $('#updraft-backupnow-modal').on('click', '#backupnow_includecloud_showmoreoptions', function(e) { e.preventDefault(); $('#backupnow_includecloud_moreoptions').toggle(); }); $('#updraft-navtab-backups-content').on('click', 'a.updraft_diskspaceused_update',function(e) { e.preventDefault(); updraftplus_diskspace(); }); // For Advanced Tools > Site information > Web-server disk space in use by UpdraftPlus $('.advanced_settings_content a.updraft_diskspaceused_update').on('click', function(e) { e.preventDefault(); jQuery('.advanced_settings_content .updraft_diskspaceused').html(''+updraftlion.calculating+''); updraft_send_command('get_fragment', { fragment: 'disk_usage', data: 'updraft' }, function(response) { jQuery('.advanced_settings_content .updraft_diskspaceused').html(response.output); }, { type: 'GET' }); }); $('#updraft-navtab-backups-content a.updraft_uploader_toggle').on('click', function(e) { e.preventDefault(); $('#updraft-plupload-modal').slideToggle(); }); $('#updraft-navtab-backups-content a.updraft_rescan_local').on('click', function(e) { e.preventDefault(); updraft_updatehistory(1, 0); }); $('#updraft-navtab-backups-content a.updraft_rescan_remote').on('click', function(e) { e.preventDefault(); if (!confirm(updraftlion.remote_scan_warning)) return; updraft_updatehistory(1, 1); }); $('#updraftplus-remote-rescan-debug').on('click', function(e) { e.preventDefault(); updraft_updatehistory(1, 1, 1); }); jQuery('#updraft_reset_sid').on('click', function(e) { e.preventDefault(); updraft_send_command('reset_site_id', null, function(response) { jQuery('#updraft_show_sid').html(response); }, { json_parse: false }); }); jQuery("#updraft-navtab-settings-content form input:not('.udignorechange'), #updraft-navtab-settings-content form select").on('change', function(e) { updraft_settings_form_changed = true; }); jQuery("#updraft-navtab-settings-content form input[type='submit']").on('click', function (e) { updraft_settings_form_changed = false; }); var bigbutton_width = 180; jQuery('.updraft-bigbutton').each(function(x,y) { var bwid = jQuery(y).width(); if (bwid > bigbutton_width) bigbutton_width = bwid; }); if (bigbutton_width > 180) jQuery('.updraft-bigbutton').width(bigbutton_width); if (jQuery('#updraft-navtab-backups-content').length) { // setTimeout(function(){updraft_showlastlog(true);}, 1200); setInterval(function() { updraft_activejobs_update(false);}, 1250); } // Prevent profusion of notices setTimeout(function() { jQuery('#setting-error-settings_updated').slideUp();}, 5000); jQuery('#updraft_restore_db').on('change', function() { if (jQuery('#updraft_restore_db').is(':checked') && 1 == jQuery(this).data('encrypted')) { jQuery('#updraft_restorer_dboptions').slideDown(); } else { jQuery('#updraft_restorer_dboptions').slideUp(); } }); updraft_check_same_times(); var updraft_message_modal_buttons = {}; updraft_message_modal_buttons[updraftlion.close] = function() { jQuery(this).dialog("close"); }; jQuery("#updraft-message-modal").dialog({ autoOpen: false, resizeOnWindowResize: true, scrollWithViewport: true, resizeAccordingToViewport: true, useContentSize: false, open: function(event, ui) { $(this).dialog('option', 'width', 520); $(this).dialog('option', 'minHeight', 260); if ($(window).height() > 360 ) { $(this).dialog('option', 'height', 360); } else { $(this).dialog('option', 'height', $(window).height()-30); } }, modal: true, buttons: updraft_message_modal_buttons }); var updraft_delete_modal_buttons = {}; updraft_delete_modal_buttons[updraftlion.deletebutton] = function() { updraft_remove_backup_sets(0, 0, 0, 0); }; function updraft_remove_backup_sets(deleted_counter, backup_local, backup_remote, backup_sets) { jQuery("#updraft-delete-modal").dialog('close'); var deleted_files_counter = deleted_counter; var local_deleted = backup_local; var remote_deleted = backup_remote; var sets_deleted = backup_sets; var timestamps = jQuery('#updraft_delete_timestamp').val().split(','); var error_log_prompt = ''; var form_data = jQuery('#updraft_delete_form').serializeArray(); var data = {}; $.each(form_data, function() { if (undefined !== data[this.name]) { if (!data[this.name].push) { data[this.name] = [data[this.name]]; } data[this.name].push(this.value || ''); } else { data[this.name] = this.value || ''; } }); if (data.delete_remote) { jQuery('#updraft-delete-waitwarning').find('.updraft-deleting-remote').show(); } else { jQuery('#updraft-delete-waitwarning').find('.updraft-deleting-remote').hide(); } jQuery('#updraft-delete-waitwarning').slideDown().addClass('active'); data.remote_delete_limit = updraftlion.remote_delete_limit; delete data.action; delete data.subaction; delete data.nonce; updraft_send_command('deleteset', data, function(resp) { if (!resp.hasOwnProperty('result') || resp.result == null) { jQuery('#updraft-delete-waitwarning').slideUp(); return; } if (resp.result == 'error') { jQuery('#updraft-delete-waitwarning').slideUp(); alert(updraftlion.error+' '+resp.message); } else if (resp.result == 'continue') { deleted_files_counter = deleted_files_counter + resp.backup_local + resp.backup_remote; local_deleted = local_deleted + resp.backup_local; remote_deleted = remote_deleted + resp.backup_remote; sets_deleted = sets_deleted + resp.backup_sets; var deleted_timestamps = resp.deleted_timestamps.split(','); for (var i = 0; i < deleted_timestamps.length; i++) { var timestamp = deleted_timestamps[i]; jQuery('#updraft-navtab-backups-content .updraft_existing_backups_row_' + timestamp).slideUp().remove(); } jQuery('#updraft_delete_timestamp').val(resp.timestamps); jQuery('#updraft-deleted-files-total').text(deleted_files_counter + ' ' + updraftlion.remote_files_deleted); updraft_remove_backup_sets(deleted_files_counter, local_deleted, remote_deleted, sets_deleted); } else if (resp.result == 'success') { setTimeout(function() { jQuery('#updraft-deleted-files-total').text(''); jQuery('#updraft-delete-waitwarning').slideUp(); }, 500); update_backupnow_modal(resp); if (resp.hasOwnProperty('backupnow_file_entities')) { impossible_increment_entities = resp.backupnow_file_entities; } if (resp.hasOwnProperty('count_backups')) { jQuery('#updraft-existing-backups-heading').html(updraftlion.existing_backups+' '+resp.count_backups+''); } for (var i = 0; i < timestamps.length; i++) { var timestamp = timestamps[i]; jQuery('#updraft-navtab-backups-content .updraft_existing_backups_row_'+timestamp).slideUp().remove(); } updraft_backups_selection.checkSelectionStatus(); updraft_history_lastchecksum = false; local_deleted = local_deleted + resp.backup_local; remote_deleted = remote_deleted + resp.backup_remote; sets_deleted = sets_deleted + resp.backup_sets; if ('' != resp.error_messages) { error_log_prompt = updraftlion.delete_error_log_prompt; } setTimeout(function() { alert(resp.set_message + " " + sets_deleted + "\n" + resp.local_message + " " + local_deleted + "\n" + resp.remote_message + " " + remote_deleted + "\n\n" + resp.error_messages + "\n" + error_log_prompt); }, 900); } }); }; updraft_delete_modal_buttons[updraftlion.cancel] = function() { jQuery(this).dialog("close"); }; jQuery("#updraft-delete-modal").dialog({ autoOpen: false, resizeOnWindowResize: true, scrollWithViewport: true, resizeAccordingToViewport: true, useContentSize: false, open: function(event, ui) { $(this).css('minHeight', 83); }, modal: true, buttons: updraft_delete_modal_buttons }); var updraft_restore_modal = { initialized: false, init: function() { if (this.initialized) return; this.initialized = true; // Setup cancel button events $('.updraft-restore--cancel').on('click', function(e) { e.preventDefault(); jQuery('#ud_downloadstatus2').html(''); this.close(); }.bind(this)); this.default_next_text = $('.updraft-restore--next-step').eq(0).text(); // Setup next button event $('.updraft-restore--next-step').on('click', function(e) { e.preventDefault(); this.process_next_action(); }.bind(this)); }, close: function() { $('.updraft_restore_container').hide(); $('body').removeClass('updraft-modal-is-opened'); }, open: function() { this.init(); // reset elements $('#updraft-restore-modal-stage1').show(); $('#updraft-restore-modal-stage2').hide(); $('#updraft-restore-modal-stage2a').html(''); $('.updraft-restore--next-step').text(this.default_next_text); $('.updraft-restore--stages li').removeClass('active').first().addClass('active'); // Show restoration window $('.updraft_restore_container').show(); $('body').addClass('updraft-modal-is-opened'); }, process_next_action: function() { var anyselected = 0; var moreselected = 0; var dbselected = 0; var pluginselected = 0; var themeselected = 0; var whichselected = []; // Make a list of what files we want var already_added_wpcore = 0; var meta_foreign = $('#updraft_restore_meta_foreign').val(); $('input[name="updraft_restore[]"]').each(function(x, y) { if ($(y).is(':checked') && !$(y).is(':disabled')) { anyselected = 1; var howmany = $(y).data('howmany'); var type = $(y).val(); if ('more' == type) moreselected = 1; if ('db' == type) dbselected = 1; if ('plugins' == type) pluginselected = 1; if ('themes' == type) themeselected = 1; if (1 == meta_foreign || (2 == meta_foreign && 'db' != type)) { if ('wpcore' != type) { howmany = $('#updraft_restore_form #updraft_restore_wpcore').data('howmany'); } type = 'wpcore'; } if ('wpcore' != type || already_added_wpcore == 0) { var restobj = [ type, howmany ]; whichselected.push(restobj); // alert($(y).val()); if ('wpcore' == type) { already_added_wpcore = 1; } } } }); if (1 == anyselected) { // Work out what to download if (1 == updraft_restore_stage) { // meta_foreign == 1 : All-in-one format: the only thing to download, always, is wpcore // if ('1' == meta_foreign) { // whichselected = []; // whichselected.push([ 'wpcore', 0 ]); // } else if ('2' == meta_foreign) { // $(whichselected).each(function(x,y) { // restobj = whichselected[x]; // }); // whichselected = []; // whichselected.push([ 'wpcore', 0 ]); // } $('.updraft-restore--stages li').removeClass('active').eq(1).addClass('active'); $('#updraft-restore-modal-stage1').slideUp('slow'); $('#updraft-restore-modal-stage2').show(); updraft_restore_stage = 2; var pretty_date = $('.updraft_restore_date').first().text(); // Create the downloader active widgets // See if we some are already known to be downloaded - in which case, skip creating the download widget. (That saves on HTTP round-trips, as each widget creates a new POST request. Of course, this is at the expense of one extra one here). var which_to_download = whichselected; var backup_timestamp = $('#updraft_restore_timestamp').val(); try { $('.updraft-restore--next-step').prop('disabled', true); $('#updraft-restore-modal-stage2a').html(' '+updraftlion.maybe_downloading_entities); updraft_send_command('whichdownloadsneeded', { downloads: whichselected, timestamp: backup_timestamp }, function(response) { $('.updraft-restore--next-step').prop('disabled', false); if (response.hasOwnProperty('downloads')) { console.log('UpdraftPlus: items which still require downloading follow'); which_to_download = response.downloads; console.log(which_to_download); } // Kick off any downloads, if needed if (0 == which_to_download.length) { updraft_restorer_checkstage2(0); } else { for (var i=0; i'+resp.fatal_error_message+'

                '); } else { var error_message = "updraft_send_command: error: "+status+" ("+error_code+")"; $('#updraft-restore-modal-stage2a').html('

                '+error_message+'

                '); console.log(error_message); console.log(response); } } }); } catch (err) { console.log("UpdraftPlus: error (follows) when looking for items needing downloading"); console.log(err); alert(updraftlion.jsonnotunderstood); } // Make sure all are downloaded } else if (2 == updraft_restore_stage) { updraft_restorer_checkstage2(1); } else if (3 == updraft_restore_stage) { var continue_restore = 1; jQuery('.updraft-restore--next-step, .updraft-restore--cancel').prop('disabled', true); $('#updraft_restoreoptions_ui input.required').each(function(index) { if (continue_restore == 0) return; var sitename = $(this).val(); if (sitename == '') { alert(updraftlion.pleasefillinrequired); jQuery('.updraft-restore--next-step, .updraft-restore--cancel').prop('disabled', false); continue_restore = 0; } else if ($(this).attr('pattern') != '') { var pattern = $(this).attr('pattern'); var re = new RegExp(pattern, "g"); if (!re.test(sitename)) { alert($(this).data('invalidpattern')); jQuery('.updraft-restore--next-step, .updraft-restore--cancel').prop('disabled', false); continue_restore = 0; } } }); if (1 == dbselected) { anyselected = 0; jQuery('input[name="updraft_restore_tables_options[]"').each(function (x, y) { if (jQuery(y).is(':checked') && !jQuery(y).is(':disabled')) anyselected = 1; }); if (0 == anyselected && !skipped_db_scan) { alert(updraftlion.youdidnotselectany); jQuery('.updraft-restore--next-step, .updraft-restore--cancel').prop('disabled', false); return; } } if (1 == pluginselected) { anyselected = 0; if (!jQuery(".updraftplus_restore_plugins_options_container").length) anyselected = 1; jQuery('input[name="updraft_restore_plugins_options[]"').each(function (x, y) { if (jQuery(y).is(':checked') && !jQuery(y).is(':disabled')) anyselected = 1; }); if (0 == anyselected) { alert(updraftlion.youdidnotselectany); jQuery('.updraft-restore--next-step, .updraft-restore--cancel').prop('disabled', false); return; } } if (1 == themeselected) { anyselected = 0; if (!jQuery(".updraftplus_restore_themes_options_container").length) anyselected = 1; jQuery('input[name="updraft_restore_themes_options[]"').each(function (x, y) { if (jQuery(y).is(':checked') && !jQuery(y).is(':disabled')) anyselected = 1; }); if (0 == anyselected) { alert(updraftlion.youdidnotselectany); jQuery('.updraft-restore--next-step, .updraft-restore--cancel').prop('disabled', false); return; } } if (1 == moreselected) { anyselected = 0; jQuery('input[name="updraft_include_more_index[]"').each(function (x, y) { if (jQuery(y).is(':checked') && !jQuery(y).is(':disabled')) { anyselected = 1; if ('' == jQuery('#updraft_include_more_path_restore' + x).val()) { alert(updraftlion.emptyrestorepath); } } }); if (0 == anyselected) { alert(updraftlion.youdidnotselectany); jQuery('.updraft-restore--next-step, .updraft-restore--cancel').prop('disabled', false); return; } } if (!continue_restore) return; var restore_options = $('#updraft_restoreoptions_ui select, #updraft_restoreoptions_ui input').serialize(); // jQuery serialize does not pick up unchecked checkboxes, but we want to include these so that we have a list of table/plugins/themes the user does not want to restore we prepend these with udp-skip-{entity}- and check this on the backend var entities = ['table', 'plugins', 'themes']; jQuery.each(entities, function(i, entity) { jQuery.each(jQuery('input[name="updraft_restore_' + entity + '_options[]').filter(function(idx) { return jQuery(this).prop('checked') === false }), function(idx, el) { restore_options += '&' + jQuery(el).attr('name') + '=' + 'udp-skip-' + entity + '-' + jQuery(el).val(); }); }) console.log("Restore options: "+restore_options); if (typeof php_max_input_vars !== 'undefined') { var restore_options_length = restore_options.split("&").length; var warning_template_start = '

                ' + updraftlion.warnings +'

                  '; var warning_template_end = '
                '; // If we can't detect the php_max_input_vars assume the PHP default of 1000 if (!php_max_input_vars && 1000 <= restore_options_length) { console.log('Restore options: ' + restore_options_length + ' PHP max input vars not detected; using default: 1000'); } else if (php_max_input_vars && restore_options_length >= php_max_input_vars) { var warning = '
              • ' + updraftlion.php_max_input_vars_detected_warning + '
              • '; if (1 != jQuery('#updraft-restore-modal-stage2a .notice-warning').length) { var final_warning = warning_template_start + warning + warning_template_end; jQuery('#updraft_restoreoptions_ui').prepend(final_warning); } else { jQuery('#updraft-restore-modal-stage2a #updraft_restore_warnings').append(warning); } console.log('Restore options: ' + restore_options_length + ' PHP max input vars: ' + php_max_input_vars); jQuery('.updraft-restore--next-step, .updraft-restore--cancel').prop('disabled', false); php_max_input_vars = undefined; return; } } $('#updraft_restorer_restore_options').val(restore_options); // This must be done last, as it wipes out the section with #updraft_restoreoptions_ui $('#updraft-restore-modal-stage2a').html(updraftlion.restore_proceeding); $('#updraft_restore_form').trigger('submit'); // In progress; prevent the button being pressed again updraft_restore_stage = 4; } } else { alert(updraftlion.youdidnotselectany); } } } var original_restore_main_activity_width = $('.updraft_restore_main--activity').width(); jQuery('#activity-full-log').on('click', function() { var activity_log_max_width = $('.updraft_restore_main').css('max-width') == '1460px' ? '860px' : '1460px'; var restore_main_activity_width = $('.updraft_restore_main--activity').width() == original_restore_main_activity_width ? '100%' : original_restore_main_activity_width + 'px'; var activity_log_max_height = $('.updraft_restore_main--activity').css('min-height') == '600px' ? '0px' : '600px'; var activity_log_icon_title = $('#activity-full-log').attr('title') == updraftlion.restoreactivitylogscreenexit ? updraftlion.restoreactivitylogfullscreen : updraftlion.restoreactivitylogscreenexit; $('#activity-full-log').toggleClass('dashicons-fullscreen-exit-alt'); $('#activity-full-log').attr('title', activity_log_icon_title); $('.updraft_restore_main--components').toggle('fast'); $('.updraft_restore_main--header').toggle('fast'); $('.updraft_restore_main--activity').animate({minHeight: activity_log_max_height, width: restore_main_activity_width}); $('.updraft_restore_main').animate({maxWidth: activity_log_max_width}); }); jQuery("#updraft-iframe-modal").dialog({ autoOpen: false, height: 500, width: 780, modal: true }); jQuery("#updraft-backupnow-inpage-modal").dialog({ autoOpen: false, modal: true, resizeOnWindowResize: true, scrollWithViewport: true, resizeAccordingToViewport: true, useContentSize: false, open: function(event, ui) { $(this).dialog('option', 'width', 580); $(this).dialog('option', 'minHeight', 261); $(this).dialog('option', 'height', 380); }, }); var backupnow_modal_buttons = {}; backupnow_modal_buttons[updraftlion.backupnow] = function() { var backupnow_nodb = jQuery('#backupnow_includedb').is(':checked') ? 0 : 1; var backupnow_nofiles = jQuery('#backupnow_includefiles').is(':checked') ? 0 : 1; var backupnow_nocloud = jQuery('#backupnow_includecloud').is(':checked') ? 0 : 1; var db_anon_all = jQuery('#backupnow_db_anon_all').is(':checked') ? 1 : 0; var db_anon_non_staff = jQuery('#backupnow_db_anon_non_staff').is(':checked') ? 1 : 0; var db_anon_wc_orders = jQuery('#backupnow_db_anon_wc_order_data').is(':checked') ? 1 : 0; var onlythesetableentities = backupnow_whichtables_checked(''); var always_keep = jQuery('#always_keep').is(':checked') ? 1 : 0; var incremental = ('incremental' == jQuery('#updraft-backupnow-modal').data('backup-type')) ? 1 : 0; if (updraftlion.hosting_restriction.includes('only_one_backup_per_month') && !incremental) { alert(updraftlion.hosting_restriction_one_backup_permonth); return; } if (updraftlion.hosting_restriction.includes('only_one_incremental_per_day') && incremental) { alert(updraftlion.hosting_restriction_one_incremental_perday); return; } if ('' == onlythesetableentities && 0 == backupnow_nodb) { alert(updraftlion.notableschosen); jQuery('#backupnow_database_moreoptions').show(); return; } if (typeof onlythesetableentities === 'boolean') { onlythesetableentities = null; } var onlythesefileentities = backupnow_whichfiles_checked(''); if ('' == onlythesefileentities && 0 == backupnow_nofiles) { alert(updraftlion.nofileschosen); jQuery('#backupnow_includefiles_moreoptions').show(); return; } var only_these_cloud_services = jQuery("input[name^='updraft_include_remote_service_']").serializeArray(); if ('' == only_these_cloud_services && 0 == backupnow_nocloud) { alert(updraftlion.nocloudserviceschosen); jQuery('#backupnow_includecloud_moreoptions').show(); return; } if (typeof only_these_cloud_services === 'boolean') { only_these_cloud_services = null; } if (backupnow_nodb && backupnow_nofiles) { alert(updraftlion.excludedeverything); return; } jQuery(this).dialog("close"); setTimeout(function() { jQuery('#updraft_lastlogmessagerow').fadeOut('slow', function() { jQuery(this).fadeIn('slow'); }); }, 1700); updraft_backupnow_go(backupnow_nodb, backupnow_nofiles, backupnow_nocloud, onlythesefileentities, {always_keep: always_keep, incremental: incremental, db_anon: { all: db_anon_all, non_staff: db_anon_non_staff, wc_orders: db_anon_wc_orders }}, jQuery('#backupnow_label').val(), onlythesetableentities, only_these_cloud_services); }; backupnow_modal_buttons[updraftlion.cancel] = function() { jQuery(this).dialog("close"); }; jQuery("#updraft-backupnow-modal").dialog({ autoOpen: false, resizeOnWindowResize: true, scrollWithViewport: true, resizeAccordingToViewport: true, useContentSize: false, open: function(event, ui) { $(this).dialog('option', 'width', 610); $(this).dialog('option', 'minHeight', 300); $(this).dialog('option', 'height', 472); }, modal: true, buttons: backupnow_modal_buttons, create: function () { $(this).closest(".ui-dialog") .find(".ui-dialog-buttonpane .ui-button").first() // the first button .addClass("js-tour-backup-now-button"); } }); jQuery("#updraft-poplog").dialog({ autoOpen: false, modal: true, resizeOnWindowResize: true, scrollWithViewport: true, resizeAccordingToViewport: true, useContentSize: false, open: function(event, ui) { $(this).dialog('option', 'width', 860); $(this).dialog('option', 'minHeight', 260); if ($(window).height() > 600) { $(this).dialog('option', 'height', 600); } else { $(this).dialog('option', 'height', $(window).height()-50); } }, }); jQuery('#updraft-navtab-settings-content .enableexpertmode').on('click', function() { jQuery('#updraft-navtab-settings-content .expertmode').fadeIn(); jQuery('#updraft-navtab-settings-content .enableexpertmode').off('click'); return false; }); jQuery('#updraft-navtab-settings-content .backupdirrow').on('click', 'a.updraft_backup_dir_reset', function() { jQuery('#updraft_dir').val('updraft'); return false; }); function setup_file_entity_exclude_field(field, instant) { if (jQuery('#updraft-navtab-settings-content #updraft_include_'+field).is(':checked')) { if (instant) { jQuery('#updraft-navtab-settings-content #updraft_include_'+field+'_exclude_container').show(); } else { jQuery('#updraft-navtab-settings-content #updraft_include_'+field+'_exclude_container').slideDown(); } } else { if (instant) { jQuery('#updraft-navtab-settings-content #updraft_include_'+field+'_exclude').hide(); } else { jQuery('#updraft-navtab-settings-content #updraft_include_'+field+'_exclude_container').slideUp(); } } } jQuery('#updraft-navtab-settings-content .updraft_include_entity').on('click', function() { var has_exclude_field = jQuery(this).data('toggle_exclude_field'); if (has_exclude_field) { setup_file_entity_exclude_field(has_exclude_field, false); } }); jQuery('.updraft_exclude_entity_container').on('click', '.updraft_exclude_entity_delete', function(event) { event.preventDefault(); if (!confirm(updraftlion.exclude_rule_remove_conformation_msg)) return; var include_entity_name = jQuery(this).data('include-backup-file'); jQuery.when( jQuery(this).closest('.updraft_exclude_entity_wrapper').remove() ).then( updraft_exclude_entity_update(include_entity_name) ); }); jQuery('.updraft_exclude_entity_container').on('click', '.updraft_exclude_entity_edit', function(event) { event.preventDefault(); var wrapper = jQuery(this).hide().closest('.updraft_exclude_entity_wrapper'); var input = wrapper.find('input'); input.prop('readonly', false).trigger('focus'); // place caret at the end of the text var input_val = input.val(); input.val(''); input.val(input_val); wrapper.find('.updraft_exclude_entity_update').addClass('is-active').show(); }); jQuery('.updraft_exclude_entity_container').on('click', '.updraft_exclude_entity_update', function(event) { event.preventDefault(); var wrapper = jQuery(this).closest('.updraft_exclude_entity_wrapper'); var include_backup_file = jQuery(this).data('include-backup-file') var exclude_item_val = wrapper.find('input').val().trim(); var should_be_updated = false; if (exclude_item_val == wrapper.find('input').data('val')) { should_be_updated = true; } else if (updraft_is_unique_exclude_rule(exclude_item_val, include_backup_file)) { should_be_updated = true; } if (should_be_updated) { jQuery(this).hide().removeClass('is-active'); jQuery.when( wrapper.find('input').prop('readonly', 'readonly').data('val', exclude_item_val) ).then(function() { wrapper.find('.updraft_exclude_entity_edit').show(); updraft_exclude_entity_update(include_backup_file); }); } }); jQuery('#updraft_exclude_modal').dialog({ autoOpen: false, modal: true, resizeOnWindowResize: true, scrollWithViewport: true, resizeAccordingToViewport: true, useContentSize: false, open: function(event,ui) { $(this).parent().trigger('focus'); $(this).dialog('option', 'width', 520); $(this).dialog('option', 'minHeight', 260); if ($(window).height() > 579) { $(this).css('height', 'auto'); } else if ($(window).height() < 580 && $(window).height() > 410) { $(this).dialog('option', 'height', 410); $(this).css('height', 'auto'); } else { $(this).dialog('option', 'height', $(window).height()-20); } } }); jQuery('#updraft_include_others_exclude_container, #updraft_include_uploads_exclude_container, .updraft_exclude_container').on('click', 'a.updraft_add_exclude_item', function(event) { event.preventDefault(); var backup_entity = jQuery(this).data('include-backup-file'); jQuery('#updraft_exclude_modal_for').val(backup_entity); jQuery('#updraft_exclude_modal_path').val(jQuery(this).data('path')); if ('uploads' == backup_entity) { jQuery('#updraft-exclude-file-dir-prefix').html(jQuery('#updraft-exclude-upload-base-dir').val()); } jQuery('.updraft-exclude-modal-reset').trigger('click'); jQuery('#updraft_exclude_modal').dialog('open'); }); jQuery('.updraft-exclude-link').on('click', function(event) { event.preventDefault(); var panel = jQuery(this).data('panel'); if ('file-dir' == panel) { jQuery('#updraft_exclude_files_folders_jstree').jstree({ "core": { "multiple": false, "data": function (nodeid, callback) { updraft_send_command('get_jstree_directory_nodes', {entity: 'filebrowser', node:nodeid, path: jQuery('#updraft_exclude_modal_path').val(), findex: 0, skip_root_node: true}, function(response) { if (response.hasOwnProperty('error')) { alert(response.error); } else { callback.call(this, response.nodes); } }, { error_callback: function(response, status, error_code, resp) { if (typeof resp !== 'undefined' && resp.hasOwnProperty('fatal_error')) { console.error(resp.fatal_error_message); jQuery('#updraft_zip_files_jstree').html('

                '+resp.fatal_error_message+'

                '); alert(resp.fatal_error_message); } else { var error_message = "updraft_send_command: error: "+status+" ("+error_code+")"; jQuery('#updraft_zip_files_jstree').html('

                '+error_message+'

                '); console.log(error_message); alert(error_message); console.log(response); } } }); }, "error": function(error) { alert(error); console.log(error); }, }, "search": { "show_only_matches": true }, "plugins": ["sort"], }); } else if ('contain-clause' == panel) { jQuery('#updraft_exclude_files_folders_wildcards_jstree').jstree({ "core": { "multiple": false, "data": function (nodeid, callback) { updraft_send_command('get_jstree_directory_nodes', {entity: 'filebrowser', directories_only: 1, node:nodeid, path: jQuery('#updraft_exclude_modal_path').val(), findex: 0, skip_root_node: 0}, function(response) { if (response.hasOwnProperty('error')) { alert(response.error); } else { callback.call(this, response.nodes); } }, { error_callback: function(response, status, error_code, resp) { if (typeof resp !== 'undefined' && resp.hasOwnProperty('fatal_error')) { console.error(resp.fatal_error_message); jQuery('#updraft_zip_files_jstree').html('

                '+resp.fatal_error_message+'

                '); alert(resp.fatal_error_message); } else { var error_message = "updraft_send_command: error: "+status+" ("+error_code+")"; jQuery('#updraft_zip_files_jstree').html('

                '+error_message+'

                '); console.log(error_message); alert(error_message); console.log(response); } } }); }, "error": function(error) { alert(error); console.log(error); }, }, "search": { "show_only_matches": true }, "plugins": ["sort"], }); } jQuery('#updraft_exclude_modal_main').slideUp(); jQuery('.updraft-exclude-panel').hide(); jQuery('.updraft-exclude-panel[data-panel='+panel+']').slideDown(); }); jQuery('.updraft-exclude-modal-reset').on('click', function(event) { event.preventDefault(); jQuery('#updraft_exclude_files_folders_jstree').jstree("destroy"); jQuery('#updraft_exclude_files_folders_wildcards_jstree').jstree("destroy"); jQuery('#updraft_exclude_extension_field').val(''); jQuery('#updraft_exclude_prefix_field').val(''); jQuery('.updraft-exclude-panel').slideUp(); jQuery('#updraft_exclude_modal_main').slideDown(); }); jQuery('.updraft-exclude-submit').on('click', function() { var panel = jQuery(this).data('panel'); var exclude_item_val = ''; switch (panel) { case 'file-dir': var exclude_jstree_selected = jQuery("#updraft_exclude_files_folders_jstree").jstree("get_selected"); if (0 == exclude_jstree_selected.length) { alert(updraftlion.exclude_select_file_or_folder_msg); return; } var selected_file_or_folder = exclude_jstree_selected[0]; var prefix_path = jQuery('#updraft_exclude_modal_path').val(); if (selected_file_or_folder.substr(0, prefix_path.length) == prefix_path) { selected_file_or_folder = selected_file_or_folder.substr(prefix_path.length, selected_file_or_folder.length); } if ('/' == selected_file_or_folder.charAt(0)) selected_file_or_folder = selected_file_or_folder.substr(1); if ('/' == selected_file_or_folder.charAt(selected_file_or_folder.length - 1)) selected_file_or_folder = selected_file_or_folder.substr(0, selected_file_or_folder.length - 1); exclude_item_val = selected_file_or_folder; break; case 'extension': var exclude_extension = jQuery('#updraft_exclude_extension_field').val(); if ('' == exclude_extension) { alert(updraftlion.exclude_type_ext_msg); return; } if (!exclude_extension.match(/^[0-9a-zA-Z]+$/)) { alert(updraftlion.exclude_ext_error_msg); return; } exclude_item_val = 'ext:'+exclude_extension; break; case 'begin-with': var prefix = jQuery('#updraft_exclude_prefix_field').val(); if ('' == prefix) { alert(updraftlion.exclude_type_prefix_msg); return; } if (!prefix.match(/^\s*[a-z-_\d,\s]+\s*$/i)) { alert(updraftlion.exclude_prefix_error_msg); return; } exclude_item_val = 'prefix:'+prefix; break; case 'contain-clause': var exclude_jstree_selected = jQuery("#updraft_exclude_files_folders_wildcards_jstree").jstree("get_selected"); if (0 == exclude_jstree_selected.length) { alert(updraftlion.exclude_select_folder_wildcards_msg); return; } var clause_val = jQuery(this).parents('div.updraft-exclude-panel').find('div.clause-input-container input').val(); jQuery(this).parents('div.updraft-exclude-panel').find('div.clause-input-container input').val(''); var clause_type = jQuery(this).parents('div.updraft-exclude-panel').find('div.clause-input-container select').val(); if ('' == clause_val) { alert(updraftlion.exclude_contain_error_msg); return; } jQuery(this).parents('div.updraft-exclude-panel').find('div.clause-input-container select option').eq(0).prop('selected', true); var selected_file_or_folder = exclude_jstree_selected[0]; var prefix_path = jQuery('#updraft_exclude_modal_path').val(); if (selected_file_or_folder.substr(0, prefix_path.length) == prefix_path) { selected_file_or_folder = selected_file_or_folder.substr(prefix_path.length, selected_file_or_folder.length); } if ('/' == selected_file_or_folder.charAt(0)) selected_file_or_folder = selected_file_or_folder.substr(1); if ('/' == selected_file_or_folder.charAt(selected_file_or_folder.length - 1)) selected_file_or_folder = selected_file_or_folder.substr(0, selected_file_or_folder.length - 1); exclude_item_val = selected_file_or_folder; if ('' !== exclude_item_val) exclude_item_val += '/'; clause_val = clause_val.replace(/\*/g, '\\*'); if ('beginning' === clause_type) { exclude_item_val += clause_val + '*'; } else if ('middle' === clause_type) { exclude_item_val += '*' + clause_val + '*'; } else if ('end' === clause_type) { exclude_item_val += '*' + clause_val; } break; default: return; } var include_backup_file = jQuery('#updraft_exclude_modal_for').val(); if (!updraft_is_unique_exclude_rule(exclude_item_val, include_backup_file)) return; var exclude_entity_html = '
                '; jQuery('.updraft_exclude_entity_container[data-include-backup-file="' + include_backup_file + '"]').append(exclude_entity_html); updraft_exclude_entity_update(include_backup_file); jQuery('#updraft_exclude_modal').dialog('close'); }); // TODO: This is suspected to be obsolete. Confirm + remove. jQuery('#updraft-navtab-settings-content .updraft-service').on('change', function() { var active_class = jQuery(this).val(); jQuery('#updraft-navtab-settings-content .updraftplusmethod').hide(); jQuery('#updraft-navtab-settings-content .'+active_class).show(); }); jQuery('#updraft-navtab-settings-content a.updraft_show_decryption_widget').on('click', function(e) { e.preventDefault(); jQuery('#updraftplus_db_decrypt').val(jQuery('#updraft_encryptionphrase').val()); jQuery('#updraft-manualdecrypt-modal').slideToggle(); }); jQuery('#updraftplus-phpinfo').on('click', function(e) { e.preventDefault(); updraft_iframe_modal('phpinfo', updraftlion.phpinfo); }); jQuery('#updraftplus-rawbackuphistory').on('click', function(e) { e.preventDefault(); updraft_iframe_modal('rawbackuphistory', updraftlion.raw); }); // + Added addons navtab jQuery('#updraft-navtab-status').on('click', function(e) { e.preventDefault(); updraft_open_main_tab('status'); updraft_page_is_visible = 1; updraft_console_focussed_tab = 'status'; // Refresh the console, as its next update might be far away updraft_activejobs_update(true); }); jQuery('#updraft-navtab-expert').on('click', function(e) { e.preventDefault(); updraft_open_main_tab('expert'); updraft_page_is_visible = 1; }); jQuery('#updraft-navtab-settings, #updraft-navtab-settings2, #updraft_backupnow_gotosettings').on('click', function(e) { e.preventDefault(); // These next two should only do anything if the relevant selector was clicked jQuery(this).parents('.updraftmessage').remove(); jQuery('#updraft-backupnow-modal').dialog('close'); updraft_open_main_tab('settings'); updraft_page_is_visible = 1; }); jQuery('#updraft-navtab-addons').on('click', function(e) { e.preventDefault(); jQuery(this).addClass('b#nav-tab-active'); updraft_open_main_tab('addons'); updraft_page_is_visible = 1; }); jQuery('#updraft-navtab-backups').on('click', function(e) { e.preventDefault(); updraft_console_focussed_tab = 'backups'; updraft_historytimertoggle(1); updraft_open_main_tab('backups'); }); jQuery('#updraft-navtab-migrate').on('click', function(e) { e.preventDefault(); jQuery('#updraft_migrate_tab_alt').html('').hide(); updraft_open_main_tab('migrate'); updraft_page_is_visible = 1; if (!jQuery('#updraft_migrate .updraft_migrate_widget_module_content').is(':visible')) { jQuery('.updraft_migrate_intro').show(); } }); if ('migrate' == updraftlion.tab) jQuery('#updraft-navtab-migrate').trigger('click'); updraft_send_command('ping', null, function(data, response) { if ('success' == response && data != 'pong' && data.indexOf('pong')>=0) { jQuery('#updraft-navtab-backups-content .ud-whitespace-warning').show(); console.log("UpdraftPlus: Extra output warning: response (which should be just (string)'pong') follows."); console.log(data); } }, { json_parse: false, type: 'GET' }); // Section: Plupload try { if (typeof updraft_plupload_config !== 'undefined') { plupload_init(); } } catch (err) { console.log(err); } function plupload_init() { // create the uploader and pass the config from above var uploader = new plupload.Uploader(updraft_plupload_config); // checks if browser supports drag and drop upload, makes some css adjustments if necessary uploader.bind('Init', function(up) { var uploaddiv = jQuery('#plupload-upload-ui'); if (up.features.dragdrop) { uploaddiv.addClass('drag-drop'); jQuery('#drag-drop-area') .on('dragover.wp-uploader', function() { uploaddiv.addClass('drag-over'); }) .on('dragleave.wp-uploader, drop.wp-uploader', function() { uploaddiv.removeClass('drag-over'); }); } else { uploaddiv.removeClass('drag-drop'); jQuery('#drag-drop-area').off('.wp-uploader'); } }); uploader.init(); // a file was added in the queue uploader.bind('FilesAdded', function(up, files) { if ($('#updraft-plupload-modal').is(':hidden')) { $('#updraft-plupload-modal').slideToggle(); } // var hundredmb = 100 * 1024 * 1024, max = parseInt(up.settings.max_file_size, 10); plupload.each(files, function(file) { // @codingStandardsIgnoreLine if (! /^backup_([\-0-9]{15})_.*_([0-9a-f]{12})-[\-a-z]+([0-9]+?)?(\.(zip|gz|gz\.crypt))?$/i.test(file.name) && ! /^log\.([0-9a-f]{12})\.txt$/.test(file.name)) { var accepted_file = false; for (var i = 0; i'+file.name+"

                "+updraftlion.notarchive2); jQuery('#updraft-message-modal').dialog('open'); } else { alert(file.name+": "+updraftlion.notarchive); } uploader.removeFile(file); return; } } // a file was added, you may want to update your DOM here... jQuery('#filelist').append( '
                ' + file.name + ' (' + plupload.formatSize(0) + '/' + plupload.formatSize(file.size) + ') ' + '
                '); }); up.refresh(); up.start(); }); uploader.bind('UploadProgress', function(up, file) { jQuery('#' + file.id + " .fileprogress").width(file.percent + "%"); jQuery('#' + file.id + " span").html(plupload.formatSize(parseInt(file.size * file.percent / 100))); if (file.size == file.loaded) { jQuery('#' + file.id).html('
                ' + file.name + ' (' + plupload.formatSize(parseInt(file.size * file.percent / 100)) + '/' + plupload.formatSize(file.size) + ') - ' + updraftlion.complete + '
                '); // Removed
                (just before closing
                ) to make clearer it's complete. jQuery('#' + file.id + " .fileprogress").width(file.percent + "%"); } }); uploader.bind('Error', function(up, error) { console.log(error); var err_makesure; if (error.code == "-200") { err_makesure = '\n'+updraftlion.makesure2; } else { err_makesure = updraftlion.makesure; } var msg = updraftlion.uploaderr+' (code '+error.code+') : '+error.message; if (error.hasOwnProperty('status') && error.status) { msg += ' ('+updraftlion.http_code+' '+error.status+')'; } if (error.hasOwnProperty('response')) { console.log('UpdraftPlus: plupload error: '+error.response); if (error.response.length < 100) msg += ' '+updraftlion.error+' '+error.response+'\n'; } msg += ' '+err_makesure; alert(msg); }); // a file was uploaded uploader.bind('FileUploaded', function(up, file, response) { if (response.status == '200') { // this is your ajax response, update the DOM with it or something... try { resp = ud_parse_json(response.response); if (resp.e) { alert(updraftlion.uploaderror+" "+resp.e); } else if (resp.dm) { alert(resp.dm); updraft_updatehistory(1, 0); } else if (resp.m) { updraft_updatehistory(1, 0); } else { alert('Unknown server response: '+response.response); } } catch (err) { console.log(response); alert(updraftlion.jsonnotunderstood); } } else { alert('Unknown server response status: '+response.code); console.log(response); } }); } // Functions in the debugging console jQuery('#updraftplus_httpget_go').on('click', function(e) { e.preventDefault(); updraftplus_httpget_go(0); }); jQuery('#updraftplus_httpget_gocurl').on('click', function(e) { e.preventDefault(); updraftplus_httpget_go(1); }); jQuery('#updraftplus_callwpaction_go').on('click', function(e) { e.preventDefault(); params = { wpaction: jQuery('#updraftplus_callwpaction').val() }; updraft_send_command('call_wordpress_action', params, function(response) { if (response.e) { alert(response.e); } else if (response.s) { // Silence } else if (response.r) { jQuery('#updraftplus_callwpaction_results').html(response.r); } else { console.log(response); alert(updraftlion.jsonnotunderstood); } }); }); function updraftplus_httpget_go(curl) { params = { uri: jQuery('#updraftplus_httpget_uri').val() }; params.curl = curl; updraft_send_command('httpget', params, function(resp) { if (resp.e) { alert(resp.e); } if (resp.r) { jQuery('#updraftplus_httpget_results').html('
                '+resp.r+'
                '); } else { console.log(resp); } }, { type: 'GET' }); } jQuery('#updraft_activejobs_table, #updraft-navtab-migrate-content').on('click', '.updraft_jobinfo_delete', function(e) { e.preventDefault(); var job_id = jQuery(this).data('jobid'); if (job_id) { $(this).addClass('disabled'); updraft_activejobs_delete(job_id); } else { console.log("UpdraftPlus: A stop job link was clicked, but the Job ID could not be found"); } }); jQuery('#updraft_activejobs_table, #updraft-navtab-backups-content .updraft_existing_backups, #updraft-backupnow-inpage-modal, #updraft-navtab-migrate-content').on('click', '.updraft-log-link', function(e) { e.preventDefault(); var file_id = jQuery(this).data('fileid'); var job_id = jQuery(this).data('jobid'); if (file_id) { updraft_popuplog(file_id); } else if (job_id) { updraft_popuplog(job_id); } else { console.log("UpdraftPlus: A log link was clicked, but the Job ID could not be found"); } }); function updraft_restore_setup(entities, key, show_data) { updraft_restore_setoptions(entities); jQuery('#updraft_restore_timestamp').val(key); jQuery('.updraft_restore_date').html(show_data); updraft_restore_stage = 1; // jQuery('#updraft-restore-modal').dialog('open'); updraft_restore_modal.open(); updraft_activejobs_update(true); } jQuery('#updraft-navtab-backups-content .updraft_existing_backups').on('click', 'button.choose-components-button', function(e) { var entities = jQuery(this).data('entities'); var backup_timestamp = jQuery(this).data('backup_timestamp'); var show_data = jQuery(this).data('showdata'); updraft_restore_setup(entities, backup_timestamp, show_data); }); /** * Get the value of a named URL parameter - https://stackoverflow.com/questions/4548487/jquery-read-query-string * * @param {string} name - URL parameter to return the value of * * @returns {string} */ function get_parameter_by_name(name) { name = name.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]"); var regex_s = "[\\?&]"+name+"=([^&#]*)"; var regex = new RegExp(regex_s); var results = regex.exec(window.location.href); if (results == null) { return ''; } else { return decodeURIComponent(results[1].replace(/\+/g, ' ')); } } if (get_parameter_by_name('udaction') == 'initiate_restore') { var entities = get_parameter_by_name('entities'); var backup_timestamp = get_parameter_by_name('backup_timestamp'); var show_data = get_parameter_by_name('showdata'); updraft_restore_setup(entities, backup_timestamp, show_data); } var updraft_upload_modal_buttons = {}; updraft_upload_modal_buttons[updraftlion.uploadbutton] = function () { var key = jQuery('#updraft_upload_timestamp').val(); var nonce = jQuery('#updraft_upload_nonce').val(); var services = ''; var send_list = false; jQuery('.updraft_remote_storage_destination').each(function (index) { if (jQuery(this).is(':checked')) { send_list = true; } }); if (!send_list) { jQuery('#updraft-upload-modal-error').html(updraftlion.local_upload_error); return; } else { services = jQuery("input[name^='updraft_remote_storage_destination_']").serializeArray(); } jQuery(this).dialog("close"); alert(updraftlion.local_upload_started); updraft_send_command('upload_local_backup', { use_nonce: nonce, use_timestamp: key, services: services }, function (response) {}); }; updraft_upload_modal_buttons[updraftlion.cancel] = function () { jQuery(this).dialog("close"); }; jQuery("#updraft-upload-modal").dialog({ autoOpen: false, modal: true, resizeOnWindowResize: true, scrollWithViewport: true, resizeAccordingToViewport: true, useContentSize: false, open: function(event, ui) { $(this).parent().trigger('focus'); $(this).dialog('option', 'width', 308); if (jQuery(window).height() > 460) { $(this).dialog('option', 'height', 318); } else if (jQuery(window).height() > 250 && jQuery(window).height() < 461) { $(this).dialog('option', 'height', 460); } else { $(this).dialog('option', 'height', jQuery(window).height() - 20); } }, buttons: updraft_upload_modal_buttons }); jQuery('#updraft-navtab-backups-content .updraft_existing_backups').on('click', 'button.updraft-upload-link', function (e) { e.preventDefault(); var nonce = jQuery(this).data('nonce').toString(); var key = jQuery(this).data('key').toString(); var services = jQuery(this).data('services').toString(); if (nonce) { updraft_upload(key, nonce, services); } else { console.log("UpdraftPlus: A upload link was clicked, but the Job ID could not be found"); } }); jQuery('#updraft-navtab-backups-content .updraft_existing_backups').on('click', '.updraft-load-more-backups', function (e) { e.preventDefault(); var backup_count = parseInt(jQuery('#updraft-navtab-backups-content .updraft_existing_backups .updraft_existing_backups_row').length) + parseInt(updraftlion.existing_backups_limit); updraft_updatehistory(0, 0, 0, backup_count); }); jQuery('#updraft-navtab-backups-content .updraft_existing_backups').on('click', '.updraft-load-all-backups', function (e) { e.preventDefault(); updraft_updatehistory(0, 0, 0, 9999999); }); /** * Opens the dialog box for confirmation of where to upload the backup * * @param {string} key - The UNIX timestamp of the backup * @param {string} nonce - The backup job ID * @param {string} services - A list of services that have not been uploaded to yet */ function updraft_upload(key, nonce, services) { jQuery('#updraft_upload_timestamp').val(key); jQuery('#updraft_upload_nonce').val(nonce); var services_array = services.split(","); jQuery('.updraft_remote_storage_destination').each(function (index) { var name = jQuery(this).val(); if (jQuery.inArray(name, services_array) == -1) { jQuery(this).prop('checked', false); jQuery(this).prop('disabled', true); var label = $(this).prop("labels"); jQuery(label).find('span').show(); } }); jQuery('#updraft-upload-modal').dialog('open'); } jQuery('#updraft-navtab-backups-content .updraft_existing_backups').on('click', '.updraft-delete-link', function(e) { e.preventDefault(); var hasremote = jQuery(this).data('hasremote'); var nonce = jQuery(this).data('nonce').toString(); var key = jQuery(this).data('key').toString(); if (nonce) { updraft_delete(key, nonce, hasremote); } else { console.log("UpdraftPlus: A delete link was clicked, but the Job ID could not be found"); } }); jQuery('#updraft-navtab-backups-content .updraft_existing_backups').on('click', 'button.updraft_download_button', function(e) { e.preventDefault(); var base = 'uddlstatus_'; var backup_timestamp = jQuery(this).data('backup_timestamp'); var what = jQuery(this).data('what'); var whicharea = '.ud_downloadstatus'; var set_contents = jQuery(this).data('set_contents'); var prettydate = jQuery(this).data('prettydate'); var async = true; updraft_downloader(base, backup_timestamp, what, whicharea, set_contents, prettydate, async); }); jQuery('#updraft-navtab-backups-content .updraft_existing_backups').on('dblclick', '.updraft_existingbackup_date', function (e) { e.preventDefault(); var nonce = jQuery(this).data('nonce').toString(); var timestamp = jQuery(this).data('timestamp').toString(); updraft_send_command('rawbackup_history', { timestamp: timestamp, nonce: nonce }, function (response) { if (response.hasOwnProperty('rawbackup')) { var textArea = document.createElement('textarea'); textArea.innerHTML = response.rawbackup; updraft_html_modal(textArea.value, updraftlion.raw, 780, 500); } else { updraft_html_modal(updraftlion.jsonnotunderstood, updraftlion.raw, 780, 500); } }, { type: 'POST' }); updraft_html_modal('

                '+ updraftlion.loading +'
                ', updraftlion.raw, 780, 500); }); jQuery('#backupnow_database_moreoptions').on('click', 'div.backupnow-db-tables > a', function(e) { e.preventDefault(); jQuery('> input', jQuery(this).parents('div.backupnow-db-tables')).prop('checked', false); if (jQuery(this).hasClass('backupnow-select-all-table')) { jQuery('> input', jQuery(this).parents('div.backupnow-db-tables')).prop('checked', true); } else if (jQuery(this).hasClass('backupnow-select-all-this-site')) { jQuery('> input', jQuery(this).parents('div.backupnow-db-tables')).not('[data-non_wp_table]').prop('checked', true); } }); jQuery('#updraft-restore-modal').on('click', '.updraft_restore_select_all_themes', function(e) { e.preventDefault(); jQuery('.updraft_restore_themes_options').prop('checked', true); }); jQuery('#updraft-restore-modal').on('click', '.updraft_restore_deselect_all_themes', function(e) { e.preventDefault(); jQuery('.updraft_restore_themes_options').prop('checked', false); }); jQuery('#updraft-restore-modal').on('click', '.updraft_restore_select_all_plugins', function(e) { e.preventDefault(); jQuery('.updraft_restore_plugins_options').prop('checked', true); }); jQuery('#updraft-restore-modal').on('click', '.updraft_restore_deselect_all_plugins', function(e) { e.preventDefault(); jQuery('.updraft_restore_plugins_options').prop('checked', false); }); jQuery('.updraftmessage.admin-warning-litespeed').on('click', '.notice-dismiss', function(e) { e.preventDefault(); updraft_send_command('dismiss_admin_warning_litespeed', 1, function (response) {}); }); function apply_search_on_db_size() { var value = jQuery('.db-search').val().toLowerCase(); jQuery(".db-size-content tr").filter(function() { jQuery(this).toggle(jQuery(this).text().toLowerCase().indexOf(value) > -1) }); } jQuery('#db_size.advanced_tools_button, .db-size-refresh').on('click', function(e) { e.preventDefault(); var $total_size = jQuery('.advanced_settings_content .advanced_tools.db_size .total-size'); var $table_body = jQuery('.advanced_settings_content .advanced_tools.db_size tbody.db-size-content'); // trigger the ajax from the 'Database size' menu only for the first time if (jQuery(this).hasClass('advanced_tools_button') && '' != $table_body.html()) { return; } $table_body.html(''); updraft_send_command('db_size', 1, function (response) { $total_size.html(response.size); $table_body.html(response.html); apply_search_on_db_size(); }); }); jQuery('.db-search').on('input', function() { apply_search_on_db_size(); }); jQuery('.db-search-clear').on('click', function(e) { e.preventDefault(); jQuery('.db-search').val(''); apply_search_on_db_size(); }); }); // UpdraftVault jQuery(function($) { var settings_css_prefix = '#updraft-navtab-settings-content '; $(settings_css_prefix+'#remote-storage-holder').on('click', '.updraftvault_backtostart', function(e) { e.preventDefault(); $(settings_css_prefix+'#updraftvault_settings_showoptions').slideUp(); $(settings_css_prefix+'#updraftvault_settings_connect').slideUp(); $(settings_css_prefix+'#updraftvault_settings_connected').slideUp(); $(settings_css_prefix+'#updraftvault_settings_default').slideDown(); }); // Prevent default event when pressing return in the form $(settings_css_prefix).on('keypress','#updraftvault_settings_connect input', function(e) { if (13 == e.which) { $(settings_css_prefix+'#updraftvault_connect_go').trigger('click'); return false; } }); $(settings_css_prefix+'#remote-storage-holder').on('click', '#updraftvault_recountquota', function(e) { e.preventDefault(); $(settings_css_prefix+'#updraftvault_recountquota').html(updraftlion.counting); try { updraft_send_command('vault_recountquota', { instance_id: $('#updraftvault_settings_connect').data('instance_id') }, function(response) { $(settings_css_prefix+'#updraftvault_recountquota').html(updraftlion.updatequotacount); if (response.hasOwnProperty('html')) { $(settings_css_prefix+'#updraftvault_settings_connected').html(response.html); if (response.hasOwnProperty('connected')) { if (response.connected) { $(settings_css_prefix+'#updraftvault_settings_default').hide(); $(settings_css_prefix+'#updraftvault_settings_connected').show(); } else { $(settings_css_prefix+'#updraftvault_settings_connected').hide(); $(settings_css_prefix+'#updraftvault_settings_default').show(); } } } }, { error_callback: function(response, status, error_code, resp) { $(settings_css_prefix+'#updraftvault_recountquota').html(updraftlion.updatequotacount); if (typeof resp !== 'undefined' && resp.hasOwnProperty('fatal_error')) { console.error(resp.fatal_error_message); alert(resp.fatal_error_message); } else { var error_message = "updraft_send_command: error: "+status+" ("+error_code+")"; console.log(error_message); alert(error_message); console.log(response); } } }); } catch (err) { $(settings_css_prefix+'#updraftvault_recountquota').html(updraftlion.updatequotacount); console.log(err); } }); $(settings_css_prefix+'#remote-storage-holder').on('click', '#updraftvault_disconnect', function(e) { e.preventDefault(); $(settings_css_prefix+'#updraftvault_disconnect').html(updraftlion.disconnecting); try { updraft_send_command('vault_disconnect', { immediate_echo: true, instance_id: $('#updraftvault_settings_connect').data('instance_id') }, function(response) { $(settings_css_prefix+'#updraftvault_disconnect').html(updraftlion.disconnect); if (response.hasOwnProperty('html')) { $(settings_css_prefix+'#updraftvault_settings_connected').html(response.html).slideUp(); $(settings_css_prefix+'#updraftvault_settings_default').slideDown(); } }, { error_callback: function(response, status, error_code, resp) { $(settings_css_prefix+'#updraftvault_disconnect').html(updraftlion.disconnect); if (typeof resp !== 'undefined' && resp.hasOwnProperty('fatal_error')) { console.error(resp.fatal_error_message); alert(resp.fatal_error_message); } else { var error_message = "updraft_send_command: error: "+status+" ("+error_code+")"; console.log(error_message); alert(error_message); console.log(response); } } }); } catch (err) { $(settings_css_prefix+'#updraftvault_disconnect').html(updraftlion.disconnect); console.log(err); } }); $(settings_css_prefix+'#remote-storage-holder').on('click', '#updraftvault_connect', function(e) { e.preventDefault(); $(settings_css_prefix+'#updraftvault_settings_default').slideUp(); $(settings_css_prefix+'#updraftvault_settings_connect').slideDown(); }); $(settings_css_prefix+'#remote-storage-holder').on('click', '#updraftvault_showoptions', function(e) { e.preventDefault(); $(settings_css_prefix+'#updraftvault_settings_default').slideUp(); $(settings_css_prefix+'#updraftvault_settings_showoptions').slideDown(); }); $('#remote-storage-holder').on('keyup', '.updraftplus_onedrive_folder_input', function(e) { var folder = $(this).val(); var td_container = $(this).closest('td') if (0 == folder.indexOf('https:') || 0 == folder.indexOf('http:')) { if (!td_container.find('.onedrive_folder_error').length) { td_container.append('
                '+updraftlion.onedrive_folder_url_warning+'
                '); } } else { td_container.find('.onedrive_folder_error').slideUp('slow', function() { td_container.find('.onedrive_folder_error').remove(); }); } }); $(settings_css_prefix+'#remote-storage-holder').on('click', '#updraftvault_connect_go', function(e) { $(settings_css_prefix+'#updraftvault_connect_go').html(updraftlion.connecting); updraft_send_command('vault_connect', { email: $('#updraftvault_email').val(), pass: $('#updraftvault_pass').val(), instance_id: $('#updraftvault_settings_connect').data('instance_id'), }, function(resp, status, response) { $(settings_css_prefix+'#updraftvault_connect_go').html(updraftlion.connect); if (resp.hasOwnProperty('e')) { updraft_html_modal('

                '+updraftlion.errornocolon+'

                '+resp.e+'

                ', updraftlion.disconnect, 400, 250); if (resp.hasOwnProperty('code') && resp.code == 'no_quota') { $(settings_css_prefix+'#updraftvault_settings_connect').slideUp(); $(settings_css_prefix+'#updraftvault_settings_default').slideDown(); } } else if (resp.hasOwnProperty('connected') && resp.connected && resp.hasOwnProperty('html')) { $(settings_css_prefix+'#updraftvault_settings_connect').slideUp(); $(settings_css_prefix+'#updraftvault_settings_connected').html(resp.html).slideDown(); } else { console.log(resp); alert(updraftlion.unexpectedresponse+' '+response); } }, { error_callback: function(response, status, error_code, resp) { $(settings_css_prefix+'#updraftvault_connect_go').html(updraftlion.connect); if (typeof resp !== 'undefined' && resp.hasOwnProperty('fatal_error')) { console.error(resp.fatal_error_message); alert(resp.fatal_error_message); } else { var error_message = "updraft_send_command: error: "+status+" ("+error_code+")"; console.log(error_message); alert(error_message); console.log(response); } } }); return false; }); // Mark a backup as always keep (do not delete) $('#updraft-iframe-modal').on('change', '#always_keep_this_backup', function() { var backup_key = $(this).data('backup_key'); var params = { backup_key: backup_key, always_keep: $(this).is(':checked') ? 1 : 0, }; updraft_send_command('always_keep_this_backup', params, function(resp) { if (resp.hasOwnProperty('rawbackup')) { jQuery('#updraft-iframe-modal').dialog('close'); jQuery('.updraft_existing_backups_row_'+backup_key+' .updraft_existingbackup_date').data('rawbackup', resp.rawbackup); updraft_html_modal(jQuery('.updraft_existing_backups_row_'+backup_key+' .updraft_existingbackup_date').data('rawbackup'), updraftlion.raw, 780, 500); } }); }); }); // End ready Vault // Next: the encrypted database pluploader jQuery(function($) { try { if (typeof updraft_plupload_config2 !== 'undefined') { plupload_init(); } } catch (err) { console.log(err); } function plupload_init() { // create the uploader and pass the config from above var uploader = new plupload.Uploader(updraft_plupload_config2); // checks if browser supports drag and drop upload, makes some css adjustments if necessary uploader.bind('Init', function(up) { var uploaddiv = jQuery('#plupload-upload-ui2'); if (up.features.dragdrop) { uploaddiv.addClass('drag-drop'); jQuery('#drag-drop-area2') .on('dragover.wp-uploader', function() { uploaddiv.addClass('drag-over'); }) .on('dragleave.wp-uploader, drop.wp-uploader', function() { uploaddiv.removeClass('drag-over'); }); } else { uploaddiv.removeClass('drag-drop'); jQuery('#drag-drop-area2').off('.wp-uploader'); } }); uploader.init(); // a file was added in the queue uploader.bind('FilesAdded', function(up, files) { // var hundredmb = 100 * 1024 * 1024, max = parseInt(up.settings.max_file_size, 10); plupload.each(files, function(file) { // @codingStandardsIgnoreLine if (!/^backup_([\-0-9]{15})_.*_([0-9a-f]{12})-db([0-9]+)?\.(gz\.crypt)$/i.test(file.name)) { alert(file.name+': '+updraftlion.notdba); uploader.removeFile(file); return; } // a file was added, you may want to update your DOM here... jQuery('#filelist2').append( '
                ' + file.name + ' (' + plupload.formatSize(0) + '/' + plupload.formatSize(file.size) + ') ' + '
                '); }); up.refresh(); up.start(); }); uploader.bind('UploadProgress', function(up, file) { jQuery('#' + file.id + " .fileprogress").width(file.percent + "%"); jQuery('#' + file.id + " span").html(plupload.formatSize(parseInt(file.size * file.percent / 100))); }); uploader.bind('Error', function(up, error) { if ('-200' == error.code) { err_makesure = '\n'+updraftlion.makesure2; } else { err_makesure = updraftlion.makesure; } alert(updraftlion.uploaderr+' (code '+error.code+") : "+error.message+" "+err_makesure); }); // a file was uploaded uploader.bind('FileUploaded', function(up, file, response) { if (response.status == '200') { // this is your ajax response, update the DOM with it or something... if (response.response.substring(0,6) == 'ERROR:') { alert(updraftlion.uploaderror+" "+response.response.substring(6)); } else if (response.response.substring(0,3) == 'OK:') { bkey = response.response.substring(3); jQuery('#' + file.id + " .fileprogress").hide(); jQuery('#' + file.id).append(updraftlion.uploaded+' '+updraftlion.followlink+' '+updraftlion.thiskey+' '+jQuery('#updraftplus_db_decrypt').val().replace(/&/g, "&").replace(//g, ">")); } else { alert(updraftlion.unknownresp+' '+response.response); } } else { alert(updraftlion.ukrespstatus+' '+response.code); } }); } jQuery('#updraft-hidethis').remove(); /* * A Handlebarsjs helper function that is used to compare * two values if they are equal. Please refer to the example below. * Assuming "comment_status" contains the value of "spam". * * @param {mixed} a The first value to compare * @param {mixed} b The second value to compare * * @example * // returns "I am spam!", otherwise "I am not a spam!" * {{#ifeq "spam" comment_status}} * I am spam! * {{else}} * I am not a spam! * {{/ifeq}} * * @return {string} */ Handlebars.registerHelper('ifeq', function (a, b, opts) { if ('string' !== typeof a && 'undefined' !== typeof a && null !== a) a = a.toString(); if ('string' !== typeof b && 'undefined' !== typeof b && null !== b) b = b.toString(); if (a === b) { return opts.fn(this); } else { return opts.inverse(this); } }); /* * Handlebars helper function to replace all password chars into asterisk char * * @param {string} password Required. The plain-text password * * @return {string} */ Handlebars.registerHelper('maskPassword', function(password) { return password.replace(/./gi,'*'); }); /* * Handlebars helper function that wraps javascript encodeURIComponent so that it could encode the following characters: , / ? : @ & = + $ # * * @param {string} uri Required. The URI to be encoded */ Handlebars.registerHelper('encodeURIComponent', function(uri) { return encodeURIComponent(uri); }); /** * Handlebars helper function to compare two values using a specified operator * * @see https://stackoverflow.com/questions/8853396/logical-operator-in-a-handlebars-js-if-conditional#answer-16315366 * * @param {mixed} v1 the first value to compare * @param {mixed} v2 the second value to compare * * @return {boolean} true if the first value matched against the second value, false otherwise */ Handlebars.registerHelper('ifCond', function(v1, operator, v2, options) { switch (operator) { case '==': return (v1 == v2) ? options.fn(this) : options.inverse(this); case '===': return (v1 === v2) ? options.fn(this) : options.inverse(this); case '!=': return (v1 != v2) ? options.fn(this) : options.inverse(this); case '!==': return (v1 !== v2) ? options.fn(this) : options.inverse(this); case '<': return (v1 < v2) ? options.fn(this) : options.inverse(this); case '<=': return (v1 <= v2) ? options.fn(this) : options.inverse(this); case '>': return (v1 > v2) ? options.fn(this) : options.inverse(this); case '>=': return (v1 >= v2) ? options.fn(this) : options.inverse(this); case '&&': return (v1 && v2) ? options.fn(this) : options.inverse(this); case '||': return (v1 || v2) ? options.fn(this) : options.inverse(this); case 'typeof': return (v1 === typeof v2) ? options.fn(this) : options.inverse(this); case 'not_typeof': return (v1 !== typeof v2) ? options.fn(this) : options.inverse(this); default: return options.inverse(this); } }); /** * Handlebars helper function for looping through a block of code a specified number of times * * @param {mixed} from the start value * @param {mixed} to the end value where the loop will stop * @param {mixed} incr the increment number * * @return {mixed} the current processing number */ Handlebars.registerHelper('for', function(from, to, incr, block) { var accum = ''; for (var i = from; i < to; i += incr) accum += block.fn(i); return accum; }); /** * Assign value into a variable * * @param {string} name the variable name * @param {mixed} val the value */ Handlebars.registerHelper('set_var', function(name, val, options) { if (!options.data.root) { options.data.root = {}; } options.data.root[name] = val; }); /** * Get length of an array/object * * @param {mixed} object the object */ Handlebars.registerHelper('get_length', function(object) { if ("undefined" !== typeof object && false === object instanceof Array) { return Object.keys(object).length; } else if (true === object instanceof Array) { return object.length; } else { return 0; } }); /** * Return a space-separated list of CSS classes suitable for rows in the configuration section * * @see UpdraftPlus_BackupModule::get_css_classes() * * @param {boolean} include_instance a boolean value to indicate if we want to include the instance_id in the css class, we may not want to include the instance if it's for a UI element that we don't want to be removed along with other UI elements that do include a instance id * @return {string} the list of CSS classes */ Handlebars.registerHelper('get_template_css_classes', function(include_instance, options) { var css_classes = options.data.root.css_class + ' ' + options.data.root.method_id; if (!include_instance || !options.data.root['is_multi_options_feature_supported']) return css_classes; if (options.data.root['is_config_templates_feature_supported']) { css_classes += ' ' + options.data.root.method_id + '-' + options.data.root.instance_id; } else { css_classes += ' ' + options.data.root.method_id + '-' + options.data.root._instance_id; } return css_classes; }); /** * Output the value of an id or name attribute, as if currently within an input tag * This assumes standardised options handling (i.e. that the options array is updraft_(method-id)) * * @see UpdraftPlus_BackupModule::output_settings_field_name_and_id() * * @param {string} input_attribute The attribute of an input tag * @param {mixed} fields the field identifiers * @return {string} a specific value to the given input attribute */ Handlebars.registerHelper('get_template_input_attribute_value', function(input_attribute, fields, options) { var instance_id = options.data.root['is_config_templates_feature_supported'] ? options.data.root.instance_id : options.data.root._instance_id; var id = ename = ''; var method_id = options.data.root.method_id; try { fields = JSON.parse(fields); } catch (e) {} if ("undefined" !== typeof fields && Array === fields.constructor) { for (var i=0; i \ \ \

                \ \

                \ \ '; }); // Add remote methods html using handlebarjs if ($('#remote-storage-holder').length) { var html = ''; var not_instance_ids = ['default', 'template_properties']; for (var method in updraftlion.remote_storage_templates) { if ('undefined' != typeof updraftlion.remote_storage_options[method] && not_instance_ids.length < Object.keys(updraftlion.remote_storage_options[method]).length) { var template = Handlebars.compile(updraftlion.remote_storage_templates[method]); for (var partial_template_name in updraftlion.remote_storage_partial_templates[method]) { Handlebars.registerPartial(partial_template_name, Handlebars.compile(updraftlion.remote_storage_partial_templates[method][partial_template_name])); } var first_instance = true; var instance_count = 1; for (var instance_id in updraftlion.remote_storage_options[method]) { if (not_instance_ids.indexOf(instance_id) > -1) continue; var context = {}; // Initiate a reference by assigning an empty object to a variable (in this case the context variable) so that it can be used as a target of merging one or more other objects. Unlike basic values (boolean, string, integer, etc.), in Javascript objects and arrays are passed by reference // copy what are in the template properties to the context overwriting the same object properties, and then copy what are in the instance settings to the context overwriting all the same properties from the previous merging operation (if any). The context properties are overwritten by other objects that have the same properties later in the parameters order Object.assign(context, updraftlion.remote_storage_options[method]['template_properties'], updraftlion.remote_storage_options[method][instance_id]); if ('undefined' == typeof context['instance_conditional_logic']) { context['instance_conditional_logic'] = { type: '', // always by default rules: [], }; } context['instance_conditional_logic'].day_of_the_week_options = updraftlion.conditional_logic.day_of_the_week_options; context['instance_conditional_logic'].logic_options = updraftlion.conditional_logic.logic_options; context['instance_conditional_logic'].operand_options = updraftlion.conditional_logic.operand_options; context['instance_conditional_logic'].operator_options = updraftlion.conditional_logic.operator_options; context['first_instance'] = first_instance; if ('undefined' == typeof context['instance_enabled']) { context['instance_enabled'] = 1; } if ('undefined' == typeof context['instance_label'] || '' == context['instance_label']) { var method_name = updraftlion.remote_storage_methods[method]; var instance_label = ' (' + instance_count + ')'; if (1 == instance_count) { instance_label = ''; } context['instance_label'] = method_name + instance_label; } html += template(context); first_instance = false; instance_count++; } } else { html += updraftlion.remote_storage_templates[method]; } } $('#remote-storage-holder').append(html).ready(function () { $('.updraftplusmethod').not('.none').hide(); updraft_remote_storage_tabs_setup(); // Displays warning to the user of their mistake if they try to enter a URL in the OneDrive settings and saved $('#remote-storage-holder .updraftplus_onedrive_folder_input').trigger('keyup'); }); } }); // Save/Export/Import settings via AJAX jQuery(function($) { // Pre-load the image so that it doesn't jerk when first used var my_image = new Image(); my_image.src = updraftlion.ud_url+'/images/notices/updraft_logo.png'; // When inclusion options for file entities in the settings tab, reflect that in the "Backup Now" dialog, to prevent unexpected surprises $('#updraft-navtab-settings-content input.updraft_include_entity').on('change', function(e) { var event_target = $(this).attr('id'); var checked = $(this).is(':checked'); var backup_target = '#backupnow_files_'+event_target; $(backup_target).prop('checked', checked); }); $('#updraftplus-settings-save').on('click', function(e) { e.preventDefault(); $.blockUI({ css: { width: '300px', border: 'none', 'border-radius': '10px', left: 'calc(50% - 150px)', padding: '20px', }, message: '

                '+updraftlion.saving+'
                ' }); var form_data = gather_updraft_settings('string'); // POST the settings back to the AJAX handler updraft_send_command('savesettings', { settings: form_data, updraftplus_version: updraftlion.updraftplus_version }, function(resp, status, response) { // Add page updates etc based on response updraft_handle_page_updates(resp, response); $('#updraft-wrap .fade').delay(6000).fadeOut(2000); if (window.updraft_main_tour && !window.updraft_main_tour.canceled) { window.updraft_main_tour.show('settings_saved'); check_cloud_authentication(); } else { $('html, body').animate({ scrollTop: $("#updraft-wrap").offset().top }, 1000, function() { check_cloud_authentication() }); } $.unblockUI(); }, { action: 'updraft_savesettings', error_callback: function(response, status, error_code, resp) { $.unblockUI(); if (typeof resp !== 'undefined' && resp.hasOwnProperty('fatal_error')) { console.error(resp.fatal_error_message); alert(resp.fatal_error_message); } else { var error_message = "updraft_send_command: error: "+status+" ("+error_code+")"; console.log(error_message); alert(error_message); console.log(response); } }, nonce: updraftplus_settings_nonce}); }); $('#updraftplus-settings-export').on('click', function() { if (updraft_settings_form_changed) { alert(updraftlion.unsaved_settings_export); } export_settings(); }); $('#updraftplus-settings-import').on('click', function() { $.blockUI({ css: { width: '300px', border: 'none', 'border-radius': '10px', left: 'calc(50% - 150px)', padding: '20px', }, message: '

                '+updraftlion.importing+'
                ' }); var updraft_import_file_input = document.getElementById('import_settings'); if (updraft_import_file_input.files.length == 0) { alert(updraftlion.import_select_file); $.unblockUI(); return; } var updraft_import_file_file = updraft_import_file_input.files[0]; var updraft_import_file_reader = new FileReader(); updraft_import_file_reader.onload = function() { import_settings(this.result); }; updraft_import_file_reader.readAsText(updraft_import_file_file); }); function export_settings() { var form_data = gather_updraft_settings('object'); var date_now = new Date(); // The 'version' attribute indicates the last time the format changed - i.e. do not update this unless there is a format change form_data = JSON.stringify({ version: '1.12.40', epoch_date: date_now.getTime(), local_date: date_now.toLocaleString(), network_site_url: updraftlion.network_site_url, data: form_data }); // Attach this data to an anchor on page var link = document.body.appendChild(document.createElement('a')); link.setAttribute('download', updraftlion.export_settings_file_name); link.setAttribute('style', "display:none;"); link.setAttribute('href', 'data:text/json' + ';charset=UTF-8,' + encodeURIComponent(form_data)); link.click(); } function import_settings(updraft_file_result) { var parsed; try { parsed = ud_parse_json(updraft_file_result); } catch (e) { $.unblockUI(); jQuery('#import_settings').val(''); console.log(updraft_file_result); console.log(e); alert(updraftlion.import_invalid_json_file); return; } if (window.confirm(updraftlion.importing_data_from + ' ' + parsed['network_site_url'] + "\n" + updraftlion.exported_on + ' ' + parsed['local_date'] + "\n" + updraftlion.continue_import)) { // GET the settings back to the AJAX handler var stringified = JSON.stringify(parsed['data']); updraft_send_command('importsettings', { settings: stringified, updraftplus_version: updraftlion.updraftplus_version, }, function(decoded_response, status, response) { var resp = updraft_handle_page_updates(decoded_response); if (!resp.hasOwnProperty('saved') || resp.saved) { // Prevent the user being told they have unsaved settings updraft_settings_form_changed = false; // Add page updates etc based on response location.replace(updraftlion.updraft_settings_url); } else { $.unblockUI(); if (resp.hasOwnProperty('error_message') && resp.error_message) { alert(resp.error_message); } } }, { action: 'updraft_importsettings', nonce: updraftplus_settings_nonce, error_callback: function(response, status, error_code, resp) { $.unblockUI(); if (typeof resp !== 'undefined' && resp.hasOwnProperty('fatal_error')) { console.error(resp.fatal_error_message); alert(resp.fatal_error_message); } else { var error_message = "updraft_send_command: error: "+status+" ("+error_code+")"; console.log(error_message); console.log(response); alert(error_message); } } }); } else { $.unblockUI(); } } /** * Retrieve the current settings from the DOM * * @param {string} output_format - the output format; valid values are 'string' or 'object' * * @returns String|Object */ function gather_updraft_settings(output_format) { var form_data = ''; var output_format = ('undefined' === typeof output_format) ? 'string' : output_format; if ('object' == output_format) { // Excluding the unnecessary 'action' input avoids triggering a very mis-conceived mod_security rule seen on one user's site form_data = $("#updraft-navtab-settings-content form input[name!='action'][name!='option_page'][name!='_wpnonce'][name!='_wp_http_referer'], #updraft-navtab-settings-content form textarea, #updraft-navtab-settings-content form select, #updraft-navtab-settings-content form input[type=checkbox]").serializeJSON({checkboxUncheckedValue: '0', useIntKeysAsArrayIndex: true}); } else { // Excluding the unnecessary 'action' input avoids triggering a very mis-conceived mod_security rule seen on one user's site form_data = $("#updraft-navtab-settings-content form input[name!='action'], #updraft-navtab-settings-content form textarea, #updraft-navtab-settings-content form select").serialize(); // include unchecked checkboxes. user filter to only include unchecked boxes. $.each($('#updraft-navtab-settings-content form input[type=checkbox]') .filter(function(idx) { return $(this).prop('checked') == false }), function(idx, el) { // attach matched element names to the form_data with chosen value. var empty_val = '0'; form_data += '&' + $(el).attr('name') + '=' + empty_val; } ); } return form_data; } /** * Method to parse the response from the backend and update the page with the returned content or display error messages if failed * * @param {array} resp - the JSON-decoded response containing information to update the settings page with * @param {string} response - the JSON-encoded response containing information to update the settings page with * * @return {object} - the decoded response (empty if decoding was not successful) */ function updraft_handle_page_updates(resp, response) { try { var messages = resp.messages; // var debug = resp.changed.updraft_debug_mode; // If backup dir is not writable, change the text, and grey out the 'Backup Now' button var backup_dir_writable = resp.backup_dir.writable; var backup_dir_message = resp.backup_dir.message; var backup_button_title = resp.backup_dir.button_title; } catch (e) { console.log(e); console.log(response); alert(updraftlion.jsonnotunderstood); $.unblockUI(); return {}; } if (resp.hasOwnProperty('changed')) { console.log("UpdraftPlus: savesettings: some values were changed after being filtered"); console.log(resp.changed); for (prop in resp.changed) { if ('object' === typeof resp.changed[prop]) { for (innerprop in resp.changed[prop]) { if (!$("[name='"+innerprop+"']").is(':checkbox')) { $("[name='"+prop+"["+innerprop+"]']").val(resp.changed[prop][innerprop]); } } } else { if (!$("[name='"+prop+"']").is(':checkbox')) { $("[name='"+prop+"']").val(resp.changed[prop]); } } } } $('#updraft_writable_mess').html(backup_dir_message); if (false == backup_dir_writable) { $('#updraft-backupnow-button').attr('disabled', 'disabled'); $('#updraft-backupnow-button').attr('title', backup_button_title); $('.backupdirrow').css('display', 'table-row'); } else { $('#updraft-backupnow-button').prop('disabled', false); $('#updraft-backupnow-button').removeAttr('title'); // $('.backupdirrow').hide(); } if (resp.hasOwnProperty('updraft_include_more_path')) { $('#backupnow_includefiles_moreoptions').html(resp.updraft_include_more_path); } if (resp.hasOwnProperty('backup_now_message')) { $('#backupnow_remote_container').html(resp.backup_now_message); } // Move from 2 to 1 $('.updraftmessage').remove(); $('#updraft_backup_started').before(resp.messages); console.log(resp); // $('#updraft-next-backup-inner').html(resp.scheduled); $('#updraft-next-files-backup-inner').html(resp.files_scheduled); $('#updraft-next-database-backup-inner').html(resp.database_scheduled); return resp; } /** * This function has the workings for checking if any cloud storage needs authentication * If so, these are amended to the HTML and the popup is shown to the users. */ function check_cloud_authentication(){ var show_auth_modal = false; jQuery('#updraft-authenticate-modal-innards').html(''); jQuery("div[class*=updraft_authenticate_] a.updraft_authlink").each(function () { var pretext = jQuery(this).data('pretext'); if ('undefined' === typeof pretext) pretext = ''; jQuery("#updraft-authenticate-modal-innards").append(pretext+'

                '+jQuery(this).html()+'

                '); show_auth_modal = true; }); if (show_auth_modal) { var updraft_authenticate_modal_buttons = {}; updraft_authenticate_modal_buttons[updraftlion.cancel] = function() { jQuery(this).dialog("close"); }; jQuery('#updraft-authenticate-modal').dialog({autoOpen: true, modal: true, resizable: false, draggable: false, resizeOnWindowResize: true, scrollWithViewport: true, resizeAccordingToViewport: true, useContentSize: false, open: function(event, ui) { $(this).dialog('option', 'width', 860); $(this).dialog('option', 'height', 260); }, buttons: updraft_authenticate_modal_buttons}).dialog('open'); } } $('.udp-replace-with-iframe--js').on('click', function(e) { e.preventDefault(); var url = $(this).prop('href'); var iframe = $(''),jQuery("#updraft-iframe-modal").dialog({title:e,resizeOnWindowResize:!0,scrollWithViewport:!0,resizeAccordingToViewport:!0,useContentSize:!1,open:function(t,e){jQuery(this).dialog("option","width",780),jQuery(this).dialog("option","minHeight",260),500r?jQuery(this).dialog("option","height",r):jQuery(this).dialog("option","height",jQuery(window).height()-30)}}).dialog("open")}function updraftplus_diskspace(){jQuery("#updraft-navtab-backups-content .updraft_diskspaceused").html(""+updraftlion.calculating+""),updraft_send_command("get_fragment",{fragment:"disk_usage",data:"updraft"},function(t){jQuery("#updraft-navtab-backups-content .updraft_diskspaceused").html(t.output)},{type:"GET"})}"undefined"!=typeof updraft_siteurl&&setInterval(function(){jQuery.get(updraft_siteurl+"/wp-cron.php")},21e4);lastlog_lastmessage="";function updraftplus_deletefromserver(t,e,a){updraft_send_command("updraft_download_backup",{stage:"delete",timestamp:t,type:e,findex:a=a||0},null,{action:"updraft_download_backup",nonce:updraft_download_nonce,nonce_key:"_wpnonce"})}function updraftplus_downloadstage2(t,e,a){location.href=ajaxurl+"?_wpnonce="+updraft_download_nonce+"×tamp="+t+"&type="+e+"&stage=2&findex="+a+"&action=updraft_download_backup"}function updraftplus_show_contents(t,e,a){updraft_html_modal('

                '+updraftlion.zip_file_contents_info+' -

                '+updraftlion.browse_download_link+'
                ',updraftlion.zip_file_contents,780,500),zip_files_jstree("zipbrowser",t,e,a)}function zip_files_jstree(a,r,n,o){jQuery("#updraft_zip_files_jstree").jstree({core:{multiple:!1,data:function(t,e){updraft_send_command("get_jstree_directory_nodes",{entity:a,node:t,timestamp:r,type:n,findex:o},function(t){t.hasOwnProperty("error")?alert(t.error):e.call(this,t.nodes)},{error_callback:function(t,e,a,r){void 0!==r&&r.hasOwnProperty("fatal_error")?(console.error(r.fatal_error_message),jQuery("#updraft_zip_files_jstree").html('

                '+r.fatal_error_message+"

                "),alert(r.fatal_error_message)):(r="updraft_send_command: error: "+e+" ("+a+")",jQuery("#updraft_zip_files_jstree").html('

                '+r+"

                "),console.log(r),alert(r),console.log(t))}})},error:function(t){alert(t),console.log(t)}},search:{show_only_matches:!0},plugins:["search","sort"]}),jQuery("#updraft_zip_files_jstree").on("ready.jstree",function(t,e){jQuery("#updraft-iframe-modal").dialog("option","title",updraftlion.zip_file_contents+": "+e.instance.get_node("#").children[0])});var t=!1;jQuery("#zip_files_jstree_search").on("keyup",function(){t&&clearTimeout(t),t=setTimeout(function(){var t=jQuery("#zip_files_jstree_search").val();jQuery("#updraft_zip_files_jstree").jstree(!0).search(t)},250)}),jQuery("#updraft_zip_files_jstree").on("changed.jstree",function(t,e){jQuery("#updraft_zip_path_text").text(e.node.li_attr.path),e.node.li_attr.size?(jQuery("#updraft_zip_size_text").text(e.node.li_attr.size),jQuery("#updraft_zip_download_item").show()):(jQuery("#updraft_zip_size_text").text(""),jQuery("#updraft_zip_download_item").hide())}),jQuery("#updraft_zip_download_item").on("click",function(t){t.preventDefault(),updraft_send_command("get_zipfile_download",{path:jQuery("#updraft_zip_path_text").text(),timestamp:r,type:n,findex:o},function(t){t.hasOwnProperty("error")?alert(t.error):t.hasOwnProperty("path")?location.href=ajaxurl+"?_wpnonce="+updraft_download_nonce+"×tamp="+r+"&type="+n+"&stage=2&findex="+o+"&filepath="+t.path+"&action=updraft_download_backup":alert(updraftlion.download_timeout)},{error_callback:function(t,e,a,r){void 0!==r&&r.hasOwnProperty("fatal_error")?(console.error(r.fatal_error_message),alert(r.fatal_error_message)):(r="updraft_send_command: error: "+e+" ("+a+")",console.log(r),alert(r),console.log(t))}})})}function remove_updraft_downloader(t,e){jQuery(t).closest(".updraftplus_downloader").fadeOut().remove(),0==jQuery(".updraftplus_downloader_container_"+e+" .updraftplus_downloader").length&&jQuery(".updraftplus_downloader_container_"+e).remove()}function updraft_downloader(t,e,a,r,n,o,d){"string"!=typeof n&&(n=n.toString()),jQuery(".ud_downloadstatus").show();var n=n.split(","),o=o||e,u=jQuery("#updraft-navtab-backups-content .uddownloadform_"+a+"_"+e+"_"+n[0]).data("wp_nonce").toString();jQuery(".updraftplus_downloader_container_"+a).length||(jQuery(r).append('
                '),jQuery(".updraftplus_downloader_container_"+a).append(''+updraftlion.download+" "+a+" ("+o+"):"));for(var s=0;s'+a+l+':
                '+updraftlion.begunlooking+'
                '),jQuery(p).data("downloaderfor",{base:t,nonce:e,what:a,index:n[s]}),setTimeout(function(){updraft_activejobs_update(!0)},1500)),jQuery(p).data("lasttimebegan",(new Date).getTime())}return updraft_send_command("updraft_download_backup",{type:a,timestamp:e,findex:n},function(t){},{action:"updraft_download_backup",nonce_key:"_wpnonce",nonce:u,timeout:1e4,async:d=!!d}),!1}function ud_parse_json(e,a){if(!(a=void 0!==a))try{return JSON.parse(e)}catch(t){console.log("UpdraftPlus: Exception when trying to parse JSON (1) - will attempt to fix/re-parse based upon first/last curly brackets"),console.log(e)}var r=e.indexOf("{"),n=e.lastIndexOf("}");if(-1 '+updraftlion.preparing_backup_files),updraft_send_command("restore_alldownloaded",{timestamp:jQuery("#updraft_restore_timestamp").val(),restoreopts:jQuery("#updraft_restore_form").serialize()},function(e,t,a){var r=null;jQuery("#updraft_restorer_restore_options").val(""),jQuery(".updraft-restore--next-step").prop("disabled",!1);try{if(null==e)jQuery("#updraft-restore-modal-stage2a").html(updraftlion.emptyresponse);else{var n=e.m;if(""!=e.w&&(n=n+'

                '+updraftlion.warnings+"

                "+e.w+"
                "),""!=e.e?n=n+'

                '+updraftlion.errors+"

                "+e.e+"
                ":updraft_restore_stage=3,e.hasOwnProperty("i")){try{(r=ud_parse_json(e.i)).hasOwnProperty("addui")&&(console.log("Further UI options are being displayed"),n+='
                '+r.addui+"
                ","object"==typeof JSON)&&"function"==typeof JSON.stringify&&(delete r.addui,e.i=JSON.stringify(r)),r.hasOwnProperty("php_max_input_vars")&&(php_max_input_vars=parseInt(r.php_max_input_vars)),r.hasOwnProperty("skipped_db_scan")&&(skipped_db_scan=parseInt(r.skipped_db_scan))}catch(t){console.log(t),console.log(e)}jQuery("#updraft_restorer_backup_info").val(e.i)}else jQuery("#updraft_restorer_backup_info").val();jQuery("#updraft-restore-modal-stage2a").html(n),jQuery(".updraft-restore--next-step").text(updraftlion.restore),0'+r.fatal_error_message+"

                "),alert(r.fatal_error_message)):(r="updraft_send_command: error: "+e+" ("+a+")",jQuery("#updraft-restore-modal-stage2a").html('

                '+r+"

                "),console.log(r),alert(r),console.log(t))}}))}function updraft_downloader_status(t,e,a,r){}function updraft_downloader_status_update(t,n){var o=0;return jQuery(t).each(function(t,e){var a,r;""!=e.base&&(a="."+(e.base+e.timestamp+"_"+e.what+"_"+e.findex),null!=e.e?(jQuery(a+" .raw").html(""+updraftlion.error+" "+e.e),console.log(e)):null!=e.p?(jQuery(a+"_st .dlfileprogress").width(e.p+"%"),null!=e.a&&0"+updraftlion.downloadtocomputer+' \t\t\t\t",e.hasOwnProperty("can_show_contents")&&e.can_show_contents&&(r+=' "),jQuery(a+" .raw").html(r),jQuery(a+"_st").remove()))):null!=e.m?jQuery(a+" .raw").html(e.m):(jQuery(a+" .raw").html(updraftlion.jsonnotunderstood+" ("+n+")"),o=1))}),o}function updraft_backupnow_go(t,e,a,r,n,o,d,u){var s,t={backupnow_nodb:t,backupnow_nofiles:e,backupnow_nocloud:a,backupnow_label:o,extradata:n};""!=r&&(t.onlythisfileentity=r),""!=d&&(t.onlythesetableentities=d),""!=u&&(t.only_these_cloud_services=u),t.always_keep=void 0!==n.always_keep?n.always_keep:0,delete n.always_keep,t.incremental=void 0!==n.incremental?n.incremental:0,delete n.incremental,t.db_anon_all=void 0!==n.db_anon&&void 0!==n.db_anon.all?n.db_anon.all:0,t.db_anon_non_staff=void 0!==n.db_anon&&void 0!==n.db_anon.non_staff?n.db_anon.non_staff:0,t.db_anon_wc_orders=void 0!==n.db_anon&&void 0!==n.db_anon.wc_orders?n.db_anon.wc_orders:0,void 0!==n.db_anon&&(delete n.db_anon.all,delete n.db_anon.non_staff,delete n.db_anon.wc_orders),jQuery(".updraft_requeststart").length||((s=jQuery('
                ').html(''+updraftlion.requeststart)).data("remove",!1),setTimeout(function(){s.data("remove",!0)},3e3),setTimeout(function(){s.remove()},75e3),jQuery("#updraft_activejobsrow").before(s)),updraft_activejobslist_backupnownonce_only=1,updraft_send_command("backupnow",t,function(t){t.hasOwnProperty("error")?(jQuery(".updraft_requeststart").remove(),alert(t.error)):(jQuery("#updraft_backup_started").html(t.m),t.hasOwnProperty("nonce")&&(updraft_backupnow_nonce=t.nonce,console.log("UpdraftPlus: ID of started job: "+updraft_backupnow_nonce)),setTimeout(function(){updraft_activejobs_update(!0)},500))})}function updraft_process_status_check(t,e,a){if(t.hasOwnProperty("fatal_error"))console.error(t.fatal_error_message),!0===updraftplus_activejobs_list_fatal_error_alert&&(updraftplus_activejobs_list_fatal_error_alert=!1,alert(this.alert_done+" "+t.fatal_error_message));else try{t.hasOwnProperty("l")&&(t.l?(jQuery("#updraft_lastlogmessagerow").show(),jQuery("#updraft_lastlogcontainer").html(t.l)):(jQuery("#updraft_lastlogmessagerow").hide(),jQuery("#updraft_lastlogcontainer").html("("+updraftlion.nothing_yet_logged+")"))),updraftlion.hasOwnProperty("hosting_restriction")&&updraftlion.hosting_restriction instanceof Array&&(updraftlion.hosting_restriction.length=0,t.hasOwnProperty("hosting_restriction"))&&(t.hosting_restriction&&t.hosting_restriction.includes("only_one_backup_per_month")&&updraftlion.hosting_restriction.push("only_one_backup_per_month"),t.hosting_restriction)&&t.hosting_restriction.includes("only_one_incremental_per_day")&&updraftlion.hosting_restriction.push("only_one_incremental_per_day"),jQuery("#updraft-wrap #updraft-navtab-settings-content").is(":hidden")||t.hasOwnProperty("automatic_updates")&&jQuery('input[name="updraft_auto_updates"]').prop("checked",t.automatic_updates);var r,n,o=-1,d=jQuery(".updraft_requeststart"),u=(t.j&&d.length&&d.data("remove")&&d.remove(),jQuery(t.j)),s=(u.find(".updraft_jobtimings").each(function(t,e){var a,e=jQuery(e);e.data("jobid")&&(a=e.data("jobid"),e=e.closest(".updraft_row"),updraft_aborted_jobs[a])&&e.hide()}),jQuery("#updraft_activejobsrow").html(u),u.find('.job-id[data-isclone="1"]'));0updraft_last_forced_when+1e5&&(updraft_last_forced_jobid!=a||e!=updraft_last_forced_resumption)&&(updraft_last_forced_resumption=e,updraft_last_forced_jobid=a,updraft_last_forced_when=timenow,console.log("UpdraftPlus: force resumption: job_id="+a+", resumption="+e),updraft_send_command("forcescheduledresumption",{resumption:e,job_id:a},function(t){console.log(t)},{json_parse:!1,alert_on_error:!1}))}),timenow=(new Date).getTime(),updraft_activejobs_nextupdate=timenow+18e4,1==updraft_page_is_visible&&"backups"==updraft_console_focussed_tab&&(updraft_activejobs_nextupdate=-1"+updraftlion.error+" "+updraftlion.servererrorcode)):0<=a.url.search("subaction=restore_alldownloaded")&&jQuery("#updraft-restore-modal-stage2a").append("
                "+updraftlion.error+" "+updraftlion.servererrorcode+": "+r))}),jQuery(function(h){var e;h(document).on("udp/checkout/done",function(t,e){e.hasOwnProperty("product")&&"updraftpremium"===e.product&&"complete"===e.status&&(h(".premium-upgrade-purchase-success").show(),h(".updraft_feat_table").closest("section").hide(),h(".updraft_premium_cta__action").hide())}),h(".expertmode .advanced_settings_container .advanced_tools_button").on("click",function(){var t;t=h(this).attr("id"),h('.expertmode .advanced_settings_container .advanced_tools:not(".'+t+'")').hide(),h(".expertmode .advanced_settings_container .advanced_tools."+t).fadeIn("slow"),h(".expertmode .advanced_settings_container .advanced_tools_button:not(#"+t+")").removeClass("active"),h(".expertmode .advanced_settings_container .advanced_tools_button#"+t).addClass("active")}),jQuery.ui&&jQuery.ui.dialog&&jQuery.ui.dialog.prototype._allowInteraction&&(e=jQuery.ui.dialog.prototype._allowInteraction,jQuery.ui.dialog.prototype._allowInteraction=function(t){return!!jQuery(t.target).closest(".select2-dropdown").length||e.apply(this,arguments)}),h("#updraft-navtab-settings-content #remote-storage-holder").on("change keyup paste",".updraft_webdav_settings",function(){var t,e,r=[],a=(h(".updraft_webdav_settings").each(function(t,e){var a,e=h(e).attr("id");e&&"updraft_webdav_"==e.substring(0,15)&&(e=e.substring(15),e=(id_split=e.split("_"))[0],a=id_split[1],void 0===r[a]&&(r[a]=[]),r[a][e]=this.value)}),"@"),n="/",o=":",d=":";for(e in r)(0<=r[e].host.indexOf("@")||""===r[e].host)&&(a=""),0<=r[e].host.indexOf("/")?h(".webdav-"+e+" .updraft_webdav_host_error").show():h(".webdav-"+e+" .updraft_webdav_host_error").hide(),0!=r[e].path.indexOf("/")&&""!==r[e].path||(n=""),""!==r[e].user&&""!==r[e].pass||(o=""),""!==r[e].host&&""!==r[e].port||(d=""),t=r[e].webdav+r[e].user+o+r[e].pass+a+encodeURIComponent(r[e].host)+d+r[e].port+n+r[e].path,masked_webdav_url=r[e].webdav+r[e].user+o+r[e].pass.replace(/./gi,"*")+a+encodeURIComponent(r[e].host)+d+r[e].port+n+r[e].path,h("#updraft_webdav_url_"+e).val(t),h("#updraft_webdav_masked_url_"+e).val(masked_webdav_url)}),h("div.ud-phpseclib-notice").on("click","button.notice-dismiss",function(t){t.stopImmediatePropagation(),updraft_send_command("dismiss_phpseclib_notice",null,function(t,e,a){t.hasOwnProperty("success")&&1===t.success||(console.log(t),alert(updraftlion.unexpectedresponse+" "+a))})}),h("#updraft-navtab-backups-content").on("click",".js--delete-selected-backups",function(t){t.preventDefault(),updraft_deleteallselected()}),h("#updraft-navtab-backups-content").on("click",".updraft_existing_backups .backup-select input",function(t){updraft_backups_selection.toggle(h(this).closest(".updraft_existing_backups_row"))}),h("#updraft-navtab-backups-content").on("click","#cb-select-all",function(t){h(this).is(":checked")?updraft_backups_selection.selectAll():updraft_backups_selection.deselectAll()}),h("#updraft-wrap").on("click","[id^=updraftplus_manual_authorisation_submit_]",function(t){t.preventDefault();var e,t=h(this).data("method"),a=h("#updraftplus_manual_authentication_data_"+t).val();h("#updraftplus_manual_authentication_error_"+t).text(),h("#updraft-wrap #updraftplus_manual_authorisation_template_"+t+" .updraftplus_spinner.spinner").addClass("visible"),h("#updraftplus_manual_authorisation_submit_"+t).prop("disabled",!0),updraft_send_command("manual_remote_storage_authentication",{method:e=t,auth_data:a},function(t){h("#updraft-wrap #updraftplus_manual_authorisation_template_"+e+" .updraftplus_spinner.spinner").removeClass("visible"),t.hasOwnProperty("result")&&"success"===t.result?(h("#updraft-wrap .updraftplus-top-menu").before(t.data),h("#updraft-wrap #updraftplus_manual_authorisation_template_"+e).parent().remove(),h("#updraft-wrap .updraft_authenticate_"+e).remove()):t.hasOwnProperty("result")&&"error"===t.result&&(h("#updraftplus_manual_authentication_error_"+e).text(t.data),h("#updraftplus_manual_authorisation_submit_"+e).prop("disabled",!1))})}),h("#updraft-navtab-backups-content").on("click",".js--select-all-backups",function(t){updraft_backups_selection.selectAll()}),h("#updraft-navtab-backups-content").on("click",".js--deselect-all-backups",function(t){updraft_backups_selection.deselectAll()}),h("#updraft-navtab-backups-content").on("click",".updraft_existing_backups .updraft_existing_backups_row",function(t){(t.ctrlKey||t.metaKey)&&(t.shiftKey?(void 0===updraft_backups_selection.firstMultipleSelectionIndex?(h(document).on("keyup.MultipleSelection",function(t){updraft_backups_selection.unregister_highlight_mode(),h(document).off(".MultipleSelection")}),updraft_backups_selection.select(this),h(this).addClass("range-selection-start"),updraft_backups_selection.register_highlight_mode()):(updraft_backups_selection.selectAllInBetween(this),jQuery("#updraft-navtab-backups-content .updraft_existing_backups .updraft_existing_backups_row").removeClass("range-selection")),updraft_backups_selection.firstMultipleSelectionIndex=this.rowIndex-1):updraft_backups_selection.toggle(this))}),updraft_backups_selection.checkSelectionStatus(),h("#updraft-navtab-addons-content .wrap").on("click",".updraftplus_com_login .ud_connectsubmit",function(t){t.preventDefault();var t=h("#updraft-navtab-addons-content .wrap .updraftplus_com_login #updraftplus-addons_options_email").val(),e=h("#updraft-navtab-addons-content .wrap .updraftplus_com_login #updraftplus-addons_options_password").val(),a=h("#updraft-navtab-addons-content .wrap .updraftplus_com_login #updraftplus-addons_options_auto_updates").is(":checked")?1:0,r=h("#updraft-navtab-addons-content .wrap .updraftplus_com_login #updraftplus-addons_options_auto_udc_connect").is(":checked")?1:0;n.submit({email:t,password:e,auto_update:a,auto_udc_connect:r})}),h("#updraft-navtab-addons-content .wrap").on("keydown",".updraftplus_com_login input",function(t){var e,a,r;13==t.which&&(t.preventDefault(),t=h("#updraft-navtab-addons-content .wrap .updraftplus_com_login #updraftplus-addons_options_email").val(),e=h("#updraft-navtab-addons-content .wrap .updraftplus_com_login #updraftplus-addons_options_password").val(),a=h("#updraft-navtab-addons-content .wrap .updraftplus_com_login #updraftplus-addons_options_auto_updates").is(":checked")?1:0,r=h("#updraft-navtab-addons-content .wrap .updraftplus_com_login #updraftplus-addons_options_auto_udc_connect").is(":checked")?1:0,n.submit({email:t,password:e,auto_update:a,auto_udc_connect:r}))}),h("#updraft-navtab-migrate-content").on("click",".updraftclone_show_step_1",function(t){h(".updraftplus-clone").addClass("opened"),h(".updraftclone_show_step_1").hide(),h(".updraft_migrate_widget_temporary_clone_stage1").show(),h(".updraft_migrate_widget_temporary_clone_stage0").hide()}),h("#updraft-navtab-migrate-content").on("click",".updraft_migrate_widget_temporary_clone_show_stage0",function(t){t.preventDefault(),h(".updraft_migrate_widget_temporary_clone_stage0").toggle()}),setup_migrate_tabs(),h("#updraft-navtab-migrate-content").on("click",".updraft_migrate_widget_module_content .close",function(t){h(".updraft_migrate_intro").show(),h(this).closest(".updraft_migrate_widget_module_content").hide()}),h("#updraft-navtab-migrate-content").on("click","#updraft_migrate_tab_alt .close",function(t){t.preventDefault(),h(".updraft_migrate_intro").show(),h("#updraft_migrate_tab_alt").html("").hide()}),h("#updraft-navtab-migrate-content").on("click",".updraft_migrate_add_site--trigger",function(t){t.preventDefault(),h(".updraft_migrate_add_site").toggle()}),h("#updraft-navtab-migrate-content").on("click",".updraft_migrate_widget_module_content .updraftplus_com_login .ud_connectsubmit",function(t){t.preventDefault();var t=h("#updraft-navtab-migrate-content .updraft_migrate_widget_module_content .updraftplus_com_login #temporary_clone_options_email").val(),e=h("#updraft-navtab-migrate-content .updraft_migrate_widget_module_content .updraftplus_com_login #temporary_clone_options_password").val(),a=h("#updraft-navtab-migrate-content .updraft_migrate_widget_module_content .updraftplus_com_login #temporary_clone_options_two_factor_code").val(),r=h("#updraft-navtab-migrate-content .updraft_migrate_widget_module_content .updraftplus_com_login .temporary_clone_terms_and_conditions").is(":checked")?1:0;t&&e?o({form_data:{email:t,password:e,two_factor_code:a,consent:r}}):h("#updraft-navtab-migrate-content .updraft_migrate_widget_module_content .updraftplus_com_login_status").html(""+updraftlion.error+" "+updraftlion.username_password_required).show()}),h("#updraft-navtab-migrate-content").on("keydown",".updraft_migrate_widget_module_content .updraftplus_com_login input",function(t){var e,a,r;13==t.which&&(t.preventDefault(),t=h("#updraft-navtab-migrate-content .updraft_migrate_widget_module_content .updraftplus_com_login #temporary_clone_options_email").val(),e=h("#updraft-navtab-migrate-content .updraft_migrate_widget_module_content .updraftplus_com_login #temporary_clone_options_password").val(),a=h("#updraft-navtab-migrate-content .updraft_migrate_widget_module_content .updraftplus_com_login #temporary_clone_options_two_factor_code").val(),r=h("#updraft-navtab-migrate-content .updraft_migrate_widget_module_content .updraftplus_com_login .temporary_clone_terms_and_conditions").is(":checked")?1:0,t&&e?o({form_data:{email:t,password:e,two_factor_code:a,consent:r}}):h("#updraft-navtab-migrate-content .updraft_migrate_widget_module_content .updraftplus_com_login_status").html(""+updraftlion.error+" "+updraftlion.username_password_required).show())}),h("#updraft-navtab-migrate-content").on("click",".updraft_migrate_widget_module_content .updraftplus_com_key .ud_key_connectsubmit",function(t){t.preventDefault();var t=h("#updraft-navtab-migrate-content .updraft_migrate_widget_module_content .updraftplus_com_key #temporary_clone_options_key").val(),e=h("#updraft-navtab-migrate-content .updraft_migrate_widget_module_content .updraftplus_com_key .temporary_clone_terms_and_conditions").is(":checked")?1:0;t?a({form_data:{clone_key:t,consent:e}}):h("#updraft-navtab-migrate-content .updraft_migrate_widget_module_content .updraftplus_com_key_status").html(""+updraftlion.error+" "+updraftlion.clone_key_required).show()}),h("#updraft-navtab-migrate-content").on("keydown",".updraft_migrate_widget_module_content .updraftplus_com_key input",function(t){var e;13==t.which&&(t.preventDefault(),t=h("#updraft-navtab-migrate-content .updraft_migrate_widget_module_content .updraftplus_com_key #temporary_clone_options_key").val(),e=h("#updraft-navtab-migrate-content .updraft_migrate_widget_module_content .updraftplus_com_key .temporary_clone_terms_and_conditions").is(":checked")?1:0,t?a({form_data:{clone_key:t,consent:e}}):h("#updraft-navtab-migrate-content .updraft_migrate_widget_module_content .updraftplus_com_key_status").html(""+updraftlion.error+" "+updraftlion.clone_key_required).show())}),h("#updraft-navtab-migrate-content").on("change",".updraft_migrate_widget_module_content #updraftplus_clone_php_options",function(){var t=h(this).data("php_version");h(this).val() option").each(function(){var t=h(this).val();"starter"==t&&h('#updraft-navtab-migrate-content .updraft_migrate_widget_module_content #updraftplus_clone_package_options option[value="'+t+'"]').prop("selected",!0),h('#updraft-navtab-migrate-content .updraft_migrate_widget_module_content #updraftplus_clone_package_options option[value="'+t+'"]').prop("disabled",!1)});var a,t=h(this).find("option:selected");"current"!=h(t).data("nonce")&&"wp_only"!=h(t).data("nonce")&&(a=h(t).data("size"),h("#updraft-navtab-migrate-content .updraft_migrate_widget_module_content #updraftplus_clone_package_options > option").each(function(){var t=h(this).data("size"),e=h(this).val();if(!(t<=a))return h('#updraft-navtab-migrate-content .updraft_migrate_widget_module_content #updraftplus_clone_package_options option[value="'+e+'"]').prop("selected",!0),!1;h('#updraft-navtab-migrate-content .updraft_migrate_widget_module_content #updraftplus_clone_package_options option[value="'+e+'"]').prop("disabled",!0)}))}),h("#updraft-navtab-migrate-content").on("click",".updraft_migrate_widget_module_content #updraft_migrate_createclone",function(t){t.preventDefault(),h("#updraft-navtab-migrate-content .updraft_migrate_widget_module_content #updraft_migrate_createclone").prop("disabled",!0),h("#updraft-navtab-migrate-content .updraft_migrate_widget_module_content .updraftplus_clone_status").html(""),h("#updraft-navtab-migrate-content .updraft_migrate_widget_module_content .updraftplus_spinner.spinner").addClass("visible");var t=h(this).data("clone_id"),e=h(this).data("secret_token"),a=h("#updraft-navtab-migrate-content .updraft_migrate_widget_module_content #updraftplus_clone_php_options").val(),r=h("#updraft-navtab-migrate-content .updraft_migrate_widget_module_content #updraftplus_clone_wp_options").val(),n=h("#updraft-navtab-migrate-content .updraft_migrate_widget_module_content #updraftplus_clone_region_options").val(),o=h("#updraft-navtab-migrate-content .updraft_migrate_widget_module_content #updraftplus_clone_package_options").val(),d=h("#updraft-navtab-migrate-content .updraft_migrate_widget_module_content #updraftplus_clone_updraftclone_branch").val(),u=h("#updraft-navtab-migrate-content .updraft_migrate_widget_module_content #updraftplus_clone_updraftplus_branch").val(),s=h("#updraft-navtab-migrate-content .updraft_migrate_widget_module_content .updraftplus_clone_admin_login_options").is(":checked"),i=h("#updraftplus_clone_use_queue").is(":checked")?1:0,p=h("#updraft-navtab-migrate-content .updraft_migrate_widget_module_content #updraftplus_clone_backupnow_db_anon_all").is(":checked")?1:0,l=h("#updraft-navtab-migrate-content .updraft_migrate_widget_module_content #updraftplus_clone_backupnow_db_anon_non_staff").is(":checked")?1:0,_=h("#updraft-navtab-migrate-content .updraft_migrate_widget_module_content #updraftplus_clone_backupnow_db_anon_wc_order_data").is(":checked")?1:0,c="current",f="current",m=h("#updraft-navtab-migrate-content .updraft_migrate_widget_module_content #updraftplus_clone_backup_options").length,g=h("#updraft-navtab-migrate-content .updraft_migrate_widget_module_content #updraftplus_clone_backup_options").find("option:selected"),m=(0!==m&&void 0!==g&&(c=g.data("nonce"),f=g.data("timestamp")),{form_data:{clone_id:t,secret_token:e,install_info:{php_version:a,wp_version:r,region:n,package:o,admin_only:s,updraftclone_branch:void 0===d?"":d,updraftplus_branch:void 0===u?"":u,use_queue:void 0===i?1:i}}}),g={db_anon_all:p,db_anon_non_staff:l,db_anon_wc_orders:_,clone_region:n};"wp_only"===c&&(m.form_data.install_info.wp_only=1),function t(r,n,o,d){var u="";"current"!=n&&updraft_send_command("whichdownloadsneeded",{updraftplus_clone:!0,timestamp:n},function(t){if(t.hasOwnProperty("downloads")&&(console.log("UpdraftPlus: items which still require downloading follow"),u=t.downloads,console.log(u)),0!=u.length)for(var e=0;e'+r.fatal_error_message+"

                ")):(r="updraft_send_command: error: "+e+" ("+a+")",h("#updraft-navtab-migrate-content .updraft_migrate_widget_module_content .updraftplus_clone_status").html('

                '+r+"

                "),console.log(r),console.log(t))}});setTimeout(function(){var e,a;0!=u.length?t(r,n,o,d):(e=r.form_data.clone_id,a=r.form_data.secret_token,updraft_send_command("process_updraftplus_clone_create",r,function(t){try{h("#updraft-navtab-migrate-content .updraft_migrate_widget_module_content #updraft_migrate_createclone").prop("disabled",!1),h("#updraft-navtab-migrate-content .updraft_migrate_widget_module_content .updraftplus_spinner.spinner").removeClass("visible"),t.hasOwnProperty("status")&&"error"==t.status?h("#updraft-navtab-migrate-content .updraft_migrate_widget_module_content .updraftplus_clone_status").html(updraftlion.error+" "+t.message).show():"success"===t.status&&(h("#updraft-navtab-migrate-content .updraft_migrate_widget_module_content .updraft_migrate_widget_temporary_clone_stage2").hide(),h("#updraft-navtab-migrate-content .updraft_migrate_widget_module_content .updraft_migrate_widget_temporary_clone_stage3").show(),h("#updraft-navtab-migrate-content .updraft_migrate_widget_module_content .updraft_migrate_widget_temporary_clone_stage3").html(t.html),temporary_clone_timeout&&clearTimeout(temporary_clone_timeout),t.hasOwnProperty("secret_token")&&(a=t.secret_token),"wp_only"===o?(jQuery("#updraft_clone_progress .updraftplus_spinner.spinner").addClass("visible"),y(e,a)):(jQuery("#updraft_clone_progress .updraftplus_spinner.spinner").addClass("visible"),b(e,a,t.url,t.key,o,n,d)))}catch(t){h("#updraft-navtab-migrate-content .updraft_migrate_widget_module_content #updraft_migrate_createclone").prop("disabled",!1),console.log("Error when processing the response of process_updraftplus_clone_create (as follows)"),console.log(t)}}))},5e3)}(m,f,c,g)});var n={};function o(t){h("#updraft-navtab-migrate-content .updraft_migrate_widget_module_content .updraftplus_com_login_status").html("").hide(),h("#updraft-navtab-migrate-content .updraft_migrate_widget_module_content .updraftplus_com_login .updraftplus_spinner.spinner").addClass("visible"),updraft_send_command("process_updraftplus_clone_login",t,function(t){try{h("#updraft-navtab-migrate-content .updraft_migrate_widget_module_content .updraftplus_com_login .updraftplus_spinner.spinner").removeClass("visible"),t.hasOwnProperty("status")&&"error"==t.status?(h("#updraft-navtab-migrate-content .updraft_migrate_widget_module_content .updraftplus_com_login_status").html(t.message).show(),h("#updraft-navtab-migrate-content .updraft_migrate_widget_module_content .updraft_migrate_widget_temporary_clone_stage1 .tfa_fields").hide(),h("#updraft-navtab-migrate-content .updraft_migrate_widget_module_content .updraft_migrate_widget_temporary_clone_stage1 .non_tfa_fields").show(),h("#updraft-navtab-migrate-content .updraft_migrate_widget_module_content .updraftplus_com_login #temporary_clone_options_two_factor_code").val("")):(t.hasOwnProperty("tfa_enabled")&&1==t.tfa_enabled&&(h("#updraft-navtab-migrate-content .updraft_migrate_widget_module_content .updraft_migrate_widget_temporary_clone_stage1 .non_tfa_fields").hide(),h("#updraft-navtab-migrate-content .updraft_migrate_widget_module_content .updraft_migrate_widget_temporary_clone_stage1 .tfa_fields").show(),h("#updraft-navtab-migrate-content .updraft_migrate_widget_module_content .updraft_migrate_widget_temporary_clone_stage1 input#temporary_clone_options_two_factor_code").trigger("focus")),"authenticated"===t.status&&(h("#updraft-navtab-migrate-content .updraft_migrate_widget_module_content .updraft_migrate_widget_temporary_clone_stage1").hide(),h("#updraft-navtab-migrate-content .updraft_migrate_widget_module_content .updraft_migrate_widget_temporary_clone_stage1 .non_tfa_fields").show(),h("#updraft-navtab-migrate-content .updraft_migrate_widget_module_content .updraft_migrate_widget_temporary_clone_stage1 .tfa_fields").hide(),h("#updraft-navtab-migrate-content .updraft_migrate_widget_module_content .updraft_migrate_widget_temporary_clone_stage1 input#temporary_clone_options_two_factor_code").val(""),h("#updraft-navtab-migrate-content .updraft_migrate_widget_module_content .updraft_migrate_widget_temporary_clone_stage2").show(),h("#updraft-navtab-migrate-content .updraft_migrate_widget_module_content .updraft_migrate_widget_temporary_clone_stage2").html(t.html),t.hasOwnProperty("clone_info"))&&t.clone_info.hasOwnProperty("expires_after")&&r(t.clone_info.expires_after))}catch(t){console.log(t)}})}function a(t){h("#updraft-navtab-migrate-content .updraft_migrate_widget_module_content .updraftplus_com_key_status").html("").hide(),h("#updraft-navtab-migrate-content .updraft_migrate_widget_module_content .updraftplus_com_key .updraftplus_spinner.spinner").addClass("visible"),updraft_send_command("process_updraftplus_clone_login",t,function(t){try{h("#updraft-navtab-migrate-content .updraft_migrate_widget_module_content .updraftplus_com_key .updraftplus_spinner.spinner").removeClass("visible"),t.hasOwnProperty("status")&&"error"==t.status?h("#updraft-navtab-migrate-content .updraft_migrate_widget_module_content .updraftplus_com_key_status").html(t.message).show():"authenticated"===t.status&&(h("#updraft-navtab-migrate-content .updraft_migrate_widget_module_content .updraft_migrate_widget_temporary_clone_stage1").hide(),h("#updraft-navtab-migrate-content .updraft_migrate_widget_module_content .updraft_migrate_widget_temporary_clone_stage2").show(),h("#updraft-navtab-migrate-content .updraft_migrate_widget_module_content .updraft_migrate_widget_temporary_clone_stage2").html(t.html),t.hasOwnProperty("clone_info"))&&t.clone_info.hasOwnProperty("expires_after")&&r(t.clone_info.expires_after)}catch(t){console.log(t)}})}function r(t){temporary_clone_timeout=setTimeout(function(){h("#updraft-navtab-migrate-content .updraft_migrate_widget_module_content .updraft_migrate_widget_temporary_clone_stage2").hide(),h("#updraft-navtab-migrate-content .updraft_migrate_widget_module_content .updraft_migrate_widget_temporary_clone_stage2").html(""),h("#updraft-navtab-migrate-content .updraft_migrate_widget_module_content .updraft_migrate_widget_temporary_clone_stage1").show()},1e3*t)}function b(t,e,a,r,n,o,d){t={updraftplus_clone_backup:1,backupnow_nodb:0,backupnow_nofiles:0,backupnow_nocloud:0,backupnow_label:"UpdraftClone",extradata:"",onlythisfileentity:"plugins,themes,uploads,others",clone_id:t,secret_token:e,clone_url:a,key:r,backup_nonce:n,backup_timestamp:o,db_anon_all:d.db_anon_all,db_anon_non_staff:d.db_anon_non_staff,db_anon_wc_orders:d.db_anon_wc_orders,clone_region:d.clone_region};updraft_activejobslist_backupnownonce_only=1,updraft_send_command("backupnow",t,function(t){jQuery("#updraft_clone_progress .updraftplus_spinner.spinner").removeClass("visible"),jQuery("#updraft_backup_started").html(t.m),t.hasOwnProperty("nonce")&&(updraft_backupnow_nonce=t.nonce,updraft_clone_jobs.push(updraft_backupnow_nonce),updraft_inpage_success_callback=function(){jQuery("#updraft_clone_activejobsrow").hide(),updraft_aborted_jobs[updraft_backupnow_nonce]?jQuery("#updraft_clone_progress").html(updraftlion.clone_backup_aborted):jQuery("#updraft_clone_progress").html(updraftlion.clone_backup_complete)},console.log("UpdraftPlus: ID of started job: "+updraft_backupnow_nonce)),updraft_activejobs_update(!0)})}function y(e,a){var t={clone_id:e,secret_token:a};setTimeout(function(){updraft_send_command("process_updraftplus_clone_poll",t,function(t){if(t.hasOwnProperty("status")){if("error"==t.status)return void h("#updraft-navtab-migrate-content .updraft_migrate_widget_module_content .updraftplus_clone_status").html(updraftlion.error+" "+t.message).show();if("success"===t.status&&t.hasOwnProperty("data")&&t.data.hasOwnProperty("wordpress_credentials"))return h("#updraft-navtab-migrate-content .updraft_migrate_widget_module_content .updraftplus_spinner.spinner").removeClass("visible"),void h("#updraft-navtab-migrate-content .updraft_migrate_widget_module_content #updraft_clone_progress").append("
                WordPress "+updraftlion.credentials+":
                "+updraftlion.username+": "+t.data.wordpress_credentials.username+"
                "+updraftlion.password+": "+t.data.wordpress_credentials.password)}else console.log(t);y(e,a)})},6e4)}function d(t){var e=Handlebars.compile(updraftlion.remote_storage_templates[t]),a={},r=(Object.assign(a,updraftlion.remote_storage_options[t].template_properties,updraftlion.remote_storage_options[t].default),updraftlion.remote_storage_methods[t]),r=(a.instance_id="s-"+function(t){for(var e="",a="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",r=0;r li").each(function(){jQuery(this).find("select").each(function(){jQuery(this).prop("disabled",!1)})})):(jQuery(this).parents("tr.updraftplusmethod").find("div.logic ul.rules > li").each(function(){jQuery(this).find("select").each(function(){jQuery(this).prop("disabled",!0)})}),jQuery(this).parents("tr.updraftplusmethod").find("div.logic").hide())}),jQuery("#updraft-navtab-settings-content #remote-storage-holder").on("change","select[class='conditional_logic_operand']",function(){if(updraft_settings_form_changed=!0,jQuery(this).parent().find("select:nth(2)").empty(),"day_of_the_week"===jQuery(this).val())for(var t=0;t').text(updraftlion.conditional_logic.day_of_the_week_options[t].value));else if("day_of_the_month"===jQuery(this).val())for(t=1;t<=31;t++)jQuery(this).parent().find("select:nth(2)").append(jQuery('').text(t))}),jQuery("#updraft-navtab-settings-content #remote-storage-holder").on("click","div.conditional_remote_backup ul.rules li span",function(){updraft_settings_form_changed=!0;var t=jQuery(this).parents("ul.rules");jQuery(this).hasClass("remove-rule")&&jQuery(this).parent().slideUp(function(){jQuery(this).remove(),jQuery(t).find("> li").length<2&&jQuery("li:nth(0) span.remove-rule",t).remove()})}),jQuery("#updraft-navtab-settings-content #remote-storage-holder").on("click","div.conditional_remote_backup input.add-new-rule",function(){var t=jQuery(this).parent().find("ul.rules");jQuery(t).find("> li").length<2&&jQuery(t).find("li:nth(0)").append(''),$cloned_item=jQuery(t).find("> li").last().clone(),jQuery($cloned_item).find("> select").each(function(){jQuery(this).prop("name",jQuery(this).prop("name").replace(/\[instance_conditional_logic\]\[rules\]\[[0-9]+\]/gi,"[instance_conditional_logic][rules]["+jQuery(t).data("rules")+"]"))}),jQuery(t).append($cloned_item),jQuery(t).data("rules",parseInt(jQuery(t).data("rules"))+1),jQuery($cloned_item).find('select[name*="[operand]"]').trigger("change")}),jQuery("#updraft-navtab-settings-content #remote-storage-holder").on("click",".updraftplusmethod button.updraft-test-button",function(){var r=jQuery(this).data("method"),n=jQuery(this).data("instance_id");updraft_remote_storage_test(r,function(t,e,a){return"sftp"==r&&(a.hasOwnProperty("scp")&&a.scp?alert(updraftlion.settings_test_result.replace("%s","SCP")+" "+t.output):alert(updraftlion.settings_test_result.replace("%s","SFTP")+" "+t.output),t.hasOwnProperty("data")&&t.data&&t.data.hasOwnProperty("valid_md5_fingerprint")&&t.data.valid_md5_fingerprint&&h("#updraft_sftp_fingerprint_"+n).val(t.data.valid_md5_fingerprint),!0)},n)}),h("#updraft-navtab-settings-content select.updraft_interval, #updraft-navtab-settings-content select.updraft_interval_database").on("change",function(){updraft_check_same_times()}),h("#backupnow_includefiles_showmoreoptions").on("click",function(t){t.preventDefault(),h("#backupnow_includefiles_moreoptions").toggle()}),h("#backupnow_database_showmoreoptions").on("click",function(t){t.preventDefault(),h("#backupnow_database_moreoptions").toggle()}),h("#updraft-navtab-migrate-content").on("click","#backupnow_database_showmoreoptions",function(t){t.preventDefault(),h("#updraft-navtab-migrate-content #backupnow_database_moreoptions").toggle()}),h("#backupnow_db_anon_all").on("click",function(t){h("#backupnow_db_anon_non_staff").prop("checked")&&h("#backupnow_db_anon_non_staff").prop("checked",!1)}),h("#backupnow_db_anon_non_staff").on("click",function(t){h("#backupnow_db_anon_all").prop("checked")&&h("#backupnow_db_anon_all").prop("checked",!1)}),h("#updraft-navtab-migrate-content").on("click","#updraftplus_migration_backupnow_db_anon_all",function(){h("#updraftplus_migration_backupnow_db_anon_non_staff").prop("checked")&&h("#updraftplus_migration_backupnow_db_anon_non_staff").prop("checked",!1)}),h("#updraft-navtab-migrate-content").on("click","#updraftplus_migration_backupnow_db_anon_non_staff",function(){h("#updraftplus_migration_backupnow_db_anon_all").prop("checked")&&h("#updraftplus_migration_backupnow_db_anon_all").prop("checked",!1)}),h("#updraft-navtab-migrate-content").on("click","#updraftplus_clone_backupnow_db_anon_all",function(){h("#updraftplus_clone_backupnow_db_anon_non_staff").prop("checked")&&h("#updraftplus_clone_backupnow_db_anon_non_staff").prop("checked",!1)}),h("#updraft-navtab-migrate-content").on("click","#updraftplus_clone_backupnow_db_anon_non_staff",function(){h("#updraftplus_clone_backupnow_db_anon_all").prop("checked")&&h("#updraftplus_clone_backupnow_db_anon_all").prop("checked",!1)}),h("#updraft-backupnow-modal").on("click","#backupnow_includecloud_showmoreoptions",function(t){t.preventDefault(),h("#backupnow_includecloud_moreoptions").toggle()}),h("#updraft-navtab-backups-content").on("click","a.updraft_diskspaceused_update",function(t){t.preventDefault(),updraftplus_diskspace()}),h(".advanced_settings_content a.updraft_diskspaceused_update").on("click",function(t){t.preventDefault(),jQuery(".advanced_settings_content .updraft_diskspaceused").html(""+updraftlion.calculating+""),updraft_send_command("get_fragment",{fragment:"disk_usage",data:"updraft"},function(t){jQuery(".advanced_settings_content .updraft_diskspaceused").html(t.output)},{type:"GET"})}),h("#updraft-navtab-backups-content a.updraft_uploader_toggle").on("click",function(t){t.preventDefault(),h("#updraft-plupload-modal").slideToggle()}),h("#updraft-navtab-backups-content a.updraft_rescan_local").on("click",function(t){t.preventDefault(),updraft_updatehistory(1,0)}),h("#updraft-navtab-backups-content a.updraft_rescan_remote").on("click",function(t){t.preventDefault(),confirm(updraftlion.remote_scan_warning)&&updraft_updatehistory(1,1)}),h("#updraftplus-remote-rescan-debug").on("click",function(t){t.preventDefault(),updraft_updatehistory(1,1,1)}),jQuery("#updraft_reset_sid").on("click",function(t){t.preventDefault(),updraft_send_command("reset_site_id",null,function(t){jQuery("#updraft_show_sid").html(t)},{json_parse:!1})}),jQuery("#updraft-navtab-settings-content form input:not('.udignorechange'), #updraft-navtab-settings-content form select").on("change",function(t){updraft_settings_form_changed=!0}),jQuery("#updraft-navtab-settings-content form input[type='submit']").on("click",function(t){updraft_settings_form_changed=!1});var u=180,t=(jQuery(".updraft-bigbutton").each(function(t,e){e=jQuery(e).width();u'+t.count_backups+"");for(a=0;a '+updraftlion.maybe_downloading_entities),updraft_send_command("whichdownloadsneeded",{downloads:s,timestamp:_},function(t){if(h(".updraft-restore--next-step").prop("disabled",!1),t.hasOwnProperty("downloads")&&(console.log("UpdraftPlus: items which still require downloading follow"),l=t.downloads,console.log(l)),0==l.length)updraft_restorer_checkstage2(0);else for(var e=0;e'+r.fatal_error_message+"

                ")):(r="updraft_send_command: error: "+e+" ("+a+")",h("#updraft-restore-modal-stage2a").html('

                '+r+"

                "),console.log(r),console.log(t))}})}catch(t){console.log("UpdraftPlus: error (follows) when looking for items needing downloading"),console.log(t),alert(updraftlion.jsonnotunderstood)}}else if(2==updraft_restore_stage)updraft_restorer_checkstage2(1);else if(3==updraft_restore_stage){var c=1;if(jQuery(".updraft-restore--next-step, .updraft-restore--cancel").prop("disabled",!0),h("#updraft_restoreoptions_ui input.required").each(function(t){var e,a;0!=c&&(""==(e=h(this).val())?(alert(updraftlion.pleasefillinrequired),jQuery(".updraft-restore--next-step, .updraft-restore--cancel").prop("disabled",!1),c=0):""!=h(this).attr("pattern")&&(a=h(this).attr("pattern"),new RegExp(a,"g").test(e)||(alert(h(this).data("invalidpattern")),jQuery(".updraft-restore--next-step, .updraft-restore--cancel").prop("disabled",!1),c=0)))}),1!=o||(r=0,jQuery('input[name="updraft_restore_tables_options[]"').each(function(t,e){jQuery(e).is(":checked")&&!jQuery(e).is(":disabled")&&(r=1)}),0!=r)||skipped_db_scan){if(1==d&&(r=0,jQuery(".updraftplus_restore_plugins_options_container").length||(r=1),jQuery('input[name="updraft_restore_plugins_options[]"').each(function(t,e){jQuery(e).is(":checked")&&!jQuery(e).is(":disabled")&&(r=1)}),0==r))alert(updraftlion.youdidnotselectany),jQuery(".updraft-restore--next-step, .updraft-restore--cancel").prop("disabled",!1);else if(1==u&&(r=0,jQuery(".updraftplus_restore_themes_options_container").length||(r=1),jQuery('input[name="updraft_restore_themes_options[]"').each(function(t,e){jQuery(e).is(":checked")&&!jQuery(e).is(":disabled")&&(r=1)}),0==r))alert(updraftlion.youdidnotselectany),jQuery(".updraft-restore--next-step, .updraft-restore--cancel").prop("disabled",!1);else if(1==n&&(r=0,jQuery('input[name="updraft_include_more_index[]"').each(function(t,e){jQuery(e).is(":checked")&&!jQuery(e).is(":disabled")&&(r=1,""==jQuery("#updraft_include_more_path_restore"+t).val())&&alert(updraftlion.emptyrestorepath)}),0==r))alert(updraftlion.youdidnotselectany),jQuery(".updraft-restore--next-step, .updraft-restore--cancel").prop("disabled",!1);else if(c){var f=h("#updraft_restoreoptions_ui select, #updraft_restoreoptions_ui input").serialize();if(jQuery.each(["table","plugins","themes"],function(t,a){jQuery.each(jQuery('input[name="updraft_restore_'+a+"_options[]").filter(function(t){return!1===jQuery(this).prop("checked")}),function(t,e){f+="&"+jQuery(e).attr("name")+"=udp-skip-"+a+"-"+jQuery(e).val()})}),console.log("Restore options: "+f),void 0!==php_max_input_vars){var t,e=f.split("&").length,m='

                '+updraftlion.warnings+'

                  ';if(!php_max_input_vars&&1e3<=e)console.log("Restore options: "+e+" PHP max input vars not detected; using default: 1000");else if(php_max_input_vars&&php_max_input_vars<=e)return t="
                • "+updraftlion.php_max_input_vars_detected_warning+"
                • ",1!=jQuery("#updraft-restore-modal-stage2a .notice-warning").length?(m=m+t+"
                ",jQuery("#updraft_restoreoptions_ui").prepend(m)):jQuery("#updraft-restore-modal-stage2a #updraft_restore_warnings").append(t),console.log("Restore options: "+e+" PHP max input vars: "+php_max_input_vars),jQuery(".updraft-restore--next-step, .updraft-restore--cancel").prop("disabled",!1),void(php_max_input_vars=void 0)}h("#updraft_restorer_restore_options").val(f),h("#updraft-restore-modal-stage2a").html(updraftlion.restore_proceeding),h("#updraft_restore_form").trigger("submit"),updraft_restore_stage=4}}else alert(updraftlion.youdidnotselectany),jQuery(".updraft-restore--next-step, .updraft-restore--cancel").prop("disabled",!1)}}else alert(updraftlion.youdidnotselectany)}},p=h(".updraft_restore_main--activity").width(),t=(jQuery("#activity-full-log").on("click",function(){var t="1460px"==h(".updraft_restore_main").css("max-width")?"860px":"1460px",e=h(".updraft_restore_main--activity").width()==p?"100%":p+"px",a="600px"==h(".updraft_restore_main--activity").css("min-height")?"0px":"600px",r=h("#activity-full-log").attr("title")==updraftlion.restoreactivitylogscreenexit?updraftlion.restoreactivitylogfullscreen:updraftlion.restoreactivitylogscreenexit;h("#activity-full-log").toggleClass("dashicons-fullscreen-exit-alt"),h("#activity-full-log").attr("title",r),h(".updraft_restore_main--components").toggle("fast"),h(".updraft_restore_main--header").toggle("fast"),h(".updraft_restore_main--activity").animate({minHeight:a,width:e}),h(".updraft_restore_main").animate({maxWidth:t})}),jQuery("#updraft-iframe-modal").dialog({autoOpen:!1,height:500,width:780,modal:!0}),jQuery("#updraft-backupnow-inpage-modal").dialog({autoOpen:!1,modal:!0,resizeOnWindowResize:!0,scrollWithViewport:!0,resizeAccordingToViewport:!0,useContentSize:!1,open:function(t,e){h(this).dialog("option","width",580),h(this).dialog("option","minHeight",261),h(this).dialog("option","height",380)}}),{});t[updraftlion.backupnow]=function(){var t,e,a=jQuery("#backupnow_includedb").is(":checked")?0:1,r=jQuery("#backupnow_includefiles").is(":checked")?0:1,n=jQuery("#backupnow_includecloud").is(":checked")?0:1,o=jQuery("#backupnow_db_anon_all").is(":checked")?1:0,d=jQuery("#backupnow_db_anon_non_staff").is(":checked")?1:0,u=jQuery("#backupnow_db_anon_wc_order_data").is(":checked")?1:0,s=backupnow_whichtables_checked(""),i=jQuery("#always_keep").is(":checked")?1:0,p="incremental"==jQuery("#updraft-backupnow-modal").data("backup-type")?1:0;updraftlion.hosting_restriction.includes("only_one_backup_per_month")&&!p?alert(updraftlion.hosting_restriction_one_backup_permonth):updraftlion.hosting_restriction.includes("only_one_incremental_per_day")&&p?alert(updraftlion.hosting_restriction_one_incremental_perday):""==s&&0==a?(alert(updraftlion.notableschosen),jQuery("#backupnow_database_moreoptions").show()):("boolean"==typeof s&&(s=null),""==(t=backupnow_whichfiles_checked(""))&&0==r?(alert(updraftlion.nofileschosen),jQuery("#backupnow_includefiles_moreoptions").show()):""==(e=jQuery("input[name^='updraft_include_remote_service_']").serializeArray())&&0==n?(alert(updraftlion.nocloudserviceschosen),jQuery("#backupnow_includecloud_moreoptions").show()):("boolean"==typeof e&&(e=null),a&&r?alert(updraftlion.excludedeverything):(jQuery(this).dialog("close"),setTimeout(function(){jQuery("#updraft_lastlogmessagerow").fadeOut("slow",function(){jQuery(this).fadeIn("slow")})},1700),updraft_backupnow_go(a,r,n,t,{always_keep:i,incremental:p,db_anon:{all:o,non_staff:d,wc_orders:u}},jQuery("#backupnow_label").val(),s,e))))},t[updraftlion.cancel]=function(){jQuery(this).dialog("close")},jQuery("#updraft-backupnow-modal").dialog({autoOpen:!1,resizeOnWindowResize:!0,scrollWithViewport:!0,resizeAccordingToViewport:!0,useContentSize:!1,open:function(t,e){h(this).dialog("option","width",610),h(this).dialog("option","minHeight",300),h(this).dialog("option","height",472)},modal:!0,buttons:t,create:function(){h(this).closest(".ui-dialog").find(".ui-dialog-buttonpane .ui-button").first().addClass("js-tour-backup-now-button")}}),jQuery("#updraft-poplog").dialog({autoOpen:!1,modal:!0,resizeOnWindowResize:!0,scrollWithViewport:!0,resizeAccordingToViewport:!0,useContentSize:!1,open:function(t,e){h(this).dialog("option","width",860),h(this).dialog("option","minHeight",260),600'+r.fatal_error_message+"

                "),alert(r.fatal_error_message)):(r="updraft_send_command: error: "+e+" ("+a+")",jQuery("#updraft_zip_files_jstree").html('

                '+r+"

                "),console.log(r),alert(r),console.log(t))}})},error:function(t){alert(t),console.log(t)}},search:{show_only_matches:!0},plugins:["sort"]}):"contain-clause"==t&&jQuery("#updraft_exclude_files_folders_wildcards_jstree").jstree({core:{multiple:!1,data:function(t,e){updraft_send_command("get_jstree_directory_nodes",{entity:"filebrowser",directories_only:1,node:t,path:jQuery("#updraft_exclude_modal_path").val(),findex:0,skip_root_node:0},function(t){t.hasOwnProperty("error")?alert(t.error):e.call(this,t.nodes)},{error_callback:function(t,e,a,r){void 0!==r&&r.hasOwnProperty("fatal_error")?(console.error(r.fatal_error_message),jQuery("#updraft_zip_files_jstree").html('

                '+r.fatal_error_message+"

                "),alert(r.fatal_error_message)):(r="updraft_send_command: error: "+e+" ("+a+")",jQuery("#updraft_zip_files_jstree").html('

                '+r+"

                "),console.log(r),alert(r),console.log(t))}})},error:function(t){alert(t),console.log(t)}},search:{show_only_matches:!0},plugins:["sort"]}),jQuery("#updraft_exclude_modal_main").slideUp(),jQuery(".updraft-exclude-panel").hide(),jQuery(".updraft-exclude-panel[data-panel="+t+"]").slideDown()}),jQuery(".updraft-exclude-modal-reset").on("click",function(t){t.preventDefault(),jQuery("#updraft_exclude_files_folders_jstree").jstree("destroy"),jQuery("#updraft_exclude_files_folders_wildcards_jstree").jstree("destroy"),jQuery("#updraft_exclude_extension_field").val(""),jQuery("#updraft_exclude_prefix_field").val(""),jQuery(".updraft-exclude-panel").slideUp(),jQuery("#updraft_exclude_modal_main").slideDown()}),jQuery(".updraft-exclude-submit").on("click",function(){var t,e="";switch(jQuery(this).data("panel")){case"file-dir":if(0==(t=jQuery("#updraft_exclude_files_folders_jstree").jstree("get_selected")).length)return void alert(updraftlion.exclude_select_file_or_folder_msg);var a=t[0],r=jQuery("#updraft_exclude_modal_path").val(),e=a="/"==(a="/"==(a=a.substr(0,r.length)==r?a.substr(r.length,a.length):a).charAt(0)?a.substr(1):a).charAt(a.length-1)?a.substr(0,a.length-1):a;break;case"extension":var n=jQuery("#updraft_exclude_extension_field").val();if(""==n)return void alert(updraftlion.exclude_type_ext_msg);if(!n.match(/^[0-9a-zA-Z]+$/))return void alert(updraftlion.exclude_ext_error_msg);e="ext:"+n;break;case"begin-with":n=jQuery("#updraft_exclude_prefix_field").val();if(""==n)return void alert(updraftlion.exclude_type_prefix_msg);if(!n.match(/^\s*[a-z-_\d,\s]+\s*$/i))return void alert(updraftlion.exclude_prefix_error_msg);e="prefix:"+n;break;case"contain-clause":if(0==(t=jQuery("#updraft_exclude_files_folders_wildcards_jstree").jstree("get_selected")).length)return void alert(updraftlion.exclude_select_folder_wildcards_msg);var n=jQuery(this).parents("div.updraft-exclude-panel").find("div.clause-input-container input").val(),o=(jQuery(this).parents("div.updraft-exclude-panel").find("div.clause-input-container input").val(""),jQuery(this).parents("div.updraft-exclude-panel").find("div.clause-input-container select").val());if(""==n)return void alert(updraftlion.exclude_contain_error_msg);jQuery(this).parents("div.updraft-exclude-panel").find("div.clause-input-container select option").eq(0).prop("selected",!0);a=t[0],r=jQuery("#updraft_exclude_modal_path").val();""!==(e=a="/"==(a="/"==(a=a.substr(0,r.length)==r?a.substr(r.length,a.length):a).charAt(0)?a.substr(1):a).charAt(a.length-1)?a.substr(0,a.length-1):a)&&(e+="/"),n=n.replace(/\*/g,"\\*"),"beginning"===o?e+=n+"*":"middle"===o?e+="*"+n+"*":"end"===o&&(e+="*"+n);break;default:return}var d,u=jQuery("#updraft_exclude_modal_for").val();updraft_is_unique_exclude_rule(e,u)&&(d='
                ',jQuery('.updraft_exclude_entity_container[data-include-backup-file="'+u+'"]').append(d),updraft_exclude_entity_update(u),jQuery("#updraft_exclude_modal").dialog("close"))}),jQuery("#updraft-navtab-settings-content .updraft-service").on("change",function(){var t=jQuery(this).val();jQuery("#updraft-navtab-settings-content .updraftplusmethod").hide(),jQuery("#updraft-navtab-settings-content ."+t).show()}),jQuery("#updraft-navtab-settings-content a.updraft_show_decryption_widget").on("click",function(t){t.preventDefault(),jQuery("#updraftplus_db_decrypt").val(jQuery("#updraft_encryptionphrase").val()),jQuery("#updraft-manualdecrypt-modal").slideToggle()}),jQuery("#updraftplus-phpinfo").on("click",function(t){t.preventDefault(),updraft_iframe_modal("phpinfo",updraftlion.phpinfo)}),jQuery("#updraftplus-rawbackuphistory").on("click",function(t){t.preventDefault(),updraft_iframe_modal("rawbackuphistory",updraftlion.raw)}),jQuery("#updraft-navtab-status").on("click",function(t){t.preventDefault(),updraft_open_main_tab("status"),updraft_page_is_visible=1,updraft_console_focussed_tab="status",updraft_activejobs_update(!0)}),jQuery("#updraft-navtab-expert").on("click",function(t){t.preventDefault(),updraft_open_main_tab("expert"),updraft_page_is_visible=1}),jQuery("#updraft-navtab-settings, #updraft-navtab-settings2, #updraft_backupnow_gotosettings").on("click",function(t){t.preventDefault(),jQuery(this).parents(".updraftmessage").remove(),jQuery("#updraft-backupnow-modal").dialog("close"),updraft_open_main_tab("settings"),updraft_page_is_visible=1}),jQuery("#updraft-navtab-addons").on("click",function(t){t.preventDefault(),jQuery(this).addClass("b#nav-tab-active"),updraft_open_main_tab("addons"),updraft_page_is_visible=1}),jQuery("#updraft-navtab-backups").on("click",function(t){t.preventDefault(),updraft_console_focussed_tab="backups",updraft_historytimertoggle(1),updraft_open_main_tab("backups")}),jQuery("#updraft-navtab-migrate").on("click",function(t){t.preventDefault(),jQuery("#updraft_migrate_tab_alt").html("").hide(),updraft_open_main_tab("migrate"),updraft_page_is_visible=1,jQuery("#updraft_migrate .updraft_migrate_widget_module_content").is(":visible")||jQuery(".updraft_migrate_intro").show()}),"migrate"==updraftlion.tab&&jQuery("#updraft-navtab-migrate").trigger("click"),updraft_send_command("ping",null,function(t,e){"success"==e&&"pong"!=t&&0<=t.indexOf("pong")&&(jQuery("#updraft-navtab-backups-content .ud-whitespace-warning").show(),console.log("UpdraftPlus: Extra output warning: response (which should be just (string)'pong') follows."),console.log(t))},{json_parse:!1,type:"GET"});try{"undefined"!=typeof updraft_plupload_config&&((s=new plupload.Uploader(updraft_plupload_config)).bind("Init",function(t){var e=jQuery("#plupload-upload-ui");t.features.dragdrop?(e.addClass("drag-drop"),jQuery("#drag-drop-area").on("dragover.wp-uploader",function(){e.addClass("drag-over")}).on("dragleave.wp-uploader, drop.wp-uploader",function(){e.removeClass("drag-over")})):(e.removeClass("drag-drop"),jQuery("#drag-drop-area").off(".wp-uploader"))}),s.init(),s.bind("FilesAdded",function(t,e){h("#updraft-plupload-modal").is(":hidden")&&h("#updraft-plupload-modal").slideToggle(),plupload.each(e,function(t){if(!/^backup_([\-0-9]{15})_.*_([0-9a-f]{12})-[\-a-z]+([0-9]+?)?(\.(zip|gz|gz\.crypt))?$/i.test(t.name)&&!/^log\.([0-9a-f]{12})\.txt$/.test(t.name)){for(var e=!1,a=0;a"+t.name+"

                "+updraftlion.notarchive2),jQuery("#updraft-message-modal").dialog("open")):alert(t.name+": "+updraftlion.notarchive),void s.removeFile(t)}jQuery("#filelist").append('
                '+t.name+" ("+plupload.formatSize(0)+"/"+plupload.formatSize(t.size)+')
                ')}),t.refresh(),t.start()}),s.bind("UploadProgress",function(t,e){jQuery("#"+e.id+" .fileprogress").width(e.percent+"%"),jQuery("#"+e.id+" span").html(plupload.formatSize(parseInt(e.size*e.percent/100))),e.size==e.loaded&&(jQuery("#"+e.id).html('
                '+e.name+" ("+plupload.formatSize(parseInt(e.size*e.percent/100))+"/"+plupload.formatSize(e.size)+") - "+updraftlion.complete+"
                "),jQuery("#"+e.id+" .fileprogress").width(e.percent+"%"))}),s.bind("Error",function(t,e){console.log(e),a="-200"==e.code?"\n"+updraftlion.makesure2:updraftlion.makesure;var a,r=updraftlion.uploaderr+" (code "+e.code+") : "+e.message;e.hasOwnProperty("status")&&e.status&&(r+=" ("+updraftlion.http_code+" "+e.status+")"),e.hasOwnProperty("response")&&(console.log("UpdraftPlus: plupload error: "+e.response),e.response.length<100)&&(r+=" "+updraftlion.error+" "+e.response+"\n"),r+=" "+a,alert(r)}),s.bind("FileUploaded",function(t,e,a){if("200"==a.status)try{(resp=ud_parse_json(a.response)).e?alert(updraftlion.uploaderror+" "+resp.e):resp.dm?(alert(resp.dm),updraft_updatehistory(1,0)):resp.m?updraft_updatehistory(1,0):alert("Unknown server response: "+a.response)}catch(t){console.log(a),alert(updraftlion.jsonnotunderstood)}else alert("Unknown server response status: "+a.code),console.log(a)}))}catch(t){console.log(t)}function l(t){(params={uri:jQuery("#updraftplus_httpget_uri").val()}).curl=t,updraft_send_command("httpget",params,function(t){t.e&&alert(t.e),t.r?jQuery("#updraftplus_httpget_results").html("
                "+t.r+"
                "):console.log(t)},{type:"GET"})}function _(t,e,a){updraft_restore_setoptions(t),jQuery("#updraft_restore_timestamp").val(e),jQuery(".updraft_restore_date").html(a),updraft_restore_stage=1,i.open(),updraft_activejobs_update(!0)}function c(t){t=t.replace(/[\[]/,"\\[").replace(/[\]]/,"\\]");t=new RegExp("[\\?&]"+t+"=([^&#]*)").exec(window.location.href);return null==t?"":decodeURIComponent(t[1].replace(/\+/g," "))}jQuery("#updraftplus_httpget_go").on("click",function(t){t.preventDefault(),l(0)}),jQuery("#updraftplus_httpget_gocurl").on("click",function(t){t.preventDefault(),l(1)}),jQuery("#updraftplus_callwpaction_go").on("click",function(t){t.preventDefault(),updraft_send_command("call_wordpress_action",params={wpaction:jQuery("#updraftplus_callwpaction").val()},function(t){t.e?alert(t.e):t.s||(t.r?jQuery("#updraftplus_callwpaction_results").html(t.r):(console.log(t),alert(updraftlion.jsonnotunderstood)))})}),jQuery("#updraft_activejobs_table, #updraft-navtab-migrate-content").on("click",".updraft_jobinfo_delete",function(t){t.preventDefault();t=jQuery(this).data("jobid");t?(h(this).addClass("disabled"),updraft_activejobs_delete(t)):console.log("UpdraftPlus: A stop job link was clicked, but the Job ID could not be found")}),jQuery("#updraft_activejobs_table, #updraft-navtab-backups-content .updraft_existing_backups, #updraft-backupnow-inpage-modal, #updraft-navtab-migrate-content").on("click",".updraft-log-link",function(t){t.preventDefault();var t=jQuery(this).data("fileid"),e=jQuery(this).data("jobid");t?updraft_popuplog(t):e?updraft_popuplog(e):console.log("UpdraftPlus: A log link was clicked, but the Job ID could not be found")}),jQuery("#updraft-navtab-backups-content .updraft_existing_backups").on("click","button.choose-components-button",function(t){_(jQuery(this).data("entities"),jQuery(this).data("backup_timestamp"),jQuery(this).data("showdata"))}),"initiate_restore"==c("udaction")&&_(c("entities"),c("backup_timestamp"),c("showdata"));t={};function f(){var t=jQuery(".db-search").val().toLowerCase();jQuery(".db-size-content tr").filter(function(){jQuery(this).toggle(-1
                '+updraftlion.loading+"
                ",updraftlion.raw,780,500)}),jQuery("#backupnow_database_moreoptions").on("click","div.backupnow-db-tables > a",function(t){t.preventDefault(),jQuery("> input",jQuery(this).parents("div.backupnow-db-tables")).prop("checked",!1),jQuery(this).hasClass("backupnow-select-all-table")?jQuery("> input",jQuery(this).parents("div.backupnow-db-tables")).prop("checked",!0):jQuery(this).hasClass("backupnow-select-all-this-site")&&jQuery("> input",jQuery(this).parents("div.backupnow-db-tables")).not("[data-non_wp_table]").prop("checked",!0)}),jQuery("#updraft-restore-modal").on("click",".updraft_restore_select_all_themes",function(t){t.preventDefault(),jQuery(".updraft_restore_themes_options").prop("checked",!0)}),jQuery("#updraft-restore-modal").on("click",".updraft_restore_deselect_all_themes",function(t){t.preventDefault(),jQuery(".updraft_restore_themes_options").prop("checked",!1)}),jQuery("#updraft-restore-modal").on("click",".updraft_restore_select_all_plugins",function(t){t.preventDefault(),jQuery(".updraft_restore_plugins_options").prop("checked",!0)}),jQuery("#updraft-restore-modal").on("click",".updraft_restore_deselect_all_plugins",function(t){t.preventDefault(),jQuery(".updraft_restore_plugins_options").prop("checked",!1)}),jQuery(".updraftmessage.admin-warning-litespeed").on("click",".notice-dismiss",function(t){t.preventDefault(),updraft_send_command("dismiss_admin_warning_litespeed",1,function(t){})}),jQuery("#db_size.advanced_tools_button, .db-size-refresh").on("click",function(t){t.preventDefault();var e=jQuery(".advanced_settings_content .advanced_tools.db_size .total-size"),a=jQuery(".advanced_settings_content .advanced_tools.db_size tbody.db-size-content");jQuery(this).hasClass("advanced_tools_button")&&""!=a.html()||(a.html(""),updraft_send_command("db_size",1,function(t){e.html(t.size),a.html(t.html),f()}))}),jQuery(".db-search").on("input",function(){f()}),jQuery(".db-search-clear").on("click",function(t){t.preventDefault(),jQuery(".db-search").val(""),f()})}),jQuery(function(n){var o="#updraft-navtab-settings-content ";n(o+"#remote-storage-holder").on("click",".updraftvault_backtostart",function(t){t.preventDefault(),n(o+"#updraftvault_settings_showoptions").slideUp(),n(o+"#updraftvault_settings_connect").slideUp(),n(o+"#updraftvault_settings_connected").slideUp(),n(o+"#updraftvault_settings_default").slideDown()}),n(o).on("keypress","#updraftvault_settings_connect input",function(t){if(13==t.which)return n(o+"#updraftvault_connect_go").trigger("click"),!1}),n(o+"#remote-storage-holder").on("click","#updraftvault_recountquota",function(t){t.preventDefault(),n(o+"#updraftvault_recountquota").html(updraftlion.counting);try{updraft_send_command("vault_recountquota",{instance_id:n("#updraftvault_settings_connect").data("instance_id")},function(t){n(o+"#updraftvault_recountquota").html(updraftlion.updatequotacount),t.hasOwnProperty("html")&&(n(o+"#updraftvault_settings_connected").html(t.html),t.hasOwnProperty("connected"))&&(t.connected?(n(o+"#updraftvault_settings_default").hide(),n(o+"#updraftvault_settings_connected")):(n(o+"#updraftvault_settings_connected").hide(),n(o+"#updraftvault_settings_default"))).show()},{error_callback:function(t,e,a,r){n(o+"#updraftvault_recountquota").html(updraftlion.updatequotacount),void 0!==r&&r.hasOwnProperty("fatal_error")?(console.error(r.fatal_error_message),alert(r.fatal_error_message)):(r="updraft_send_command: error: "+e+" ("+a+")",console.log(r),alert(r),console.log(t))}})}catch(t){n(o+"#updraftvault_recountquota").html(updraftlion.updatequotacount),console.log(t)}}),n(o+"#remote-storage-holder").on("click","#updraftvault_disconnect",function(t){t.preventDefault(),n(o+"#updraftvault_disconnect").html(updraftlion.disconnecting);try{updraft_send_command("vault_disconnect",{immediate_echo:!0,instance_id:n("#updraftvault_settings_connect").data("instance_id")},function(t){n(o+"#updraftvault_disconnect").html(updraftlion.disconnect),t.hasOwnProperty("html")&&(n(o+"#updraftvault_settings_connected").html(t.html).slideUp(),n(o+"#updraftvault_settings_default").slideDown())},{error_callback:function(t,e,a,r){n(o+"#updraftvault_disconnect").html(updraftlion.disconnect),void 0!==r&&r.hasOwnProperty("fatal_error")?(console.error(r.fatal_error_message),alert(r.fatal_error_message)):(r="updraft_send_command: error: "+e+" ("+a+")",console.log(r),alert(r),console.log(t))}})}catch(t){n(o+"#updraftvault_disconnect").html(updraftlion.disconnect),console.log(t)}}),n(o+"#remote-storage-holder").on("click","#updraftvault_connect",function(t){t.preventDefault(),n(o+"#updraftvault_settings_default").slideUp(),n(o+"#updraftvault_settings_connect").slideDown()}),n(o+"#remote-storage-holder").on("click","#updraftvault_showoptions",function(t){t.preventDefault(),n(o+"#updraftvault_settings_default").slideUp(),n(o+"#updraftvault_settings_showoptions").slideDown()}),n("#remote-storage-holder").on("keyup",".updraftplus_onedrive_folder_input",function(t){var e=n(this).val(),a=n(this).closest("td");0==e.indexOf("https:")||0==e.indexOf("http:")?a.find(".onedrive_folder_error").length||a.append('
                '+updraftlion.onedrive_folder_url_warning+"
                "):a.find(".onedrive_folder_error").slideUp("slow",function(){a.find(".onedrive_folder_error").remove()})}),n(o+"#remote-storage-holder").on("click","#updraftvault_connect_go",function(t){return n(o+"#updraftvault_connect_go").html(updraftlion.connecting),updraft_send_command("vault_connect",{email:n("#updraftvault_email").val(),pass:n("#updraftvault_pass").val(),instance_id:n("#updraftvault_settings_connect").data("instance_id")},function(t,e,a){n(o+"#updraftvault_connect_go").html(updraftlion.connect),t.hasOwnProperty("e")?(updraft_html_modal('

                '+updraftlion.errornocolon+"

                "+t.e+"

                ",updraftlion.disconnect,400,250),t.hasOwnProperty("code")&&"no_quota"==t.code&&(n(o+"#updraftvault_settings_connect").slideUp(),n(o+"#updraftvault_settings_default").slideDown())):t.hasOwnProperty("connected")&&t.connected&&t.hasOwnProperty("html")?(n(o+"#updraftvault_settings_connect").slideUp(),n(o+"#updraftvault_settings_connected").html(t.html).slideDown()):(console.log(t),alert(updraftlion.unexpectedresponse+" "+a))},{error_callback:function(t,e,a,r){n(o+"#updraftvault_connect_go").html(updraftlion.connect),void 0!==r&&r.hasOwnProperty("fatal_error")?(console.error(r.fatal_error_message),alert(r.fatal_error_message)):(r="updraft_send_command: error: "+e+" ("+a+")",console.log(r),alert(r),console.log(t))}}),!1}),n("#updraft-iframe-modal").on("change","#always_keep_this_backup",function(){var e=n(this).data("backup_key");updraft_send_command("always_keep_this_backup",{backup_key:e,always_keep:n(this).is(":checked")?1:0},function(t){t.hasOwnProperty("rawbackup")&&(jQuery("#updraft-iframe-modal").dialog("close"),jQuery(".updraft_existing_backups_row_"+e+" .updraft_existingbackup_date").data("rawbackup",t.rawbackup),updraft_html_modal(jQuery(".updraft_existing_backups_row_"+e+" .updraft_existingbackup_date").data("rawbackup"),updraftlion.raw,780,500))})})}),jQuery(function(t){try{"undefined"!=typeof updraft_plupload_config2&&((a=new plupload.Uploader(updraft_plupload_config2)).bind("Init",function(t){var e=jQuery("#plupload-upload-ui2");t.features.dragdrop?(e.addClass("drag-drop"),jQuery("#drag-drop-area2").on("dragover.wp-uploader",function(){e.addClass("drag-over")}).on("dragleave.wp-uploader, drop.wp-uploader",function(){e.removeClass("drag-over")})):(e.removeClass("drag-drop"),jQuery("#drag-drop-area2").off(".wp-uploader"))}),a.init(),a.bind("FilesAdded",function(t,e){plupload.each(e,function(t){/^backup_([\-0-9]{15})_.*_([0-9a-f]{12})-db([0-9]+)?\.(gz\.crypt)$/i.test(t.name)?jQuery("#filelist2").append('
                '+t.name+" ("+plupload.formatSize(0)+"/"+plupload.formatSize(t.size)+')
                '):(alert(t.name+": "+updraftlion.notdba),a.removeFile(t))}),t.refresh(),t.start()}),a.bind("UploadProgress",function(t,e){jQuery("#"+e.id+" .fileprogress").width(e.percent+"%"),jQuery("#"+e.id+" span").html(plupload.formatSize(parseInt(e.size*e.percent/100)))}),a.bind("Error",function(t,e){err_makesure="-200"==e.code?"\n"+updraftlion.makesure2:updraftlion.makesure,alert(updraftlion.uploaderr+" (code "+e.code+") : "+e.message+" "+err_makesure)}),a.bind("FileUploaded",function(t,e,a){"200"==a.status?"ERROR:"==a.response.substring(0,6)?alert(updraftlion.uploaderror+" "+a.response.substring(6)):"OK:"==a.response.substring(0,3)?(bkey=a.response.substring(3),jQuery("#"+e.id+" .fileprogress").hide(),jQuery("#"+e.id).append(updraftlion.uploaded+' '+updraftlion.followlink+" "+updraftlion.thiskey+" "+jQuery("#updraftplus_db_decrypt").val().replace(/&/g,"&").replace(//g,">"))):alert(updraftlion.unknownresp+" "+a.response):alert(updraftlion.ukrespstatus+" "+a.code)}))}catch(t){console.log(t)}var a;if(jQuery("#updraft-hidethis").remove(),Handlebars.registerHelper("ifeq",function(t,e,a){return(t="string"!=typeof t&&null!=t?t.toString():t)===(e="string"!=typeof e&&null!=e?e.toString():e)?a.fn(this):a.inverse(this)}),Handlebars.registerHelper("maskPassword",function(t){return t.replace(/./gi,"*")}),Handlebars.registerHelper("encodeURIComponent",function(t){return encodeURIComponent(t)}),Handlebars.registerHelper("ifCond",function(t,e,a,r){switch(e){case"==":return t==a?r.fn(this):r.inverse(this);case"===":return t===a?r.fn(this):r.inverse(this);case"!=":return t!=a?r.fn(this):r.inverse(this);case"!==":return t!==a?r.fn(this):r.inverse(this);case"<":return t":return a=":return a<=t?r.fn(this):r.inverse(this);case"&&":return t&&a?r.fn(this):r.inverse(this);case"||":return t||a?r.fn(this):r.inverse(this);case"typeof":return t===typeof a?r.fn(this):r.inverse(this);case"not_typeof":return t!==typeof a?r.fn(this):r.inverse(this);default:return r.inverse(this)}}),Handlebars.registerHelper("for",function(t,e,a,r){for(var n="",o=t;o \t\t\t \t\t\t \t\t\t\t

                \t\t\t\t\t \t\t\t\t

                \t\t\t \t\t"}),t("#remote-storage-holder").length){var e,r="",n=["default","template_properties"];for(e in updraftlion.remote_storage_templates)if(void 0!==updraftlion.remote_storage_options[e]&&n.length'+jQuery(this).html()+"

                "),e=!0}),e&&((t={})[updraftlion.cancel]=function(){jQuery(this).dialog("close")},jQuery("#updraft-authenticate-modal").dialog({autoOpen:!0,modal:!0,resizable:!1,draggable:!1,resizeOnWindowResize:!0,scrollWithViewport:!0,resizeAccordingToViewport:!0,useContentSize:!1,open:function(t,e){o(this).dialog("option","width",860),o(this).dialog("option","height",260)},buttons:t}).dialog("open"))}(new Image).src=updraftlion.ud_url+"/images/notices/updraft_logo.png",o("#updraft-navtab-settings-content input.updraft_include_entity").on("change",function(t){var e=o(this).attr("id"),a=o(this).is(":checked");o("#backupnow_files_"+e).prop("checked",a)}),o("#updraftplus-settings-save").on("click",function(t){t.preventDefault(),o.blockUI({css:{width:"300px",border:"none","border-radius":"10px",left:"calc(50% - 150px)",padding:"20px"},message:'

                '+updraftlion.saving+"
                "}),updraft_send_command("savesettings",{settings:a("string"),updraftplus_version:updraftlion.updraftplus_version},function(t,e,a){r(t,a),o("#updraft-wrap .fade").delay(6e3).fadeOut(2e3),window.updraft_main_tour&&!window.updraft_main_tour.canceled?(window.updraft_main_tour.show("settings_saved"),n()):o("html, body").animate({scrollTop:o("#updraft-wrap").offset().top},1e3,function(){n()}),o.unblockUI()},{action:"updraft_savesettings",error_callback:function(t,e,a,r){o.unblockUI(),void 0!==r&&r.hasOwnProperty("fatal_error")?(console.error(r.fatal_error_message),alert(r.fatal_error_message)):(r="updraft_send_command: error: "+e+" ("+a+")",console.log(r),alert(r),console.log(t))},nonce:updraftplus_settings_nonce})}),o("#updraftplus-settings-export").on("click",function(){var t,e;updraft_settings_form_changed&&alert(updraftlion.unsaved_settings_export),t=a("object"),e=new Date,t=JSON.stringify({version:"1.12.40",epoch_date:e.getTime(),local_date:e.toLocaleString(),network_site_url:updraftlion.network_site_url,data:t}),(e=document.body.appendChild(document.createElement("a"))).setAttribute("download",updraftlion.export_settings_file_name),e.setAttribute("style","display:none;"),e.setAttribute("href","data:text/json;charset=UTF-8,"+encodeURIComponent(t)),e.click()}),o("#updraftplus-settings-import").on("click",function(){o.blockUI({css:{width:"300px",border:"none","border-radius":"10px",left:"calc(50% - 150px)",padding:"20px"},message:'

                '+updraftlion.importing+"
                "});var t,e=document.getElementById("import_settings");0==e.files.length?(alert(updraftlion.import_select_file),o.unblockUI()):(e=e.files[0],(t=new FileReader).onload=function(){var t,e=this.result;try{t=ud_parse_json(e)}catch(t){return void(o.unblockUI(),jQuery("#import_settings").val(""),console.log(e),console.log(t),alert(updraftlion.import_invalid_json_file))}window.confirm(updraftlion.importing_data_from+" "+t.network_site_url+"\n"+updraftlion.exported_on+" "+t.local_date+"\n"+updraftlion.continue_import)?updraft_send_command("importsettings",{settings:JSON.stringify(t.data),updraftplus_version:updraftlion.updraftplus_version},function(t,e,a){t=r(t);!t.hasOwnProperty("saved")||t.saved?(updraft_settings_form_changed=!1,location.replace(updraftlion.updraft_settings_url)):(o.unblockUI(),t.hasOwnProperty("error_message")&&t.error_message&&alert(t.error_message))},{action:"updraft_importsettings",nonce:updraftplus_settings_nonce,error_callback:function(t,e,a,r){o.unblockUI(),void 0!==r&&r.hasOwnProperty("fatal_error")?(console.error(r.fatal_error_message),alert(r.fatal_error_message)):(r="updraft_send_command: error: "+e+" ("+a+")",console.log(r),console.log(t),alert(r))}}):o.unblockUI()},t.readAsText(e))}),o(".udp-replace-with-iframe--js").on("click",function(t){t.preventDefault();t=o(this).prop("href");o('