PKi<\T?IIlanguages/ld_propanel.potnuW+A# Translation of the WordPress plugin LearnDash ProPanel 2.1.2.2 by LearnDash. # Copyright (C) 2018 LearnDash # This file is distributed under the same license as the LearnDash ProPanel package. # FIRST AUTHOR , 2018. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: LearnDash ProPanel 2.1.2.2\n" "Report-Msgid-Bugs-To: http://wordpress.org/tag/learndash-propanel\n" "POT-Creation-Date: 2018-03-21 07:22-0500\n" "PO-Revision-Date: 2018-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" #: includes/class-ld-propanel-activity.php:26 msgid "ProPanel Activity" msgstr "" #: includes/class-ld-propanel-activity.php:218 msgid "course_total_time_on" msgstr "" #: includes/class-ld-propanel-activity.php:226 msgid "course_last_step_id" msgstr "" #: includes/class-ld-propanel-activity.php:234 msgid "course_last_step_type" msgstr "" #: includes/class-ld-propanel-activity.php:242 msgid "course_last_step_title" msgstr "" #: includes/class-ld-propanel-activity.php:250 msgid "last_login_date" msgstr "" #: includes/class-ld-propanel-activity.php:663 msgid "View Quiz Statistics" msgstr "" #: includes/class-ld-propanel-activity.php:663 msgid "Statistics" msgstr "" #: includes/class-ld-propanel-base-widget.php:85 msgid "ProPanel Email: AJAX submission could not complete, please try again." msgstr "" #: includes/class-ld-propanel-filtering.php:31 #: templates/ld-propanel-full-page.php:54 msgid "ProPanel Filtering" msgstr "" #: includes/class-ld-propanel-filtering.php:293 #: includes/class-ld-propanel-reporting.php:284 #, php-format msgid "Email sent to %d destinations" msgstr "" #: includes/class-ld-propanel-filtering.php:304 #: includes/class-ld-propanel-reporting.php:295 #, php-format msgid "" "We could not send the email successfully. Please try again or check with " "your hosting provider.\n" "Error: %s" msgstr "" #: includes/class-ld-propanel-filtering.php:310 #: includes/class-ld-propanel-reporting.php:301 msgid "We do not have any email addresses to send your message to." msgstr "" #: includes/class-ld-propanel-overview.php:27 #: templates/ld-propanel-full-page.php:48 msgid "ProPanel Overview" msgstr "" #: includes/class-ld-propanel-progress-chart.php:27 #: templates/ld-propanel-full-page.php:60 msgid "ProPanel Progress Chart" msgstr "" #: includes/class-ld-propanel-progress-chart.php:36 #: includes/class-ld-tinymce-courseinfo.php:71 #: templates/ld-propanel-activity-rows.php:323 #: templates/reporting-filters/courses/ld-propanel-reporting-filter-course-row.php:41 #: templates/reporting-filters/groups/ld-propanel-reporting-filter-group-row.php:56 #: templates/reporting-filters/status/ld-propanel-reporting-filter-status.php:38 #: templates/reporting-filters/users/ld-propanel-reporting-filter-user-row.php:34 msgid "Not Started" msgstr "" #: includes/class-ld-propanel-progress-chart.php:42 #: includes/class-ld-tinymce-courseinfo.php:72 #: templates/reporting-filters/status/ld-propanel-reporting-filter-status.php:42 msgid "In Progress" msgstr "" #: includes/class-ld-propanel-progress-chart.php:48 #: includes/class-ld-tinymce-courseinfo.php:73 #: templates/reporting-filters/status/ld-propanel-reporting-filter-status.php:46 msgid "Completed" msgstr "" #: includes/class-ld-propanel-progress-chart.php:81 msgid "< 20%" msgstr "" #: includes/class-ld-propanel-progress-chart.php:87 msgid "< 40%" msgstr "" #: includes/class-ld-propanel-progress-chart.php:93 msgid "< 60%" msgstr "" #: includes/class-ld-propanel-progress-chart.php:99 msgid "< 80%" msgstr "" #: includes/class-ld-propanel-progress-chart.php:105 msgid "< 100%" msgstr "" #: includes/class-ld-propanel-reporting.php:40 #: includes/class-ld-propanel.php:67 includes/class-ld-propanel.php:68 #: templates/ld-propanel-full-page.php:35 msgid "ProPanel Reporting" msgstr "" #: includes/class-ld-propanel-shortcodes.php:57 msgid "Show ProPanel Full Page" msgstr "" #: includes/class-ld-propanel.php:156 msgid "" "LearnDash is required to be activated before LearnDash ProPanel can work " "properly." msgstr "" #: includes/class-ld-tinymce-courseinfo.php:9 msgid "ProPanel" msgstr "" #: includes/class-ld-tinymce-courseinfo.php:11 msgid "This shortcode displays widgets from ProPanel." msgstr "" #: includes/class-ld-tinymce-courseinfo.php:22 msgid "Widget" msgstr "" #: includes/class-ld-tinymce-courseinfo.php:23 msgid "Select which ProPanel widget to dislay" msgstr "" #: includes/class-ld-tinymce-courseinfo.php:26 msgid "Link to ProPanel Full Page" msgstr "" #: includes/class-ld-tinymce-courseinfo.php:27 msgid "Overview Widget" msgstr "" #: includes/class-ld-tinymce-courseinfo.php:28 msgid "Filtering Widget" msgstr "" #: includes/class-ld-tinymce-courseinfo.php:29 msgid "Reporting Widget" msgstr "" #: includes/class-ld-tinymce-courseinfo.php:30 msgid "Activity Widget" msgstr "" #: includes/class-ld-tinymce-courseinfo.php:31 msgid "Progress Chart Widget" msgstr "" #: includes/class-ld-tinymce-courseinfo.php:38 msgid "Filter Groups" msgstr "" #: includes/class-ld-tinymce-courseinfo.php:39 msgid "Filter Widget by Group ID" msgstr "" #: includes/class-ld-tinymce-courseinfo.php:47 msgid "Filter Courses" msgstr "" #: includes/class-ld-tinymce-courseinfo.php:48 msgid "Filter Widget by Course ID" msgstr "" #: includes/class-ld-tinymce-courseinfo.php:56 msgid "Filter Users" msgstr "" #: includes/class-ld-tinymce-courseinfo.php:57 msgid "Filter Widget by User ID" msgstr "" #: includes/class-ld-tinymce-courseinfo.php:65 msgid "Filter Course Status" msgstr "" #: includes/class-ld-tinymce-courseinfo.php:66 msgid "Filter Widget by Course Status" msgstr "" #: includes/class-ld-tinymce-courseinfo.php:70 msgid "All Statuses" msgstr "" #: includes/class-ld-tinymce-courseinfo.php:82 msgid "Display Chart" msgstr "" #: includes/class-ld-tinymce-courseinfo.php:83 msgid "Display Chart Orientation" msgstr "" #: includes/class-ld-tinymce-courseinfo.php:86 msgid "Stacked (default)" msgstr "" #: includes/class-ld-tinymce-courseinfo.php:87 msgid "Side by Side" msgstr "" #: includes/class-ld-tinymce-courseinfo.php:95 msgid "Per Page" msgstr "" #: includes/class-ld-tinymce-courseinfo.php:96 msgid "Pagination for Widget output" msgstr "" #: includes/class-ld-tinymce-courseinfo.php:138 msgid "" "When using the \"reporting\" or \"progress_chart\" widget shortcodes. A " "selection from the Group, Course or User filters is required unless also " "using the \"filtering\" widget shortcode on the same page." msgstr "" #. #-#-#-#-# learndash-propanel.pot (LearnDash ProPanel 2.1.2.2) #-#-#-#-# #. Plugin Name of the plugin/theme #: includes/class-ld-translations-propanel.php:17 #: templates/ld-propanel-full-page.php:20 msgid "LearnDash ProPanel" msgstr "" #: learndash-propanel.php:68 #, php-format msgid "LearnDash ProPanel requires the following plugin(s) be active: %s " msgstr "" #: learndash-propanel.php:130 msgid "ProPanel License" msgstr "" #: templates/_ld-propanel-reporting.php:20 #: templates/ld-propanel-filtering.php:20 msgid "Filters" msgstr "" #: templates/_ld-propanel-reporting.php:23 #: templates/ld-propanel-filtering.php:23 msgid "Email" msgstr "" #: templates/_ld-propanel-reporting.php:24 #: templates/ld-propanel-filtering.php:24 msgid "Full Page" msgstr "" #: templates/_ld-propanel-reporting.php:25 #: templates/ld-propanel-filtering.php:25 msgid "Dashboard" msgstr "" #: templates/ld-propanel-activity-pagination-shortcode.php:9 msgctxt "activity widget pagnation previous page link" msgid "« Previous" msgstr "" #: templates/ld-propanel-activity-pagination-shortcode.php:13 msgctxt "activity widget pagnation next page link" msgid "Next »" msgstr "" #: templates/ld-propanel-activity-pagination.php:21 #: templates/ld-propanel-reporting-pager.php:1 msgid "First Page" msgstr "" #: templates/ld-propanel-activity-pagination.php:22 #: templates/ld-propanel-reporting-pager.php:1 msgid "Previous Page" msgstr "" #: templates/ld-propanel-activity-pagination.php:23 #: templates/ld-propanel-reporting-pager.php:1 msgid "page" msgstr "" #: templates/ld-propanel-activity-pagination.php:24 #: templates/ld-propanel-reporting-pager.php:1 msgid "Next Page" msgstr "" #: templates/ld-propanel-activity-pagination.php:25 #: templates/ld-propanel-reporting-pager.php:1 msgid "Last Page" msgstr "" #: templates/ld-propanel-activity-report-header.php:6 #: templates/ld-propanel-reporting-download-button.php:1 #, php-format msgctxt "Export Course Data" msgid "Export %s Data" msgstr "" #: templates/ld-propanel-activity-report-header.php:6 #: templates/reporting-filters/users/ld-propanel-reporting-filter-user.php:354 #: templates/reporting-filters/users/ld-propanel-reporting-filter-user.php:361 #: templates/reporting-filters/users/ld-propanel-reporting-filter-user.php:367 #, php-format msgctxt "Course" msgid "%s" msgstr "" #: templates/ld-propanel-activity-report-header.php:7 #, php-format msgctxt "Export Quiz Data" msgid "Export %s Data" msgstr "" #: templates/ld-propanel-activity-report-header.php:7 #, php-format msgctxt "Quiz" msgid "%s" msgstr "" #: templates/ld-propanel-activity-rows.php:23 msgid "Completed Date (Duration)" msgstr "" #: templates/ld-propanel-activity-rows.php:25 msgid "Completed Date" msgstr "" #: templates/ld-propanel-activity-rows.php:35 msgid "Started Date (Duration)" msgstr "" #: templates/ld-propanel-activity-rows.php:37 msgid "Started Date" msgstr "" #: templates/ld-propanel-activity-rows.php:44 #: templates/ld-propanel-activity-rows.php:111 #: templates/ld-propanel-activity-rows.php:150 #: templates/ld-propanel-activity-rows.php:182 #: templates/ld-propanel-activity-rows.php:243 #: templates/ld-propanel-activity-rows.php:304 msgid "See User Progress" msgstr "" #: templates/ld-propanel-activity-rows.php:56 #, php-format msgctxt "Quiz Completed:" msgid "%s Completed:" msgstr "" #. translators: %s: Name of current post #: templates/ld-propanel-activity-rows.php:61 #: templates/ld-propanel-activity-rows.php:75 #: templates/ld-propanel-activity-rows.php:129 #: templates/ld-propanel-activity-rows.php:206 #: templates/ld-propanel-activity-rows.php:220 #: templates/ld-propanel-activity-rows.php:267 #: templates/ld-propanel-activity-rows.php:281 #: templates/ld-propanel-activity-rows.php:313 #, php-format msgid " (edit \"%s\")" msgstr "" #: templates/ld-propanel-activity-rows.php:71 #: templates/ld-propanel-activity-rows.php:124 #: templates/ld-propanel-activity-rows.php:216 #: templates/ld-propanel-activity-rows.php:277 #: templates/ld-propanel-activity-rows.php:309 #, php-format msgctxt "Course:" msgid "%s:" msgstr "" #: templates/ld-propanel-activity-rows.php:86 #: templates/ld-propanel-activity-rows.php:88 #: templates/ld-propanel-activity-rows.php:139 #: templates/ld-propanel-activity-rows.php:231 #: templates/ld-propanel-activity-rows.php:292 #: templates/ld-propanel-activity-rows.php:323 msgid "Result:" msgstr "" #: templates/ld-propanel-activity-rows.php:86 msgid "Pending" msgstr "" #: templates/ld-propanel-activity-rows.php:88 msgid "Passed" msgstr "" #: templates/ld-propanel-activity-rows.php:88 msgid "Failed" msgstr "" #: templates/ld-propanel-activity-rows.php:99 msgid "Points:" msgstr "" #: templates/ld-propanel-activity-rows.php:139 #: templates/ld-propanel-activity-rows.php:292 #, php-format msgid "Completed %d out of %d" msgstr "" #: templates/ld-propanel-activity-rows.php:170 #, php-format msgctxt "Gained Course Access:" msgid "Gained %s Access:" msgstr "" #: templates/ld-propanel-activity-rows.php:202 #, php-format msgctxt "Lesson:" msgid "%s:" msgstr "" #: templates/ld-propanel-activity-rows.php:231 #, php-format msgid "Completed %d out of %d steps" msgstr "" #: templates/ld-propanel-activity-rows.php:263 #, php-format msgctxt "Topic:" msgid "%s:" msgstr "" #: templates/ld-propanel-filtering-emails.php:8 msgid "Please select user(s) to send an email to." msgstr "" #: templates/ld-propanel-filtering-emails.php:12 msgid "Your Message" msgstr "" #: templates/ld-propanel-filtering-emails.php:13 msgid "Send" msgstr "" #: templates/ld-propanel-filtering-emails.php:13 #: templates/ld-propanel-filtering-filters.php:26 msgid "Reset" msgstr "" #: templates/ld-propanel-filtering-emails.php:15 msgid "Sending..." msgstr "" #: templates/ld-propanel-filtering-filters.php:8 msgid "Filter By:" msgstr "" #: templates/ld-propanel-filtering-filters.php:11 msgid "Per Page:" msgstr "" #: templates/ld-propanel-filtering-filters.php:26 msgid "Filter" msgstr "" #: templates/ld-propanel-full-admin.php:7 msgid "LearnDash ProPanel Reporting" msgstr "" #: templates/ld-propanel-full-page.php:41 msgid "ProPanel Progress Activity" msgstr "" #: templates/ld-propanel-no-results.php:8 #: templates/ld-propanel-reporting-no-results.php:7 msgid "No Results Found." msgstr "" #: templates/ld-propanel-overview.php:20 msgid "Total Students" msgstr "" #: templates/ld-propanel-overview.php:56 #, php-format msgctxt "Courses" msgid "%s" msgstr "" #: templates/ld-propanel-overview.php:85 msgid "Assignments Pending" msgstr "" #: templates/ld-propanel-overview.php:96 msgid "Essays Pending" msgstr "" #: templates/ld-propanel-progress-chart.php:10 msgid "Progress Distribution" msgstr "" #: templates/ld-propanel-progress-chart.php:12 msgid "No All-Progress items found" msgstr "" #: templates/ld-propanel-progress-chart.php:18 msgid "In Progress Breakdown" msgstr "" #: templates/ld-propanel-progress-chart.php:20 msgid "No In-Progress items found" msgstr "" #: templates/ld-propanel-reporting-choose-filter.php:8 msgid "Please choose a filter in ProPanel Reporting." msgstr "" #: templates/ld-propanel-reporting-download-button.php:1 msgid "Download" msgstr "" #: templates/reporting-filters/courses/ld-propanel-reporting-filter-course-row.php:27 #: templates/reporting-filters/groups/ld-propanel-reporting-filter-group-row.php:35 #: templates/reporting-filters/groups/ld-propanel-reporting-filter-group-row.php:46 #, php-format msgid "Compose a new mail to %s" msgstr "" #: templates/reporting-filters/courses/ld-propanel-reporting-filter-course-row.php:36 #: templates/reporting-filters/groups/ld-propanel-reporting-filter-group-row.php:52 #: templates/reporting-filters/users/ld-propanel-reporting-filter-user-row.php:30 #, php-format msgid "%d of %d steps completed" msgstr "" #: templates/reporting-filters/courses/ld-propanel-reporting-filter-course.php:7 msgid "Search Users" msgstr "" #: templates/reporting-filters/courses/ld-propanel-reporting-filter-course.php:89 #, php-format msgctxt "All Courses" msgid "All %s" msgstr "" #: templates/reporting-filters/courses/ld-propanel-reporting-filter-course.php:237 #: templates/reporting-filters/courses/ld-propanel-reporting-filter-course.php:244 #: templates/reporting-filters/groups/ld-propanel-reporting-filter-group.php:273 #: templates/reporting-filters/groups/ld-propanel-reporting-filter-group.php:280 msgid "Checkbox" msgstr "" #: templates/reporting-filters/courses/ld-propanel-reporting-filter-course.php:238 #: templates/reporting-filters/courses/ld-propanel-reporting-filter-course.php:246 #: templates/reporting-filters/courses/ld-propanel-reporting-filter-course.php:253 #: templates/reporting-filters/groups/ld-propanel-reporting-filter-group.php:284 msgid "User" msgstr "" #: templates/reporting-filters/courses/ld-propanel-reporting-filter-course.php:239 #: templates/reporting-filters/courses/ld-propanel-reporting-filter-course.php:247 #: templates/reporting-filters/courses/ld-propanel-reporting-filter-course.php:254 #: templates/reporting-filters/groups/ld-propanel-reporting-filter-group.php:275 #: templates/reporting-filters/groups/ld-propanel-reporting-filter-group.php:285 #: templates/reporting-filters/groups/ld-propanel-reporting-filter-group.php:291 #: templates/reporting-filters/users/ld-propanel-reporting-filter-user.php:355 #: templates/reporting-filters/users/ld-propanel-reporting-filter-user.php:362 #: templates/reporting-filters/users/ld-propanel-reporting-filter-user.php:368 msgid "Progress" msgstr "" #: templates/reporting-filters/courses/ld-propanel-reporting-filter-course.php:245 msgid "User ID" msgstr "" #: templates/reporting-filters/courses/ld-propanel-reporting-filter-course.php:248 #: templates/reporting-filters/groups/ld-propanel-reporting-filter-group.php:286 #: templates/reporting-filters/users/ld-propanel-reporting-filter-user.php:363 msgid "Completed On" msgstr "" #: templates/reporting-filters/groups/ld-propanel-reporting-filter-group-row.php:33 #: templates/reporting-filters/users/ld-propanel-reporting-filter-user-row.php:25 #, php-format msgctxt "Course ID:" msgid "%s ID:" msgstr "" #: templates/reporting-filters/groups/ld-propanel-reporting-filter-group.php:7 msgid "Search Groups" msgstr "" #: templates/reporting-filters/groups/ld-propanel-reporting-filter-group.php:111 msgid "All Groups" msgstr "" #: templates/reporting-filters/groups/ld-propanel-reporting-filter-group.php:274 #: templates/reporting-filters/groups/ld-propanel-reporting-filter-group.php:282 #: templates/reporting-filters/groups/ld-propanel-reporting-filter-group.php:290 msgid "Course" msgstr "" #: templates/reporting-filters/groups/ld-propanel-reporting-filter-group.php:281 msgid "C-ID" msgstr "" #: templates/reporting-filters/groups/ld-propanel-reporting-filter-group.php:283 msgid "U-ID" msgstr "" #: templates/reporting-filters/users/ld-propanel-reporting-filter-user.php:7 #, php-format msgctxt "Search Courses" msgid "Search %s" msgstr "" #: templates/reporting-filters/users/ld-propanel-reporting-filter-user.php:162 msgid "All Users" msgstr "" #: templates/reporting-filters/users/ld-propanel-reporting-filter-user.php:162 msgid "Select User" msgstr "" #: templates/reporting-filters/users/ld-propanel-reporting-filter-user.php:360 #, php-format msgctxt "Course ID" msgid "%s ID" msgstr "" #: wp_autoupdate_propanel.php:267 msgid "You do not have sufficient permissions to access this page." msgstr "" #: wp_autoupdate_propanel.php:290 msgid "settings saved." msgstr "" #: wp_autoupdate_propanel.php:305 msgid "License Settings" msgstr "" #: wp_autoupdate_propanel.php:307 msgid "Email:" msgstr "" #: wp_autoupdate_propanel.php:309 msgid "License Key:" msgstr "" #: wp_autoupdate_propanel.php:313 msgid "Update License" msgstr "" #. #-#-#-#-# learndash-propanel.pot (LearnDash ProPanel 2.1.2.2) #-#-#-#-# #. Plugin URI of the plugin/theme #. #-#-#-#-# learndash-propanel.pot (LearnDash ProPanel 2.1.2.2) #-#-#-#-# #. Author URI of the plugin/theme msgid "http://www.learndash.com" msgstr "" #. Description of the plugin/theme msgid "Easily manage and view your LearnDash LMS activity." msgstr "" #. Author of the plugin/theme msgid "LearnDash" msgstr "" PKi<\;GCClearndash_propanel.phpnuW+Aset_dependencies( array( 'sfwd-lms/sfwd_lms.php' => array( 'label' => 'LearnDash LMS', 'class' => 'SFWD_LMS', ) ) ); LearnDash_Dependency_Check_ProPanel::get_instance()->set_message( __( 'LearnDash ProPanel requires the following plugin(s) be active: %s ', 'ld_propanel' ) ); /** * Activation */ function activate_learndash_propanel() { $roles = get_editable_roles(); if ( !empty( $roles ) ) { if ( !defined( 'LEARNDASH_ADMIN_CAPABILITY_CHECK' ) ) { define( 'LEARNDASH_ADMIN_CAPABILITY_CHECK', 'manage_options' ); } if ( !defined( 'LEARNDASH_GROUP_LEADER_CAPABILITY_CHECK' ) ) { define( 'LEARNDASH_GROUP_LEADER_CAPABILITY_CHECK', 'group_leader' ); } foreach ( $roles as $role_name => $role_info ) { $role = get_role( $role_name ); if ( ( $role ) && ( $role instanceof WP_Role ) ) { if ( ! $role->has_cap( 'propanel_widgets' ) ) { $cap_enabled = false; if ( ( defined( 'LEARNDASH_ADMIN_CAPABILITY_CHECK' ) ) && ( $role->has_cap( LEARNDASH_ADMIN_CAPABILITY_CHECK ) ) ) { $cap_enabled = true; } else if ( ( defined( 'LEARNDASH_GROUP_LEADER_CAPABILITY_CHECK' ) ) && ( ( $role_name == LEARNDASH_GROUP_LEADER_CAPABILITY_CHECK ) || $role->has_cap( LEARNDASH_GROUP_LEADER_CAPABILITY_CHECK ) ) ) { $cap_enabled = true; } $role->add_cap( 'propanel_widgets', $cap_enabled ); } } } } } /** * Deactivation */ function deactivate_learndash_propanel() { } register_activation_hook( __FILE__, 'activate_learndash_propanel' ); register_deactivation_hook( __FILE__, 'deactivate_learndash_propanel' ); // Load the auto-update class add_action('init', 'nss_plugin_updater_activate_learndash_propanel'); function nss_plugin_updater_activate_learndash_propanel() { //if(!class_exists('nss_plugin_updater')) require_once (dirname(__FILE__).'/wp_autoupdate_propanel.php'); $nss_plugin_updater_plugin_remote_path = 'http://support.learndash.com/'; $nss_plugin_updater_plugin_slug = plugin_basename(__FILE__); new nss_plugin_updater_learndash_propanel ($nss_plugin_updater_plugin_remote_path, $nss_plugin_updater_plugin_slug); } function learndash_propanel_admin_tabs($admin_tabs) { $admin_tabs["propanel"] = array( "link" => 'admin.php?page=nss_plugin_license-learndash_propanel-settings', "name" => __("ProPanel License","learndash_propanel"), "id" => "admin_page_nss_plugin_license-learndash_propanel-settings", "menu_link" => "edit.php?post_type=sfwd-courses&page=sfwd-lms_sfwd_lms.php_post_type_sfwd-courses", ); return $admin_tabs; } add_filter("learndash_admin_tabs", "learndash_propanel_admin_tabs", 1, 1); function learndash_propanel_learndash_admin_tabs_on_page($admin_tabs_on_page, $admin_tabs, $current_page_id) { if(empty($admin_tabs_on_page["admin_page_nss_plugin_license-learndash_propanel-settings"]) || !count($admin_tabs_on_page["admin_page_nss_plugin_license-learndash_propanel-settings"])) $admin_tabs_on_page["admin_page_nss_plugin_license-learndash_propanel-settings"] = array(); $admin_tabs_on_page["admin_page_nss_plugin_license-learndash_propanel-settings"] = array_merge($admin_tabs_on_page["sfwd-courses_page_sfwd-lms_sfwd_lms_post_type_sfwd-courses"], (array) $admin_tabs_on_page["admin_page_nss_plugin_license-learndash_propanel-settings"]); foreach ($admin_tabs as $key => $value) { if($value["id"] == $current_page_id && $value["menu_link"] == "edit.php?post_type=sfwd-courses&page=sfwd-lms_sfwd_lms.php_post_type_sfwd-courses") { $admin_tabs_on_page[$current_page_id][] = "propanel"; return $admin_tabs_on_page; } } return $admin_tabs_on_page; } add_filter("learndash_admin_tabs_on_page", "learndash_propanel_learndash_admin_tabs_on_page", 3, 3); PKi<\ changelog.txtnuW+APKi<\\v[)[)wp_autoupdate_propanel.phpnuW+Aupdate_path = $update_path; $this->plugin_slug = $plugin_slug; $this->current_version = $this->get_plugin_data()->Version; list ($t1, $t2) = explode('/', $plugin_slug); $this->slug = str_replace('.php', '', $t2); $code = $this->code = $this->slug; $license = get_option('nss_plugin_license_'.$code); $licenseemail = get_option('nss_plugin_license_email_'.$code); $this->update_path = $update_path.'?pluginupdate='.$code.'&licensekey='.urlencode($license).'&licenseemail='.urlencode($licenseemail).'&nsspu_wpurl='.urlencode(get_bloginfo('wpurl')).'&nsspu_admin='.urlencode(get_bloginfo('admin_email')).'¤t_version='.$this->current_version; //Add Menu add_action('admin_menu', array(&$this, 'nss_plugin_license_menu'), 1); // define the alternative API for updating checking add_filter('pre_set_site_transient_update_plugins', array(&$this, 'check_update')); // Define the alternative response for information checking add_filter('plugins_api', array(&$this, 'check_info'), 10, 3); } function admin_notice() { echo ""; $licensepage = get_admin_url(null,'admin.php?page=nss_plugin_license-'.$this->code.'-settings'); echo "

License of your plugin ".$this->get_plugin_data()->Name." is invalid or incomplete. Please click here and update your license.

"; } function invalid_current_license() { add_action( 'admin_notices', array(&$this, 'admin_notice')); deactivate_plugins( $this->plugin_slug ); } function get_plugin_data() { if(!function_exists('get_plugin_data')) include_once( ABSPATH.'wp-admin'.DIRECTORY_SEPARATOR.'includes'.DIRECTORY_SEPARATOR.'plugin.php'); return (object) get_plugin_data(dirname(dirname(__FILE__)).DIRECTORY_SEPARATOR.$this->plugin_slug); } /** * Add our self-hosted autoupdate plugin to the filter transient * * @param $transient * @return object $ transient */ public function check_update($transient) { if (empty($transient->checked)) { // return $transient; } //print_r($transient); // Get the remote version $remote_version = $this->getRemote_version(); $license = $this->getRemote_license(); if ( empty( $license ) ) $this->getRemote_current_license(); // If a newer version is available, add the update if ( version_compare( $this->current_version, $remote_version, '<' ) ) { $obj = new stdClass(); $obj->slug = $this->slug; $obj->new_version = $remote_version; $obj->url = $this->update_path; $obj->package = $this->update_path; if ( is_null( $this->ld_updater ) ) { $this->ld_updater = new LearnDash_Addon_Updater(); } $plugin_readme = $this->ld_updater->update_plugin_readme( 'learndash-propanel-readme' ); if ( !empty( $plugin_readme ) ) { // First we remove the properties we DON'T want from the support site foreach( array( 'sections', 'requires', 'tested', 'last_updated' ) as $property_key ) { if ( property_exists ( $obj, $property_key ) ) { unset( $obj->$property_key ); } } foreach( $plugin_readme as $key => $val ) { if ( !property_exists ( $obj, $key ) ) { $obj->$key = $val; } } } if ( !property_exists ( $obj, 'icons' ) ) { // Add an image for the WP 4.9.x plugins update screen. $obj->icons = array( 'default' => LD_PP_PLUGIN_URL .'/assets/images/learndash-propanel.jpg' ); } $transient->response[$this->plugin_slug] = $obj; } ///var_dump($transient); return $transient; } /** * Add our self-hosted description to the filter * * @param boolean $false * @param array $action * @param object $arg * @return bool|object */ public function check_info($false, $action, $arg) { if ( empty( $arg ) || empty( $arg->slug ) || empty( $this->slug ) ) return $false; if ($arg->slug === $this->slug) { $information = $this->getRemote_information(); return $information; } return $false; } /** * Return the remote version * @return string $remote_version */ public function getRemote_version() { $request = wp_remote_post($this->update_path, array('body' => array('action' => 'version'))); if (!is_wp_error($request) || wp_remote_retrieve_response_code($request) === 200) { return $request['body']; } return false; } /** * Get information about the remote version * @return bool|object */ public function getRemote_information() { $request = wp_remote_post($this->update_path, array('body' => array('action' => 'info'))); if (!is_wp_error($request) || wp_remote_retrieve_response_code($request) === 200) { //return unserialize($request['body']); $information = @unserialize( $request['body'] ); if ( empty( $information ) ) { $information = new stdClass(); } if ( is_null( $this->ld_updater ) ) { $this->ld_updater = new LearnDash_Addon_Updater(); } $plugin_readme = $this->ld_updater->update_plugin_readme( 'learndash-propanel-readme' ); if ( !empty( $plugin_readme ) ) { // First we remove the properties we DON'T want from the support site foreach( array( 'sections', 'requires', 'tested', 'last_updated' ) as $property_key ) { if ( property_exists ( $information, $property_key ) ) { unset( $information->$property_key ); } } foreach( $plugin_readme as $key => $val ) { if ( !property_exists ( $information, $key ) ) { $information->$key = $val; } } //$information_array = $this->ld_updater->convert_readme( (array)$information ); //$information = (object)$information_array; } return $information; } return false; } /** * Return the status of the plugin licensing * @return boolean $remote_license */ public function getRemote_license() { $request = wp_remote_post($this->update_path, array('body' => array('action' => 'license'))); if (!is_wp_error($request) || wp_remote_retrieve_response_code($request) === 200) { if($request['body'] == "false" || $request['body'] == "not_found" || empty($request['body'])) add_action( 'admin_notices', array(&$this, 'admin_notice')); return $request['body']; } //add_action( 'admin_notices', array(&$this, 'admin_notice')); return true; } public function getRemote_current_license() { $request = wp_remote_post($this->update_path, array('body' => array('action' => 'current_license'))); if (!is_wp_error($request) || wp_remote_retrieve_response_code($request) === 200) { if($request['body'] == "not_found") $this->invalid_current_license(); return $request['body']; } //$this->invalid_current_license(); return true; } function nss_plugin_license_menu() { add_submenu_page("learndash-lms-non-existant", $this->get_plugin_data()->Name." License", $this->get_plugin_data()->Name." License",'manage_options','nss_plugin_license-'.$this->code.'-settings', array(&$this, 'nss_plugin_license_menupage')); } function nss_plugin_license_menupage() { $code = $this->code; //must check that the user has the required capability if (!current_user_can('manage_options')) { wp_die( __('You do not have sufficient permissions to access this page.') ); } // Read in existing option value from database $license = get_option('nss_plugin_license_'.$code); $email = get_option('nss_plugin_license_email_'.$code); // See if the user has posted us some information // If they did, this hidden field will be set to 'Y' if( isset($_POST[ "update_nss_plugin_license_".$code ]) ) { // Read their posted value $license = $_POST['nss_plugin_license_'.$code]; $email = $_POST['nss_plugin_license_email_'.$code]; // Save the posted value in the database update_option( 'nss_plugin_license_'.$code, $license); update_option( 'nss_plugin_license_email_'.$code, $email); // Put an settings updated message on the screen ?>

">






wp_create_nonce( 'ld-propanel-widget-'. $atts['widget'] .'-'. time() ), 'html_class' => '', 'label' => __( 'Show ProPanel Full Page', 'ld_propanel' ) ); $atts = shortcode_atts( $default_atts, $atts ); $content .= ''; break; case 'overview': case 'filtering': $default_atts = array( 'widget' => '', 'html_id' => wp_create_nonce( 'ld-propanel-widget-'. $atts['widget'] .'-'. time() ), 'html_class' => '', ); $atts = shortcode_atts( $default_atts, $atts ); $widget_key = str_replace('_', '-', $atts['widget'] ); // force this these settings $atts['template'] = $atts['widget']; // At this point we are a go to display something. so we load of the needed JS/CSS $ld_propanel = LearnDash_ProPanel::get_instance(); $ld_propanel->scripts( true ); $content .= '
'', 'html_id' => wp_create_nonce( 'ld-propanel-widget-'. $atts['widget'] .'-'. time() ), 'html_class' => '', 'per_page' => get_option( 'posts_per_page' ), 'filter_type' => '', // (optional) Should be single 'user', 'course' or 'group' 'filter_id' => '', // (optional) The ID of the type to filter on. Will be a course ID or User ID. // The value 'CURRENT_ID' can be used for current User or current Course (if on a course post) 'filter_groups' => '', 'filter_courses' => '', 'filter_users' => '', 'filter_status' => '', 'activity_types' => '', 'orderby_order' => 'ld_user_activity.activity_updated DESC', 'export_buttons' => 1, 'nav_top' => 1, 'display_chart' => '' ); $atts = shortcode_atts( $default_atts, $atts ); $widget_key = str_replace('_', '-', $atts['widget'] ); // force this these settings $atts['template'] = $atts['widget']; if ( !empty( $atts['filter_groups'] ) ) { $atts['filter_groups'] = explode(',', $atts['filter_groups'] ); $atts['filter_groups'] = array_map( 'trim', $atts['filter_groups'] ); $atts['groups'] = $atts['filter_groups']; unset( $atts['filter_groups'] ); } else { $atts['groups'] = array(); } if ( !empty( $atts['filter_courses'] ) ) { $atts['filter_courses'] = explode(',', $atts['filter_courses'] ); $atts['filter_courses'] = array_map( 'trim', $atts['filter_courses'] ); $atts['courses'] = $atts['filter_courses']; unset( $atts['filter_courses'] ); } else { $atts['courses'] = array(); } if ( !empty( $atts['filter_users'] ) ) { $atts['filter_users'] = explode(',', $atts['filter_users'] ); $atts['filter_users'] = array_map( 'trim', $atts['filter_users'] ); $atts['users'] = $atts['filter_users']; unset( $atts['filter_users'] ); } else { $atts['users'] = array(); } if ( ( !empty( $atts['filter_type'] ) ) && ( !empty( $atts['filter_id'] ) ) ) { switch( $atts['filter_type'] ) { case 'user': $atts['users'][] = $atts['filter_id']; break; case 'course': $atts['courses'][] = $atts['filter_id']; break; case 'group': $atts['groups'][] = $atts['filter_id']; break; default: break; } } else { if ( !empty( $atts['groups'] ) ) { $atts['filter_type'] = 'group'; $atts['filter_id'] = $atts['groups'][0]; // For now we only send a single vlaue for filtering $atts['groups'] = $atts['groups'][0]; } else { unset( $atts['groups'] ); } if ( !empty( $atts['courses'] ) ) { $atts['filter_type'] = 'course'; $atts['filter_id'] = $atts['courses'][0]; // For now we only send a single vlaue for filtering $atts['courses'] = $atts['courses'][0]; } else { unset( $atts['courses'] ); } if ( !empty( $atts['users'] ) ) { $atts['filter_type'] = 'user'; $atts['filter_id'] = $atts['users'][0]; // For now we only send a single vlaue for filtering $atts['users'] = $atts['users'][0]; } else { unset( $atts['users'] ); } } if ( !empty( $atts['filter_status'] ) ) { $atts['filter_status'] = explode(',', $atts['filter_status'] ); $atts['filter_status'] = array_map( 'trim', $atts['filter_status'] ); $atts['courseStatus'] = $atts['filter_status']; unset( $atts['filter_status'] ); } else { $atts['courseStatus'] = array(); } if ( !empty( $atts['activity_types'] ) ) { $atts['activity_types'] = explode(',', $atts['activity_types'] ); $atts['activity_types'] = array_map( 'trim', $atts['activity_types'] ); } if ( !empty( $atts['per_page'] ) ) { $atts['reporting_pager'] = array( 'current_page' => 1, 'per_page' => intval( $atts['per_page'] ) ); unset( $atts['per_page'] ); } foreach( $atts as $key => $val ) { if ( empty( $val ) ) unset( $atts['key'] ); } // At this point we are a go to display something. so we load of the needed JS/CSS $ld_propanel = LearnDash_ProPanel::get_instance(); $ld_propanel->scripts( true ); $widget_classes_str = ''; $widget_classes = array( 'ld-propanel-widget', 'ld-propanel-widget-'. $widget_key, ld_propanel_get_widget_screen_type_class( $widget_key ) ); if ( !empty( $atts['html_class'] ) ) { $widget_classes[] = $atts['html_class']; } if ( $atts['widget'] == 'progress_chart' ) { if ( ( isset( $atts['display_chart'] ) ) && ( !empty( $atts['display_chart'] ) ) ) { $widget_classes[] = $atts['display_chart']; } } $widget_classes = apply_filters('ld_propanel_widget_classes_array', $widget_classes ); if ( ( !empty( $widget_classes ) ) && ( is_array( $widget_classes ) ) ) { foreach( $widget_classes as $widget_class ) { $widget_class = esc_html( $widget_class ); if ( !empty( $widget_class ) ) { if ( !empty( $widget_classes_str ) ) $widget_classes_str .= ' '; $widget_classes_str .= esc_html( $widget_class ); } } } $content .= '
true, 'fields' => 'ID' ); $user_query_args = apply_filters( 'ld_propanel_overview_students_count_args', $user_query_args ); if ( !empty( $user_query_args ) ) { $user_query = new WP_User_Query( $user_query_args ); if ( $user_query instanceof WP_User_Query ) { $all_user_ids = $user_query->get_results(); } } } else { // Else if there are no open courses we the query users with 'learndash_group_users_%' OR 'course_%_access_from' meta_keys global $wpdb; //$users_courses_sql = "SELECT DISTINCT um.user_id FROM ". $wpdb->usermeta ." um WHERE um.meta_key IN ( SELECT CONCAT('course_', p.ID, '_access_from') FROM ". $wpdb->posts ." p WHERE p.post_type='sfwd-courses' AND p.post_status='publish' )"; $users_courses_sql = "SELECT DISTINCT users.ID FROM {$wpdb->users} as users LEFT JOIN {$wpdb->usermeta} as um1 ON ( users.ID = um1.user_id ) LEFT JOIN {$wpdb->usermeta} as um2 ON ( users.ID = um2.user_id ) WHERE 1=1 AND ( um1.meta_key = '{$wpdb->prefix}capabilities' AND ( um2.meta_key IN ( SELECT DISTINCT CONCAT('course_', p.ID, '_access_from') FROM {$wpdb->prefix}posts p WHERE p.post_type='sfwd-courses' AND p.post_status='publish' UNION ALL SELECT DISTINCT CONCAT('course_completed_', p.ID, '') FROM {$wpdb->prefix}posts p WHERE p.post_type='sfwd-courses' AND p.post_status='publish' UNION ALL SELECT DISTINCT CONCAT('learndash_course_expired_', p.ID, '') FROM {$wpdb->prefix}posts p WHERE p.post_type='sfwd-courses' AND p.post_status='publish' ) ) )"; $users_courses_results = $wpdb->get_col( $users_courses_sql ); //$users_groups_sql = "SELECT DISTINCT um.user_id FROM ". $wpdb->usermeta ." um WHERE um.meta_key IN ( SELECT CONCAT('learndash_group_users_', p.ID, '') FROM ". $wpdb->posts ." p WHERE p.post_type='groups' AND p.post_status='publish' )"; $users_groups_sql = "SELECT DISTINCT users.ID FROM {$wpdb->users} users LEFT JOIN {$wpdb->usermeta} as um1 ON ( users.ID = um1.user_id ) LEFT JOIN {$wpdb->usermeta} as um2 ON ( users.ID = um2.user_id ) WHERE 1=1 AND ( um1.meta_key = '{$wpdb->prefix}capabilities' AND ( um2.meta_key IN ( SELECT CONCAT('learndash_group_users_', p.ID, '') FROM {$wpdb->prefix}posts p WHERE p.post_type='groups' AND p.post_status='publish' ) ) )"; $users_groups_results = $wpdb->get_col( $users_groups_sql ); $all_user_ids = array_merge( $users_courses_results, $users_groups_results ); } if ( ( $exclude_admin_users !== true ) && ( $auto_enroll_admin_users === true ) && ( !empty( $admin_user_ids ) ) ) { $all_user_ids = array_merge( $all_user_ids, $admin_user_ids ); } else if ( ( $exclude_admin_users === true ) && ( !empty( $admin_user_ids ) ) ) { $all_user_ids = array_diff( $all_user_ids, $admin_user_ids ); } if ( ( !empty( $all_user_ids ) ) && ( is_array( $all_user_ids ) ) ) { $all_user_ids = array_map( 'intval', $all_user_ids ); $all_user_ids = array_unique( $all_user_ids ); $return_total_users = count( $all_user_ids ); } } return $return_total_users; } function ld_propanel_exclude_admin_users() { $reports_exclude_admin_users = false; if ( version_compare( LEARNDASH_VERSION, '2.4.0') >= 0 ) { $reports_exclude_admin_users = LearnDash_Settings_Section::get_section_setting('LearnDash_Settings_Section_General_Admin_User', 'reports_include_admin_users' ); if ( $reports_exclude_admin_users == 'yes' ) $reports_exclude_admin_users = false; else $reports_exclude_admin_users = true; } return apply_filters( 'ld_propanel_exclude_admin_users', $reports_exclude_admin_users ); } function ld_propanel_auto_enroll_admin_users() { $auto_enroll_admin_users = false; if ( version_compare( LEARNDASH_VERSION, '2.4.0') >= 0 ) { $auto_enroll_admin_users = LearnDash_Settings_Section::get_section_setting('LearnDash_Settings_Section_General_Admin_User', 'courses_autoenroll_admin_users' ); if ( $auto_enroll_admin_users == 'yes' ) $auto_enroll_admin_users = true; else $auto_enroll_admin_users = false; } return apply_filters( 'ld_propanel_auto_enroll_admin_users', $auto_enroll_admin_users ); } function ld_propanel_get_admin_user_ids( $return_count = false ) { $admin_user_query_args = array( 'fields' => 'ID', 'role' => 'administrator' ); if ( $return_count === true ) { $admin_user_query_args['count_total'] = true; } $admin_user_query = new WP_User_Query( $admin_user_query_args ); if ( $return_count === true ) { return $admin_user_query->get_total(); } else { $admin_user_ids = $admin_user_query->get_results(); if ( !empty( $admin_user_ids ) ) { $admin_user_ids = array_map( 'intval', $admin_user_ids ); } return $admin_user_ids; } } function ld_propanel_adjust_admin_users( $activity_query_args = array() ) { if ( !empty( $activity_query_args ) ) { $exclude_admin_users = ld_propanel_exclude_admin_users(); if ( ( isset( $activity_query_args['user_ids'] ) ) && ( !empty( $activity_query_args['user_ids'] ) ) ) { if ( !isset( $activity_query_args['user_ids_action'] ) ) { $activity_query_args['user_ids_action'] = 'IN'; } if ( $exclude_admin_users ) { $admin_user_query_args = array( 'fields' => 'ID', 'role' => 'administrator' ); $admin_user_query = new WP_User_Query( $admin_user_query_args ); $admin_user_ids = $admin_user_query->get_results(); if ( !empty( $admin_user_ids ) ) { if ( $activity_query_args['user_ids_action'] == 'IN' ) $activity_query_args['user_ids'] = array_diff( $activity_query_args['user_ids'], $admin_user_ids ); else $activity_query_args['user_ids'] = array_merge( $activity_query_args['user_ids'], $admin_user_ids ); } } } else { if ( $exclude_admin_users ) { $admin_user_query_args = array( 'fields' => 'ID', 'role' => 'administrator' ); $admin_user_query = new WP_User_Query( $admin_user_query_args ); $admin_user_ids = $admin_user_query->get_results(); if ( !empty( $admin_user_ids ) ) { $activity_query_args['user_ids_action'] = 'NOT IN'; $activity_query_args['user_ids'] = $admin_user_ids; } } } } return $activity_query_args; } function ld_propanel_convert_fewer_users( $activity_query_args = array() ) { if ( ( !is_multisite() ) && ( !empty( $activity_query_args ) ) ) { if ( !isset( $activity_query_args['user_ids_action'] ) ) $activity_query_args['user_ids_action'] = 'IN'; if ( $activity_query_args['user_ids_action'] !== 'NOT IN' ) { //$total_users = ld_propanel_get_users_count(); //if ( count( $activity_query_args['user_ids'] ) > ( $total_users / 2 ) ) { $result = count_users(); if ( !isset( $activity_query_args['user_ids'] ) ) $activity_query_args['user_ids'] = array(); if ( count( $activity_query_args['user_ids'] ) > ( $result['total_users'] / 2 ) ) { $user_query_args = array( 'fields' => 'ID', 'exclude' => $activity_query_args['user_ids'] ); $user_query = new WP_User_Query( $user_query_args ); if ( $user_query instanceof WP_User_Query ) { $exclude_user_ids = $user_query->get_results(); if ( !empty( $exclude_user_ids ) ) { $activity_query_args['user_ids'] = $exclude_user_ids; $activity_query_args['user_ids_action'] = 'NOT IN'; } } } } } return $activity_query_args; } function ld_propanel_load_post_data( $post_data = array(), $_get = array() ) { if ( empty( $_get ) ) $_get = $_GET; $per_page_array = ld_propanel_get_pager_values(); if ( empty( $per_page_array ) ) { $per_page_array = array(5); } if ( ( isset( $_get['container_type'] ) ) && ( !empty( $_get['container_type'] ) ) ) $post_data['container_type'] = esc_attr( $_get['container_type'] ); else $post_data['container_type'] = ''; if ( ( isset( $_get['template'] ) ) && ( !empty( $_get['template'] ) ) ) $post_data['template'] = esc_attr( $_get['template'] ); else $post_data['template'] = ''; $post_data['filters'] = array( 'id' => 0, 'type' => '', 'courseStatus' => array(), 'search' => '', 'reporting_pager' => array( 'current_page' => 1, 'per_page' => $per_page_array[0] ) ); if ( isset( $_get['filters'] ) ) { if ( ( isset( $_get['filters']['id'] ) ) && ( !empty( $_get['filters']['id'] ) ) ) $post_data['filters']['id'] = intval( $_get['filters']['id'] ); if ( ( isset( $_get['filters']['type'] ) ) && ( !empty( $_get['filters']['type'] ) ) ) $post_data['filters']['type'] = esc_attr( $_get['filters']['type'] ); if ( ( isset( $_get['filters']['search'] ) ) && ( !empty( $_get['filters']['search'] ) ) ) $post_data['filters']['search'] = esc_attr( $_get['filters']['search'] ); if ( ( isset( $_get['filters']['courseStatus'] ) ) && ( !empty( $_get['filters']['courseStatus'] ) ) ) { $post_data['filters']['courseStatus'] = array(); $courseStatus = $_get['filters']['courseStatus']; if ( is_string( $courseStatus ) ) $courseStatus = array( $courseStatus ); if ( in_array( 'not-started', $courseStatus ) !== false) { $post_data['filters']['courseStatus'][] = 'NOT_STARTED'; } if ( in_array( 'in-progress', $courseStatus ) !== false) { $post_data['filters']['courseStatus'][] = 'IN_PROGRESS'; } if ( in_array( 'completed', $courseStatus ) !== false) { $post_data['filters']['courseStatus'][] = 'COMPLETED'; } } if ( ( isset( $_get['filters']['users'] ) ) && ( !empty( $_get['filters']['users'] ) ) ) $post_data['filters']['users'] = intval( $_get['filters']['users'] ); if ( ( isset( $_get['filters']['courses'] ) ) && ( !empty( $_get['filters']['courses'] ) ) ) $post_data['filters']['courses'] = intval( $_get['filters']['courses'] ); if ( ( isset( $_get['filters']['groups'] ) ) && ( !empty( $_get['filters']['groups'] ) ) ) $post_data['filters']['groups'] = intval( $_get['filters']['groups'] ); if ( ( isset( $_get['filters']['reporting_pager'] ) ) && ( !empty( $_get['filters']['reporting_pager'] ) ) ) { if ( ( isset( $_get['filters']['reporting_pager']['current_page'] ) ) && ( !empty( $_get['filters']['reporting_pager']['current_page'] ) ) ) $post_data['filters']['reporting_pager']['current_page'] = intval( $_get['filters']['reporting_pager']['current_page'] ); if ( ( isset( $_get['filters']['reporting_pager']['per_page'] ) ) && ( !empty( $_get['filters']['reporting_pager']['per_page'] ) ) ) $post_data['filters']['reporting_pager']['per_page'] = intval( $_get['filters']['reporting_pager']['per_page'] ); } } $post_data = apply_filters( 'ld_propanel_reporting_post_args', $post_data, $_get ); return $post_data; } function ld_propanel_load_activity_query_args( $activity_query_args = array(), $post_data = array() ) { $activity_query_args['per_page'] = $post_data['filters']['reporting_pager']['per_page']; $activity_query_args['paged'] = $post_data['filters']['reporting_pager']['current_page']; if ( !isset( $activity_query_args['activity_status'] ) ) $activity_query_args['activity_status'] = array(); if ( !empty( $post_data['filters']['courseStatus'] ) ) { $activity_query_args['activity_status'] = $post_data['filters']['courseStatus']; // if ( in_array( 'not-started', $post_data['filters']['courseStatus'] ) !== false) { // $activity_query_args['activity_status'][] = 'NOT_STARTED'; // } // // if ( in_array( 'in-progress', $post_data['filters']['courseStatus'] ) !== false) { // $activity_query_args['activity_status'][] = 'IN_PROGRESS'; // } // // if ( in_array( 'completed', $post_data['filters']['courseStatus'] ) !== false) { // $activity_query_args['activity_status'][] = 'COMPLETED'; // } } if ( empty( $activity_query_args['activity_status'] ) ) $activity_query_args['activity_status'] = array( 'NOT_STARTED', 'IN_PROGRESS', 'COMPLETED' ); if ( !empty( $post_data['filters']['search'] ) ) $activity_query_args['s'] = sprintf( '%%%s%%', esc_html( $post_data['filters']['search'] ) ); else $activity_query_args['s'] = ''; $activity_query_args = apply_filters( 'ld_propanel_reporting_activity_args', $activity_query_args, $post_data ); return $activity_query_args; } function ld_propanel_get_course_post_items( $course_id = 0, $post_types = array( 'sfwd-courses', 'sfwd-quiz', 'sfwd-lessons', 'sfwd-topic' ) ) { if ( !empty( $course_id ) ) { $query_course_args = array( 'post_type' => $post_types, 'post_status' => 'publish', 'posts_per_page' => -1, 'fields' => 'ids', 'meta_query' => array( 'relation' => 'OR', array( 'key' => 'course_id', 'value' => $course_id, 'compare' => '=', ) ) ); if ( version_compare( LEARNDASH_VERSION, '2.4.9.9') >= 0 ) { $query_course_args['meta_query'][] = array( 'key' => 'ld_course_' . $course_id, 'value' => $course_id, 'compare' => '=', ); } //error_log('query_course_args
'. print_r($query_course_args, true) .'
'); $query_course = new WP_Query( $query_course_args ); if ( ! empty( $query_course->posts ) ) { //error_log('course_id['. $course_id .'] count['. count( $query_course->posts ).']
'. print_r($query_course, true) .'
'); return $query_course->posts; } } } // General utility function to count various post types function ld_propanel_count_post_type( $post_type = '' ) { if ( !empty( $post_type ) ) { $query_args = array( 'post_type' => $post_type, 'post_status' => 'publish', ); return learndash_get_courses_count( $query_args ); } } function ld_propanel_get_assignments_pending_count( $query_args = array(), $return_field = 'found_posts' ) { $return = 0; $default_args = array( 'post_type' => 'sfwd-assignment', 'post_status' => 'publish', 'fields' => 'ids', 'meta_query' => array( array( 'key' => 'approval_status', 'compare' => 'NOT EXISTS', ), ), ); // added logic for non-admin user like group leaders who will only see a sub-set of assignments $user_id = get_current_user_id(); if ( learndash_is_admin_user() ) { if ( ld_propanel_exclude_admin_users( $user_id ) ) { $admin_user_ids = ld_propanel_get_admin_user_ids(); if ( !empty( $admin_user_ids ) ) { $default_args['author__not_in'] = $admin_user_ids; } } } else if ( learndash_is_group_leader_user( $user_id ) ) { $group_ids = learndash_get_administrators_group_ids( $user_id ); $user_ids = array(); $course_ids = array(); if ( ! empty( $group_ids ) && is_array( $group_ids ) ) { foreach( $group_ids as $group_id ) { $group_users = learndash_get_groups_user_ids( $group_id ); if ( ! empty( $group_users ) && is_array( $group_users ) ) { foreach( $group_users as $group_user_id ) { $user_ids[ $group_user_id ] = $group_user_id; } } $group_course_ids = learndash_group_enrolled_courses( $group_id ); if ( ( !empty( $group_course_ids ) ) && (is_array( $group_course_ids ) ) ) { $course_ids = array_merge( $course_ids, $group_course_ids ); } } } else { return $return; } if ( ! empty( $course_ids ) && count( $course_ids ) ) { $default_args['meta_query'][] = array( 'key' => 'course_id', 'value' => $course_ids, 'compare' => 'IN', ); } else { return $return; } if ( ! empty( $user_ids ) && count( $user_ids ) ) { if ( ld_propanel_exclude_admin_users() ) { $admin_user_ids = ld_propanel_get_admin_user_ids(); if ( !empty( $admin_user_ids ) ) { //$user_ids = array_intersect( $user_ids, $admin_user_ids ); $user_ids = array_diff( $user_ids, $admin_user_ids ); } } $default_args['author__in'] = $user_ids; } else { return $return; } } $query_args = wp_parse_args( $query_args, $default_args ); $query_args = apply_filters( 'learndash_get_assignments_pending_count_query_args', $query_args ); if ( $return_field == 'found_posts' ) { $query_args['posts_per_page'] = 1; $query_args['paged'] = 1; } if ( ( is_array( $query_args ) ) && ( !empty( $query_args ) ) ) { $query = new WP_Query( $query_args ); if ( ( !empty( $return_field ) ) && ( property_exists( $query, $return_field ) ) ) { $return = $query->$return_field; } else { $return = $query; } } return $return; } /** * Get count of pending Essays posts ( sfwd-essays ) * * @param array $essays_query_args override query arguments * @param string $return_field specific field from WP_Query to return. Default is 'found_posts' * @return mixed $assignments_return if $return_field is empty then return is WP_Query instance. Otherwise specific field from WP_Query returned * * @since 2.3 */ function ld_propanel_get_essays_pending_count( $query_args = array(), $return_field = 'found_posts' ) { $return = 0; $default_args = array( 'post_type' => 'sfwd-essays', 'post_status' => 'not_graded', 'fields' => 'ids', ); // added logic for non-admin user like group leaders who will only see a sub-set of assignments $user_id = get_current_user_id(); if ( learndash_is_admin_user( $user_id ) ) { if ( ld_propanel_exclude_admin_users() ) { $admin_user_ids = ld_propanel_get_admin_user_ids(); if ( !empty( $admin_user_ids ) ) { $default_args['author__not_in'] = $admin_user_ids; } } } else if ( learndash_is_group_leader_user( $user_id ) ) { $group_ids = learndash_get_administrators_group_ids( $user_id ); $user_ids = array(); $course_ids = array(); if ( ! empty( $group_ids ) && is_array( $group_ids ) ) { foreach( $group_ids as $group_id ) { $group_users = learndash_get_groups_user_ids( $group_id ); if ( ! empty( $group_users ) && is_array( $group_users ) ) { foreach( $group_users as $group_user_id ) { $user_ids[ $group_user_id ] = $group_user_id; } } $group_course_ids = learndash_group_enrolled_courses( $group_id ); if ( ( !empty( $group_course_ids ) ) && (is_array( $group_course_ids ) ) ) { $course_ids = array_merge( $course_ids, $group_course_ids ); } } } else { return $return; } if ( ! empty( $course_ids ) && count( $course_ids ) ) { $default_args['meta_query'][] = array( 'key' => 'course_id', 'value' => $course_ids, 'compare' => 'IN', ); } else { return $return; } if ( ! empty( $user_ids ) && count( $user_ids ) ) { if ( ld_propanel_exclude_admin_users() ) { $admin_user_ids = ld_propanel_get_admin_user_ids(); if ( !empty( $admin_user_ids ) ) { //$user_ids = array_intersect( $user_ids, $admin_user_ids ); $user_ids = array_diff( $user_ids, $admin_user_ids ); } } $default_args['author__in'] = $user_ids; } else { return $return; } } $query_args = wp_parse_args( $query_args, $default_args ); $query_args = apply_filters( 'learndash_get_essays_pending_count_query_args', $query_args ); if ( $return_field == 'found_posts' ) { $query_args['posts_per_page'] = 1; $query_args['paged'] = 1; } if ( ( is_array( $query_args ) ) && ( !empty( $query_args ) ) ) { $query = new WP_Query( $query_args ); if ( ( !empty( $return_field ) ) && ( property_exists( $query, $return_field ) ) ) { $return = $query->$return_field; } else { $return = $query; } } return $return; } function ld_propanel_get_widget_screen_type_class( $widget_id = '', $screen_class_prefix = 'ld-propanel-screen-' ) { if ( !empty( $widget_id ) ) { $screen_type = ''; if ( is_admin() ) { $screen = get_current_screen(); if ( in_array( $screen->id, array( 'dashboard', 'dashboard_page_propanel-reporting' ) ) ) { $screen_type = 'dashboard'; } } else { global $learndash_shortcode_used; if ( $learndash_shortcode_used === true ) { $screen_type = 'shortcode'; } } $screen_type = apply_filters('ld_propanel_screen_type', $screen_type, $widget_id, $screen_class_prefix ); if ( !empty( $screen_type ) ) { return $screen_class_prefix .= $screen_type; } } }PKi<\)  &includes/class-ld-dependency-check.phpnuW+A label paird. The label can be anything to display */ private $plugins_to_check = array(); /** * Array to hold the inactive plugins. This is populated during the * admin_init action via the function call to check_inactive_plugin_dependency() */ private $plugins_inactive = array(); /** * LearnDash_ProPanel constructor. */ public function __construct() { add_action( 'plugins_loaded', array( $this, 'plugins_loaded' ), 1 ); } public static function get_instance() { if ( null === static::$instance ) { static::$instance = new static(); } return static::$instance; } /** * LearnDash_ProPanel constructor. */ public function check_dependency_results() { if ( empty( $this->plugins_inactive ) ) { return true; } return false; } /** * callback function for the admin_init action */ function plugins_loaded() { $this->check_inactive_plugin_dependency(); } /** * Function called during the admin_init process to check if required plugins * are present and active. Handles regular and Multisite checks. */ function check_inactive_plugin_dependency( $set_admin_notice = true ) { if ( ! function_exists( 'get_plugins' ) ) { require_once ABSPATH . 'wp-admin/includes/plugin.php'; } //$all_plugins = get_plugins(); //error_log('all_plugins
'. print_r($all_plugins, true) .'
'); //$current_plugins = get_site_transient( 'update_plugins' ); //error_log('current_plugins
'. print_r($current_plugins, true) .'
'); if ( !empty( $this->plugins_to_check ) ) { if ( !function_exists('is_plugin_active' ) ) { include_once( ABSPATH . 'wp-admin/includes/plugin.php' ); } foreach( $this->plugins_to_check as $plugin_key => $plugin_data ) { if ( !is_plugin_active( $plugin_key ) ) { if ( is_multisite() ) { if ( !is_plugin_active_for_network( $plugin_key ) ) { $this->plugins_inactive[$plugin_key] = $plugin_data; } } else { $this->plugins_inactive[$plugin_key] = $plugin_data; } } else { if ( ( isset( $plugin_data['class'] ) ) && ( !empty( $plugin_data['class'] ) ) && ( !class_exists( $plugin_data['class'] ) ) ) { $this->plugins_inactive[$plugin_key] = $plugin_data; } } } if ( ( !empty( $this->plugins_inactive ) ) && ( $set_admin_notice ) ) { add_action( 'admin_notices', array( $this, 'notify_user_learndash_required' ) ); } } return $this->plugins_inactive; } /** * Function to set custom admin motice message */ public function set_message( $message = '' ) { if ( !empty( $message ) ) { $this->admin_notice_message = $message; } } public function set_dependencies( $plugins = array() ) { if ( is_array( $plugins ) ) $this->plugins_to_check = $plugins; } /** * Notify user that LearnDash is required. */ public function notify_user_learndash_required() { if ( ( !empty( $this->admin_notice_message ) ) && ( !empty( $this->plugins_inactive ) ) ) { $admin_notice_message = sprintf( $this->admin_notice_message, implode(', ', wp_list_pluck($this->plugins_inactive, 'label' ) ) ); if ( !empty( $admin_notice_message ) ) { ?>

fields_args = $fields_args; $this->shortcodes_section_key = 'ld_propanel'; $this->shortcodes_section_title = __( 'ProPanel', 'ld_propanel' ); $this->shortcodes_section_type = 1; $this->shortcodes_section_description = __( 'This shortcode displays widgets from ProPanel.', 'ld_propanel' ); parent::__construct(); } function init_shortcodes_section_fields() { $this->shortcodes_option_fields = array( 'widget' => array( 'id' => $this->shortcodes_section_key . '_widget', 'name' => 'widget', 'type' => 'select', 'label' => __( 'Widget', 'ld_propanel' ), 'help_text' => __( 'Select which ProPanel widget to dislay', 'ld_propanel' ), 'value' => '', 'options' => array( 'link' => __('Link to ProPanel Full Page', 'ld_propanel' ), 'overview' => __('Overview Widget', 'ld_propanel' ), 'filtering' => __('Filtering Widget', 'ld_propanel' ), 'reporting' => __('Reporting Widget', 'ld_propanel' ), 'activity' => __('Activity Widget', 'ld_propanel' ), 'progress_chart' => __('Progress Chart Widget', 'ld_propanel' ), ) ), 'filter_groups' => array( 'id' => $this->shortcodes_section_key . '_filter_groups', 'name' => 'filter_groups', 'type' => 'number', 'label' => __( 'Filter Groups', 'learndash'), 'help_text' => __( 'Filter Widget by Group ID', 'ld_propanel' ), 'value' => '', ), 'filter_courses' => array( 'id' => $this->shortcodes_section_key . '_filter_courses', 'name' => 'filter_courses', 'type' => 'number', 'label' => __( 'Filter Courses', 'learndash'), 'help_text' => __( 'Filter Widget by Course ID', 'ld_propanel' ), 'value' => '', ), 'filter_users' => array( 'id' => $this->shortcodes_section_key . '_filter_users', 'name' => 'filter_users', 'type' => 'number', 'label' => __( 'Filter Users', 'learndash'), 'help_text' => __( 'Filter Widget by User ID', 'ld_propanel' ), 'value' => '', ), 'filter_status' => array( 'id' => $this->shortcodes_section_key . '_filter_status', 'name' => 'filter_status', 'type' => 'select', 'label' => __( 'Filter Course Status', 'learndash'), 'help_text' => __( 'Filter Widget by Course Status', 'ld_propanel' ), 'value' => '', //'attrs' => array( 'multiple' => 'multiple' ), 'options' => array( '' => __('All Statuses', 'ld_propanel' ), 'not-started' => __('Not Started', 'ld_propanel' ), 'in-progress' => __('In Progress', 'ld_propanel' ), 'completed' => __('Completed', 'ld_propanel' ) ) ), 'display_chart' => array( 'id' => $this->shortcodes_section_key . '_display_chart', 'name' => 'display_chart', 'type' => 'select', 'label' => __( 'Display Chart', 'learndash'), 'help_text' => __( 'Display Chart Orientation', 'ld_propanel' ), 'value' => '', 'options' => array( '' => __('Stacked (default)', 'ld_propanel' ), 'side-by-side' => __('Side by Side', 'ld_propanel' ), ) ), 'per_page' => array( 'id' => $this->shortcodes_section_key . '_per_page', 'name' => 'per_page', 'type' => 'number', 'label' => __( 'Per Page', 'learndash'), 'help_text' => __( 'Pagination for Widget output', 'ld_propanel' ), 'value' => '', ), ); $this->shortcodes_option_fields = apply_filters( 'learndash_settings_fields', $this->shortcodes_option_fields, $this->shortcodes_section_key ); parent::init_shortcodes_section_fields(); } function show_shortcodes_section_footer_extra() { ?> name = 'progress-chart'; $this->label = esc_html__( 'ProPanel Progress Chart', 'ld_propanel' ); parent::__construct(); add_filter( 'learndash_propanel_template_ajax', array( $this, 'progress_chart_template' ), 10, 2 ); add_action( 'wp_ajax_learndash_propanel_get_progress_charts_data', array( $this, 'get_progress_course_data_for_chart' ), 10, 2 ); $this->chart_info['all_progress'] = array(); $this->chart_info['all_progress']['query'] = array( 'not_started' => array( 'label' => __( 'Not Started', 'ld_propanel' ), 'backgroundColor' => "#2D97C5", 'hoverBackgroundColor' => "#2D97C5", 'data' => 0 ), 'in_progress' => array( 'label' => __( 'In Progress', 'ld_propanel' ), 'backgroundColor' => "#5BAED2", 'hoverBackgroundColor' => "#5BAED2", 'data' => 0 ), 'completed' => array( 'label' => __( 'Completed', 'ld_propanel' ), 'backgroundColor' => "#8AC5DF", 'hoverBackgroundColor' => "#8AC5DF", 'data' => 0 ) ); $this->chart_info['all_progress']['options'] = array( 'tooltips' => array( 'backgroundColor' => "#3B3E44", 'titleMarginBottom' => 15, 'titleFontSize' => 18, 'cornerRadius' => 4, 'bodyFontSize' => 14, 'xPadding' => 10, 'yPadding' => 15, 'bodySpacing' => 10, 'fontFamily' => "'Open Sans',sans-serif" ), 'legend' => array( 'display' => true, 'labels' => array( 'boxWidth' => 14, 'fontFamily' => "'Open Sans',sans-serif" ) ) ); $this->chart_info['all_percentages'] = array(); $this->chart_info['all_percentages']['query'] = array( '20' => array( 'label' => __( '< 20%', 'ld_propanel' ), 'backgroundColor' => "#2D97C5", 'hoverBackgroundColor' => "#2D97C5", 'data' => 0 ), '40' => array( 'label' => __( '< 40%', 'ld_propanel' ), 'backgroundColor' => "#5BAED2", 'hoverBackgroundColor' => "#5BAED2", 'data' => 0 ), '60' => array( 'label' => __( '< 60%', 'ld_propanel' ), 'backgroundColor' => "#8AC5DF", 'hoverBackgroundColor' => "#8AC5DF", 'data' => 0 ), '80' => array( 'label' => __( '< 80%', 'ld_propanel' ), 'backgroundColor' => "#B9DCEB", 'hoverBackgroundColor' => "#B9DCEB", 'data' => 0 ), '100' => array( 'label' => __( '< 100%', 'ld_propanel' ), 'backgroundColor' => "#E7F3F8", 'hoverBackgroundColor' => "#E7F3F8", 'data' => 0 ) ); $this->chart_info['all_percentages']['options'] = array( 'tooltips' => array( 'backgroundColor' => "#3B3E44", 'titleMarginBottom' => 15, 'titleFontSize' => 18, 'cornerRadius' => 4, 'bodyFontSize' => 14, 'xPadding' => 10, 'yPadding' => 15, 'bodySpacing' => 10, 'fontFamily' => "'Open Sans',sans-serif" ), 'legend' => array( 'display' => true, 'labels' => array( 'boxWidth' => 14, 'fontFamily' => "'Open Sans',sans-serif" ) ) ); } function initial_template() { ?>
'sfwd-courses', 'activity_types' => 'course', 'activity_status' => '', 'orderby_order' => 'users.display_name, posts.post_title', 'date_format' => 'F j, Y H:i:s', ); $activity_query_args = ld_propanel_load_activity_query_args( $activity_query_args, $post_data ); // Assed in v2.1.3 we remove the pager logic from the chart queries. $activity_query_args['paged'] = 1; $activity_query_args['per_page'] = 0; $activity_query_args = apply_filters( 'ld_propanel_reporting_activity_args', $activity_query_args, $post_data ); $activity_query_args = ld_propanel_adjust_admin_users( $activity_query_args ); $activity_query_args = ld_propanel_convert_fewer_users( $activity_query_args ); $course_id = 0; $response = $this->get_status_breakdown( $activity_query_args ); wp_send_json_success( $response ); die(); } function get_status_breakdown( $activity_query_args ) { // Let the outside world change elements as needed BEFORE we run the queries. $this->chart_info = apply_filters( 'ld_propanel_chart_info_query', $this->chart_info ); // We store the various query results for post processing logic like building the in_motion data // sets based on the 'in_progress' query results. $activity_query_results = array(); if ( !empty( $activity_query_args ) ) { // Build the 'all_progress' chart data from queries if (!empty( $this->chart_info['all_progress']['query'] ) ) { foreach( $this->chart_info['all_progress']['query'] as $chart_key => $chart_data ) { switch( $chart_key ) { case 'not_started': $activity_query_args['activity_status'] = 'NOT_STARTED'; break; case 'in_progress': $activity_query_args['activity_status'] = 'IN_PROGRESS'; break; case 'completed': $activity_query_args['activity_status'] = 'COMPLETED'; break; default: $activity_query_args['activity_status'] = ''; } if ( !empty( $activity_query_args['activity_status'] ) ) { //$activity_query_results[$chart_key] = learndash_report_course_users_progress( $course_id, array(), $activity_query_args ); $activity_query_results[$chart_key] = learndash_reports_get_activity( $activity_query_args ); //if ( isset( $activity_query_results[$chart_key]['pager']['total_items'] ) ) { // $this->chart_info['all_progress']['query'][$chart_key]['data'] = intval( $activity_query_results[$chart_key]['pager']['total_items'] ); //} if ( ( isset( $activity_query_results[$chart_key]['results'] ) ) && ( !empty( $activity_query_results[$chart_key]['results'] ) ) ) $this->chart_info['all_progress']['query'][$chart_key]['data'] = count( $activity_query_results[$chart_key]['results'] ); else { $this->chart_info['all_progress']['query'][$chart_key]['data'] = array(); } } } } // Now build the 'in_motion' chart data from the in_progress data results if ( ( isset( $activity_query_results['in_progress'] ) ) && ( !empty( $activity_query_results['in_progress'] ) ) ) { foreach ( $activity_query_results['in_progress']['results'] as $in_progress_user ) { $steps_total = LearnDash_ProPanel_Activity::get_activity_steps_total( $in_progress_user ); $steps_completed = LearnDash_ProPanel_Activity::get_activity_steps_completed( $in_progress_user ); if ( ( 0 != intval( $steps_total ) ) || ( 0 != $steps_completed ) ) { $this_percentage = 100 * ( intval( $steps_completed ) / intval( $steps_total ) ); } foreach ( $this->chart_info['all_percentages']['query'] as $percentage_breakdown => $percentage_count ) { if ( intval($this_percentage) < intval( $percentage_breakdown ) ) { $this->chart_info['all_percentages']['query'][ $percentage_breakdown ]['data'] += 1; continue 2; } } } } $this->chart_info = apply_filters( 'ld_propanel_chart_info_results', $this->chart_info ); if ( !empty( $this->chart_info['all_progress'] ) ) { // First we want to remove any empty items foreach( $this->chart_info['all_progress']['query'] as $key => $data ) { if ( empty( $data['data'] ) ) { unset( $this->chart_info['all_progress']['query'][$key] ); } } $this->chart_info['all_progress']['data'] = array(); $this->chart_info['all_progress']['data']['datasets'] = array(); // Now we need to reorganize the array into what Chart.js needs. if ( !empty( $this->chart_info['all_progress']['query'] ) ) { $this->chart_info['all_progress']['data']['labels'] = wp_list_pluck( $this->chart_info['all_progress']['query'], 'label' ); if ( ( !empty( $this->chart_info['all_progress']['data']['labels'] ) ) && ( is_array( $this->chart_info['all_progress']['data']['labels'] ) ) ) { $this->chart_info['all_progress']['data']['labels'] = array_values( $this->chart_info['all_progress']['data']['labels'] ); } $chart_data = array(); $chart_data['data'] = wp_list_pluck( $this->chart_info['all_progress']['query'], 'data' ); if ( ( !empty( $chart_data['data'] ) ) && ( is_array( $chart_data['data'] ) ) ) { $chart_data['data'] = array_values( $chart_data['data'] ); } $chart_data['backgroundColor'] = wp_list_pluck( $this->chart_info['all_progress']['query'], 'backgroundColor' ); if ( ( !empty( $chart_data['backgroundColor'] ) ) && ( is_array( $chart_data['backgroundColor'] ) ) ) { $chart_data['backgroundColor'] = array_values( $chart_data['backgroundColor'] ); } $chart_data['hoverBackgroundColor'] = wp_list_pluck( $this->chart_info['all_progress']['query'], 'hoverBackgroundColor' ); if ( ( !empty( $chart_data['hoverBackgroundColor'] ) ) && ( is_array( $chart_data['hoverBackgroundColor'] ) ) ) { $chart_data['hoverBackgroundColor'] = array_values( $chart_data['hoverBackgroundColor'] ); } if ( !empty( $chart_data ) ) $this->chart_info['all_progress']['data']['datasets'][] = $chart_data; } unset( $this->chart_info['all_progress']['query'] ); } } if ( !empty( $this->chart_info['all_percentages'] ) ) { // First we want to remove any empty items foreach( $this->chart_info['all_percentages']['query'] as $key => $data ) { if ( empty( $data['data'] ) ) { unset( $this->chart_info['all_percentages']['query'][$key] ); } } $this->chart_info['all_percentages']['data'] = array(); $this->chart_info['all_percentages']['data']['datasets'] = array(); // Now we need to reorganize the array into what Chart.js needs. if ( !empty( $this->chart_info['all_percentages']['query'] ) ) { $chart_data = array(); $this->chart_info['all_percentages']['data']['labels'] = wp_list_pluck( $this->chart_info['all_percentages']['query'], 'label' ); if ( ( !empty( $this->chart_info['all_percentages']['data']['labels'] ) ) && ( is_array( $this->chart_info['all_percentages']['data']['labels'] ) ) ) { $this->chart_info['all_percentages']['data']['labels'] = array_values( $this->chart_info['all_percentages']['data']['labels'] ); } $chart_data['data'] = wp_list_pluck( $this->chart_info['all_percentages']['query'], 'data' ); if ( ( !empty( $chart_data['data'] ) ) && ( is_array( $chart_data['data'] ) ) ) { $chart_data['data'] = array_values( $chart_data['data'] ); } $chart_data['backgroundColor'] = wp_list_pluck( $this->chart_info['all_percentages']['query'], 'backgroundColor' ); if ( ( !empty( $chart_data['backgroundColor'] ) ) && ( is_array( $chart_data['backgroundColor'] ) ) ) { $chart_data['backgroundColor'] = array_values( $chart_data['backgroundColor'] ); } $chart_data['hoverBackgroundColor'] = wp_list_pluck( $this->chart_info['all_percentages']['query'], 'hoverBackgroundColor' ); if ( ( !empty( $chart_data['hoverBackgroundColor'] ) ) && ( is_array( $chart_data['hoverBackgroundColor'] ) ) ) { $chart_data['hoverBackgroundColor'] = array_values( $chart_data['hoverBackgroundColor'] ); } if ( !empty( $chart_data ) ) $this->chart_info['all_percentages']['data']['datasets'][] = $chart_data; } unset( $this->chart_info['all_percentages']['query'] ); } return $this->chart_info; } } } PKi<\V]a*includes/class-ld-propanel-base-widget.phpnuW+Aid, array( 'dashboard', 'dashboard_page_propanel-reporting' ) ) ) { $menu_user_cap = ''; if ( learndash_is_admin_user() ) $menu_user_cap = LEARNDASH_ADMIN_CAPABILITY_CHECK; else if ( learndash_is_group_leader_user() ) $menu_user_cap = LEARNDASH_GROUP_LEADER_CAPABILITY_CHECK; else if (current_user_can( 'propanel_widgets' ) ) { $menu_user_cap = 'propanel_widgets'; } if ( !empty( $menu_user_cap ) ) { // Specific code to deregister the BadgeOS version of select JS libs. This seems to // cause a conflict with the version needed for PP on the Dashboard. wp_deregister_script( 'badgeos-select2' ); wp_deregister_style( 'badgeos-select2-css' ); wp_enqueue_script( 'ld-propanel-select2-script' ); wp_enqueue_script( 'ld-propanel-chart-script' ); wp_enqueue_style( 'ld-propanel-select2-style' ); wp_localize_script( 'ld-propanel-script', 'ld_propanel_reporting', array( /** * Filter CSV Export File Name */ 'filename' => apply_filters( 'ld_propanel_export_filename', 'learndash-report-' . current_time( 'Y-m-d' ) ) . '.csv', 'ajax_email_error' => esc_html__( 'ProPanel Email: AJAX submission could not complete, please try again.', 'ld_propanel' ), ) ); } else { wp_deregister_script( 'ld-propanel-select2-script' ); wp_deregister_script( 'ld-propanel-chart-script' ); wp_deregister_style( 'ld-propanel-select2-style' ); } } } else { wp_enqueue_style( 'ld-propanel-select2-style' ); } } /** * Register Widget */ function register_widget() { // Only show the ProPanel widgets for admin and group leaders if ( ( learndash_is_group_leader_user() ) || ( learndash_is_admin_user() ) || ( current_user_can( 'propanel_widgets' ) ) ) { wp_add_dashboard_widget( 'learndash-propanel-' . $this->name, $this->label, array( $this, 'initial_template' ) ); } } /** * Initial Template */ function initial_template() {} /** * Load Template(s) */ function load_template() { check_ajax_referer( 'ld-propanel', 'nonce' ); if ( isset( $_GET['template'] ) && ! empty( $_GET['template'] ) ) { $output = apply_filters( 'learndash_propanel_template_ajax', '', $_GET['template'] ); wp_send_json_success( array( 'output' => $output ) ); } die(); } } }PKi<\x|vv%includes/class-ld-propanel-trends.phpnuW+Aname = 'trends'; // $this->label = esc_html__( 'ProPanel Trends', 'ld_propanel' ); // // parent::__construct(); // add_filter( 'learndash_propanel_template_ajax', array( $this, 'trends_template' ), 10, 2 ); } public function trends_template( $output, $template ) { if ( 'trends' == $template ) { ob_start(); include ld_propanel_get_template( 'ld-propanel-trends.php' ); $output = ob_get_clean(); } return $output; } } } PKi<\Y))+includes/class-ld-translations-propanel.phpnuW+Asettings_page_id = 'learndash_lms_translations'; // Used within the Settings API to uniquely identify this section $this->settings_section_key = 'settings_translations_'. $this->project_slug; // Section label/header $this->settings_section_label = __( 'LearnDash ProPanel', 'ld_propanel' ); if ( class_exists( 'LearnDash_Translations' ) ) { if ( method_exists( 'LearnDash_Translations', 'register_translation_slug' ) ) { $this->registered = true; LearnDash_Translations::register_translation_slug( $this->project_slug, LD_PP_PLUGIN_DIR .'languages' ); } } parent::__construct(); } function add_meta_boxes( $settings_screen_id = '' ) { if ( ( $settings_screen_id == $this->settings_screen_id ) && ( $this->registered === true ) ) { parent::add_meta_boxes( $settings_screen_id ); } } function show_meta_box() { $ld_translations = new LearnDash_Translations( $this->project_slug ); $ld_translations->show_meta_box(); } } LearnDash_Settings_Section_Translations_Learndash_ProPanel::add_section_instance(); } PKi<\/D'includes/class-ld-propanel-overview.phpnuW+Aname = 'overview'; $this->label = esc_html__( 'ProPanel Overview', 'ld_propanel' ); parent::__construct(); add_filter( 'learndash_propanel_template_ajax', array( $this, 'overview_template' ), 10, 2 ); } function initial_template() { ?>
name = 'filtering'; $this->label = esc_html__( 'ProPanel Filtering', 'ld_propanel' ); parent::__construct(); $this->filters_init(); add_filter( 'ld_propanel_reporting_filters_register', array( $this, 'filter_register' ), 20 ); add_action( 'wp_ajax_learndash_propanel_filters_search', array( $this, 'filters_search' ) ); add_filter( 'learndash_propanel_template_ajax', array( $this, 'filtering_template' ), 10, 2 ); //add_action( 'wp_ajax_learndash_propanel_reporting_get_result_rows', array( $this, 'get_result_rows' ) ); add_action( 'wp_ajax_learndash_propanel_email_users', array( $this, 'ajax_email_users' ) ); } function initial_template() { ?>
registered_filters = apply_filters( 'ld_propanel_filtering_register_filters', $this->registered_filters ); } public function filter_register( $registered_filters = array() ) { if ( !array_key_exists( $this->filter_key, $registered_filters ) ) { $registered_filters[$this->filter_key] = array( 'class' => get_class( $this ), 'instance' => $this, 'filter_key' => $this->filter_key ); } return $registered_filters; } function get_filters() { return $this->registered_filters; } function show_filters() { if ( !empty( $this->registered_filters ) ) { foreach( $this->registered_filters as $filter_key => $filter_set ) { ?>
filter_display(); ?>
post_data = ld_propanel_load_post_data(); $this->activity_query_args = ld_propanel_load_activity_query_args( array(), $this->post_data ); $this->activity_query_args = apply_filters( 'ld_propanel_reporting_activity_args', $this->activity_query_args, $this->post_data ); if ( isset( $_GET['filter_key'] ) ) { $filter_key = esc_attr( $_GET['filter_key'] ); if ( array_key_exists( $filter_key, $this->registered_filters ) ) { $this->registered_filters[$filter_key]['instance']->post_data = $this->post_data; $this->registered_filters[$filter_key]['instance']->activity_query_args = $this->activity_query_args; $filter_results = $this->registered_filters[$filter_key]['instance']->filter_search(); } } wp_send_json_success( $filter_results ); die(); } /** * */ // function full_reporting_page_output() { // ob_start(); // $container_type = 'full'; // include ld_propanel_get_template( 'ld-propanel-full-reporting.php' ); // echo ob_get_clean(); // } public function filter_activity_args( $activity_args = array(), $post_data = array() ) { return $activity_args; } /** * */ /* function get_result_rows() { check_ajax_referer( 'ld-propanel', 'nonce' ); $this->post_data = ld_propanel_load_post_data(); $this->activity_query_args = ld_propanel_load_activity_query_args( array(), $this->post_data ); if ( 'course' == $this->post_data['filters']['type'] ) { if ( array_key_exists( 'courses', $this->registered_filters ) ) { $this->registered_filters['courses']['instance']->post_data = $this->post_data; $this->registered_filters['courses']['instance']->activity_query_args = $this->activity_query_args; $response = $this->registered_filters['courses']['instance']->filter_result_rows( $this->post_data['filters']['id'] ); } } else if ( 'user' == $this->post_data['filters']['type'] ) { if ( array_key_exists( 'users', $this->registered_filters ) ) { $this->registered_filters['users']['instance']->post_data = $this->post_data; $this->registered_filters['users']['instance']->activity_query_args = $this->activity_query_args; $response = $this->registered_filters['users']['instance']->filter_result_rows( $this->post_data['filters']['id'] ); } } else if ( 'group' == $this->post_data['filters']['type'] ) { if ( array_key_exists( 'groups', $this->registered_filters ) ) { $this->registered_filters['groups']['instance']->post_data = $this->post_data; $this->registered_filters['groups']['instance']->activity_query_args = $this->activity_query_args; $response = $this->registered_filters['groups']['instance']->filter_result_rows( $this->post_data['filters']['id'] ); } } wp_send_json( $response ); die(); } */ /** * @param array $user_ids * @param $subject * @param $message * * @return bool */ function email_users( $user_ids = array(), $subject, $message ) { global $wpdb; if ( !empty( $user_ids ) ) { $offset = 0; $email_users_batch_size = apply_filters('ld_propanel_email_users_batch_size', 100 ); while( true ) { $user_ids_part = array_slice( $user_ids, $offset, $email_users_batch_size ); if ( empty( $user_ids_part ) ) break; else { $mail_args = array( 'to' => wp_get_current_user()->user_email, 'subject' => $subject, 'message' => wpautop( $message ), 'attachments' => '', 'headers' => array( 'content-type: text/html', 'From: '. wp_get_current_user()->user_email, 'Reply-to: '. wp_get_current_user()->user_email ) ); $mail_ret = false; $email_sql_str = "SELECT user_email from ". $wpdb->users ." WHERE ID IN (". implode( ',', $user_ids_part ) .")"; $email_addresses = $wpdb->get_col( $email_sql_str ); if ( $email_addresses ) { $mail_args['headers'][] = 'Bcc: '. implode( ',', $email_addresses ); $mail_args = apply_filters( 'ld_propanel_email_users_args', $mail_args ); if ( !empty( $mail_args ) ) { do_action( 'ld_propanel_email_users_before', $mail_args ); add_action('wp_mail_failed', array( $this, 'ajax_mail_failed' ) ); $mail_ret = wp_mail( $mail_args['to'], $mail_args['subject'], $mail_args['message'], $mail_args['headers'], $mail_args['attachments'] ); if ( !empty( $this->is_debug ) ) { $this->debug_message .= "mail_ret: ". $mail_ret ."\r\n"; $this->debug_message .= "mail_args
". print_r($mail_args, true) ."
\r\n"; } remove_action('wp_mail_failed', array( $this, 'ajax_mail_failed' ) ); do_action( 'ld_propanel_email_users_after', $mail_args, $mail_ret ); if ( !$mail_ret ) break; } else { break; } } else { break; } $offset += $email_users_batch_size; } } } return $mail_ret; } /** * */ function ajax_email_users() { check_ajax_referer( 'ld-propanel', 'nonce' ); $user_ids = isset( $_POST['user_ids'] ) ? $_POST['user_ids'] : null; $filter = isset( $_POST['filter'] ) ? $_POST['filter'] : null; $subject = isset( $_POST['subject'] ) ? sanitize_text_field( stripslashes( $_POST['subject'] ) ) : ''; $message = isset( $_POST['message'] ) ? wp_kses_post( stripslashes( $_POST['message'] ) ) : ''; $this->is_debug = isset( $_POST['is_debug'] ) ? wp_kses_post( stripslashes( $_POST['is_debug'] ) ) : ''; $response = array( ); if ( !empty( $user_ids ) ) { $user_ids = array_map( 'intval', explode( ',', $user_ids ) ); } else { $this->post_data = ld_propanel_load_post_data( array(), $_POST ); $this->activity_query_args = ld_propanel_load_activity_query_args( array(), $this->post_data ); $this->activity_query_args = ld_propanel_adjust_admin_users( $this->activity_query_args ); //$this->activity_query_args = ld_propanel_convert_fewer_users( $this->activity_query_args ); //if ( ( isset( $this->activity_query_args['user_ids'] ) ) && ( !empty( $this->activity_query_args['user_ids'] ) ) ) { // $user_ids = $this->activity_query_args['user_ids']; //} $this->activity_query_args['per_page'] = 100; $this->activity_query_args['paged'] = 1; $user_ids = array(); while( true ) { $activities = learndash_reports_get_activity( $this->activity_query_args ); if ( ( isset( $activities['results'] ) ) && ( !empty( $activities['results'] ) ) ) { $user_ids = array_merge( $user_ids, wp_list_pluck( $activities['results'], 'user_id' ) ); $this->activity_query_args['paged'] += 1; } else { break; } } } if ( ( ! empty( $user_ids ) ) && ( !empty( $subject ) ) && ( !empty( $message ) ) ) { $user_ids = array_unique( $user_ids ); $result = $this->email_users( $user_ids, $subject, $message, $filter ); if ( $result ) { wp_send_json_success( array( 'message' => sprintf( __('Email sent to %d destinations', 'ld_propanel' ), count( $user_ids ) ), 'debug' => $this->debug_message ) ); } else { $error_string = ''; if ( is_wp_error( $this->mail_error ) ) { $error_string = $this->mail_error->get_error_message(); } wp_send_json_error( array( 'message' => sprintf( esc_html__( "We could not send the email successfully. Please try again or check with your hosting provider. Error: %s", 'ld_propanel' ), $error_string ) ) ); } } else { wp_send_json_error( array( 'message' => esc_html__( 'We do not have any email addresses to send your message to.', 'ld_propanel' ) ) ); } die(); } // Capture the wp_mail() failure. Will then be appended to the json message sent back to the browser. function ajax_mail_failed( $mail_error ) { $this->mail_error = $mail_error; } } } require_once LD_PP_PLUGIN_DIR . 'templates/reporting-filters/groups/ld-propanel-reporting-filter-group.php'; require_once LD_PP_PLUGIN_DIR . 'templates/reporting-filters/courses/ld-propanel-reporting-filter-course.php'; require_once LD_PP_PLUGIN_DIR . 'templates/reporting-filters/users/ld-propanel-reporting-filter-user.php'; require_once LD_PP_PLUGIN_DIR . 'templates/reporting-filters/status/ld-propanel-reporting-filter-status.php';PKi<\JS))(includes/class-ld-propanel-reporting.phpnuW+Aname = 'reporting'; $this->label = esc_html__( 'ProPanel Reporting', 'ld_propanel' ); parent::__construct(); add_filter( 'learndash_propanel_template_ajax', array( $this, 'reporting_template' ), 10, 2 ); add_action( 'wp_ajax_learndash_propanel_reporting_get_result_rows', array( $this, 'get_result_rows' ) ); } function initial_template() { ?>
filtering_widget->get_filters(); $this->post_data = ld_propanel_load_post_data(); $this->activity_query_args = ld_propanel_load_activity_query_args( array(), $this->post_data ); if ( 'course-reporting' == $this->post_data['template'] ) { if ( array_key_exists( 'courses', $registered_filters ) ) { $registered_filters['courses']['instance']->post_data = $this->post_data; $registered_filters['courses']['instance']->activity_query_args = $this->activity_query_args; $output = $registered_filters['courses']['instance']->filter_build_table(); } } else if ( 'user-reporting' == $this->post_data['template'] ) { if ( array_key_exists( 'users', $registered_filters ) ) { $registered_filters['users']['instance']->post_data = $this->post_data; $registered_filters['users']['instance']->activity_query_args = $this->activity_query_args; $output = $registered_filters['users']['instance']->filter_build_table(); } } else if ( 'group-reporting' == $this->post_data['template'] ) { if ( array_key_exists( 'groups', $registered_filters ) ) { $registered_filters['groups']['instance']->post_data = $this->post_data; $registered_filters['groups']['instance']->activity_query_args = $this->activity_query_args; $output = $registered_filters['groups']['instance']->filter_build_table(); } } break; } return $output; } /** * */ // function full_reporting_page_output() { // ob_start(); // $container_type = 'full'; // include ld_propanel_get_template( 'ld-propanel-full-reporting.php' ); // echo ob_get_clean(); // } public function filter_activity_args( $activity_args = array(), $post_data = array() ) { return $activity_args; } /** * */ function get_result_rows() { check_ajax_referer( 'ld-propanel', 'nonce' ); $registered_filters = LearnDash_ProPanel::get_instance()->filtering_widget->get_filters(); $this->post_data = ld_propanel_load_post_data(); $this->activity_query_args = ld_propanel_load_activity_query_args( array(), $this->post_data ); if ( 'course' == $this->post_data['filters']['type'] ) { if ( array_key_exists( 'courses', $registered_filters ) ) { $registered_filters['courses']['instance']->post_data = $this->post_data; $registered_filters['courses']['instance']->activity_query_args = $this->activity_query_args; $response = $registered_filters['courses']['instance']->filter_result_rows( $this->post_data['filters']['id'] ); } } else if ( 'user' == $this->post_data['filters']['type'] ) { if ( array_key_exists( 'users', $registered_filters ) ) { $registered_filters['users']['instance']->post_data = $this->post_data; $registered_filters['users']['instance']->activity_query_args = $this->activity_query_args; $response = $registered_filters['users']['instance']->filter_result_rows( $this->post_data['filters']['id'] ); } } else if ( 'group' == $this->post_data['filters']['type'] ) { if ( array_key_exists( 'groups', $registered_filters ) ) { $registered_filters['groups']['instance']->post_data = $this->post_data; $registered_filters['groups']['instance']->activity_query_args = $this->activity_query_args; $response = $registered_filters['groups']['instance']->filter_result_rows( $this->post_data['filters']['id'] ); } } wp_send_json( $response ); die(); } /** * @param array $user_ids * @param $subject * @param $message * * @return bool */ function email_users( $user_ids = array(), $subject, $message ) { global $wpdb; if ( !empty( $user_ids ) ) { $offset = 0; $email_users_batch_size = apply_filters('ld_propanel_email_users_batch_size', 100 ); while( true ) { $user_ids_part = array_slice( $user_ids, $offset, $email_users_batch_size ); if ( empty( $user_ids_part ) ) break; else { $mail_args = array( 'to' => wp_get_current_user()->user_email, 'subject' => $subject, 'message' => wpautop( $message ), 'attachments' => '', 'headers' => array( 'content-type: text/html', 'From: '. wp_get_current_user()->user_email, 'Reply-to: '. wp_get_current_user()->user_email ) ); $mail_ret = false; $email_sql_str = "SELECT user_email from ". $wpdb->users ." WHERE ID IN (". implode( ',', $user_ids_part ) .")"; $email_addresses = $wpdb->get_col( $email_sql_str ); if ( $email_addresses ) { $mail_args['headers'][] = 'Bcc: '. implode( ',', $email_addresses ); $mail_args = apply_filters( 'ld_propanel_email_users_args', $mail_args ); if ( !empty( $mail_args ) ) { do_action( 'ld_propanel_email_users_before', $mail_args ); add_action('wp_mail_failed', array( $this, 'ajax_mail_failed' ) ); $mail_ret = wp_mail( $mail_args['to'], $mail_args['subject'], $mail_args['message'], $mail_args['headers'], $mail_args['attachments'] ); if ( !empty( $this->is_debug ) ) { $this->debug_message .= "mail_ret: ". $mail_ret ."\r\n"; $this->debug_message .= "mail_args
". print_r($mail_args, true) ."
\r\n"; } remove_action('wp_mail_failed', array( $this, 'ajax_mail_failed' ) ); do_action( 'ld_propanel_email_users_after', $mail_args, $mail_ret ); if ( !$mail_ret ) break; } else { break; } } else { break; } $offset += $email_users_batch_size; } } } return $mail_ret; } /** * */ function ajax_email_users() { check_ajax_referer( 'ld-propanel', 'nonce' ); $user_ids = isset( $_POST['user_ids'] ) ? $_POST['user_ids'] : null; $filter = isset( $_POST['filter'] ) ? $_POST['filter'] : null; $subject = isset( $_POST['subject'] ) ? sanitize_text_field( stripslashes( $_POST['subject'] ) ) : ''; $message = isset( $_POST['message'] ) ? wp_kses_post( stripslashes( $_POST['message'] ) ) : ''; $this->is_debug = isset( $_POST['is_debug'] ) ? wp_kses_post( stripslashes( $_POST['is_debug'] ) ) : ''; $response = array( ); if ( !empty( $user_ids ) ) { $user_ids = array_map( 'intval', explode( ',', $user_ids ) ); } else { $this->post_data = ld_propanel_load_post_data( array(), $_POST ); $this->activity_query_args = ld_propanel_load_activity_query_args( array(), $this->post_data ); $this->activity_query_args = ld_propanel_adjust_admin_users( $this->activity_query_args ); //$this->activity_query_args = ld_propanel_convert_fewer_users( $this->activity_query_args ); //if ( ( isset( $this->activity_query_args['user_ids'] ) ) && ( !empty( $this->activity_query_args['user_ids'] ) ) ) { // $user_ids = $this->activity_query_args['user_ids']; //} $this->activity_query_args['per_page'] = 100; $this->activity_query_args['paged'] = 1; $user_ids = array(); while( true ) { $activities = learndash_reports_get_activity( $this->activity_query_args ); if ( ( isset( $activities['results'] ) ) && ( !empty( $activities['results'] ) ) ) { $user_ids = array_merge( $user_ids, wp_list_pluck( $activities['results'], 'user_id' ) ); $this->activity_query_args['paged'] += 1; } else { break; } } } if ( ( ! empty( $user_ids ) ) && ( !empty( $subject ) ) && ( !empty( $message ) ) ) { $user_ids = array_unique( $user_ids ); $result = $this->email_users( $user_ids, $subject, $message, $filter ); if ( $result ) { wp_send_json_success( array( 'message' => sprintf( __('Email sent to %d destinations', 'ld_propanel' ), count( $user_ids ) ), 'debug' => $this->debug_message ) ); } else { $error_string = ''; if ( is_wp_error( $this->mail_error ) ) { $error_string = $this->mail_error->get_error_message(); } wp_send_json_error( array( 'message' => sprintf( esc_html__( "We could not send the email successfully. Please try again or check with your hosting provider. Error: %s", 'ld_propanel' ), $error_string ) ) ); } } else { wp_send_json_error( array( 'message' => esc_html__( 'We do not have any email addresses to send your message to.', 'ld_propanel' ) ) ); } die(); } // Capture the wp_mail() failure. Will then be appended to the json message sent back to the browser. function ajax_mail_failed( $mail_error ) { $this->mail_error = $mail_error; } } } PKi<\&(.(.includes/class-ld-propanel.phpnuW+Acheck_dependency_results()) { if ( learndash_is_admin_user() ) $menu_user_cap = LEARNDASH_ADMIN_CAPABILITY_CHECK; else if ( learndash_is_group_leader_user() ) $menu_user_cap = LEARNDASH_GROUP_LEADER_CAPABILITY_CHECK; if ( !empty( $menu_user_cap ) ) { $r_page = add_submenu_page( null, esc_html__( 'ProPanel Reporting', 'ld_propanel' ), esc_html__( 'ProPanel Reporting', 'ld_propanel' ), $menu_user_cap, 'propanel-reporting', array( $this, 'admin_full_page_output' ) ); // Found out the following is needed needed mainly for group leaders to be able to see the full page reporting screen. Not really needed for admin users. global $_registered_pages; $_registered_pages['admin_page_propanel-reporting'] = true; } } } function admin_full_page_output() { $this->init(); ob_start(); $container_type = 'full'; include ld_propanel_get_template( 'ld-propanel-full-admin.php' ); echo ob_get_clean(); } function parse_request() { //$current_template = get_current_template(); //error_log('current_template['. $current_template .']'); //if ( is_page_template('ld-propanel-full-page.php') ) { // error_log('ARE using the template'); //} else { // error_log('NOT using the template'); //} // Check if we are doing the full page front-end ld_propanel template if ( ( !is_admin()) && ( isset( $_GET['ld_propanel'] ) ) ) { if ( ( learndash_is_group_leader_user() ) || ( learndash_is_admin_user() ) || ( current_user_can( 'propanel_widgets' ) ) ) { $this->scripts(true); $template_full_page_css = ld_propanel_get_template( 'ld-propanel-full-page.css' ); if ( !empty( $template_full_page_css ) ) { $template_full_page_css_url = learndash_template_url_from_path( $template_full_page_css ); wp_enqueue_style( 'ld-propanel-full-page-style', $template_full_page_css_url, null, LD_PP_VERSION ); } ob_start(); include ld_propanel_get_template( 'ld-propanel-full-page.php' ); echo ob_get_clean(); die(); } } } function add_ld_tinymce_shortcode( $shortcode_sections = array() ) { if ( is_admin() ) { $fields_args = array( 'post_type' => '' ); if ( ( isset( $_GET['post_type'] ) ) && ( !empty( $_GET['post_type'] ) ) ) { $fields_args['post_type'] = esc_attr( $_GET['post_type'] ); } if ( $fields_args['post_type'] != 'sfwd-certificates' ) { require_once LD_PP_PLUGIN_DIR . 'includes/class-ld-tinymce-courseinfo.php'; $shortcode_sections['ld_propanel'] = new LearnDash_Shortcodes_Section_ld_propanel( array() ); } } return $shortcode_sections; } public function init() { $this->load_textdomain(); $this->includes(); } /** * Notify user that LearnDash is required. */ public function notify_user_learndash_required() { ?>

check_dependency_results()) { if ( is_admin() ) { require_once LD_PP_PLUGIN_DIR . 'includes/class-ld-propanel-base-widget.php'; // Support for LearnDash Translation admin panel require_once LD_PP_PLUGIN_DIR . 'includes/class-ld-translations-propanel.php'; // ProPanel Overview if ( ( learndash_is_group_leader_user() ) || ( learndash_is_admin_user() ) ) { require_once LD_PP_PLUGIN_DIR . 'includes/class-ld-propanel-overview.php'; $this->overview_widget = new LearnDash_ProPanel_Overview(); } require_once LD_PP_PLUGIN_DIR . 'includes/class-ld-propanel-filtering.php'; $this->filtering_widget = new LearnDash_ProPanel_Filtering(); require_once LD_PP_PLUGIN_DIR . 'includes/class-ld-propanel-reporting.php'; $this->reporting_widget = new LearnDash_ProPanel_Reporting(); require_once LD_PP_PLUGIN_DIR . 'includes/class-ld-propanel-activity.php'; $this->activity_widget = new LearnDash_ProPanel_Activity(); require_once LD_PP_PLUGIN_DIR . 'includes/class-ld-propanel-progress-chart.php'; $this->progress_chart_widget = new LearnDash_ProPanel_Progress_Chart(); //require_once LD_PP_PLUGIN_DIR . 'includes/class-ld-propanel-trends.php'; //$this->trends_widget = new LearnDash_ProPanel_Trends(); require_once LD_PP_PLUGIN_DIR . 'includes/functions.php'; require_once LD_PP_PLUGIN_DIR . 'includes/class-ld-propanel-shortcodes.php'; LearnDash_ProPanel_Shortcode::get_instance(); //LearnDash_ProPanel_Shortcodes_Filtering::get_instance(); //if ( ( learndash_is_group_leader_user() ) || ( learndash_is_admin_user() ) ) { // LearnDash_ProPanel_Shortcodes_Overview::get_instance(); //} //LearnDash_ProPanel_Shortcodes_Activity::get_instance(); //LearnDash_ProPanel_Shortcodes_Reporting::get_instance(); //LearnDash_ProPanel_Shortcodes_Progress_Chart::get_instance(); } else { require_once LD_PP_PLUGIN_DIR . 'includes/class-ld-propanel-base-widget.php'; // ProPanel Overview if ( ( learndash_is_group_leader_user() ) || ( learndash_is_admin_user() ) ) { require_once LD_PP_PLUGIN_DIR . 'includes/class-ld-propanel-overview.php'; $this->overview_widget = new LearnDash_ProPanel_Overview(); } // ProPanel Filtering require_once LD_PP_PLUGIN_DIR . 'includes/class-ld-propanel-filtering.php'; $this->filtering_widget = new LearnDash_ProPanel_Filtering(); // ProPanel Reporting require_once LD_PP_PLUGIN_DIR . 'includes/class-ld-propanel-reporting.php'; $this->reporting_widget = new LearnDash_ProPanel_Reporting(); // ProPanel Activity require_once LD_PP_PLUGIN_DIR . 'includes/class-ld-propanel-activity.php'; $this->activity_widget = new LearnDash_ProPanel_Activity(); // ProPanel Charts require_once LD_PP_PLUGIN_DIR . 'includes/class-ld-propanel-progress-chart.php'; $this->progress_chart_widget = new LearnDash_ProPanel_Progress_Chart(); require_once LD_PP_PLUGIN_DIR . 'includes/functions.php'; require_once LD_PP_PLUGIN_DIR . 'includes/class-ld-propanel-shortcodes.php'; LearnDash_ProPanel_Shortcode::get_instance(); //LearnDash_ProPanel_Shortcodes_Filtering::get_instance(); //if ( ( learndash_is_group_leader_user() ) || ( learndash_is_admin_user() ) ) { // LearnDash_ProPanel_Shortcodes_Overview::get_instance(); //} //LearnDash_ProPanel_Shortcodes_Activity::get_instance(); //LearnDash_ProPanel_Shortcodes_Reporting::get_instance(); //LearnDash_ProPanel_Shortcodes_Progress_Chart::get_instance(); //LearnDash_ProPanel_Shortcodes_Link::get_instance(); } } } /** * Load ProPanel Text Domain */ private function load_textdomain() { load_plugin_textdomain( 'ld_propanel', false, dirname( plugin_basename( __FILE__ ) ) . '/languages/' ); } /** * Register scripts for any widgets that may need to enqueue them. */ public function scripts( $force_load_scripts = false ) { if ( LearnDash_Dependency_Check_ProPanel::get_instance()->check_dependency_results()) { $is_dashboard = false; if ( is_admin() ) { $screen = get_current_screen(); if ( in_array( $screen->id, array( 'dashboard', 'dashboard_page_propanel-reporting' ) ) ) { $force_load_scripts = true; $is_dashboard = true; } } if ( true === $force_load_scripts ) { $ld_script_prereq = array( 'jquery' ); // For now these are only loaded on admin Dashboard //if ( is_admin() ) { //wp_register_script( 'ld-propanel-chart-script', LD_PP_PLUGIN_URL . 'assets/js/vendor/Chart.js', array( 'jquery'), LD_PP_VERSION, true ); //$ld_script_prereq[] = 'ld-propanel-chart-script'; wp_register_script( 'ld-propanel-chart-script', LD_PP_PLUGIN_URL . 'assets/js/vendor/Chart.js', array( 'jquery' ), LD_PP_VERSION, false ); $ld_script_prereq[] = 'ld-propanel-chart-script'; wp_register_script( 'ld-propanel-select2-script', LD_PP_PLUGIN_URL . 'assets/js/vendor/select2.js', array( 'jquery' ), '4.0.3', true ); $ld_script_prereq[] = 'ld-propanel-select2-script'; //wp_register_style( 'ld-propanel-select2-style', LD_PP_PLUGIN_URL . 'assets/css/vendor/select2.min.css' ); wp_enqueue_style( 'ld-propanel-select2-style', LD_PP_PLUGIN_URL . 'assets/css/vendor/select2.min.css' ); //} wp_register_script( 'ld-propanel-script', LD_PP_PLUGIN_URL . 'assets/js/ld-propanel.js', $ld_script_prereq, LD_PP_VERSION, true ); $pager_values = ld_propanel_get_pager_values(); if ( empty( $pager_values ) ) { $pager_values = array( get_option( 'posts_per_page' ) ); } wp_localize_script( 'ld-propanel-script', 'ld_propanel_settings', array( 'nonce' => wp_create_nonce( 'ld-propanel' ), 'ajaxurl' => admin_url( 'admin-ajax.php' ), 'spinner_admin_img' => admin_url( '/images/spinner.gif' ), 'is_dashboard' => $is_dashboard, 'is_debug' => false, 'template_load_delay' => apply_filters('ld_propanel_js_template_load_delay', 1000), 'default_per_page' => $pager_values[0] ) ); wp_enqueue_script( 'ld-propanel-script' ); wp_enqueue_style( 'dashicons' ); wp_register_style( 'ld-propanel-style', LD_PP_PLUGIN_URL . 'assets/css/ld-propanel.css', null, LD_PP_VERSION ); wp_enqueue_style( 'ld-propanel-style' ); global $learndash_assets_loaded; if ( !isset( $learndash_assets_loaded['scripts']['learndash_template_script_js'] ) ) { $filepath = SFWD_LMS::get_template( 'learndash_template_script.js', null, null, true ); if ( !empty( $filepath ) ) { wp_enqueue_script( 'learndash_template_script_js', learndash_template_url_from_path( $filepath ), array( 'jquery' ), LEARNDASH_SCRIPT_VERSION_TOKEN, true ); $learndash_assets_loaded['scripts']['learndash_template_script_js'] = __FUNCTION__; $data = array(); $data['ajaxurl'] = admin_url('admin-ajax.php'); $data = array( 'json' => json_encode( $data ) ); wp_localize_script( 'learndash_template_script_js', 'sfwd_data', $data ); } } LD_QuizPro::showModalWindow(); } } } }PKi<\b!bb'includes/class-ld-propanel-activity.phpnuW+Aname = 'activity'; $this->label = esc_html__( 'ProPanel Activity', 'ld_propanel' ); parent::__construct(); add_filter( 'learndash_propanel_template_ajax', array( $this, 'activity_template' ), 10, 2 ); add_filter( 'learndash_propanel_template_ajax', array( $this, 'activity_template_rows' ), 10, 2 ); add_filter( 'learndash_data_reports_headers', array( $this, 'learndash_data_reports_headers' ), 10, 2 ); } function initial_template() { ?>
false); if ( isset( $_GET['args'] ) ) $post_data = $_GET['args']; else $post_data = array(); $report_post_args = array(); if ( isset( $_GET['args'] ) ) $report_post_args = array_merge( $report_post_args, $_GET['args'] ); if ( ( isset( $report_post_args['init'] ) ) && ( $report_post_args['init'] == '1' ) ) { $_GET['filters'] = $_GET['args']['filters']; $post_data = ld_propanel_load_post_data( $post_data ); if ( !empty( $post_data['filters']['courseStatus'] ) ) { $report_post_args['filters']['activity_status'] = $post_data['filters']['courseStatus']; } else { $report_post_args['filters']['activity_status'] = array( 'NOT_STARTED', 'IN_PROGRESS', 'COMPLETED' ); } $activity_query_args = array(); $activity_query_args = ld_propanel_load_activity_query_args( $activity_query_args, $post_data ); if ( !empty( $activity_query_args ) ) { if ( ( !isset( $report_post_args['filters']['users_ids'] ) ) && ( isset( $activity_query_args['user_ids'] ) ) ) { $report_post_args['filters']['users_ids'] = $activity_query_args['user_ids']; //unset( $report_post_args['filters']['user_ids'] ); } else { $report_post_args['filters']['users_ids'] = learndash_get_report_user_ids(); } if ( !empty( $report_post_args['filters']['users_ids'] ) ) { $exclude_admin_users = ld_propanel_exclude_admin_users(); if ( $exclude_admin_users ) { $admin_user_ids = ld_propanel_get_admin_user_ids(); if ( !empty( $admin_user_ids ) ) { $report_post_args['filters']['users_ids'] = array_diff( $report_post_args['filters']['users_ids'], $admin_user_ids ); } } } /* if ( ( !isset( $report_post_args['filters']['posts_ids'] ) ) && ( isset( $activity_query_args['post_ids'] ) ) ) { $report_post_args['filters']['posts_ids'] = $activity_query_args['post_ids']; foreach( $report_post_args['filters']['posts_ids'] as $course_id ) { $course_post_status = get_post_status( $course_id ); if ( $course_post_status == 'publish' ) { if ( 'activity-courses' == $template ) { $report_post_types = array( 'sfwd-courses', 'sfwd-lessons', 'sfwd-topic' ); } else if ( 'activity-quizzes' == $template ) { $report_post_types = array( 'sfwd-quiz' ); } $course_post_ids = ld_propanel_get_course_post_items( $course_id, $report_post_types ); if ( !empty( $course_post_ids ) ) { $report_post_args['filters']['posts_ids'] = array_merge( $report_post_args['filters']['posts_ids'], $course_post_ids ); $report_post_args['filters']['posts_ids'] = array_unique( $report_post_args['filters']['posts_ids'] ); } } } } */ if ( ( !isset( $report_post_args['filters']['posts_ids'] ) ) && ( isset( $activity_query_args['post_ids'] ) ) ) { $_process_legacy = true; // If the admin has performed the needed upgrade on the courses and quizzes... if ( version_compare( LEARNDASH_VERSION, '2.4.9.9') >= 0 ) { $ld_data_upgrade = Learndash_Admin_Settings_Data_Upgrades::get_instance(); $data_settings_courses = $ld_data_upgrade->get_data_settings('user-meta-courses'); $data_settings_quizzes = $ld_data_upgrade->get_data_settings('user-meta-quizzes'); if ( ( isset( $data_settings_courses['version'] ) ) && ( version_compare( $data_settings_courses['version'], '2.5', '>=') ) && ( isset( $data_settings_quizzes['version'] ) ) && ( version_compare( $data_settings_quizzes['version'], '2.5', '>=') ) ) { // we can simple query by course_id since that column will be filled in now. $report_post_args['filters']['course_ids'] = $activity_query_args['post_ids']; $_process_legacy = false; } } // But if we still need to support legacy we can still do that below. if ( $_process_legacy === true ) { $report_post_args['filters']['posts_ids'] = $activity_query_args['post_ids']; foreach( $report_post_args['filters']['posts_ids'] as $course_id ) { $course_post_status = get_post_status( $course_id ); if ( $course_post_status == 'publish' ) { if ( 'activity-courses' == $template ) { $report_post_types = array( 'sfwd-courses', 'sfwd-lessons', 'sfwd-topic' ); } else if ( 'activity-quizzes' == $template ) { $report_post_types = array( 'sfwd-quiz' ); } $course_post_ids = ld_propanel_get_course_post_items( $course_id, $report_post_types ); if ( !empty( $course_post_ids ) ) { $report_post_args['filters']['posts_ids'] = array_merge( $report_post_args['filters']['posts_ids'], $course_post_ids ); $report_post_args['filters']['posts_ids'] = array_unique( $report_post_args['filters']['posts_ids'] ); } } } } } } } if ( class_exists( 'Learndash_Admin_Settings_Data_Reports' ) ) { $ld_admin_settings_data_reports = new Learndash_Admin_Settings_Data_Reports; $reply_data['data'] = $ld_admin_settings_data_reports->do_data_reports( $report_post_args, $reply_data ); unset( $reply_data['data']['filters'] ); $output = $reply_data; } } return $output; } /** * Override the LearnDash core reporting column headers. * * @param $data_headers array of headers. See notes below for exact structure * @param $data_slug stirng for the type of report 'user-courses' or 'user-quizzes' * * @return $data_headers array * * The follow is an example of the data structure used for the headers. Note this is NOT * a simple key/value array. * $data_headers['user_id'] = array( * 'label' => 'user_id', * 'default' => '', * 'display' => array( $this, 'report_header_user_id' ) * ); * * 'label' This is used in place of the array item key for the column header value. * 'default' This is the default value of the field * 'display' This should be a callback function to handle the value determination */ function learndash_data_reports_headers( $data_headers, $data_slug ) { if ( $data_slug == 'user-courses' ) { if ( !isset( $data_headers['course_started_on'] ) ) { $data_headers['course_started_on'] = array( 'label' => 'course_started_on', 'default' => '', 'display' => array( $this, 'learndash_courses_report_display_column' ) ); } /* if ( !isset( $data_headers['course_updated_on'] ) ) { $data_headers['course_updated_on'] = array( 'label' => 'course_updated_on', 'default' => '', 'display' => array( $this, 'learndash_courses_report_display_column' ) ); } */ if ( !isset( $data_headers['course_total_time_on'] ) ) { $data_headers['course_total_time_on'] = array( 'label' => __( 'course_total_time_on', 'ld_propanel' ), 'default' => '', 'display' => array( $this, 'learndash_courses_report_display_column' ) ); } if ( !isset( $data_headers['course_last_step_id'] ) ) { $data_headers['course_last_step_id'] = array( 'label' => __( 'course_last_step_id', 'ld_propanel' ), 'default' => '', 'display' => array( $this, 'learndash_courses_report_display_column' ) ); } if ( !isset( $data_headers['course_last_step_type'] ) ) { $data_headers['course_last_step_type'] = array( 'label' => __( 'course_last_step_type', 'ld_propanel' ), 'default' => '', 'display' => array( $this, 'learndash_courses_report_display_column' ) ); } if ( !isset( $data_headers['course_last_step_title'] ) ) { $data_headers['course_last_step_title'] = array( 'label' => __( 'course_last_step_title', 'ld_propanel' ), 'default' => '', 'display' => array( $this, 'learndash_courses_report_display_column' ) ); } if ( !isset( $data_headers['last_login_date'] ) ) { $data_headers['last_login_date'] = array( 'label' => __( 'last_login_date', 'ld_propanel' ), 'default' => '', 'display' => array( $this, 'learndash_courses_report_display_column' ) ); } } else if ( $data_slug == 'user-quizzes' ) { } return $data_headers; } function learndash_courses_report_display_column( $header_output = '', $header_key, $activity, $report_user ) { $data_slug = 'user-courses'; include ld_propanel_get_template( 'ld-propanel-reporting-columns.php' ); return $header_output; } /** * Build Activity Rows * * @param $output * @param $template * * @return string */ public function activity_template_rows( $output, $template ) { if (( 'activity_rows' == $template ) || ( 'activity' == $template )) { $output = ''; //if ( ld_propanel_count_post_type( 'sfwd-courses' ) ) { if ( ld_propanel_get_users_count() ) { if ( isset( $_GET['args']['per_page'] ) ) { $per_page = abs( intval( $_GET['args']['per_page'] ) ); } else { $per_page_array = ld_propanel_get_pager_values(); if ( empty( $per_page_array ) ) { $per_page_array = array(5); } $per_page = $per_page_array[0]; } /** * Build $activity_query_args from info passed as AJAX */ $activity_query_args = array( 'per_page' => $per_page, //'activity_status' => array( 'NOT_STARTED', 'IN_PROGRESS', 'COMPLETED' ), // We are only showing completed items for now 'activity_types' => array('course', 'quiz', 'lesson', 'topic'), 'post_types' => array('sfwd-courses', 'sfwd-quiz', 'sfwd-lessons', 'sfwd-topic'), 'post_status' => 'publish', 'orderby_order' => 'ld_user_activity.activity_updated DESC', 'date_format' => 'Y-m-d H:i:s', 'export_buttons' => true, //$_GET['filters']['export_buttons'], 'nav_top' => true, //$_GET['filters']['nav_top'], //'nav_bottom' => true, //$_GET['filters']['nav_bottom'], ); foreach( $activity_query_args as $key => $val ) { if ( isset( $_GET['filters'][$key] ) ) { $activity_query_args[$key] = stripslashes_deep( $_GET['filters'][$key] ); } } if ( ( isset( $_GET['container_type'] ) ) && ( $_GET['container_type'] == 'shortcode' ) ) { if ( ( !isset( $_GET['filters']['export_buttons'] ) ) || ( $_GET['filters']['export_buttons'] !== '1' ) && ( $_GET['filters']['export_buttons'] !== 'true' ) ) unset( $activity_query_args['export_buttons'] ); if ( ( !isset( $_GET['filters']['nav_top'] ) ) || ( $_GET['filters']['nav_top'] !== '1' ) && ( $_GET['filters']['nav_top'] !== 'true' ) ) unset( $activity_query_args['nav_top'] ); } $activity_query_args = shortcode_atts( $activity_query_args, $_GET['filters'] ); $post_data = ld_propanel_load_post_data(); $activity_query_args = ld_propanel_load_activity_query_args( $activity_query_args, $post_data ); if ( !empty( $activity_query_args ) ) { $activity_query_args = ld_propanel_adjust_admin_users( $activity_query_args ); //$response['total_users'] = count( $this->activity_query_args['user_ids'] ); $activity_query_args = ld_propanel_convert_fewer_users( $activity_query_args ); // If apecific post_ids are provided we want to inlcude in all the lessons, topics, quizzes for display if ( ( isset( $activity_query_args['post_ids'] ) ) && ( !empty( $activity_query_args['post_ids'] ) ) ) { if ( version_compare( LEARNDASH_VERSION, '2.4.9.9') >= 0 ) { $activity_query_args['course_ids'] = $activity_query_args['post_ids']; $activity_query_args['post_ids'] = ''; } else { $post_ids = $activity_query_args['post_ids']; foreach( $post_ids as $course_id ) { $course_post_status = get_post_status( $course_id ); if ( $course_post_status == 'publish' ) { //$course_post_ids = learndash_get_course_steps( $course_id, $activity_query_args['post_types'] ); $course_post_ids = ld_propanel_get_course_post_items( $course_id, $activity_query_args['post_types'] ); if ( !empty( $course_post_ids ) ) { $activity_query_args['post_ids'] = array_merge( $activity_query_args['post_ids'], $course_post_ids ); $activity_query_args['post_ids'] = array_unique( $activity_query_args['post_ids'] ); } } } } } //if ( empty( $post_data['filters']['courseStatus'] ) ) { // $post_data['filters']['courseStatus'] = array( 'IN_PROGRESS', 'COMPLETED' ); //} else { // foreach( $post_data['filters']['courseStatus'] as $idx => $status ) { // if ( $status == 'NOT_STARTED' ) { // unset( $post_data['filters']['courseStatus'][$idx] ); // } // } //} $activity_query_args['activity_status'] = array( 'IN_PROGRESS', 'COMPLETED' ); $paged = 1; if ( isset( $_GET['args']['paged'] ) && ! empty( $_GET['args']['paged'] ) ) { $activity_query_args['paged'] = abs( intval( $_GET['args']['paged'] ) ); $paged = intval( $_GET['args']['paged'] ); } $activity_query_args = apply_filters( 'ld_propanel_activity_widget_query_args', $activity_query_args, $template ); if ( learndash_is_admin_user( get_current_user_id() ) ) { // Admin will see all groups } else if ( learndash_is_group_leader_user( ) ) { if ( ( !isset( $activity_query_args['user_ids'] ) ) || ( empty( $activity_query_args['user_ids'] ) ) ) { $activity_query_args = array(); } if ( version_compare( LEARNDASH_VERSION, '2.4.9.9') >= 0 ) { if ( ( !isset( $activity_query_args['course_ids'] ) ) || ( empty( $activity_query_args['course_ids'] ) ) ) { $activity_query_args = array(); } } else { if ( ( !isset( $activity_query_args['post_ids'] ) ) || ( empty( $activity_query_args['post_ids'] ) ) ) { $activity_query_args = array(); } } } else { // Regular student user if ( ( !isset( $activity_query_args['user_ids'] ) ) || ( empty( $activity_query_args['user_ids'] ) ) ) { $activity_query_args = array(); } else if ( ( !isset( $activity_query_args['post_ids'] ) ) || ( empty( $activity_query_args['post_ids'] ) ) ) { $activity_query_args = array(); } } if ( !empty( $activity_query_args ) ) { //error_log('activity_query_args
'. print_r($activity_query_args, true) .'
'); $activities = learndash_reports_get_activity( $activity_query_args ); //error_log('activities
'. print_r($activities, true) .'
'); ob_start(); if ( empty( $activities['results'] ) ) { include ld_propanel_get_template( 'ld-propanel-no-results.php' ); } else { ?>
activity_started_formatted = get_date_from_gmt( date( 'Y-m-d H:i:s', $activity->activity_started ), 'Y-m-d H:i:s' ); $activity->activity_started_formatted = date_i18n( $activity_row_date_time_format, strtotime( $activity->activity_started_formatted ), false); $activity->activity_completed_formatted = get_date_from_gmt( date( 'Y-m-d H:i:s', $activity->activity_completed ), 'Y-m-d H:i:s' ); $activity->activity_completed_formatted = date_i18n( $activity_row_date_time_format, strtotime( $activity->activity_completed_formatted ), false); $activity->activity_updated_formatted = get_date_from_gmt( date( 'Y-m-d H:i:s', $activity->activity_updated ), 'Y-m-d H:i:s' ); $activity->activity_updated_formatted = date_i18n( $activity_row_date_time_format, strtotime( $activity->activity_updated_formatted ), false); include ld_propanel_get_template( 'ld-propanel-activity-rows.php' ); } //if ( $activity_query_args['nav_bottom'] == true ) // include ld_propanel_get_template( 'ld-propanel-activity-pagination.php' ); } $output = ob_get_clean(); } else { ob_start(); include ld_propanel_get_template( 'ld-propanel-no-results.php' ); $output = ob_get_clean(); } } else { ob_start(); include ld_propanel_get_template( 'ld-propanel-no-results.php' ); $output = ob_get_clean(); } } else { ob_start(); include ld_propanel_get_template( 'ld-propanel-no-results.php' ); $output = ob_get_clean(); } } return array( 'rows_html' => $output ); } /** * @param $activity * * @return mixed */ public static function get_activity_steps_completed( $activity ) { if ( ( !empty( $activity ) ) && ( property_exists( $activity, 'activity_meta' ) ) && ( isset( $activity->activity_meta['steps_completed'] ) ) ) { return intval($activity->activity_meta['steps_completed']); } } /** * @param $activity * * @return mixed */ public static function get_activity_steps_total( $activity ) { if ( ( !empty( $activity ) ) && ( property_exists( $activity, 'activity_meta' ) ) && ( isset( $activity->activity_meta['steps_total'] ) ) ) { return intval($activity->activity_meta['steps_total']); } } /** * @param $activity * * @return array|null|WP_Post */ function get_activity_course( $activity ) { if ( ( isset( $activity->activity_course_id ) ) && ( !empty( $activity->activity_course_id ) ) ) { $course_id = intval( $activity->activity_course_id ); } else { $course_id = learndash_get_course_id( $activity->post_id ); } if ( !empty( $course_id ) ) { $course = get_post( $course_id ); if ( ( $course ) && ( $course instanceof WP_Post ) ) { return $course; } } } /** * @param $activity * * @return bool */ function quiz_activity_is_pending( $activity ) { if ( ( !empty( $activity ) ) && ( property_exists( $activity, 'activity_meta' ) ) ) { if ( ( isset( $activity->activity_meta['has_graded'] ) ) && ( true === $activity->activity_meta['has_graded'] ) && ( true === LD_QuizPro::quiz_attempt_has_ungraded_question( $activity->activity_meta ) ) ) { return true; } } return false; } /** * @param $activity * * @return bool */ function quiz_activity_is_passing( $activity ) { if ( ( !empty( $activity ) ) && ( property_exists( $activity, 'activity_meta' ) ) ) { if ( isset( $activity->activity_meta['pass'] ) ) { return (bool) $activity->activity_meta['pass']; } } return false; } /** * @param $activity * * @return mixed */ function quiz_activity_score( $activity ) { if ( ( !empty( $activity ) ) && ( property_exists( $activity, 'activity_meta' ) ) ) { if ( isset( $activity->activity_meta['score'] ) ) { return $activity->activity_meta['score']; } } } /** * @param $activity * * @return mixed */ function quiz_activity_total_points( $activity ) { if ( ( !empty( $activity ) ) && ( property_exists( $activity, 'activity_meta' ) ) ) { if ( isset( $activity->activity_meta['total_points'] ) ) { return intval($activity->activity_meta['total_points']); } } } /** * @param $activity * * @return mixed */ function quiz_activity_awarded_points( $activity ) { if ( ( !empty( $activity ) ) && ( property_exists( $activity, 'activity_meta' ) ) ) { if ( isset( $activity->activity_meta['points'] ) ) { return intval($activity->activity_meta['points']); } } } /** * @param $activity * * @return int */ function quiz_activity_points_percentage( $activity ) { $awarded_points = intval( $this->quiz_activity_awarded_points( $activity ) ); $total_points = intval( $this->quiz_activity_total_points( $activity ) ); if ( ( !empty( $awarded_points ) ) && ( !empty( $total_points ) ) ) { return round( 100 * ( intval( $awarded_points ) / intval( $total_points ) ) ); } } /** * @param $activity * * @return mixed */ function quiz_activity_total_score( $activity ) { if ( ( !empty( $activity ) ) && ( property_exists( $activity, 'activity_meta' ) ) ) { if ( isset( $activity->activity_meta['count'] ) ) { return intval($activity->activity_meta['count']); } } } /** * @param $activity * * @return mixed */ function quiz_activity_awarded_score( $activity ) { if ( ( !empty( $activity ) ) && ( property_exists( $activity, 'activity_meta' ) ) ) { if ( isset( $activity->activity_meta['score'] ) ) { return intval($activity->activity_meta['score']); } } } /** * @param $activity * * @return int */ function quiz_activity_score_percentage( $activity ) { $awarded_score = intval( $this->quiz_activity_awarded_score( $activity ) ); $total_score = intval( $this->quiz_activity_total_score( $activity ) ); if ( ( !empty( $awarded_score ) ) && ( !empty( $total_score ) ) ) { return round( 100 * ( intval( $awarded_score ) / intval( $total_score ) ) ); } } function get_quiz_scoring( $activity ) { return null; } function get_quiz_statistics_link( $activity ) { $stats_url = ''; if ( ( $activity->user_id == get_current_user_id() ) || ( learndash_is_admin_user() ) || ( learndash_is_group_leader_user() ) ) { if ( ( isset( $activity->activity_meta['statistic_ref_id'] ) ) && ( !empty( $activity->activity_meta['statistic_ref_id'] ) ) ) { /** * @since 2.3 * See snippet on use of this filter https://bitbucket.org/snippets/learndash/5o78q */ if ( apply_filters( 'show_user_profile_quiz_statistics', get_post_meta( $activity->activity_meta['quiz'], '_viewProfileStatistics', true ), $activity->user_id, $activity->activity_meta, 'learndash-propanel-activity' ) ) { $stats_url = '
'. __('Statistics', 'ld_propanel') .''; } } } return $stats_url; } } } PKi<\W) uninstall.phpnuW+A $role_info ) { $role = get_role( $role_name ); if ( ( $role ) && ( $role instanceof WP_Role ) ) { $role->remove_cap( 'propanel_widgets' ); } } } PKi<\=>81templates/ld-propanel-activity-rows-shortcode.phpnuW+A <?php _e('LearnDash ProPanel', 'ld_propanel' ); ?>

PKi<\JG621templates/ld-propanel-reporting-choose-filter.phpnuW+A
PKi<\?$templates/_ld-propanel-reporting.phpnuW+A
PKi<\1].templates/ld-propanel-reporting-no-results.phpnuW+A PKi<\ Aݡkk#templates/ld-propanel-full-page.cssnuW+A*, *:before, *:after { -moz-box-sizing: border-box; -webkit-box-sizing: border-box; box-sizing: border-box; } body { margin: 0; } .columnsContainer, footer, header { position: relative; margin: .5em; } .leftColumn, .rightColumn, footer, header { border: 1px solid #ccc; padding: 1.25em; } .leftColumn { margin-bottom: .5em; } .nav { list-style: none; margin-left: 0; margin-bottom: 0; padding-left: 0; } .nav > li, .nav > li > a { display: inline-block; *display: inline; zoom: 1; } .inline-items { margin-top: 0; } .inline-items li { margin-left: 0; border-left: 1px solid black; padding-left: 10px; padding-right: 10px; } .inline-items li:first-child { margin-left: 0; border: none; padding-left: 0; padding-right: 10px; } .inline-items li:last-child { padding-right: 0; } /* MEDIA QUERIES */ @media screen and (min-width: 47.5em ) { .leftColumn { margin-right: 29.5em; } .rightColumn { position: absolute; top: 0; right: 0; width: 28.75em; } } /* The following is general styles */ body { font-family: -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif; font-size: 13px; line-height: 1.4em; background: #FFFFFF none repeat scroll 0 0 !important; } span.screen-reader-text { display:none; } .ld-propanel-widget a { color: #000000; } /* .ld-propanel-widget-progress-chart .propanel-admin-row .col-1-2 { width: 100%; margin-bottom: 15px; } .ld-propanel-widget-progress-chart div.propanel-admin-row div.col-1-2:first-child div.title, .ld-propanel-widget-progress-chart div.propanel-admin-row div.col-1-2:last-child div.title { width: 100%; margin-left: 0; } .ld-propanel-widget-progress-chart div.propanel-admin-row div.col-1-2:first-child div.title:after { border: 0; } */ .ld-propanel-widget-activity .report-header .report-exports button { line-height: 24px; } .ld-propanel-widget-reporting table.ld-propanel-reporting-table-groups-widget th.ld-propanel-reporting-col-checkbox, .ld-propanel-widget-reporting table.ld-propanel-reporting-table-courses-widget th.ld-propanel-reporting-col-checkbox { min-width: 4%; width: 10px; } PKi<\r)templates/ld-propanel-reporting-pager.phpnuW+A

/ ()

PKi<\r55'templates/ld-propanel-activity-rows.phpnuW+A user_id ) ) { $user_link = get_edit_user_link( $activity->user_id ) ."#ld_course_info"; } else { $user_link = "#"; } if ( ( !empty( $activity->activity_completed ) ) && ( !empty( $activity->activity_started ) ) ) { $activity_diff_completed = learndash_get_activity_human_time_diff( $activity->activity_started, $activity->activity_completed, 1 ); } else { $activity_diff_completed = 0; } if ( !empty( $activity_diff_completed ) ) { $activity_abbr_label_completed = __('Completed Date (Duration)', 'ld_propanel'); } else { $activity_abbr_label_completed = __('Completed Date', 'ld_propanel'); } if ( !empty( $activity->activity_started ) ) { $activity_diff_started = learndash_get_activity_human_time_diff( $activity->activity_started, time(), 1 ); } else { $activity_diff_started = 0; } if ( !empty( $activity_diff_started ) ) { $activity_abbr_label_started = __('Started Date (Duration)', 'ld_propanel'); } else { $activity_abbr_label_started = __('Started Date', 'ld_propanel'); } ?> activity_type ) : ?>
user_display_name; ?> activity_completed ) ) { ?> activity_completed_formatted; if ( !empty( $activity_diff_completed ) ) { ?> ()
post_title; ?> "%s")', 'ld-propanel' ), get_the_title( $activity->post_id ) ), '', '', $activity->post_id ); ?>
get_activity_course( $activity ) ) : ?> ID ); ?> "%s")', 'ld-propanel' ), get_the_title( $course->ID ) ), '', '', $course->ID ); ?>
quiz_activity_is_pending( $activity ) ) : ?>
quiz_activity_is_passing( $activity ) ) ? esc_html__( 'Passed', 'ld_propanel' ) : esc_html__( 'Failed', 'ld_propanel' ); ?>get_quiz_statistics_link( $activity ); if ( !empty( $quiz_statistics_link ) ) { echo ' '. $quiz_statistics_link; } ?>
quiz_activity_score_percentage( $activity ), $this->quiz_activity_awarded_score( $activity ), $this->quiz_activity_total_score( $activity ) ); ?> quiz_activity_points_percentage( $activity ), $this->quiz_activity_awarded_points( $activity ), $this->quiz_activity_total_points( $activity ) ); ?>
activity_type ) : ?>
user_display_name; ?> activity_completed ) ) {?> activity_completed_formatted; if ( !empty( $activity_diff_completed ) ) { ?> ()
post_title; ?> "%s")', 'ld-propanel' ), get_the_title( $activity->post_id ) ), '', '', $activity->post_id ); ?>
activity_type ) : ?>
user_display_name; ?> activity_completed ) ) {?> activity_started_formatted; if ( !empty( $activity_diff_completed ) ) { ?> () activity_started ) ) { ?> activity_started_formatted; if ( !empty( $activity_diff_started ) ) { ?> ()
activity_type ) : ?>
user_display_name; ?> activity_completed ) ) {?> activity_completed_formatted; if ( !empty( $activity_diff_completed ) ) { ?> () activity_started ) ) { ?> activity_started_formatted; if ( !empty( $activity_diff_started ) ) { ?> ()
post_title; ?> "%s")', 'ld-propanel' ), get_the_title( $activity->post_id ) ), '', '', $activity->post_id ); ?>
get_activity_course( $activity ) ) : ?> ID ); ?> "%s")', 'ld-propanel' ), get_the_title( $course->ID ) ), '', '', $course->ID ); ?>
activity_type ) : ?>
user_display_name; ?> activity_completed ) ) { ?> activity_completed_formatted; if ( !empty( $activity_diff_completed ) ) { ?> () activity_started ) ) { ?> activity_started_formatted; if ( !empty( $activity_diff_started ) ) { ?> ()
post_title; ?> "%s")', 'ld-propanel' ), get_the_title( $activity->post_id ) ), '', '', $activity->post_id ); ?>
get_activity_course( $activity ) ) : ?> ID ); ?> "%s")', 'ld-propanel' ), get_the_title( $course->ID ) ), '', '', $course->ID ); ?>
activity_type ) ) : ?>
get_activity_course( $activity ) ) : ?> ID ); ?> "%s")', 'ld-propanel' ), get_the_title( $course->ID ) ), '', '', $course->ID ); ?>
PKj<\Bm>7templates/ld-propanel-activity-pagination-shortcode.phpnuW+A PKj<\(templates/ld-propanel-progress-chart.phpnuW+A
PKj<\RR-templates/ld-propanel-activity-pagination.phpnuW+A 0 ) { if ( $activities['pager']['current_page'] == 1 ) $pager_left_disabled = ' disabled="disabled" '; else $pager_left_disabled = ''; if ( $activities['pager']['current_page'] == $activities['pager']['total_pages'] ) $pager_right_disabled = ' disabled="disabled" '; else $pager_right_disabled = ''; ?>

/ ()

[ld_propanel widget="reporting"]'); ?>
PKj<\R+templates/ld-propanel-filtering-filters.phpnuW+A
filtering_widget->show_filters(); ?>

PKj<\@*templates/ld-propanel-filtering-emails.phpnuW+A PKj<\9 Qtemplates/reporting-filters/courses/ld-propanel-reporting-filter-course-table.phpnuW+A
filter_headers as $header_key => $header_label ) { switch( $header_key ) { case 'checkbox': ?>
PKj<\=u Otemplates/reporting-filters/courses/ld-propanel-reporting-filter-course-row.phpnuW+A user_id ) ) { $user_link = get_edit_user_link( $activity->user_id ) ."#ld_course_info"; } else { $user_link = "#"; } if ( current_user_can( 'edit_courses', $activity->post_id ) ) { $post_link = get_edit_post_link( $activity->post_id ) ."#ld_course_info"; } else { $post_link = "#"; } switch ( $header_key ) { case 'checkbox': ?>user_display_name ); ?>

user_email ); ?>

user_id; break; case 'progress': ?>
"> activity_status ) ) { $progress_percent = 0; $progress_label = __('Not Started', 'ld_propanel' ); $progress_label_style = 'font-size: 16px;'; } else if ( $activity->activity_status == false ) { $steps_completed = LearnDash_ProPanel_Activity::get_activity_steps_completed( $activity ); $steps_total = LearnDash_ProPanel_Activity::get_activity_steps_total( $activity ); $progress_percent = round( 100 * ( intval( $steps_completed ) / intval( $steps_total ) ) ); $progress_label = $progress_percent .'%'; $progress_label_style = ''; } else if ( $activity->activity_status == true ) { $progress_percent = 100; $progress_label = $progress_percent .'%'; } ?>
activity_completed) ); break; default: break; } PKj<\=33Ktemplates/reporting-filters/courses/ld-propanel-reporting-filter-course.phpnuW+Afilter_key = 'courses'; $this->filter_search_placeholder = __( 'Search Users', 'ld_propanel' ); $this->filter_template_table = 'reporting-filters/courses/ld-propanel-reporting-filter-course-table.php'; $this->filter_template_row = 'reporting-filters/courses/ld-propanel-reporting-filter-course-row.php'; add_filter( 'ld_propanel_filtering_register_filters', array( $this, 'filter_register' ), 20 ); add_filter( 'ld_propanel_reporting_post_args', array( $this, 'filter_post_args' ), 20, 2 ); add_filter( 'ld_propanel_reporting_activity_args', array( $this, 'filter_activity_args' ), 20, 3 ); } public function filter_post_args( $post_args = array(), $_get = array() ) { if ( ( isset( $_get['filters'][$this->filter_key] ) ) && ( !empty( $_get['filters'][$this->filter_key] ) ) ) { if ( is_string( $_get['filters'][$this->filter_key] ) ) { $post_args['filters'][$this->filter_key] = explode(',', $_get['filters'][$this->filter_key] ); } else { $post_args['filters'][$this->filter_key] = $_get['filters'][$this->filter_key]; } $post_args['filters'][$this->filter_key] = array_map( 'intval', $post_args['filters'][$this->filter_key] ); } return $post_args; } public function filter_activity_args( $activity_args = array(), $post_data = array(), $_get = array() ) { if ( !empty( $activity_args ) ) { if ( ( isset( $post_data['filters'][$this->filter_key] ) ) && ( !empty( $post_data['filters'][$this->filter_key] ) ) ) { if ( ( !isset( $activity_args['post_ids'] ) ) || ( empty( $activity_args['post_ids'] ) ) ) { $activity_args['post_ids'] = $post_data['filters'][$this->filter_key]; } } else if ( ( !isset( $activity_args['post_ids'] ) ) || ( empty( $activity_args['post_ids'] ) ) ) { if ( learndash_is_admin_user( get_current_user_id() ) ) { if ( ( empty( $activity_args['post_ids'] ) ) && ( !empty( $post_data['filters']['users'] ) ) ) { $users_course_ids = array(); foreach( $post_data['filters']['users'] as $user_id ) { $course_ids = learndash_user_get_enrolled_courses( $user_id, true ); if ( !empty( $course_ids ) ) { $users_course_ids = array_merge( $users_course_ids, $course_ids ); } } if ( !empty( $users_course_ids ) ) { $activity_args['post_ids'] = $users_course_ids; } else { $activity_args = array(); } } } else if ( learndash_is_group_leader_user( get_current_user_id() ) ) { // Check if the this groups leader is a leader of this course $group_ids = learndash_get_administrators_group_ids( get_current_user_id() ); if ( !empty( $group_ids ) ) { $course_ids = array(); foreach ( $group_ids as $group_id ) { $group_course_ids = learndash_group_enrolled_courses( $group_id ); if ( !empty( $group_course_ids ) ) { $course_ids = array_merge( $course_ids, $group_course_ids ); } } if ( !empty( $course_ids ) ) { $activity_args['post_ids'] = $course_ids; } else { $activity_args = array(); } } } else { $course_ids = learndash_user_get_enrolled_courses( get_current_user_id() ); if ( !empty( $course_ids ) ) { $activity_args['post_ids'] = $course_ids; } else { $activity_args = array(); } } } } return $activity_args; } public function filter_display() { return ''; } function filter_search() { $courses_data = array( 'total' => 0, 'items' => array() ); $course_query_args = array( 'post_type' => 'sfwd-courses', 'post_status' => 'publish', 'orderby' => 'post_title', 'order' => 'ASC', //'s' => esc_attr( $_GET['search'] ), 'posts_per_page' => 10, 'offset' => ( intval( $_GET['page'] ) - 1 ) * 10, 'paged' => intval( $_GET['page'] ), ); if ( ( isset( $_GET['search'] ) ) && ( !empty( $_GET['search'] ) ) ) { $course_query_args['s'] = esc_attr( $_GET['search'] ); } if ( learndash_is_admin_user( get_current_user_id() ) ) { $groups_course_ids = array(); if ( ( isset( $this->post_data['filters']['groups'] ) ) && ( !empty( $this->post_data['filters']['groups'] ) ) ) { foreach ( $this->post_data['filters']['groups'] as $group_id ) { $course_ids = learndash_group_enrolled_courses( $group_id ); if ( !empty( $course_ids ) ) { $groups_course_ids = array_merge( $groups_course_ids, $course_ids ); } } if ( empty( $groups_course_ids ) ) { $course_query_args = array(); } } $users_course_ids = array(); if ( ( isset( $this->post_data['filters']['users'] ) ) && ( !empty( $this->post_data['filters']['users'] ) ) ) { foreach ( $this->post_data['filters']['users'] as $user_id ) { $course_ids = learndash_user_get_enrolled_courses( $user_id ); if ( !empty( $course_ids ) ) { $users_course_ids = array_merge( $users_course_ids, $course_ids ); } if ( empty( $users_course_ids ) ) { $course_query_args = array(); } } } if ( ( !empty( $groups_course_ids ) ) && ( !empty( $users_course_ids ) ) ) { $course_query_args['post__in'] = array_intersect( $groups_course_ids, $users_course_ids ); } else if ( !empty( $groups_course_ids ) ) { $course_query_args['post__in'] = $groups_course_ids; } else if ( !empty( $users_course_ids ) ) { $course_query_args['post__in'] = $users_course_ids; } } else if ( learndash_is_group_leader_user( get_current_user_id() ) ) { $groups_course_ids = array(); if ( ( isset( $this->post_data['filters']['groups'] ) ) && ( !empty( $this->post_data['filters']['groups'] ) ) ) { foreach ( $this->post_data['filters']['groups'] as $group_id ) { $course_ids = learndash_group_enrolled_courses( $group_id ); if ( !empty( $course_ids ) ) { $groups_course_ids = array_merge( $groups_course_ids, $course_ids ); } } if ( empty( $groups_course_ids ) ) { $course_query_args = array(); } } $users_course_ids = array(); if ( ( isset( $this->post_data['filters']['users'] ) ) && ( !empty( $this->post_data['filters']['users'] ) ) ) { foreach ( $this->post_data['filters']['users'] as $user_id ) { $course_ids = learndash_user_get_enrolled_courses( $user_id ); if ( !empty( $course_ids ) ) { $users_course_ids = array_merge( $users_course_ids, $course_ids ); } } if ( empty( $users_course_ids ) ) { $course_query_args = array(); } } if ( ( !empty( $groups_course_ids ) ) && ( !empty( $users_course_ids ) ) ) { $course_query_args['post__in'] = array_intersect( $groups_course_ids, $users_course_ids ); } else if ( !empty( $groups_course_ids ) ) { $course_query_args['post__in'] = $groups_course_ids; } else if ( !empty( $users_course_ids ) ) { $course_query_args['post__in'] = $users_course_ids; } else { // If we don't have any filtered by group courses. Then grab all the courses the GL can manage. $group_ids = learndash_get_administrators_group_ids( get_current_user_id() ); if ( !empty( $group_ids ) ) { $course_ids = learndash_get_groups_courses_ids( get_current_user_id(), $group_ids ); if ( !empty( $course_ids ) ) { $course_query_args['post__in'] = $course_ids; } else { $course_query_args = array(); } } else { $course_query_args = array(); } } } else { $user_course_ids = learndash_user_get_enrolled_courses( get_current_user_id() ); if ( !empty( $user_course_ids ) ) $course_query_args['post__in'] = $user_course_ids; else $course_query_args = array(); } if ( !empty( $course_query_args ) ) { $course_query = new WP_Query( $course_query_args ); if ( $course_query->have_posts() ) { $courses_data['total'] = intval( $course_query->found_posts ); foreach ( $course_query->posts as $course ) { $courses_data['items'][] = array( 'id' => $course->ID, 'text' => strip_tags( $course->post_title ), ); } } } /** * Filter courses returned in search */ return apply_filters( 'ld_propanel_course_search', apply_filters( 'ld_propanel_course_search', $courses_data ) ); } function filter_build_table() { $this->filter_table_headers(); $container_type = $_GET['container_type']; ob_start(); include ld_propanel_get_template( $this->filter_template_table ); return ob_get_clean(); } function filter_table_headers() { if ( 'widget' == $this->post_data['container_type'] ) { $this->filter_headers = array( 'checkbox' => __( 'Checkbox', 'ld_propanel' ), 'user' => __( 'User', 'ld_propanel' ), 'progress' => __( 'Progress', 'ld_propanel' ) ); } else if ( 'full' == $this->post_data['container_type'] ) { $this->filter_headers = array( 'checkbox' => __( 'Checkbox', 'ld_propanel' ), 'user_id' => __( 'User ID', 'ld_propanel' ), 'user' => __( 'User', 'ld_propanel' ), 'progress' => __( 'Progress', 'ld_propanel' ), 'last_update' => __( 'Completed On', 'ld_propanel' ) ); } else if ( 'shortcode' == $this->post_data['container_type'] ) { $this->filter_headers = array( 'user' => __( 'User', 'ld_propanel' ), 'progress' => __( 'Progress', 'ld_propanel' ) ); } return apply_filters('ld-propanel-reporting-headers', $this->filter_headers, $this->filter_key ); } function filter_result_rows( $course_id ) { // Set the initial response. In case all following queries fail. $response = array( 'total_rows' => 0, 'rows_html' => '', //'user_ids' => array(), 'total_users' => 0 ); $this->filter_table_headers(); $activity_query_defaults = array( 'post_types' => 'sfwd-courses', 'activity_types' => 'course', 'activity_status' => '', 'orderby_order' => 'users.display_name, posts.post_title', // 'date_format' => 'F j, Y H:i:s', ); $this->activity_query_args = wp_parse_args( $this->activity_query_args, $activity_query_defaults ); $this->activity_query_args = ld_propanel_load_activity_query_args( $this->activity_query_args, $this->post_data ); if ( !empty( $this->activity_query_args ) ) { $this->activity_query_args = ld_propanel_adjust_admin_users( $this->activity_query_args ); $this->activity_query_args = ld_propanel_convert_fewer_users( $this->activity_query_args ); /** * Get the goodies */ //error_log('course: activity_query_args
'. print_r($this->activity_query_args, true) .'
'); $activities = learndash_reports_get_activity( $this->activity_query_args ); //error_log('course: activities
'. print_r($activities, true) .'
'); if ( ( isset( $activities['results'] ) ) && ( !empty( $activities['results'] ) ) ) { if ( ( isset( $activities['pager'] ) ) && ( !empty( $activities['pager'] ) ) ) { $response['total_rows'] = $activities['pager']['total_items']; $response['total_users'] = $activities['pager']['total_items']; $activities['pager']['current_page'] = $this->activity_query_args['paged']; $response[ 'pager' ] = $activities['pager']; } foreach ( $activities['results'] as $activity ) { //$response['user_ids'][$activity->user_id] = $activity->user_id; $row = array(); $row_html = ''; foreach ( $this->filter_headers as $header_key => $header_label ) { ob_start(); include ld_propanel_get_template( $this->filter_template_row ); $row = ob_get_clean(); $row_html .= ''. $row .''; } $row_html .= ''; $response['rows_html'] .= $row_html; } } } if ( empty( $response['rows_html'] ) ) { ob_start(); include ld_propanel_get_template( 'ld-propanel-reporting-no-results.php' ); $response['rows_html'] = ob_get_clean(); } if ( !empty( $response['user_ids'] ) ) $response['user_ids'] = array_values( $response['user_ids'] ); return $response; } // End of functions } } add_action( 'learndash_propanel_filtering_init', function() { new LearnDash_ProPanel_Reporting_Filter_Courses(); }); PKj<\#& Jtemplates/reporting-filters/status/ld-propanel-reporting-filter-status.phpnuW+Afilter_key = 'courseStatus'; add_filter( 'ld_propanel_filtering_register_filters', array( $this, 'filter_register' ), 30 ); } public function filter_post_args( $post_args_filters = array() ) { if ( ( isset( $_GET['filters'][$this->filter_key] ) ) && ( !empty( $_GET['filters'][$this->filter_key] ) ) ) { if ( is_string( $_GET['filters'][$this->filter_key] ) ) { $post_args_filters[$this->filter_key][] = esc_attr( $_GET['filters'][$this->filter_key] ); } else if (is_array( $_GET['filters'][$this->filter_key] ) ) { foreach( $_GET['filters'][$this->filter_key] as $idx => $val ) { $post_args_filters[$this->filter_key][$idx] = esc_attr( $val ); } } } return $post_args_filters; } public function filter_display() { //return ''; return ''; } function filter_search() { $statuses = array( array( 'id' => 'not-started', 'text' => esc_html__( 'Not Started', 'ld_propanel' ), ), array( 'id' => 'in-progress', 'text' => esc_html__( 'In Progress', 'ld_propanel' ), ), array( 'id' => 'completed', 'text' => esc_html__( 'Completed', 'ld_propanel' ), ) ); return array( 'total' => count( $statuses ), 'items' => $statuses ); } // End of functions } } add_action( 'learndash_propanel_filtering_init', function() { new LearnDash_ProPanel_Reporting_Filter_Status(); }); PKj<\+SsX X Otemplates/reporting-filters/groups/ld-propanel-reporting-filter-group-table.phpnuW+A filter_table_headers(); if ( !empty( $this->filter_headers ) ) { ob_start(); include ld_propanel_get_template( 'ld-propanel-reporting-pager.php' ); $report_pager_html = ob_get_clean(); ob_start(); include ld_propanel_get_template( 'ld-propanel-reporting-search.php' ); $report_search_html = ob_get_clean(); ob_start(); include ld_propanel_get_template( 'ld-propanel-reporting-download-button.php' ); $report_download_button_html = ob_get_clean(); ?>
filter_headers as $header_key => $header_label ) { switch( $header_key ) { case 'checkbox': ?>
user_id ) ) { $user_link = get_edit_user_link( $activity->user_id ) ."#ld_course_info"; } else { $user_link = "#"; } if ( current_user_can( 'edit_courses', $activity->post_id ) ) { $post_link = get_edit_post_link( $activity->post_id ) ."#ld_course_info"; } else { $post_link = "#"; } switch ( $header_key ) { case 'checkbox': ?>post_id; break; case 'course': if ( $this->post_data['container_type'] == 'full' ) { echo esc_html( $activity->post_title ); } else { ?> post_title ); ?>

user_email ); ?>

user_id; break; case 'user': ?>

user_email ); ?>

">activity_status ) ) { $progress_percent = 0; $progress_label = __('Not Started', 'ld_propanel' ); $progress_label_style = 'font-size: 16px;'; } else if ( $activity->activity_status == false ) { $steps_completed = LearnDash_ProPanel_Activity::get_activity_steps_completed( $activity ); $steps_total = LearnDash_ProPanel_Activity::get_activity_steps_total( $activity ); $progress_percent = round( 100 * ( intval( $steps_completed ) / intval( $steps_total ) ) ); $progress_label = $progress_percent .'%'; $progress_label_style = ''; } else if ( $activity->activity_status == true ) { $progress_percent = 100; $progress_label = $progress_percent .'%'; } ?>
activity_completed) ); break; default: break; }PKj<\7Ӟ@7@7Itemplates/reporting-filters/groups/ld-propanel-reporting-filter-group.phpnuW+Afilter_key = 'groups'; $this->filter_search_placeholder = __( 'Search Groups', 'ld_propanel' ); // Path relative to the plugin templates directory $this->filter_template_table = 'reporting-filters/groups/ld-propanel-reporting-filter-group-table.php'; $this->filter_template_row = 'reporting-filters/groups/ld-propanel-reporting-filter-group-row.php'; add_filter( 'ld_propanel_filtering_register_filters', array( $this, 'filter_register' ), 10 ); add_filter( 'ld_propanel_reporting_post_args', array( $this, 'filter_post_args' ), 10, 2 ); add_filter( 'ld_propanel_reporting_activity_args', array( $this, 'filter_activity_args' ), 10, 3 ); } public function filter_post_args( $post_args = array(), $_get = array() ) { if ( ( isset( $_get['filters'][$this->filter_key] ) ) && ( !empty( $_get['filters'][$this->filter_key] ) ) ) { if ( is_string( $_get['filters'][$this->filter_key] ) ) { $post_args['filters'][$this->filter_key] = explode(',', $_get['filters'][$this->filter_key] ); } else { $post_args['filters'][$this->filter_key] = $_get['filters'][$this->filter_key]; } $post_args['filters'][$this->filter_key] = array_map( 'intval', $post_args['filters'][$this->filter_key] ); } return $post_args; } public function filter_activity_args( $activity_args = array(), $post_data = array(), $_get = array() ) { if ( !empty( $activity_args ) ) { if ( ( isset( $post_data['filters'][$this->filter_key] ) ) && ( !empty( $post_data['filters'][$this->filter_key] ) ) ) { if ( ( !isset( $activity_args['post_ids'] ) ) || ( empty( $activity_args['post_ids'] ) ) ) { $group_course_ids = array(); foreach( $post_data['filters'][$this->filter_key] as $group_id ) { $course_ids = learndash_group_enrolled_courses( $group_id ); if ( !empty( $course_ids ) ) { $group_course_ids = array_merge( $group_course_ids, $course_ids ); } } if ( !empty( $group_course_ids ) ) { if ( ( isset( $post_data['filters']['courses'] ) ) && ( !empty( $post_data['filters']['courses'] ) ) ) { $activity_args['post_ids'] = array_intersect( $group_course_ids, $post_data['filters']['courses'] ); } else { $activity_args['post_ids'] = $group_course_ids; } } else { // If the group has no courses, abort and return $activity_args = array(); return $activity_args; } } if ( ( !isset( $activity_args['user_ids'] ) ) || ( empty( $activity_args['user_ids'] ) ) ) { if ( ( isset( $post_data['filters']['users'] ) ) && ( !empty( $post_data['filters']['users'] ) ) ) { $activity_args['user_ids'] = $post_data['filters']['users']; $activity_args['user_ids_action'] = 'IN'; } else { $group_user_ids = array(); foreach( $post_data['filters'][$this->filter_key] as $group_id ) { $user_ids = learndash_get_groups_user_ids( $group_id ); if ( !empty( $user_ids ) ) { $group_user_ids = array_merge( $group_user_ids, $user_ids ); } } if ( !empty( $group_user_ids ) ) { $activity_args['user_ids'] = $group_user_ids; $activity_args['user_ids_action'] = 'IN'; } else { // If the group has no users, abort and return $activity_args = array(); return $activity_args; } } } } } return $activity_args; } public function filter_display() { if ( learndash_is_admin_user( get_current_user_id() ) ) { if ( !ld_propanel_count_post_type( 'groups' ) ) return; } else if ( learndash_is_group_leader_user( get_current_user_id() ) ) { $leader_group_ids = learndash_get_administrators_group_ids( get_current_user_id() ); if ( empty( $leader_group_ids ) ) return; } else { $use_group_ids = learndash_get_users_group_ids( get_current_user_id() ); if ( empty( $use_group_ids ) ) return; } return ''; } public function filter_search() { $groups_data = array( 'total' => 0, 'items' => array() ); $group_query_args = array( 'post_type' => 'groups', 'post_status' => 'publish', 'orderby' => 'post_title', 'order' => 'ASC', 'posts_per_page' => 10, 'paged' => intval( $_GET['page'] ), ); if ( ( isset( $_GET['search'] ) ) && ( !empty( $_GET['search'] ) ) ) { $group_query_args['s'] = esc_attr( $_GET['search'] ); } if ( learndash_is_admin_user( get_current_user_id() ) ) { $courses_group_ids = array(); if ( !empty( $this->post_data['filters']['courses'] ) ) { foreach( $this->post_data['filters']['courses'] as $course_id ) { $group_ids = learndash_get_course_groups( $course_id ); if ( !empty( $group_ids ) ) { $courses_group_ids = array_merge( $courses_group_ids, $group_ids ); } } } $users_group_ids = array(); if ( !empty( $this->post_data['filters']['users'] ) ) { foreach( $this->post_data['filters']['users'] as $user_id ) { $group_ids = learndash_get_users_group_ids( $user_id, true ); if ( !empty( $group_ids ) ) { $users_group_ids = array_merge( $users_group_ids, $group_ids ); } } } if ( ( !empty( $this->post_data['filters']['courses'] ) ) && ( !empty( $this->post_data['filters']['users'] ) ) ) { if ( ( !empty( $courses_group_ids ) ) && ( !empty( $users_group_ids ) ) ) { $group_query_args['post__in'] = array_intersect( $courses_group_ids, $users_group_ids ); } else { $group_query_args = array(); } } else if ( !empty( $this->post_data['filters']['courses'] ) ) { if ( !empty( $courses_group_ids ) ) { $group_query_args['post__in'] = $courses_group_ids; } else { $group_query_args = array(); } } else if ( !empty( $this->post_data['filters']['users'] ) ) { if ( !empty( $users_group_ids ) ) { $group_query_args['post__in'] = $users_group_ids; } else { $group_query_args = array(); } } } else if ( learndash_is_group_leader_user( get_current_user_id() ) ) { $admin_group_ids = learndash_get_administrators_group_ids( get_current_user_id() ); if ( !empty( $admin_group_ids ) ) { $search_group_ids = array(); if ( !empty( $this->post_data['filters']['courses'] ) ) { foreach( $this->post_data['filters']['courses'] as $course_id ) { $group_ids = learndash_get_course_groups( $course_id ); if ( !empty( $group_ids ) ) { $group_ids = array_intersect( $group_ids, $admin_group_ids ); if ( !empty( $group_ids ) ) { $search_group_ids = array_merge( $search_group_ids, $group_ids ); } } } } if ( !empty( $this->post_data['filters']['users'] ) ) { foreach( $this->post_data['filters']['users'] as $user_id ) { $group_ids = learndash_get_users_group_ids( $user_id, true ); if ( !empty( $group_ids ) ) { $search_group_ids = array_merge( $search_group_ids, $group_ids ); } } } if ( !empty( $search_group_ids ) ) $group_query_args['post__in'] = $search_group_ids; else $group_query_args['post__in'] = $admin_group_ids; } else { // If group leader and no defined groups then clear out query array so they get no results. $group_query_args = array(); } } else { $user_group_ids = learndash_get_users_group_ids( get_current_user_id(), true ); if ( !empty( $user_group_ids ) ) { if ( !empty( $this->post_data['filters']['courses'] ) ) { $course_group_ids = array(); foreach( $this->post_data['filters']['courses'] as $course_id ) { $group_ids = learndash_get_course_groups( $course_id ); if ( !empty( $group_ids ) ) { $course_group_ids = array_merge( $course_group_ids, $group_ids ); } } if ( !empty( $course_group_ids ) ) { $user_group_ids = array_intersect( $user_group_ids, $course_group_ids ); } } if ( !empty( $user_group_ids ) ) $group_query_args['post__in'] = $user_group_ids; else $group_query_args = array(); } else { // If group leader and no defined groups then clear out query array so they get no results. $group_query_args = array(); } } if ( !empty( $group_query_args ) ) { $group_query = new WP_Query( $group_query_args ); if ( $group_query->have_posts() ) { $groups_data['total'] = intval( $group_query->found_posts ); foreach ( $group_query->posts as $group ) { $groups_data['items'][] = array( 'id' => $group->ID, 'text' => strip_tags( $group->post_title ), ); } } } /** * Filter courses returned in search */ return apply_filters( 'ld_propanel_filter_search', $groups_data, $this->filter_key, $group_query_args ); } function filter_build_table() { $this->filter_table_headers(); $container_type = $_GET['container_type']; ob_start(); include ld_propanel_get_template( $this->filter_template_table ); return ob_get_clean(); } function filter_table_headers() { $this->filter_headers = array(); if ( 'widget' == $this->post_data['container_type'] ) { $this->filter_headers = array( 'checkbox' => __( 'Checkbox', 'ld_propanel' ), 'course' => __( 'Course', 'ld_propanel' ), 'progress' => __( 'Progress', 'ld_propanel' ) ); } else if ( 'full' == $this->post_data['container_type'] ) { $this->filter_headers = array( 'checkbox' => __( 'Checkbox', 'ld_propanel' ), 'course_id' => __( 'C-ID', 'ld_propanel' ), 'course' => __( 'Course', 'ld_propanel' ), 'user_id' => __( 'U-ID', 'ld_propanel' ), 'user' => __( 'User', 'ld_propanel' ), 'progress' => __( 'Progress', 'ld_propanel' ), 'last_update' => __( 'Completed On', 'ld_propanel' ) ); } else if ( 'shortcode' == $this->post_data['container_type'] ) { $this->filter_headers = array( 'course' => __( 'Course', 'ld_propanel' ), 'progress' => __( 'Progress', 'ld_propanel' ) ); } return apply_filters('ld-propanel-reporting-headers', $this->filter_headers, $this->filter_key ); } function filter_result_rows( $group_id = 0 ) { // Set the initial response. In case all following queries fail. $response = array( 'rows_html' => '', //'total_users' => 0 ); $this->filter_table_headers(); $activity_query_defaults = array( 'post_types' => 'sfwd-courses', 'activity_types' => 'course', 'activity_status' => '', 'orderby_order' => 'posts.post_title, users.display_name', ); $this->activity_query_args = wp_parse_args( $this->activity_query_args, $activity_query_defaults ); //$this->activity_query_args = apply_filters( 'ld_propanel_reporting_activity_args', $this->activity_query_args, $this->post_data ); $this->activity_query_args = ld_propanel_load_activity_query_args( $this->activity_query_args, $this->post_data ); //error_log('activity_query_args
'. print_r($this->activity_query_args, true) .'
'); if ( !empty( $this->activity_query_args ) ) { //if ( !isset( $this->activity_query_args['user_ids_action'] ) ) { // $this->activity_args['user_ids_action'] = 'IN'; //} //$response['total_users'] = count( $this->activity_query_args['user_ids'] ); $this->activity_query_args = ld_propanel_adjust_admin_users( $this->activity_query_args ); //$response['total_users'] = count( $this->activity_query_args['user_ids'] ); //$response['total_users'] = 'all'; $this->activity_query_args = ld_propanel_convert_fewer_users( $this->activity_query_args ); /** * Get the goodies */ //error_log('group: activity_query_args
'. print_r($this->activity_query_args, true) .'
'); $activities = learndash_reports_get_activity( $this->activity_query_args ); //error_log('group: activities
'. print_r($activities, true) .'
'); if ( ( isset( $activities['results'] ) ) && ( !empty( $activities['results'] ) ) ) { if ( ( isset( $activities['pager'] ) ) && ( !empty( $activities['pager'] ) ) ) { //$response['total_rows'] = $activities['pager']['total_items']; $activities['pager']['current_page'] = $this->activity_query_args['paged']; $response[ 'pager' ] = $activities['pager']; } foreach ( $activities['results'] as $idx => $activity ) { $row = array(); $row_html = ''; foreach ( $this->filter_headers as $header_key => $header_label ) { ob_start(); include ld_propanel_get_template( $this->filter_template_row ); $row = ob_get_clean(); $row_html .= ''. $row .''; } $row_html .= ''; $response['rows_html'] .= $row_html; } } } if ( empty( $response['rows_html'] ) ) { ob_start(); include ld_propanel_get_template( 'ld-propanel-reporting-no-results.php' ); $response['rows_html'] = ob_get_clean(); } return $response; } // End of functions } } add_action( 'learndash_propanel_filtering_init', function() { new LearnDash_ProPanel_Reporting_Filter_Groups(); }); PKj<\%d C Mtemplates/reporting-filters/users/ld-propanel-reporting-filter-user-table.phpnuW+A filter_headers ) ) { ob_start(); include ld_propanel_get_template( 'ld-propanel-reporting-pager.php' ); $report_pager_html = ob_get_clean(); ob_start(); include ld_propanel_get_template( 'ld-propanel-reporting-search.php' ); $report_search_html = ob_get_clean(); ob_start(); include ld_propanel_get_template( 'ld-propanel-reporting-download-button.php' ); $report_download_button_html = ob_get_clean(); ?>
filter_headers as $header_key => $header_label ) { switch( $header_key ) { case 'course_id': ?>
filter_key = 'users'; $this->filter_search_placeholder = sprintf( _x( 'Search %s', 'Search Courses', 'ld_propanel' ), LearnDash_Custom_Label::get_label( 'courses' ) ); // Path relative to the plugin templates directory $this->filter_template_table = 'reporting-filters/users/ld-propanel-reporting-filter-user-table.php'; $this->filter_template_row = 'reporting-filters/users/ld-propanel-reporting-filter-user-row.php'; add_filter( 'ld_propanel_filtering_register_filters', array( $this, 'filter_register' ), 30 ); add_filter( 'ld_propanel_reporting_post_args', array( $this, 'filter_post_args' ), 30, 2 ); add_filter( 'ld_propanel_reporting_activity_args', array( $this, 'filter_activity_args' ), 30, 3 ); } public function filter_post_args( $post_args = array(), $_get = array() ) { if ( ( isset( $_get['filters'][$this->filter_key] ) ) && ( !empty( $_get['filters'][$this->filter_key] ) ) ) { if ( is_string( $_get['filters'][$this->filter_key] ) ) { $post_args['filters'][$this->filter_key] = explode(',', $_get['filters'][$this->filter_key] ); } else { $post_args['filters'][$this->filter_key] = $_get['filters'][$this->filter_key]; } $post_args['filters'][$this->filter_key] = array_map( 'intval', $post_args['filters'][$this->filter_key] ); } if ( learndash_is_admin_user( get_current_user_id() ) ) { } else if ( learndash_is_group_leader_user( get_current_user_id() ) ) { } else { $post_args['filters'][$this->filter_key] = array( get_current_user_id() ); if ( ( isset( $post_args['template'] ) ) && ( ( $post_args['template'] == 'course-reporting' ) || ( $post_args['template'] == 'group-reporting' ) ) ) { $post_args['template'] = 'user-reporting'; } if ( ( isset( $post_args['filters']['type'] ) ) && ( ( $post_args['filters']['type'] == 'course' ) || ( $post_args['filters']['type'] == 'group' ) ) ) { $post_args['filters']['type'] = 'user'; } } return $post_args; } public function filter_activity_args( $activity_args = array(), $post_data = array(), $_get = array() ) { if ( !empty( $activity_args ) ) { if ( ( isset( $post_data['filters'][$this->filter_key] ) ) && ( !empty( $post_data['filters'][$this->filter_key] ) ) ) { $activity_args['user_ids'] = $post_data['filters'][$this->filter_key]; } else if ( ( !isset( $activity_args['user_ids'] ) ) || ( empty( $activity_args['user_ids'] ) ) ){ if ( learndash_is_admin_user( get_current_user_id() ) ) { if ( ( !isset( $activity_args['user_ids'] ) ) || ( empty( $activity_args['user_ids'] ) ) ) { //$exclude_admin_users = ld_propanel_exclude_admin_users(); if ( !empty( $activity_args['post_ids'] ) ) { $course_user_ids = array(); $course_has_open = false; foreach( $activity_args['post_ids'] as $course_id ) { if ( 'open' === learndash_get_setting( $course_id, 'course_price_type' ) ) { $course_has_open = true; // If any of the courses are 'free' price type the we abort and don't include any user_ids. // This will cuase the query to user all users. $course_user_ids = array(); break; } else { $course_user_query = learndash_get_users_for_course( $course_id, array(), ld_propanel_exclude_admin_users() ); if ( $course_user_query instanceof WP_User_Query ) { $user_ids = $course_user_query->get_results(); if ( !empty( $user_ids ) ) { $course_user_ids = array_merge( $course_user_ids, $user_ids ); } } } } if ( !$course_has_open ) { if ( ( !ld_propanel_exclude_admin_users() ) && ( ld_propanel_auto_enroll_admin_users() ) ) { $admin_user_ids = ld_propanel_get_admin_user_ids(); if ( !empty( $admin_user_ids ) ) { $course_user_ids = array_merge( $course_user_ids, $admin_user_ids ); } } } if ( !empty( $course_user_ids ) ) { $activity_args['user_ids'] = array_unique( $course_user_ids ); } else { if ( !$course_has_open ) { $activity_args = array(); } else if ( is_multisite() ) { $course_user_ids = get_users( array( 'fields' => array( 'ID' ) ) ); if ( !empty( $course_user_ids ) ) { $course_user_ids = wp_list_pluck( $course_user_ids, 'ID' ); error_log('course_user_ids
'. print_r( $course_user_ids, true ) .'
'); $activity_args['user_ids'] = $course_user_ids; } } } } /* else { $user_query_args = array( 'fields' => 'ID', 'role' => 'administrator' ); $user_query = new WP_User_Query( $user_query_args ); $course_user_ids = $user_query->get_results(); if ( !empty( $course_user_ids ) ) { $activity_args['user_ids'] = $course_user_ids; $activity_args['user_ids_action'] = 'NOT IN'; } } */ } } else if ( learndash_is_group_leader_user( get_current_user_id() ) ) { $group_ids = learndash_get_administrators_group_ids( get_current_user_id() ); if ( !empty( $group_ids ) ) { $user_ids = array(); foreach ( $group_ids as $group_id ) { $group_user_ids = learndash_get_groups_user_ids( $group_id ); if ( !empty( $group_user_ids ) ) { $user_ids = array_merge( $user_ids, $group_user_ids ); } } if ( !empty( $user_ids ) ) { $activity_args['user_ids'] = $user_ids; } else { $activity_args = array(); } } else { $activity_args = array(); } } else { $activity_args['user_ids'] = get_current_user_id(); } } } return $activity_args; } public function filter_display() { if ( learndash_is_admin_user( get_current_user_id() ) ) { } else if ( learndash_is_group_leader_user( get_current_user_id() ) ) { } else { return; } return ''; } function filter_search() { $response = array( 'total' => 0, 'items' => array() ); if ( ld_propanel_get_users_count() ) { $users = array(); $user_query_args = array( 'orderby' => 'display_name', 'order' => 'ASC', 'number' => 10, 'paged' => intval( $_GET['page'] ), ); if ( ( isset( $_GET['search'] ) ) && ( !empty( $_GET['search'] ) ) ) { $user_query_args['search'] = sprintf( '*%s*', $_GET['search'] ); $user_query_args['search_columns'] = array( 'display_name' ); } if ( learndash_is_admin_user( get_current_user_id() ) ) { // Here we check the group selector first. If the group is selected then we don't need to check the course selector if ( ( isset( $this->post_data['filters']['groups'] ) ) && ( !empty( $this->post_data['filters']['groups'] ) ) ) { $groups_user_ids = array(); foreach( $this->post_data['filters']['groups'] as $group_id ) { $user_ids = learndash_get_groups_user_ids( $group_id ); if ( !empty( $user_ids ) ) { $groups_user_ids = array_merge( $groups_user_ids, $user_ids ); } else { $user_query_args = array(); } } if ( !empty( $groups_user_ids ) ) { $user_query_args['include'] = $groups_user_ids; } } else if ( ( isset( $this->post_data['filters']['courses'] ) ) && ( !empty( $this->post_data['filters']['courses'] ) ) ) { $courses_user_ids = array(); foreach( $this->post_data['filters']['courses'] as $course_id ) { $course_user_query = learndash_get_users_for_course( $course_id, array(), ld_propanel_exclude_admin_users() ); if ( $course_user_query instanceof WP_User_Query ) { $user_ids = $course_user_query->get_results(); if ( !empty( $user_ids ) ) { $courses_user_ids = array_merge( $courses_user_ids, $user_ids ); } } } if ( ( !ld_propanel_exclude_admin_users() ) && ( ld_propanel_auto_enroll_admin_users() ) ) { $admin_user_ids = ld_propanel_get_admin_user_ids(); if ( !empty( $admin_user_ids ) ) { $course_user_ids = array_merge( $course_user_ids, $admin_user_ids ); } } if ( !empty( $courses_user_ids ) ) { $user_query_args['include'] = array_unique( $courses_user_ids ); } } } else if ( learndash_is_group_leader_user( get_current_user_id() ) ) { // Here we check the group selector first. If the group is selected then we don't need to check the course selector if ( ( isset( $this->post_data['filters']['groups'] ) ) && ( !empty( $this->post_data['filters']['groups'] ) ) ) { $groups_user_ids = array(); foreach( $this->post_data['filters']['groups'] as $group_id ) { $user_ids = learndash_get_groups_user_ids( $group_id ); if ( !empty( $user_ids ) ) { $groups_user_ids = array_merge( $groups_user_ids, $user_ids ); } } if ( !empty( $groups_user_ids ) ) { $user_query_args['include'] = $groups_user_ids; } else { $user_query_args = array(); } } else if ( ( isset( $this->post_data['filters']['courses'] ) ) && ( !empty( $this->post_data['filters']['courses'] ) ) ) { $admin_group_ids = learndash_get_administrators_group_ids( get_current_user_id() ); if ( !empty( $admin_group_ids ) ) { $group_ids = array(); foreach( $admin_group_ids as $group_id ) { $group_course_ids = learndash_group_enrolled_courses( $group_id ); if ( !empty( $group_course_ids ) ) { $course_ids_intersect = array_intersect( $this->post_data['filters']['courses'], $group_course_ids ); if ( !empty( $course_ids_intersect ) ) { $group_ids[] = $group_id; } } } $groups_user_ids = array(); if ( !empty( $group_ids ) ) { foreach( $group_ids as $group_id ) { $user_ids = learndash_get_groups_user_ids( $group_id ); if ( !empty( $user_ids ) ) { $groups_user_ids = array_merge( $groups_user_ids, $user_ids ); } } } if ( !empty( $groups_user_ids ) ) { $user_query_args['include'] = $groups_user_ids; } else { $user_query_args = array(); } } else { $user_query_args = array(); } } else { $admin_group_ids = learndash_get_administrators_group_ids( get_current_user_id() ); if ( !empty( $admin_group_ids ) ) { $groups_user_ids = array(); foreach( $admin_group_ids as $group_id ) { $user_ids = learndash_get_groups_user_ids( $group_id ); if ( !empty( $user_ids ) ) { $groups_user_ids = array_merge( $groups_user_ids, $user_ids ); } } if ( !empty( $groups_user_ids ) ) { $user_query_args['include'] = $groups_user_ids; } else { $user_query_args = array(); } } else { $user_query_args = array(); } } } else { $user_query_args['include'] = get_current_user_id(); } if ( !empty( $user_query_args ) ) { // if ( ( isset( $this->post_data['filters']['courses'] ) ) && ( !empty( $this->post_data['filters']['courses'] ) ) ) { // if ( ( !isset( $this->post_data['filters']['groups'] ) ) || ( empty( $this->post_data['filters']['groups'] ) ) ) { // if ( ld_propanel_exclude_admin_users() ) { // $user_query_args['role__not_in'] = array('administrator'); // } // } // } if ( ld_propanel_exclude_admin_users() ) { $user_query_args['role__not_in'] = array('administrator'); } $user_query_args = apply_filters( 'ld_propanel_reporting_user_search_args', $user_query_args ); if ( !empty( $user_query_args ) ) { $user_query = new WP_User_Query( $user_query_args ); if ( ! empty( $user_query->results ) ) { $response['total'] = $user_query->get_total(); foreach ( $user_query->get_results() as $user ) { $users[] = array( 'id' => $user->ID, 'text' => $user->display_name, ); } } } } /** * Filter users returned in search */ $response['items'] = apply_filters( 'ld_propanel_reporting_user_search_results', $users, $user_query_args ); } return $response; } function filter_build_table() { $this->filter_table_headers(); $container_type = $_GET['container_type']; ob_start(); include ld_propanel_get_template( $this->filter_template_table ); return ob_get_clean(); } function filter_table_headers() { $this->filter_headers = array(); if ( 'widget' == $this->post_data['container_type'] ) { $this->filter_headers = array( 'course' => sprintf( _x( '%s', 'Course', 'ld_propanel' ), LearnDash_Custom_Label::get_label( 'courses' ) ), 'progress' => __( 'Progress', 'ld_propanel' ) ); } else if ( 'full' == $this->post_data['container_type'] ) { $this->filter_headers = array( 'course_id' => sprintf( _x( '%s ID', 'Course ID', 'ld_propanel' ), LearnDash_Custom_Label::get_label( 'course' ) ), 'course' => sprintf( _x( '%s', 'Course', 'ld_propanel' ), LearnDash_Custom_Label::get_label( 'course' ) ), 'progress' => __( 'Progress', 'ld_propanel' ), 'last_update' => __( 'Completed On', 'ld_propanel' ) ); } else if ( 'widget' == $this->post_data['container_type'] ) { $this->filter_headers = array( 'course' => sprintf( _x( '%s', 'Course', 'ld_propanel' ), LearnDash_Custom_Label::get_label( 'courses' ) ), 'progress' => __( 'Progress', 'ld_propanel' ) ); } return apply_filters('ld-propanel-reporting-headers', $this->filter_headers, $this->filter_key ); } function filter_result_rows( $user_id ) { /** * Build the response */ $response = array( 'total_rows' => 0, //'rows' => array(), 'rows_html' => '', 'total_users' => 1 ); $this->filter_table_headers(); $activity_query_defaults = array( 'post_types' => 'sfwd-courses', 'activity_types' => 'course', 'activity_status' => '', 'orderby_order' => 'users.display_name, posts.post_title', 'date_format' => 'F j, Y H:i:s', ); $this->activity_query_args = wp_parse_args( $this->activity_query_args, $activity_query_defaults ); $this->activity_query_args = ld_propanel_load_activity_query_args( $this->activity_query_args, $this->post_data ); /** * Build Course Query args * Search args column indexes are different on full vs widget */ if ( ( isset( $this->activity_query_args['s'] ) ) && ( !empty( $this->activity_query_args['s'] ) ) ) { $this->activity_query_args['s_context'] = 'post_title'; } /** * Get the goodies */ if ( !empty( $this->activity_query_args ) ) { $this->activity_query_args = ld_propanel_adjust_admin_users( $this->activity_query_args ); $response['total_users'] = count( $this->activity_query_args['user_ids'] ); $this->activity_query_args = ld_propanel_convert_fewer_users( $this->activity_query_args ); //error_log('users: activity_query_args
'. print_r($this->activity_query_args, true) .'
'); $activities = learndash_reports_get_activity( $this->activity_query_args ); //error_log('users: activities
'. print_r($activities, true) .'
'); if (( isset( $activities['results'] ) ) && ( !empty( $activities['results'] ) )) { if (( isset( $activities['pager'] ) ) && ( !empty( $activities['pager'] ) )) { $response['total_rows'] = $activities['pager']['total_items']; $activities['pager']['current_page'] = $this->activity_query_args['paged']; $response[ 'pager' ] = $activities['pager']; } foreach ( $activities['results'] as $activity ) { $row = array(); $row_html = ''; foreach ( $this->filter_headers as $header_key => $header_label ) { ob_start(); include ld_propanel_get_template( $this->filter_template_row ); $row = ob_get_clean(); $row_html .= ''. $row .''; } $row_html .= ''; $response['rows_html'] .= $row_html; } // Just in case the pager returns empties if ( ( empty( $response['total_rows'] ) ) && ( count( $response['rows'] ) ) ) { $response['total_rows'] = count( $response['rows'] ); } } } if ( empty( $response['rows_html'] ) ) { ob_start(); include ld_propanel_get_template( 'ld-propanel-reporting-no-results.php' ); $response['rows_html'] = ob_get_clean(); } return $response; } // End of functions } } add_action( 'learndash_propanel_filtering_init', function() { new LearnDash_ProPanel_Reporting_Filter_Users(); }); PKj<\ӨKtemplates/reporting-filters/users/ld-propanel-reporting-filter-user-row.phpnuW+A user_id ) ) { $user_link = get_edit_user_link( $activity->user_id ) ."#ld_course_info"; } else { $user_link = "#"; } if ( current_user_can( 'edit_courses', $activity->post_id ) ) { $post_link = get_edit_post_link( $activity->post_id ) ."#ld_course_info"; } else { $post_link = "#"; } switch ( $header_key ) { case 'course_id': echo $activity->post_id; break; case 'course': ?>post_title ); ?>
"> activity_status ) ) { $progress_percent = 0; $progress_label = __('Not Started', 'ld_propanel' ); } else if ( $activity->activity_status == false ) { $progress_percent = round( 100 * ( intval( LearnDash_ProPanel_Activity::get_activity_steps_completed( $activity ) ) / intval( LearnDash_ProPanel_Activity::get_activity_steps_total( $activity ) ) ) ); $progress_label = $progress_percent .'%'; } else if ( $activity->activity_status == true ) { $progress_percent = 100; $progress_label = $progress_percent.'%'; } ?>
activity_completed) ); break; }PKj<\M-883templates/ld-propanel-reporting-download-button.phpnuW+A PKj<\8 "templates/ld-propanel-overview.phpnuW+A

PKj<\+ה0templates/ld-propanel-activity-report-header.phpnuW+A PKj<\XPd*templates/ld-propanel-reporting-search.phpnuW+A

PKj<\ templates/ld-propanel-trends.phpnuW+A
PKj<\ :#templates/ld-propanel-filtering.phpnuW+A
PKj<\YCD$templates/ld-propanel-no-results.phpnuW+A
PKj<\5e͇+templates/ld-propanel-reporting-columns.phpnuW+AstdClass Object * ( * [user_id] => 6 * [user_display_name] => subscriber three * [user_email] => subscriber_3@test.com * [post_id] => 53 * [post_title] => Course * [post_type] => sfwd-courses * [activity_id] => 29 * [activity_type] => course * [activity_started] => 1471529028 * [activity_completed] => * [activity_status] => 0 * [activity_started_formatted] => August 18, 2016 10:03:48 * [activity_meta] => Array * ( * [steps_total] => 6 * [steps_completed] => 4 * [last_id] => 132 * [steps_last_id] => 72 * ) * * ) * * @var $header_key string header to be user for column output. This should match * your output logic switch/case logic in this template. */ if ( $data_slug == 'user-courses' ) { switch( $header_key ) { case 'course_started_on': if ( ( property_exists( $activity, 'activity_started' ) ) || ( !empty( $activity->activity_started ) ) ) { $header_output = learndash_adjust_date_time_display($activity->activity_started, 'Y-m-d'); } break; case 'course_total_time_on': $course_time_begin = 0; $course_time_end = 0; if ( ( property_exists( $activity, 'activity_started' ) ) || ( !empty( $activity->activity_started ) ) ) { $course_time_begin = $activity->activity_started; } if ( ( property_exists( $activity, 'activity_updated' ) ) || ( !empty( $activity->activity_updated ) ) ) { $course_time_end = $activity->activity_updated; } if ( property_exists( $activity, 'activity_status' ) ) { if ( $activity->activity_status == true ) { if ( ( property_exists( $activity, 'activity_completed' ) ) || ( !empty( $activity->activity_completed ) ) ) { //$course_time_end = learndash_adjust_date_time_display( $activity->activity_completed, 'Y-m-d' ); $course_time_end = $activity->activity_completed; } } } if ( ( !empty( $course_time_begin ) ) && ( !empty( $course_time_end ) ) ) { $course_time_diff = $course_time_end - $course_time_begin; if ( $course_time_diff > 0) { if ( $course_time_diff > 86400 ) { if ( !empty( $header_output ) ) $header_output .= ' '; $header_output .= floor($course_time_diff / 86400) .'d'; $course_time_diff %= 86400; } if ( $course_time_diff > 3600 ) { if ( !empty( $header_output ) ) $header_output .= ' '; $header_output .= floor( $course_time_diff / 3600 ) .'h'; $course_time_diff %= 3600; } if ( $course_time_diff > 60 ) { if ( !empty( $header_output ) ) $header_output .= ' '; $header_output .= floor( $course_time_diff / 60 ) .'m'; $course_time_diff %= 60; } if ( $course_time_diff > 0 ) { if ( !empty( $header_output ) ) $header_output .= ' '; $header_output .= $course_time_diff .'s'; } } } break; case 'course_last_step_id': if ( ( property_exists( $activity, 'activity_meta' ) ) || ( is_array( $activity->activity_meta ) ) ) { if ( ( isset( $activity->activity_meta['steps_last_id'] ) ) && ( !empty( $activity->activity_meta['steps_last_id'] ) ) ) { $header_output = $activity->activity_meta['steps_last_id']; } } break; case 'course_last_step_type': if ( ( property_exists( $activity, 'activity_meta' ) ) || ( is_array( $activity->activity_meta ) ) ) { if ( ( isset( $activity->activity_meta['steps_last_id'] ) ) && ( !empty( $activity->activity_meta['steps_last_id'] ) ) ) { $last_step_post = get_post( $activity->activity_meta['steps_last_id'] ); if ( $last_step_post instanceof WP_Post ) { switch( $last_step_post->post_type ) { case 'sfwd-courses': $header_output = LearnDash_Custom_Label::get_label( 'course'); break; case 'sfwd-lessons': $header_output = LearnDash_Custom_Label::get_label( 'lesson'); break; case 'sfwd-topic': $header_output = LearnDash_Custom_Label::get_label( 'topic'); break; case 'sfwd-quiz': $header_output = LearnDash_Custom_Label::get_label( 'quiz'); break; default: $header_output = ''; break; } } } } break; case 'course_last_step_title': if ( ( property_exists( $activity, 'activity_meta' ) ) || ( is_array( $activity->activity_meta ) ) ) { if ( ( isset( $activity->activity_meta['steps_last_id'] ) ) && ( !empty( $activity->activity_meta['steps_last_id'] ) ) ) { $step_title = get_the_title( $activity->activity_meta['steps_last_id'] ); $header_output = preg_replace("/&#?[a-z0-9]+;/i",'', $step_title); } } break; case 'last_login_date': if ( property_exists( $activity, 'user_id' ) ) { $header_output = learndash_adjust_date_time_display( get_user_meta( intval( $activity->user_id ), 'learndash-last-login', true ), 'Y-m-d' ); } break; default: break; } $header_output = apply_filters('learndash_report_column_item', $header_output, $header_key, $activity, $report_user, $data_slug ); }PKj<\č .gitignorenuW+Anode_modules bower_componentsPKj<\JM readme.txtnuW+A=== ProPanel by LearnDash === Author: LearnDash Author URI: https://learndash.com Plugin URI: https://learndash.com/propanel-by-learndash/ LD Requires at least: 2.4.0 Slug: learndash-propanel Requires at least: 4.9 Tested up to: 4.9 Requires PHP: 7.0 Stable tag: 2.1.2 Last Update: 2017-10-25 Easily manage and view your LearnDash LMS activity. == Description == Easily manage and view your LearnDash LMS activity. ProPanel enhances your LearnDash admin experience by consolidating reporting and assignment management, giving you the ability to send course specific communications, and showing real-time activity of your courses! See the [Features](https://www.learndash.com/propanel-by-learndash/) page for more information. == Installation == If the auto-update is not working, you always have the option to update manually. Please note, a full backup of your site is always recommended prior to updating. 1. Deactivate and delete your current version of ProPanel. 1. Download the latest version of ProPanel from our [support site](https://support.learndash.com/articles/my-downloads/). 1. Upload the zipped file via PLUGINS > ADD NEW, or to wp-content/plugins. 1. Activate the ProPanel plugin via the PLUGINS menu. == Changelog == = 2.1.2 = * Updated logic to be compatible with LearnDash v2.5 View our full changelog [here](https://support.learndash.com/articles/propanel-changelog/). == FAQ == = Do I need to update? = It is always recommended to update. However given the nature of WordPress and the option to have many other plugins installed, custom code, etc. it is possible that a conflict would arise. This is why we always recommend testing the update on a development environment first. = Why am I getting an error notice when trying to update? = If you are getting an error while trying to update your version of LearnDash LMS, verify that your license is still valid. Both your license key and email address should be entered via LEARNDASH LMS > SETTINGS > PROPANEL LICENSE. If you see an invalid license message, you can find your correct information via our [Support Site](https://support.learndash.com/articles/my-downloads/). If your license has expired, you can purchase a new one [here](https://www.learndash.com/pricing-and-purchase/). ProPanel is part of both the Plus and Pro package. == icons == 1x:https://s3.us-east-2.amazonaws.com/learndash-addon-assets/learndash-propanel_128x128.jpg 2x:https://s3.us-east-2.amazonaws.com/learndash-addon-assets/learndash-propanel_256x256.jpg == banners == low:https://s3.us-east-2.amazonaws.com/learndash-addon-assets/learndash-propanel_banner.jpg high:https://s3.us-east-2.amazonaws.com/learndash-addon-assets/learndash-propanel_banner.jpgPKj<\/l x x$assets/images/learndash-propanel.jpgnuW+AWExifMM*bj(1 r2i ' 'Adobe Photoshop CS6 (Macintosh)2018:01:16 12:18:20"*(2HH XICC_PROFILE HLinomntrRGB XYZ  1acspMSFTIEC sRGB-HP cprtP3desclwtptbkptrXYZgXYZ,bXYZ@dmndTpdmddvuedLview$lumimeas $tech0 rTRC< gTRC< bTRC< textCopyright (c) 1998 Hewlett-Packard CompanydescsRGB IEC61966-2.1sRGB IEC61966-2.1XYZ QXYZ XYZ o8XYZ bXYZ $descIEC http://www.iec.chIEC http://www.iec.chdesc.IEC 61966-2.1 Default RGB colour space - sRGB.IEC 61966-2.1 Default RGB colour space - sRGBdesc,Reference Viewing Condition in IEC61966-2.1,Reference Viewing Condition in IEC61966-2.1view_. \XYZ L VPWmeassig CRT curv #(-27;@EJOTY^chmrw| %+28>ELRY`gnu| &/8AKT]gqz !-8COZfr~ -;HUcq~ +:IXgw'7HYj{+=Oat 2FZn  % : O d y  ' = T j " 9 Q i  * C \ u & @ Z t .Id %A^z &Ca~1Om&Ed#Cc'Ij4Vx&IlAe@e Ek*Qw;c*R{Gp@j>i  A l !!H!u!!!"'"U"""# #8#f###$$M$|$$% %8%h%%%&'&W&&&''I'z''( (?(q(())8)k))**5*h**++6+i++,,9,n,,- -A-v--..L.../$/Z///050l0011J1112*2c223 3F3334+4e4455M555676r667$7`7788P8899B999:6:t::;-;k;;<' >`>>?!?a??@#@d@@A)AjAAB0BrBBC:C}CDDGDDEEUEEF"FgFFG5G{GHHKHHIIcIIJ7J}JK KSKKL*LrLMMJMMN%NnNOOIOOP'PqPQQPQQR1R|RSS_SSTBTTU(UuUVV\VVWDWWX/X}XYYiYZZVZZ[E[[\5\\]']x]^^l^__a_``W``aOaabIbbcCccd@dde=eef=ffg=ggh?hhiCiijHjjkOkklWlmm`mnnknooxop+ppq:qqrKrss]sttptu(uuv>vvwVwxxnxy*yyzFz{{c{|!||}A}~~b~#G k͂0WGrׇ;iΉ3dʋ0cʍ1fΏ6n֑?zM _ɖ4 uL$h՛BdҞ@iءG&vVǥ8nRĩ7u\ЭD-u`ֲK³8%yhYѹJº;.! zpg_XQKFAǿ=ȼ:ɹ8ʷ6˶5̵5͵6ζ7ϸ9к<Ѿ?DINU\dlvۀ܊ݖޢ)߯6DScs 2F[p(@Xr4Pm8Ww)Km Adobe_CMAdobed            "?   3!1AQa"q2B#$Rb34rC%Scs5&DTdE£t6UeuF'Vfv7GWgw5!1AQaq"2B#R3$brCScs4%&5DTdEU6teuFVfv'7GWgw ?I$gRI$I$$I)I$JRI$I$$I)I$gRI$Iǽis`4 $Kw UmaI),qk`zs8L5<01ce8-k5D1F@k>~o ۔Gn$y"f`Hi9.`F3(HX1 $cǴ0ZD|e3]I$HRI$I$gRI$];dc\usk}= =&/}_boLff<{?IgcIL_ CsɒB?\ן8.k^։.&k0YN.+S[6ߞ#DN?BH\}MA̹Ϙda[K_8I;8A )I$HI$gR}_)ԋ=&V|nﵭ-K9uQ+{1pq(9N:HU}Kk1\MljU 6TߴC?S}S +~[޻}rr6!h4A 򣇛qg'S|h?-XvMz ΪR"yܲIiD`8b:&Y呞IH*V:uSE-K,is>) hsLASQ˫\4?mZ I8r ~DxC:fKE6nu^Þ߼0W 9;18ԒI+ 7I$gR뾢X=<ʻs𣏕[_T/Wca ~'_6U |)p=ь쎋x`W/k& Af/21q1tt~;Kd'^C$rDJygfH~?֊IIX5c}@?)tՌgc\pl#YCjXVIJ+ʥ{=-sc,H~׮%\?lDDG_yOv uw%?-.Ell}]a|FvՌ8`;ާA!gDms[dkljoW~uo6)mZYzM ;bikj'}pK[~2 b}2ۍfy,ӏ-1\I$:S$$II$gRI$$A8)$]/]_C n?g%_׳Ó?屢IA>S͘ mc5TrOYUOej`X1ym#iELRY`gnu| &/8AKT]gqz !-8COZfr~ -;HUcq~ +:IXgw'7HYj{+=Oat 2FZn  % : O d y  ' = T j " 9 Q i  * C \ u & @ Z t .Id %A^z &Ca~1Om&Ed#Cc'Ij4Vx&IlAe@e Ek*Qw;c*R{Gp@j>i  A l !!H!u!!!"'"U"""# #8#f###$$M$|$$% %8%h%%%&'&W&&&''I'z''( (?(q(())8)k))**5*h**++6+i++,,9,n,,- -A-v--..L.../$/Z///050l0011J1112*2c223 3F3334+4e4455M555676r667$7`7788P8899B999:6:t::;-;k;;<' >`>>?!?a??@#@d@@A)AjAAB0BrBBC:C}CDDGDDEEUEEF"FgFFG5G{GHHKHHIIcIIJ7J}JK KSKKL*LrLMMJMMN%NnNOOIOOP'PqPQQPQQR1R|RSS_SSTBTTU(UuUVV\VVWDWWX/X}XYYiYZZVZZ[E[[\5\\]']x]^^l^__a_``W``aOaabIbbcCccd@dde=eef=ffg=ggh?hhiCiijHjjkOkklWlmm`mnnknooxop+ppq:qqrKrss]sttptu(uuv>vvwVwxxnxy*yyzFz{{c{|!||}A}~~b~#G k͂0WGrׇ;iΉ3dʋ0cʍ1fΏ6n֑?zM _ɖ4 uL$h՛BdҞ@iءG&vVǥ8nRĩ7u\ЭD-u`ֲK³8%yhYѹJº;.! zpg_XQKFAǿ=ȼ:ɹ8ʷ6˶5̵5͵6ζ7ϸ9к<Ѿ?DINU\dlvۀ܊ݖޢ)߯6DScs 2F[p(@Xr4Pm8Ww)Km Adobe_CMAdobed            "?   3!1AQa"q2B#$Rb34rC%Scs5&DTdE£t6UeuF'Vfv7GWgw5!1AQaq"2B#R3$brCScs4%&5DTdEU6teuFVfv'7GWgw ?I$gRI$I$$I)I$JRI$I$$I)I$gRI$Iǽis`4 $Kw UmaI),qk`zs8L5<01ce8-k5D1F@k>~o ۔Gn$y"f`Hi9.`F3(HX1 $cǴ0ZD|e3]I$HRI$I$gRI$];dc\usk}= =&/}_boLff<{?IgcIL_ CsɒB?\ן8.k^։.&k0YN.+S[6ߞ#DN?BH\}MA̹Ϙda[K_8I;8A )I$HI$gR}_)ԋ=&V|nﵭ-K9uQ+{1pq(9N:HU}Kk1\MljU 6TߴC?S}S +~[޻}rr6!h4A 򣇛qg'S|h?-XvMz ΪR"yܲIiD`8b:&Y呞IH*V:uSE-K,is>) hsLASQ˫\4?mZ I8r ~DxC:fKE6nu^Þ߼0W 9;18ԒI+ 7I$gR뾢X=<ʻs𣏕[_T/Wca ~'_6U |)p=ь쎋x`W/k& Af/21q1tt~;Kd'^C$rDJygfH~?֊IIX5c}@?)tՌgc\pl#YCjXVIJ+ʥ{=-sc,H~׮%\?lDDG_yOv uw%?-.Ell}]a|FvՌ8`;ާA!gDms[dkljoW~uo6)mZYzM ;bikj'}pK[~2 b}2ۍfy,ӏ-1\I$:S$$II$gRI$$A8)$]/]_C n?g%_׳Ó?屢IA>S͘ mc5TrOYUOej`X1ym#i B7B4AB49225068278E05540439445F60 XICC_PROFILE HLinomntrRGB XYZ  1acspMSFTIEC sRGB-HP cprtP3desclwtptbkptrXYZgXYZ,bXYZ@dmndTpdmddvuedLview$lumimeas $tech0 rTRC< gTRC< bTRC< textCopyright (c) 1998 Hewlett-Packard CompanydescsRGB IEC61966-2.1sRGB IEC61966-2.1XYZ QXYZ XYZ o8XYZ bXYZ $descIEC http://www.iec.chIEC http://www.iec.chdesc.IEC 61966-2.1 Default RGB colour space - sRGB.IEC 61966-2.1 Default RGB colour space - sRGBdesc,Reference Viewing Condition in IEC61966-2.1,Reference Viewing Condition in IEC61966-2.1view_. \XYZ L VPWmeassig CRT curv #(-27;@EJOTY^chmrw| %+28>ELRY`gnu| &/8AKT]gqz !-8COZfr~ -;HUcq~ +:IXgw'7HYj{+=Oat 2FZn  % : O d y  ' = T j " 9 Q i  * C \ u & @ Z t .Id %A^z &Ca~1Om&Ed#Cc'Ij4Vx&IlAe@e Ek*Qw;c*R{Gp@j>i  A l !!H!u!!!"'"U"""# #8#f###$$M$|$$% %8%h%%%&'&W&&&''I'z''( (?(q(())8)k))**5*h**++6+i++,,9,n,,- -A-v--..L.../$/Z///050l0011J1112*2c223 3F3334+4e4455M555676r667$7`7788P8899B999:6:t::;-;k;;<' >`>>?!?a??@#@d@@A)AjAAB0BrBBC:C}CDDGDDEEUEEF"FgFFG5G{GHHKHHIIcIIJ7J}JK KSKKL*LrLMMJMMN%NnNOOIOOP'PqPQQPQQR1R|RSS_SSTBTTU(UuUVV\VVWDWWX/X}XYYiYZZVZZ[E[[\5\\]']x]^^l^__a_``W``aOaabIbbcCccd@dde=eef=ffg=ggh?hhiCiijHjjkOkklWlmm`mnnknooxop+ppq:qqrKrss]sttptu(uuv>vvwVwxxnxy*yyzFz{{c{|!||}A}~~b~#G k͂0WGrׇ;iΉ3dʋ0cʍ1fΏ6n֑?zM _ɖ4 uL$h՛BdҞ@iءG&vVǥ8nRĩ7u\ЭD-u`ֲK³8%yhYѹJº;.! zpg_XQKFAǿ=ȼ:ɹ8ʷ6˶5̵5͵6ζ7ϸ9к<Ѿ?DINU\dlvۀ܊ݖޢ)߯6DScs 2F[p(@Xr4Pm8Ww)KmAdobed@     u!"1A2# QBa$3Rqb%C&4r 5'S6DTsEF7Gc(UVWdte)8fu*9:HIJXYZghijvwxyzm!1"AQ2aqB#Rb3 $Cr4%ScD&5T6Ed' sFtUeuV7)(GWf8vgwHXhx9IYiy*:JZjz ?H{_({ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽uH{_({ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽uH{_({ߺ^׽u~{ߺ^׽u~{ߺ^׽u~{ߺ^׽uH{_({ߺ^׽u~8bq9\J d39LTxV&#VN!jR4fc]ZMy{s6gw`83$һ n,&p4HQf'T|VҿGgf7[sUK֪z%<-Z9WPdjqӭOx?{?lyjYm6v/VGBD5{ΐsZr^1{ZK q&>u.vv-WmR#gi5;k(j\;V$F3!Q%TRի$+RUݣ~xNM>nti8ZIygwRI: ( GXSU6\;wpT2쪙ltZIvm)f:#;_~~,Zoq_1 'OեHzo'ܗ .i[bif.3k0R-W9\NWg1 6_S-Kd1IkhjㆪdUG9$Pєee%X" )/.v[{\J]VX-8 cSj؍%V^:\nS" m}{ uOn]g MUBWX Uf!R*_?/]nY*{OJ.}ѹ("EڇH!n9N .&CXwJ1g{u9*.l_%77h01J'ӥrr:ZJ~ڰV纷pJ#ZL@mWVlɁqJIHf@a/d=սmۗ.bTW%#\uBzɯ߱g_m k6* D!DrhB(K:(1_}yqݛ]\swqđ3VpF$#/k'{[ݽ6Xkdx ^Wfqc!ZJU %_yl#; & ¢'R85NFz=\%~ַ;xsqSPfxSQh|x .4wc}@~]QV7N=!% vD;NE2QĠFP>׽a%nv}K@ d5Ic}ŵocL7S"; RT */?m.70cֻ'WUF3#$TRn\M4?fA/rqhM1P€3ܨUP_O\gt41H8ϋs!n$,qq3?swX׽t1zfwR&omۍW6)O-dcY2pѢZAG?m<յч~ pHo8du Q/{ț9XUm庌aI1Hw"@u>+ACUrTt9RzJRxG5=MEnu!T~Ȉ~ɚR~=#n^u$ZzxPW}׮v^ loeA[ w2?}tN ԞQʮ]v3z\u>c|&bjJ^䩥&-"z$KQW/7:sXع?lfЋܪPm_ϼo hmWT4je?kL$s75]WϑR{yıf-(N/W@_o˷>:ntYHZ|Ď~Iro:w.[I@(ӡ# Zyoa@; +"[HJb4}zGAz^׽uH{_({ߺ^şȣqɷEmV1כQneLZiqQ?*_|m-ۨ_xn'УB;S)뭟ݕW{ `'2%lGS0]M[+omRapMMi(^!^v?mtnс|o˞r2Z|xbxk}P=dXoFjx*Zl{_={ߺ^׽uO|Z|.J<<]O*yGI2Y-k05_e C9|1SZHѣyK&:r'}ݹpK|qEXGGSu@_rSDŽREjbJ᧠xI$_ZrS? Oy#ۤkpwbbR;B-a滼K{I;p*-jOc#!]}뒽{ߺ^H{_({ߺ^ՙ){ ZMγg Os#UG TlXFA8}y2^l"ۆ*(&4VI"vC!{ۄ=$D2Ijx[z]M55m5Ee<5tpKMUKSOOSMB nmA$Ydd2Ţ):/GU(QvSƇ.VXpmLcx?|Kwe̦Dto.k4,JN.JH_XU׽t]w&3doWbnB:JwPn[u͕2^CjΕ5+w6RNN>zy'?`mܒQ~T}6 .T>B*:U|TW?xd7Bw.mەy>[K+1MDRl#Q鯹s.{7 n{UpDƨ.-(3! UC1uj ׻~[n\VjP:,2j3PJܹ9ɒ[uZ7 V`FDn‹(FSC;|M`v ZXon$xIgXu׽u~H{_({ߺ^ԊJ j*h!੥f&Y! P22obxhu*@!A`:v 浞i;2E ATuoeXu,=hp SVFCLo1-=bDg'Ym TfLkv?I WCb[立ܢډgv [EU{M 50OQUI MK ʅ%X2I2Aݑ7I#r)hAAz4rE,j2@ (A'[y`24Ulc#uH9Lv2JsG&&_/t)Q@)pI%>\:ƞly]pKY=xH9'­jk}u>uJ3L6s-K"fg1 ܹhk>p{rnԐ- _lHW>뽻n'8 sYtNdu{ߺ^׽uV̯-]LGdvF<./Ɨ'.VQ0tՃ$;^]^RYr2f button', widgetObjects['activity'] ).on( 'click', processActivityPagination ); //$( '.learndash-propanel-activity-shortcode .report-pagination .ld-propanel-reporting-pager-info > button' ).on( 'click', processActivityPagination ); $( document ).on( 'click', 'button.download-activity', downloadActivity ); } if ( template == 'progress-chart' ) { $( document ).on( 'proPanel.filterChanged', getProgessChartsData ); } //if ( template == 'trends' ) { // trendsBarChart(); //} }); loadWidgets(); setContainerType(); if ( typeof widgetObjects['filtering'] === 'undefined' ) { if ( typeof currentFilters !== 'undefined' ) { if ( typeof widgetObjects['reporting'] !== 'undefined' ) { if (( currentFilters.id == '') || ( currentFilters.type == '' )) { delete widgetObjects['reporting']; } } if ( typeof widgetObjects['progress-chart'] !== 'undefined' ) { if (( currentFilters.id == '') || ( currentFilters.type == '' )) { delete widgetObjects['progress-chart']; } $( document ).on( 'proPanel.filterChanged', getProgessChartsData ); } setTimeout(function() { filterReporting(); }, ld_propanel_settings.template_load_delay); } } } /** * Initialize all widgets */ function loadWidgets() { //var widgetElements = $( 'div[id^="learndash-propanel"]' ); var widgetElements = $( '.ld-propanel-widget' ); // We oad all the widget elements first. $.each( widgetElements, function () { var widget_id = $( this ).data( 'ld-widget-type' ); widgetObjects[ widget_id ] = $( this ); } ); // Then in this next loop we load in the filters $.each( widgetObjects, function () { var widget_id = $( this ).data( 'ld-widget-type' ); if ( typeof widgetObjects['filtering'] === 'undefined' ) { var filters = $( this ).data( 'filters' ); if ( ( typeof filters !== 'undefined' ) && ( filters != '' ) ) { for (var filter_key in currentFilters ) { if ( ( typeof filters[filter_key] !== 'undefined' ) && ( filters[filter_key] != '' ) ) { if ( filter_key == 'reporting_pager' ) { if ( typeof widgetObjects['filtering'] === 'undefined' ) { currentFilters[filter_key] = filters[filter_key]; } } else { currentFilters[filter_key] = filters[filter_key]; } } } } } loadTemplate( widgetObjects[ widget_id ], widget_id ); } ); if ( Object.keys(widgetObjects).length ) { if ( typeof currentFilters.reporting_pager['per_page'] === 'undefined' ) { currentFilters.reporting_pager['per_page'] = ld_propanel_settings.default_per_page; currentFilters.reporting_pager['current_page'] = 1; } } } function setContainerType() { if (( containerType == '' ) || ( containerType == null )) { if ( $( '#learndash-propanel-reporting' ).length ) { if ( $( '#learndash-propanel-reporting' ).hasClass( 'single-view' ) ) { containerType = 'full'; } else { containerType = 'widget'; } } else { containerType = 'widget'; } } } /** * Load a template via AJAX * * If data comes along with the response that other areas of propanel need to use, add it * Add/remove a spinner while loading * * @param element * @param template * @param args */ function loadTemplate( element, template, args ) { showSpinner( element ); // For Activity and Activity_rows we want to pass the per_page size to the server. if ( ( template == 'activity' ) || ( template == 'activity_rows' ) ) { if ( typeof args === 'undefined' ) { args = {}; } if ( jQuery('#dashboard-widgets').length ) { var per_page = jQuery('select#ld-propanel-pagesize').val(); if ( typeof per_page !== 'undefined' ) { args['per_page'] = per_page; } } } $.ajax( { url: ld_propanel_settings.ajaxurl, method: 'get', dataType: 'json', data: { 'action': 'learndash_propanel_template', 'template': template, 'filters': currentFilters, 'container_type': containerType, 'args' : args, 'nonce': ld_propanel_settings.nonce, }, success: function ( response ) { if ( response.hasOwnProperty( 'success' ) ) { if ( typeof response.data.output.rows_html !== 'undefined' ) { element.html( response.data.output.rows_html ); } else if ( typeof response.data.output !== 'undefined' ) { element.html( response.data.output ); } //if ( ( ld_propanel_settings.is_dashboard != '1' ) && if ( typeof widgetObjects['filtering'] === 'undefined' ) { setTimeout(function() { $( document ).trigger( 'proPanel.templateLoaded', [ template ] ); }, ld_propanel_settings.template_load_delay); } else { $( document ).trigger( 'proPanel.templateLoaded', [ template ] ); } $(window).trigger('resize'); } }, complete: function() { hideSpinner( element ); } } ); } function showSpinner( element ) { var spinnerExists = element.parents('.postbox').find( 'loading' ); if ( spinnerExists.length ) { return; } var widgetTitle = element.parents('.postbox').find( 'h2.hndle' ); widgetTitle.append( '' ); } function hideSpinner( element ) { setTimeout( function() { element.parents('.postbox').find( '.loading' ).remove(); }, 500 ); } /** * Initialize Tablesorter Reporting Tables */ function loadReportingTable() { if ( typeof widgetObjects['reporting'] !== 'undefined' ) { proPanelTable = widgetObjects['reporting'].find( '.tablesorter' ); var page_size =jQuery('select#ld-propanel-pagesize').val(); var search =jQuery('select#ld-propanel-pagesize').val(); $.ajax( { url: ld_propanel_settings.ajaxurl, method: 'get', dataType: 'json', data: { 'action': 'learndash_propanel_reporting_get_result_rows', 'nonce' : ld_propanel_settings.nonce, 'filters' : currentFilters, 'container_type' : containerType, }, success: function ( response ) { if ( typeof response['rows_html'] !== 'undefined' ) { proPanelTable.find('tbody').html( response['rows_html'] ); // Logic here is if there is no filtering widget then we can't send emails so hide the checkbox column if ( typeof widgetObjects['filtering'] === 'undefined' ) { proPanelTable.find('thead th.ld-propanel-reporting-col-checkbox').hide(); proPanelTable.find('tbody td.ld-propanel-reporting-col-checkbox').hide(); } } $(window).trigger('resize'); if ( typeof response['pager'] !== 'undefined' ) { // save the reporting pager details. currentFilters.reporting_pager = response['pager']; $('.ld-propanel-widget-reporting .pager .ld-propanel-reporting-pager-info').show(); $('.ld-propanel-widget-reporting .pager .ld-propanel-reporting-pager-info span.pagedisplay span.current_page').html( response['pager']['current_page'] ); $('.ld-propanel-widget-reporting .pager .ld-propanel-reporting-pager-info span.pagedisplay span.total_pages').html( response['pager']['total_pages'] ); $('.ld-propanel-widget-reporting .pager .ld-propanel-reporting-pager-info span.pagedisplay span.total_items').html( response['pager']['total_items'] ); if ( parseInt( response['pager']['current_page'] ) == 1 ) { $('.ld-propanel-widget-reporting .pager .ld-propanel-reporting-pager-info button.first').attr('disabled', true); $('.ld-propanel-widget-reporting .pager .ld-propanel-reporting-pager-info button.prev').attr('disabled', true); } else { $('.ld-propanel-widget-reporting .pager .ld-propanel-reporting-pager-info button.first').attr('disabled', false); $('.ld-propanel-widget-reporting .pager .ld-propanel-reporting-pager-info button.prev').attr('disabled', false); } if ( parseInt( response['pager']['current_page'] ) == parseInt( response['pager']['total_pages'] ) ) { $('.ld-propanel-widget-reporting .pager .ld-propanel-reporting-pager-info button.last').attr('disabled', true); $('.ld-propanel-widget-reporting .pager .ld-propanel-reporting-pager-info button.next').attr('disabled', true); } else { $('.ld-propanel-widget-reporting .pager .ld-propanel-reporting-pager-info button.last').attr('disabled', false); $('.ld-propanel-widget-reporting .pager .ld-propanel-reporting-pager-info button.next').attr('disabled', false); } } else { currentFilters.reporting_pager = {}; $('.ld-propanel-widget-reporting .pager .ld-propanel-reporting-pager-info span.pagedisplay span.current_page').html( '0' ); $('.ld-propanel-widget-reporting .pager .ld-propanel-reporting-pager-info span.pagedisplay span.total_pages').html( '0' ); $('.ld-propanel-widget-reporting .pager .ld-propanel-reporting-pager-info span.pagedisplay span.total_items').html( '0' ); $('.ld-propanel-widget-reporting .pager .ld-propanel-reporting-pager-info').hide(); } updateSelectedCount(); maybeHideEmailBox( ); $( document ).trigger( 'proPanel.reportingTableUpdated' ); }, error: function () { }, complete: function () { } } ); } } /** * Initialize Select2 dropdowns */ function loadSelect2s() { show_hide_FilterActionButton(); init_reporting_per_page(); $('.filter-selection select', widgetObjects['filtering'] ).each(function () { var filter_select = $( this ); var filter_section = $( filter_select ).parent('.filter-selection'); var filter_key = $( filter_section ).data('filter-key'); if ( ( typeof filter_key !== 'undefined' ) && ( filter_key != '' ) ) { $(filter_select).select2( { ajax: ajaxGetSelect2Data( filter_key ), containerCssClass : "filter-"+filter_key+"-select2" } ); } $( filter_select ).change( function() { var filter_select_changed = $( this ); var filter_val = $( this ).val(); if ( filter_val == null ) { $( this ).val(''); filter_val = ''; } var filter_section = $( this ).parent('.filter-selection'); var filter_key = $( filter_section ).data('filter-key'); if ( ( typeof filter_key !== 'undefined' ) && ( filter_key != '' ) ) { currentFilters[filter_key] = filter_val; show_hide_FilterActionButton(); } }); }); } function show_hide_FilterActionButton() { if ( ( currentFilters.groups == '' ) && ( currentFilters.courses == '' ) && ( currentFilters.users == '' )) { jQuery('button.filter', widgetObjects['filtering'] ).attr('disabled', true); } else { jQuery('button.filter', widgetObjects['filtering'] ).attr('disabled', false); } } function init_reporting_per_page() { var reporting_pagesize_selector = 'select#ld-propanel-pagesize'; if ( $(reporting_pagesize_selector).length ) { if ( typeof currentFilters.reporting_pager === 'undefined' ) currentFilters.reporting_pager = []; currentFilters.reporting_pager['per_page'] = jQuery(reporting_pagesize_selector+' option:checked').val(); if ( typeof currentFilters.reporting_pager['per_page'] === 'undefined' ) { currentFilters.reporting_pager['per_page'] = $(reporting_pagesize_selector).find('option:first-child').val(); } if ( typeof currentFilters.reporting_pager['current_page'] === 'undefined' ) { currentFilters.reporting_pager['current_page'] = 1 } $( document ).on( 'change', reporting_pagesize_selector, function() { currentFilters.reporting_pager['per_page'] = $(this).val(); } ); } } /** * Populate Select2 dropdowns with data * * @param action * @returns {{url, dataType: string, method: string, delay: number, data: data, processResults: processResults}} */ function ajaxGetSelect2Data( filter_key ) { return { url: ld_propanel_settings.ajaxurl, dataType: 'json', method: 'get', delay: 1000, cache: true, data: function ( params ) { return { 'action': 'learndash_propanel_filters_search', 'filter_key': filter_key, 'filters': currentFilters, 'search': params.term || '', 'page': params.page || 1, 'nonce': ld_propanel_settings.nonce, }; }, processResults: function ( response, params ) { params.page = params.page || 1; return { results: response.data.items, pagination: { more: ( params.page * 10 ) < response.data.total } }; }, } } /** * Toggles */ function propanelToggles() { widgetObjects['filtering'].on( 'click tap', '.section-toggle', function () { var $showThis = $( this ).attr( 'href' ); $( this ).toggleClass( 'active' ).siblings().removeClass( 'active' ); $( '' + $showThis + '' ).toggleClass( 'display' ).siblings().removeClass( 'display' ); return false; } ); //widgetObjects['reporting'].on( 'click tap', '.close', function () { // $( '.section-toggle' ).removeClass( 'active' ); // $( '.toggle-section' ).removeClass( 'display' ); // return false; //} ); } /** * Set Selected Users * * If User, set the single user * If Courses, set all the filtered users. If users are checked, set those as long * as they are filtered. */ function handleSelectedUsers( e ) { if ( typeof e !== 'undefined' ) { if ( currentFilters.type == 'user' ) { selectedUserIds = []; selectedUserIds.push( $( '.user.select2' ).val() ); } if (( currentFilters.type == 'course' ) || ( currentFilters.type == 'group' )) { var current_checkbox = e.currentTarget; var user_id = $(current_checkbox).attr('data-user-id'); var user_id_checked = false; if ( $(e.currentTarget).is(':checked') ) { var user_id_checked = true; proPanelTable.find( 'input.ld-propanel-report-checkbox[data-user-id="'+user_id+'"]' ).attr('checked', user_id_checked ); selectedUserIds.push(user_id); } else { var user_id_checked = false; proPanelTable.find( 'input.ld-propanel-report-checkbox[data-user-id="'+user_id+'"]' ).attr('checked', user_id_checked ); selectedUserIds.splice( $.inArray(user_id, selectedUserIds), 1 ); } if ( selectedUserIds.length ) { var selectedUserIds_unique = []; $.each( selectedUserIds, function(i, el){ if ( $.inArray(el, selectedUserIds_unique ) === -1 ) selectedUserIds_unique.push( el ); }); selectedUserIds = selectedUserIds_unique; } } // Let everyone know that we've set selected user(s) $( document ).trigger( 'proPanel.setSelectedUsers' ); } } function handleSelectedAllUsers( e ) { if ( typeof e !== 'undefined' ) { var allchecked = jQuery( e.currentTarget ).prop('checked'); proPanelTable.find( 'tbody input.ld-propanel-report-checkbox' ).each( function( idx, cb ) { $( cb ).attr('checked', allchecked ).trigger( 'change' ); }); } } // Called after the Reporting table rows are update. function updateSelectedAll( ) { if ( proPanelTable.find( 'tbody input.ld-propanel-report-checkbox' ).length ) { proPanelTable.find( 'thead input.ld-propanel-report-checkbox').show(); if ( proPanelTable.find( 'tbody input.ld-propanel-report-checkbox:checkbox:not(:checked)' ).length ) { proPanelTable.find( 'thead input.ld-propanel-report-checkbox').attr('checked', false ); } else { proPanelTable.find( 'thead input.ld-propanel-report-checkbox').attr('checked', true ); } } else { proPanelTable.find( 'thead input.ld-propanel-report-checkbox').hide(); } } // Here we just filtered or paged the reporting rows and need to update the state of the checkboxes of the rows. function setSelectedUsers() { if ( currentFilters.type == 'user' ) { selectedUserIds = []; selectedUserIds.push( $( '.user.select2' ).val() ); } if (( currentFilters.type == 'course' ) || ( currentFilters.type == 'group' )) { if ( selectedUserIds.length ) { $.each( selectedUserIds, function( user_idx, user_id ) { proPanelTable.find( 'input.ld-propanel-report-checkbox[data-user-id="'+user_id+'"]' ).attr('checked', true ); }); } } } function showReportingButton() { if ( typeof widgetObjects['reporting'] !== 'undefined' ) { if ( typeof widgetObjects['activity'] !== 'undefined' ) { // If we have both the reporting and activity we don't need the reporting download button. So hide it. jQuery('p.download-button-wrap', widgetObjects['reporting']).hide(); } else { // Else we show it. jQuery('p.download-button-wrap', widgetObjects['reporting']).show(); } } } /** * Email Box only shows when we have users selected */ function maybeHideEmailBox( ) { if ( ( typeof currentFilters.reporting_pager['total_items'] !== 'undefined' ) && ( parseInt( currentFilters.reporting_pager['total_items'] ) > 0 ) ) { $( '.email .no-results' ).hide(); $( '.email .results' ).show(); } else { $( '.email .no-results' ).show(); $( '.email .results' ).hide(); } } /** * Update selected user count in button */ function updateSelectedCount() { if ( currentFilters.type == 'user' ) { //$( '#propanel-send-email' ).find( 'span.count' ).html( '' ); //$( '#propanel-send-email' ).find( 'span.selected' ).hide(); $( 'a.email-toggle').find( 'span.count' ).html( '' ); } else { var selected_user_count = 0; if ( selectedUserIds.length ) selected_user_count = selectedUserIds.length; //else // selected_user_count = currentFilters.total_users; //$( '#propanel-send-email' ).find( 'span.selected' ).show(); //$( '#propanel-send-email' ).find( 'span.count' ).html( selected_user_count ); if ( selected_user_count > 0 ) { $( 'a.email-toggle').find( 'span.count' ).html( ' ('+selected_user_count+')' ); } else { $( 'a.email-toggle').find( 'span.count' ).html( '' ); } } } /** * Disable Send button unless Subject/Message is not empty */ function requireEmailFields() { if ( typeof widgetObjects['filtering'] !== 'undefined' ) { $( '#email', widgetObjects['filtering'] ).on( 'keyup', '.subject, .message', function () { var subject = $( '#email .subject', widgetObjects['filtering'] ).val(); var message = $( '#email .message', widgetObjects['filtering'] ).val(); var sendButton = $( '#propanel-send-email' ); var resetButton = $( '#propanel-reset-email' ); if ( subject == '' || message == '' ) { sendButton.prop( 'disabled', true ); resetButton.prop( 'disabled', true ); } else { sendButton.prop( 'disabled', false ); resetButton.prop( 'disabled', false ); } } ); } } /** * Email Users * * If rows are checked, grab only those User ID's for rows that are checked and not filtered * If no rows are checked, grab all User ID's for rows that are not filtered */ function sendEmailUsers() { var emailContainer, subject, message, sending, sent, sendButton; if ( typeof widgetObjects['filtering'] !== 'undefined' ) { emailContainer = $( '#email', widgetObjects['filtering'] ); subject = emailContainer.find( '.subject' ).val(); message = emailContainer.find( '.message' ).val(); if ( ! selectedUserIds ) { return; } sending = emailContainer.find( '.sending' ); sent = emailContainer.find( '.sent' ); sendButton = emailContainer.find( '#propanel-send-email' ); sending.show(); sendButton.prop( 'disabled', true ); $.ajax( { url: ld_propanel_settings.ajaxurl, method: 'post', dataType: 'json', data: { 'action': 'learndash_propanel_email_users', 'user_ids': selectedUserIds.join(), 'subject': subject, 'message': message, 'filters': currentFilters, 'nonce': ld_propanel_settings.nonce, 'is_debug': ld_propanel_settings.is_debug }, success: function ( response ) { if ( response.success ) { if ( ( typeof response.data.message !== 'undefined' ) && ( response.data.message != '' ) ) { sent.html(response.data.message); } sent.fadeIn(); if (( typeof response.data.debug !== 'undefined' ) && ( response.data.debug !== '' ) && ( ld_propanel_settings.is_debug )) { alert( response.data.debug ); } setTimeout( function () { sent.fadeOut(); sent.html(''); sendButton.prop( 'disabled', false ); }, 3000 ); } else { alert( response.data.message ); } }, error: function () { alert( ld_propanel_reporting.ajax_email_error ); }, complete: function () { sending.hide(); } } ); } } function resetEmailUsers() { if ( typeof widgetObjects['filtering'] !== 'undefined' ) { emailContainer = $( '#email', widgetObjects['filtering'] ); emailContainer.find( '.subject' ).val(''); emailContainer.find( '.message' ).val(''); var sendButton = $( '#propanel-send-email' ); sendButton.prop( 'disabled', true ); var resetButton = $( '#propanel-reset-email' ); resetButton.prop( 'disabled', true ); } } /** * Load Activity based on current filters */ function loadActivity() { if ( $( document.activeElement ).hasClass( 'course-status' ) ) { return; } //if ( jQuery('#dashboard-widgets').length ) { // var activityContainer = $( '#learndash-propanel-activity' ).find( '.inside' ); //} else { // //$.each( widgetElements, function (widget_id, widgetElement) { // //console.log('widget_id[%o] widgetElement[%o]', widget_id, widgetElement); // //}); // //var activityContainer = $( '.learndash-propanel-activity' ).find( '.inside' ); //} if ( typeof widgetObjects['activity'] !== 'undefined' ) { loadTemplate( widgetObjects['activity'], 'activity_rows' ); } } /** * Process Activity Pagination */ function processActivityPagination( event ) { event.preventDefault(); template_args = {}; var thisPagination = $(this); template_args.paged = thisPagination.attr( 'data-page' ); /* if ( jQuery('#dashboard-widgets').length ) { var activityContainer = $( '#learndash-propanel-activity' ).find( '.inside' ); } else { var activityContainer = $( event.currentTarget ).parents( 'div.learndash-propanel-activity' ); if ( typeof activityContainer !== 'undefined' ) { var filters = $(activityContainer).data('filters'); if (( typeof filters !== 'undefined' ) && ( filters != '')) { currentFilters = filters; if (( typeof filters['per_page'] !== 'undefined' ) && ( filters['per_page'] != '')) { template_args.per_page = filters['per_page']; } } } } */ if ( typeof widgetObjects['activity'] !== 'undefined' ) { loadTemplate( widgetObjects['activity'], 'activity_rows', template_args ); } } /** * Load Trends Chart */ function trendsBarChart() { var ctxProPanelTrends = document.getElementById( "proPanelTrends" ).getContext( "2d" ); var data = { labels: [ "1", "2", "3", "4", "5", "6", "7", ], datasets: [ { label: "Week", backgroundColor: "#2D97C5", borderWidth: 1, hoverBackgroundColor: "#2D97C5", data: [ 65, 59, 80, 81, 56, 55, 40 ], }, { label: "Month", backgroundColor: "#5BAED2", borderWidth: 1, hoverBackgroundColor: "#5BAED2", data: [ 40, 34, 65, 66, 36, 21, 10 ], }, { label: "6 Months", backgroundColor: "#8AC5DF", borderWidth: 1, hoverBackgroundColor: "#8AC5DF", data: [ 25, 27, 55, 44, 25, 10, 8 ], } ] }; var options = { scales: { yAxes: [ { position: "left", scaleLabel: { display: true, labelString: "# of Enrollments", fontColor: "#D3D6D7" }, ticks: { beginAtZero: true, }, gridLines: { zeroLineColor: "#eeeeee", color: "#eeeeee" } } ], xAxes: [ { position: "bottom", scaleLabel: { display: true, labelString: "Courses", fontColor: "#D3D6D7" }, gridLines: { display: false, zeroLineColor: "#eeeeee", color: "#eeeeee" } } ] }, tooltips: { mode: 'label', backgroundColor: "#3B3E44", fontFamily: "'Open Sans',sans-serif", titleMarginBottom: 15, titleFontSize: 18, cornerRadius: 4, bodyFontSize: 14, xPadding: 10, yPadding: 15, bodySpacing: 10 }, legend: { display: true, labels: { boxWidth: 14, fontFamily: "'Open Sans',sans-serif" } } }; new Chart( ctxProPanelTrends, { type: 'bar', data: data, options: options } ); } /** * Get data to display progress donut charts based on current filters * * Don't run when the course-status dropdown changes or if current filter type is user */ function getProgessChartsData( event ) { if ( $( document.activeElement ).hasClass( 'course-status' ) ) { return; } //if ( currentFilters.type == 'user' ) { // return; //} //var progressChartsContainer = $( '#learndash-propanel-progress-chart' ).find( '.inside' ); if ( typeof widgetObjects['progress-chart'] !== 'undefined' ) { loadTemplate( widgetObjects['progress-chart'], 'progress-chart-data' ); } $.ajax( { url: ld_propanel_settings.ajaxurl, method: 'get', dataType: 'json', data: { 'action': 'learndash_propanel_get_progress_charts_data', 'filters': currentFilters, 'nonce': ld_propanel_settings.nonce, }, success: function ( response ) { if ( response && response.hasOwnProperty( 'success') ) { setTimeout(function(){ buildProgressCharts( response.data ); }, 500); //buildProgressCharts( response.data ); } } } ); } /** * Build progress donut charts based on returned ajax data * @param data */ function buildProgressCharts( data ) { if ( typeof data.all_progress !== 'undefined' ) { drawProgressAllChart( data.all_progress ); } if ( typeof data.all_percentages !== 'undefined' ) { drawProgressAllPercentagesChart( data.all_percentages ); } } function drawProgressAllChart( chart_data ) { if (typeof proPanelProgressAllChart !== 'undefined') { proPanelProgressAllChart.destroy(); } if ( ( typeof chart_data.data !== 'undefined' ) && ( typeof chart_data.data.datasets !== 'undefined' ) && ( chart_data.data.datasets.length > 0 )) { jQuery('#proPanelProgressAllDefaultMessage').hide(); var ctxProPanelProgressAll = document.getElementById( "proPanelProgressAll" ).getContext( "2d" ); if ( typeof ctxProPanelProgressAll !== 'undefined' ) { var progressAllData = { labels: [], datasets: [] }; if ( typeof chart_data.data.labels !== 'undefined' ) { progressAllData.labels = chart_data.data.labels; } if ( typeof chart_data.data.datasets !== 'undefined' ) { progressAllData.datasets = chart_data.data.datasets; } var progressAllOptions = {}; if ( typeof chart_data['options'] !== 'undefined' ) { progressAllOptions = chart_data['options']; } window.proPanelProgressAllChart = new Chart( ctxProPanelProgressAll, { type: 'doughnut', data: progressAllData, options: progressAllOptions } ); } } else { jQuery('#proPanelProgressAllDefaultMessage').show(); jQuery('#proPanelProgressAll').hide(); jQuery('#proPanelProgressAll').css('height', '0'); jQuery('#proPanelProgressAll').css('width', '0'); } } function drawProgressAllPercentagesChart( chart_data ) { if (typeof proPanelProgressAllPercentagesChart !== 'undefined') { proPanelProgressAllPercentagesChart.destroy(); } if (( typeof chart_data.data.datasets !== 'undefined' ) && ( chart_data.data.datasets.length > 0 )) { jQuery('#proPanelProgressInMotionDefaultMessage').hide(); var ctxProPanelProgressInMotion = document.getElementById( "proPanelProgressInMotion" ).getContext( "2d" ); if ( typeof ctxProPanelProgressInMotion !== 'undefined' ) { var progressInMotionData = { labels: [], datasets: [] }; if ( typeof chart_data.data.labels !== 'undefined' ) { progressInMotionData.labels = chart_data.data.labels; } if ( typeof chart_data.data.datasets !== 'undefined' ) { progressInMotionData.datasets = chart_data.data.datasets; } var progressInMotionOptions = {}; if ( typeof chart_data['options'] !== 'undefined' ) { progressInMotionOptions = chart_data['options']; } window.proPanelProgressAllPercentagesChart = new Chart( ctxProPanelProgressInMotion, { type: 'doughnut', data: progressInMotionData, options: progressInMotionOptions } ); } } else { jQuery('#proPanelProgressInMotionDefaultMessage').show(); jQuery('#proPanelProgressInMotion').hide(); jQuery('#proPanelProgressInMotion').css('height', '0'); jQuery('#proPanelProgressInMotion').css('width', '0'); } } function downloadReporting(e) { e.stopImmediatePropagation(); var data_template = $(e.target).attr('data-template'); var data_slug = $(e.target).attr('data-slug'); var data_nonce = $(e.target).attr('data-nonce'); var updateElement = e.target; if ( typeof data_template !== 'undefined' ) { jQuery(e.target).prop('disabled', true); var post_data = { 'init': 1, 'nonce': data_nonce, 'slug': data_slug, 'filters': currentFilters } loadActivityTemplate( data_template, post_data, updateElement ); } } function filterReporting(e) { if ( typeof e !== 'undefined' ) { e.stopImmediatePropagation(); } selectedUserIds = []; updateSelectedCount(); if ( currentFilters.groups !== '' ) { currentFilters.type = 'group'; currentFilters.id = currentFilters.groups; } else if ( currentFilters.users !== '' ) { currentFilters.type = 'user'; currentFilters.id = currentFilters.users; } else if ( currentFilters.course !== '' ) { currentFilters.type = 'course'; currentFilters.id = currentFilters.courses; } //var reportingContainer = $( '#learndash-propanel-reporting .propanel-reporting' ); if ( typeof widgetObjects['reporting'] !== 'undefined' ) { var reportingContainer = $( '.propanel-reporting', widgetObjects['reporting'] ); if ( currentFilters.type == 'group' ) { loadTemplate( reportingContainer, 'group-reporting' ); } else if ( currentFilters.type == 'course' ) { loadTemplate( reportingContainer, 'course-reporting' ); } else if ( currentFilters.type == 'user' ) { loadTemplate( reportingContainer, 'user-reporting' ); } } // Reset the pager to 1. currentFilters.reporting_pager['current_page'] = 1; $( document ).trigger( 'proPanel.filterChanged' ); } function pagerReporting(e) { currentFilters.reporting_pager['current_page'] = parseInt( currentFilters.reporting_pager['current_page'] ); currentFilters.reporting_pager['total_pages'] = parseInt( currentFilters.reporting_pager['total_pages'] ); var pager_el = (e.currentTarget ); var pager_change = false; if ( $(pager_el).hasClass('next' ) ) { if ( currentFilters.reporting_pager['current_page'] < currentFilters.reporting_pager['total_pages'] ) { pager_change = true; currentFilters.reporting_pager['current_page'] = currentFilters.reporting_pager['current_page'] + 1; } } else if ( $(pager_el).hasClass('prev' ) ) { if ( currentFilters.reporting_pager['current_page'] > 1 ) { pager_change = true; currentFilters.reporting_pager['current_page'] = currentFilters.reporting_pager['current_page'] - 1; } } else if ( $(pager_el).hasClass('first' ) ) { if ( currentFilters.reporting_pager['current_page'] > 1 ) { pager_change = true; currentFilters.reporting_pager['current_page'] = 1; } } else if ( $(pager_el).hasClass('last' ) ) { if ( currentFilters.reporting_pager['current_page'] < currentFilters.reporting_pager['total_pages'] ) { pager_change = true; currentFilters.reporting_pager['current_page'] = currentFilters.reporting_pager['total_pages']; } } if ( pager_change == true ) { loadReportingTable(); } } function resetReporting(e) { e.stopImmediatePropagation(); window.location.reload(false); } function downloadActivity(e) { e.stopImmediatePropagation(); var data_template = $(e.target).attr('data-template'); var data_slug = $(e.target).attr('data-slug'); var data_nonce = $(e.target).attr('data-nonce'); var updateElement = e.target; // If we are NOT running under the Dashboard we need to get the filters data from the parent element in order to properly run the AJAX if ( !jQuery('#dashboard-widgets').length ) { var activityContainer = $( e.currentTarget ).parents( 'div.learndash-propanel-activity' ); if ( typeof activityContainer !== 'undefined' ) { var filters = $(activityContainer).data('filters'); if (( typeof filters !== 'undefined' ) && ( filters != '')) { currentFilters = filters; } } } if ( typeof data_template !== 'undefined' ) { jQuery(updateElement).prop('disabled', true); var post_data = { 'init': 1, 'nonce': data_nonce, 'slug': data_slug, 'filters': currentFilters } loadActivityTemplate( data_template, post_data, updateElement ); } } function loadActivityTemplate( template, args, updateElement ) { $.ajax( { url: ld_propanel_settings.ajaxurl, method: 'get', dataType: 'json', data: { 'action': 'learndash_propanel_template', 'template': template, 'args' : args, 'nonce': ld_propanel_settings.nonce, }, success: function ( response ) { if ( typeof response !== 'undefined' ) { if ( typeof response['data']['output']['rows_html'] !== 'undefined' ) { var reply_data = response['data']['output']['rows_html']; $(window).trigger('resize'); var total_count = 0; if ( typeof reply_data['data']['total_count'] !== 'undefined' ) total_count = parseInt(reply_data['data']['total_count']); var result_count = 0; if ( typeof reply_data['data']['result_count'] !== 'undefined' ) result_count = parseInt(reply_data['data']['result_count']); if ( result_count < total_count ) { // Update the progress meter if ( typeof updateElement !== 'undefined' ) { if (jQuery(updateElement).length) { if ( typeof reply_data['data']['progress_percent'] !== 'undefined' ) { var progress_percent = parseInt(reply_data['data']['progress_percent']); jQuery('span.status', updateElement).html(' '+progress_percent+'%'); } } } loadActivityTemplate( template, reply_data['data'], updateElement ); } else { // Re-enable the buttons jQuery(updateElement).prop('disabled', false); jQuery('span.status', updateElement).html(''); if (( typeof reply_data['data']['report_download_link'] !== 'undefined' ) && ( reply_data['data']['report_download_link'] != '' )) { window.location.href = reply_data['data']['report_download_link']; } } } } }, complete: function() { } }); } function reporting_init_search() { if ( typeof widgetObjects['reporting'] !== 'undefined' ) { if ( jQuery( 'input.tablesorter-search', widgetObjects['reporting'] ).length) { // Hold reference to our interval loop for key press var search_interval_ref; // Set time for .20 seconds. 1/5 of a second. var search_timeout = 200; var search_value = ''; // Activate logic on fucus. jQuery( 'input.tablesorter-search', widgetObjects['reporting'] ).focus(function() { var search_el = this; // Grab the current value of the search input and store it as part of our data. search_value = jQuery(search_el).val(); if ( search_interval_ref != '' ) { clearInterval( search_interval_ref ); } search_interval_ref = setInterval( function() { search_value = jQuery(search_el).val(); // If search was cleared we need to reset the display to show the regular non-search items if ( ( search_value == '' ) && ( search_value != currentFilters.search ) ) { currentFilters.search = search_value; currentFilters.current_page = 1; loadReportingTable(); } else { if ( ( search_value.length >= 3 ) && ( search_value != currentFilters.search ) ) { currentFilters.search = search_value; currentFilters.current_page = 1; loadReportingTable(); } if ( !jQuery( 'input.tablesorter-search', widgetObjects['reporting'] ).is(':focus')) { clearInterval( search_interval_ref ); } } }, search_timeout); }); } } } function getQSParameterByName( name ){ var vars = {}, hash; var hashes = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&'); for (var i = 0; i < hashes.length; i++) { hash = hashes[i].split('='); vars[hash[0]] = hash[1]; } if ( typeof vars[name] !== 'undefined' ) { return vars[name]; } } /* function screenResize() { $( window ).resize(function() { if ( $( '.ld-propanel-widget-reporting' ).length ) { $( '.ld-propanel-widget-reporting table.ld-propanel-reporting-table' ).each( function( i, report_item ) { console.log('i[%o] report_item[%o]', i, report_item ); if ( $( report_item ).width() < 500 ) { console.log('Less than 500'); } else { console.log('More than 500'); } }); } }); $( document ).trigger( 'resize' ); } */ function onScreenResize() { //console.log('in onScreenResize'); $( window ).resize(function() { if ( typeof widgetObjects['reporting'] !== 'undefined' ) { var widget_width = widgetObjects['reporting'].width(); if ( widget_width < 350 ) { widgetObjects['reporting'].find('.ld-propanel-reporting-pager-info').addClass('ld-propanel-full-width'); widgetObjects['reporting'].find('.search-wrap').addClass('ld-propanel-full-width'); } else { widgetObjects['reporting'].find('.ld-propanel-reporting-pager-info').removeClass('ld-propanel-full-width'); widgetObjects['reporting'].find('.search-wrap').removeClass('ld-propanel-full-width'); } if ( widgetObjects['reporting'].find( 'table.ld-propanel-reporting-table-groups-widget').length ) { if ( widget_width < 350 ) { if ( ( widgetObjects['reporting'].find( 'table tbody td.ld-propanel-reporting-col-course').length ) && ( widgetObjects['reporting'].find( 'td.ld-propanel-reporting-col-progress').length ) ) { widgetObjects['reporting'].find('table thead th.ld-propanel-reporting-col-progress').hide(); widgetObjects['reporting'].find('table tbody td.ld-propanel-reporting-col-progress').hide(); if ( widgetObjects['reporting'].find('table tbody td.ld-propanel-reporting-col-course div.ld-propanel-reporting-col-progress').length ) { widgetObjects['reporting'].find('table tbody td.ld-propanel-reporting-col-course div.ld-propanel-reporting-col-progress').show(); } else { widgetObjects['reporting'].find('table tbody tr').each(function( ) { var tr = $(this); if ( !$(tr).find( 'td.ld-propanel-reporting-col-course div.ld-propanel-reporting-col-progress').length ) { if ( $(tr).find( 'td.ld-propanel-reporting-col-progress').length ) { var td_progress_html = $(tr).find( 'td.ld-propanel-reporting-col-progress').html(); if ( typeof td_progress_html !== 'undefined' ) { $(tr).find( 'td.ld-propanel-reporting-col-course').append(''); $(tr).find( 'td.ld-propanel-reporting-col-course div.ld-propanel-reporting-col-progress').show(); } } } }); } } } else { widgetObjects['reporting'].find('table thead th.ld-propanel-reporting-col-progress').show(); widgetObjects['reporting'].find('table tbody td.ld-propanel-reporting-col-progress').show(); widgetObjects['reporting'].find('table tbody td.ld-propanel-reporting-col-course div.ld-propanel-reporting-col-progress').hide(); } } if ( widgetObjects['reporting'].find( 'table.ld-propanel-reporting-table-courses-widget').length ) { if ( widget_width < 350 ) { if ( ( widgetObjects['reporting'].find( 'table tbody td.ld-propanel-reporting-col-user').length ) && ( widgetObjects['reporting'].find( 'td.ld-propanel-reporting-col-progress').length ) ) { widgetObjects['reporting'].find('table thead th.ld-propanel-reporting-col-progress').hide(); widgetObjects['reporting'].find('table tbody td.ld-propanel-reporting-col-progress').hide(); if ( widgetObjects['reporting'].find('table tbody td.ld-propanel-reporting-col-user div.ld-propanel-reporting-col-progress').length ) { widgetObjects['reporting'].find('table tbody td.ld-propanel-reporting-col-user div.ld-propanel-reporting-col-progress').show(); } else { widgetObjects['reporting'].find('table tbody tr').each(function( ) { var tr = $(this); if ( !$(tr).find( 'td.ld-propanel-reporting-col-course div.ld-propanel-reporting-col-progress').length ) { if ( $(tr).find( 'td.ld-propanel-reporting-col-progress').length ) { var td_progress_html = $(tr).find( 'td.ld-propanel-reporting-col-progress').html(); if ( typeof td_progress_html !== 'undefined' ) { $(tr).find( 'td.ld-propanel-reporting-col-user').append(''); $(tr).find( 'td.ld-propanel-reporting-col-user div.ld-propanel-reporting-col-progress').show(); } } } }); } } } else { widgetObjects['reporting'].find('table thead th.ld-propanel-reporting-col-progress').show(); widgetObjects['reporting'].find('table tbody td.ld-propanel-reporting-col-progress').show(); widgetObjects['reporting'].find('table tbody td.ld-propanel-reporting-col-user div.ld-propanel-reporting-col-progress').hide(); } } if ( widgetObjects['reporting'].find( 'table.ld-propanel-reporting-table-users-widget').length ) { if ( widget_width < 350 ) { if ( ( widgetObjects['reporting'].find( 'table tbody td.ld-propanel-reporting-col-course').length ) && ( widgetObjects['reporting'].find( 'td.ld-propanel-reporting-col-progress').length ) ) { widgetObjects['reporting'].find('table thead th.ld-propanel-reporting-col-progress').hide(); widgetObjects['reporting'].find('table tbody td.ld-propanel-reporting-col-progress').hide(); if ( widgetObjects['reporting'].find('table tbody td.ld-propanel-reporting-col-course div.ld-propanel-reporting-col-progress').length ) { widgetObjects['reporting'].find('table tbody td.ld-propanel-reporting-col-course div.ld-propanel-reporting-col-progress').show(); } else { widgetObjects['reporting'].find('table tbody tr').each(function( ) { var tr = $(this); if ( !$(tr).find( 'td.ld-propanel-reporting-col-course div.ld-propanel-reporting-col-progress').length ) { if ( $(tr).find( 'td.ld-propanel-reporting-col-progress').length ) { var td_progress_html = $(tr).find( 'td.ld-propanel-reporting-col-progress').html(); if ( typeof td_progress_html !== 'undefined' ) { $(tr).find( 'td.ld-propanel-reporting-col-course').append(''); $(tr).find( 'td.ld-propanel-reporting-col-course div.ld-propanel-reporting-col-progress').show(); } } } }); } } } else { widgetObjects['reporting'].find('table thead th.ld-propanel-reporting-col-progress').show(); widgetObjects['reporting'].find('table tbody td.ld-propanel-reporting-col-progress').show(); widgetObjects['reporting'].find('table tbody td.ld-propanel-reporting-col-course div.ld-propanel-reporting-col-progress').hide(); } } } if ( typeof widgetObjects['activity'] !== 'undefined' ) { var widget_width = widgetObjects['activity'].width(); if ( widget_width < 350 ) { widgetObjects['activity'].find('.report-pagination').addClass('ld-propanel-full-width'); widgetObjects['activity'].find('.report-exports').addClass('ld-propanel-full-width'); } else { widgetObjects['activity'].find('.report-pagination').removeClass('ld-propanel-full-width'); widgetObjects['activity'].find('.report-exports').removeClass('ld-propanel-full-width'); } } }); $( document ).trigger( 'resize' ); } } ); jQuery(document).ready(function(){ if (typeof sfwd_data !== 'undefined') { if ( typeof sfwd_data.json !== 'undefined' ) { sfwd_data = sfwd_data.json.replace(/"/g, '"'); sfwd_data = jQuery.parseJSON( sfwd_data ); } } jQuery( '.ld-propanel-widget-activity' ).on( 'click', 'a.user_statistic', show_user_statistic ); function show_user_statistic( e ) { e.preventDefault(); var refId = jQuery(this).data('ref_id'); var quizId = jQuery(this).data('quiz_id'); var userId = jQuery(this).data('user_id'); var statistic_nonce = jQuery(this).data('statistic_nonce'); var post_data = { 'action': 'wp_pro_quiz_admin_ajax', 'func': 'statisticLoadUser', 'data': { 'quizId': quizId, 'userId': userId, 'refId': refId, 'statistic_nonce': statistic_nonce, 'avg': 0 } } jQuery('#wpProQuiz_user_overlay, #wpProQuiz_loadUserData').show(); var content = jQuery('#wpProQuiz_user_content').hide(); jQuery.ajax({ type: "POST", url: sfwd_data.ajaxurl, dataType: "json", cache: false, data: post_data, error: function(jqXHR, textStatus, errorThrown ) { }, success: function(reply_data) { if ( typeof reply_data.html !== 'undefined' ) { content.html(reply_data.html); jQuery('a.wpProQuiz_update', content).remove(); jQuery('a#wpProQuiz_resetUserStatistic', content).remove(); jQuery('#wpProQuiz_user_content').show(); jQuery('#wpProQuiz_loadUserData').hide(); content.find('.statistic_data').click(function() { jQuery(this).parents('tr').next().toggle('fast'); return false; }); } } }); jQuery('#wpProQuiz_overlay_close').click(function() { jQuery('#wpProQuiz_user_overlay').hide(); }); } }); PKj<\K;hhassets/js/vendor/Chart.jsnuW+A! function(t) { if ("object" == typeof exports && "undefined" != typeof module) module.exports = t(); else if ("function" == typeof define && define.amd) define([], t); else { var e; e = "undefined" != typeof window ? window : "undefined" != typeof global ? global : "undefined" != typeof self ? self : this, e.Chart = t() } }(function() { return function t(e, a, i) { function n(r, l) { if (!a[r]) { if (!e[r]) { var s = "function" == typeof require && require; if (!l && s) return s(r, !0); if (o) return o(r, !0); var d = new Error("Cannot find module '" + r + "'"); throw d.code = "MODULE_NOT_FOUND", d } var u = a[r] = { exports: {} }; e[r][0].call(u.exports, function(t) { var a = e[r][1][t]; return n(a ? a : t) }, u, u.exports, t, e, a, i) } return a[r].exports } for (var o = "function" == typeof require && require, r = 0; r < i.length; r++) n(i[r]); return n }({ 1: [function(t, e, a) {}, {}], 2: [function(t, e, a) { function i(t) { if (t) { var e = /^#([a-fA-F0-9]{3})$/, a = /^#([a-fA-F0-9]{6})$/, i = /^rgba?\(\s*([+-]?\d+)\s*,\s*([+-]?\d+)\s*,\s*([+-]?\d+)\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)$/, n = /^rgba?\(\s*([+-]?[\d\.]+)\%\s*,\s*([+-]?[\d\.]+)\%\s*,\s*([+-]?[\d\.]+)\%\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)$/, o = /(\w+)/, r = [0, 0, 0], l = 1, s = t.match(e); if (s) { s = s[1]; for (var d = 0; d < r.length; d++) r[d] = parseInt(s[d] + s[d], 16) } else if (s = t.match(a)) { s = s[1]; for (var d = 0; d < r.length; d++) r[d] = parseInt(s.slice(2 * d, 2 * d + 2), 16) } else if (s = t.match(i)) { for (var d = 0; d < r.length; d++) r[d] = parseInt(s[d + 1]); l = parseFloat(s[4]) } else if (s = t.match(n)) { for (var d = 0; d < r.length; d++) r[d] = Math.round(2.55 * parseFloat(s[d + 1])); l = parseFloat(s[4]) } else if (s = t.match(o)) { if ("transparent" == s[1]) return [0, 0, 0, 0]; if (r = y[s[1]], !r) return } for (var d = 0; d < r.length; d++) r[d] = v(r[d], 0, 255); return l = l || 0 == l ? v(l, 0, 1) : 1, r[3] = l, r } } function n(t) { if (t) { var e = /^hsla?\(\s*([+-]?\d+)(?:deg)?\s*,\s*([+-]?[\d\.]+)%\s*,\s*([+-]?[\d\.]+)%\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)/, a = t.match(e); if (a) { var i = parseFloat(a[4]), n = v(parseInt(a[1]), 0, 360), o = v(parseFloat(a[2]), 0, 100), r = v(parseFloat(a[3]), 0, 100), l = v(isNaN(i) ? 1 : i, 0, 1); return [n, o, r, l] } } } function o(t) { if (t) { var e = /^hwb\(\s*([+-]?\d+)(?:deg)?\s*,\s*([+-]?[\d\.]+)%\s*,\s*([+-]?[\d\.]+)%\s*(?:,\s*([+-]?[\d\.]+)\s*)?\)/, a = t.match(e); if (a) { var i = parseFloat(a[4]), n = v(parseInt(a[1]), 0, 360), o = v(parseFloat(a[2]), 0, 100), r = v(parseFloat(a[3]), 0, 100), l = v(isNaN(i) ? 1 : i, 0, 1); return [n, o, r, l] } } } function r(t) { var e = i(t); return e && e.slice(0, 3) } function l(t) { var e = n(t); return e && e.slice(0, 3) } function s(t) { var e = i(t); return e ? e[3] : (e = n(t)) ? e[3] : (e = o(t)) ? e[3] : void 0 } function d(t) { return "#" + x(t[0]) + x(t[1]) + x(t[2]) } function u(t, e) { return e < 1 || t[3] && t[3] < 1 ? c(t, e) : "rgb(" + t[0] + ", " + t[1] + ", " + t[2] + ")" } function c(t, e) { return void 0 === e && (e = void 0 !== t[3] ? t[3] : 1), "rgba(" + t[0] + ", " + t[1] + ", " + t[2] + ", " + e + ")" } function h(t, e) { if (e < 1 || t[3] && t[3] < 1) return f(t, e); var a = Math.round(t[0] / 255 * 100), i = Math.round(t[1] / 255 * 100), n = Math.round(t[2] / 255 * 100); return "rgb(" + a + "%, " + i + "%, " + n + "%)" } function f(t, e) { var a = Math.round(t[0] / 255 * 100), i = Math.round(t[1] / 255 * 100), n = Math.round(t[2] / 255 * 100); return "rgba(" + a + "%, " + i + "%, " + n + "%, " + (e || t[3] || 1) + ")" } function g(t, e) { return e < 1 || t[3] && t[3] < 1 ? p(t, e) : "hsl(" + t[0] + ", " + t[1] + "%, " + t[2] + "%)" } function p(t, e) { return void 0 === e && (e = void 0 !== t[3] ? t[3] : 1), "hsla(" + t[0] + ", " + t[1] + "%, " + t[2] + "%, " + e + ")" } function m(t, e) { return void 0 === e && (e = void 0 !== t[3] ? t[3] : 1), "hwb(" + t[0] + ", " + t[1] + "%, " + t[2] + "%" + (void 0 !== e && 1 !== e ? ", " + e : "") + ")" } function b(t) { return k[t.slice(0, 3)] } function v(t, e, a) { return Math.min(Math.max(e, t), a) } function x(t) { var e = t.toString(16).toUpperCase(); return e.length < 2 ? "0" + e : e } var y = t(6); e.exports = { getRgba: i, getHsla: n, getRgb: r, getHsl: l, getHwb: o, getAlpha: s, hexString: d, rgbString: u, rgbaString: c, percentString: h, percentaString: f, hslString: g, hslaString: p, hwbString: m, keyword: b }; var k = {}; for (var S in y) k[y[S]] = S }, { 6: 6 }], 3: [function(t, e, a) { var i = t(5), n = t(2), o = function(t) { if (t instanceof o) return t; if (!(this instanceof o)) return new o(t); this.values = { rgb: [0, 0, 0], hsl: [0, 0, 0], hsv: [0, 0, 0], hwb: [0, 0, 0], cmyk: [0, 0, 0, 0], alpha: 1 }; var e; if ("string" == typeof t) if (e = n.getRgba(t)) this.setValues("rgb", e); else if (e = n.getHsla(t)) this.setValues("hsl", e); else { if (!(e = n.getHwb(t))) throw new Error('Unable to parse color from string "' + t + '"'); this.setValues("hwb", e) } else if ("object" == typeof t) if (e = t, void 0 !== e.r || void 0 !== e.red) this.setValues("rgb", e); else if (void 0 !== e.l || void 0 !== e.lightness) this.setValues("hsl", e); else if (void 0 !== e.v || void 0 !== e.value) this.setValues("hsv", e); else if (void 0 !== e.w || void 0 !== e.whiteness) this.setValues("hwb", e); else { if (void 0 === e.c && void 0 === e.cyan) throw new Error("Unable to parse color from object " + JSON.stringify(t)); this.setValues("cmyk", e) } }; o.prototype = { rgb: function() { return this.setSpace("rgb", arguments) }, hsl: function() { return this.setSpace("hsl", arguments) }, hsv: function() { return this.setSpace("hsv", arguments) }, hwb: function() { return this.setSpace("hwb", arguments) }, cmyk: function() { return this.setSpace("cmyk", arguments) }, rgbArray: function() { return this.values.rgb }, hslArray: function() { return this.values.hsl }, hsvArray: function() { return this.values.hsv }, hwbArray: function() { var t = this.values; return 1 !== t.alpha ? t.hwb.concat([t.alpha]) : t.hwb }, cmykArray: function() { return this.values.cmyk }, rgbaArray: function() { var t = this.values; return t.rgb.concat([t.alpha]) }, hslaArray: function() { var t = this.values; return t.hsl.concat([t.alpha]) }, alpha: function(t) { return void 0 === t ? this.values.alpha : (this.setValues("alpha", t), this) }, red: function(t) { return this.setChannel("rgb", 0, t) }, green: function(t) { return this.setChannel("rgb", 1, t) }, blue: function(t) { return this.setChannel("rgb", 2, t) }, hue: function(t) { return t && (t %= 360, t = t < 0 ? 360 + t : t), this.setChannel("hsl", 0, t) }, saturation: function(t) { return this.setChannel("hsl", 1, t) }, lightness: function(t) { return this.setChannel("hsl", 2, t) }, saturationv: function(t) { return this.setChannel("hsv", 1, t) }, whiteness: function(t) { return this.setChannel("hwb", 1, t) }, blackness: function(t) { return this.setChannel("hwb", 2, t) }, value: function(t) { return this.setChannel("hsv", 2, t) }, cyan: function(t) { return this.setChannel("cmyk", 0, t) }, magenta: function(t) { return this.setChannel("cmyk", 1, t) }, yellow: function(t) { return this.setChannel("cmyk", 2, t) }, black: function(t) { return this.setChannel("cmyk", 3, t) }, hexString: function() { return n.hexString(this.values.rgb) }, rgbString: function() { return n.rgbString(this.values.rgb, this.values.alpha) }, rgbaString: function() { return n.rgbaString(this.values.rgb, this.values.alpha) }, percentString: function() { return n.percentString(this.values.rgb, this.values.alpha) }, hslString: function() { return n.hslString(this.values.hsl, this.values.alpha) }, hslaString: function() { return n.hslaString(this.values.hsl, this.values.alpha) }, hwbString: function() { return n.hwbString(this.values.hwb, this.values.alpha) }, keyword: function() { return n.keyword(this.values.rgb, this.values.alpha) }, rgbNumber: function() { var t = this.values.rgb; return t[0] << 16 | t[1] << 8 | t[2] }, luminosity: function() { for (var t = this.values.rgb, e = [], a = 0; a < t.length; a++) { var i = t[a] / 255; e[a] = i <= .03928 ? i / 12.92 : Math.pow((i + .055) / 1.055, 2.4) } return .2126 * e[0] + .7152 * e[1] + .0722 * e[2] }, contrast: function(t) { var e = this.luminosity(), a = t.luminosity(); return e > a ? (e + .05) / (a + .05) : (a + .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, e = (299 * t[0] + 587 * t[1] + 114 * t[2]) / 1e3; return e < 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, a = (e[0] + t) % 360; return e[0] = a < 0 ? 360 + a : a, this.setValues("hsl", e), this }, mix: function(t, e) { var a = this, i = t, n = void 0 === e ? .5 : e, o = 2 * n - 1, r = a.alpha() - i.alpha(), l = ((o * r === -1 ? o : (o + r) / (1 + o * r)) + 1) / 2, s = 1 - l; return this.rgb(l * a.red() + s * i.red(), l * a.green() + s * i.green(), l * a.blue() + s * i.blue()).alpha(a.alpha() * n + i.alpha() * (1 - n)) }, toJSON: function() { return this.rgb() }, clone: function() { var t, e, a = new o, i = this.values, n = a.values; for (var r in i) i.hasOwnProperty(r) && (t = i[r], e = {}.toString.call(t), "[object Array]" === e ? n[r] = t.slice(0) : "[object Number]" === e ? n[r] = t : console.error("unexpected color value:", t)); return a } }, o.prototype.spaces = { rgb: ["red", "green", "blue"], hsl: ["hue", "saturation", "lightness"], hsv: ["hue", "saturation", "value"], hwb: ["hue", "whiteness", "blackness"], cmyk: ["cyan", "magenta", "yellow", "black"] }, o.prototype.maxes = { rgb: [255, 255, 255], hsl: [360, 100, 100], hsv: [360, 100, 100], hwb: [360, 100, 100], cmyk: [100, 100, 100, 100] }, o.prototype.getValues = function(t) { for (var e = this.values, a = {}, i = 0; i < t.length; i++) a[t.charAt(i)] = e[t][i]; return 1 !== e.alpha && (a.a = e.alpha), a }, o.prototype.setValues = function(t, e) { var a, n = this.values, o = this.spaces, r = this.maxes, l = 1; if ("alpha" === t) l = e; else if (e.length) n[t] = e.slice(0, t.length), l = e[t.length]; else if (void 0 !== e[t.charAt(0)]) { for (a = 0; a < t.length; a++) n[t][a] = e[t.charAt(a)]; l = e.a } else if (void 0 !== e[o[t][0]]) { var s = o[t]; for (a = 0; a < t.length; a++) n[t][a] = e[s[a]]; l = e.alpha } if (n.alpha = Math.max(0, Math.min(1, void 0 === l ? n.alpha : l)), "alpha" === t) return !1; var d; for (a = 0; a < t.length; a++) d = Math.max(0, Math.min(r[t][a], n[t][a])), n[t][a] = Math.round(d); for (var u in o) u !== t && (n[u] = i[t][u](n[t])); return !0 }, o.prototype.setSpace = function(t, e) { var a = e[0]; return void 0 === a ? this.getValues(t) : ("number" == typeof a && (a = Array.prototype.slice.call(e)), this.setValues(t, a), this) }, o.prototype.setChannel = function(t, e, a) { var i = this.values[t]; return void 0 === a ? i[e] : a === i[e] ? this : (i[e] = a, this.setValues(t, i), this) }, "undefined" != typeof window && (window.Color = o), e.exports = o }, { 2: 2, 5: 5 }], 4: [function(t, e, a) { function i(t) { var e, a, i, n = t[0] / 255, o = t[1] / 255, r = t[2] / 255, l = Math.min(n, o, r), s = Math.max(n, o, r), d = s - l; return s == l ? e = 0 : n == s ? e = (o - r) / d : o == s ? e = 2 + (r - n) / d : r == s && (e = 4 + (n - o) / d), e = Math.min(60 * e, 360), e < 0 && (e += 360), i = (l + s) / 2, a = s == l ? 0 : i <= .5 ? d / (s + l) : d / (2 - s - l), [e, 100 * a, 100 * i] } function n(t) { var e, a, i, n = t[0], o = t[1], r = t[2], l = Math.min(n, o, r), s = Math.max(n, o, r), d = s - l; return a = 0 == s ? 0 : d / s * 1e3 / 10, s == l ? e = 0 : n == s ? e = (o - r) / d : o == s ? e = 2 + (r - n) / d : r == s && (e = 4 + (n - o) / d), e = Math.min(60 * e, 360), e < 0 && (e += 360), i = s / 255 * 1e3 / 10, [e, a, i] } function o(t) { var e = t[0], a = t[1], n = t[2], o = i(t)[0], r = 1 / 255 * Math.min(e, Math.min(a, n)), n = 1 - 1 / 255 * Math.max(e, Math.max(a, n)); return [o, 100 * r, 100 * n] } function l(t) { var e, a, i, n, o = t[0] / 255, r = t[1] / 255, l = t[2] / 255; return n = Math.min(1 - o, 1 - r, 1 - l), e = (1 - o - n) / (1 - n) || 0, a = (1 - r - n) / (1 - n) || 0, i = (1 - l - n) / (1 - n) || 0, [100 * e, 100 * a, 100 * i, 100 * n] } function s(t) { return Q[JSON.stringify(t)] } function d(t) { var e = t[0] / 255, a = t[1] / 255, i = t[2] / 255; e = e > .04045 ? Math.pow((e + .055) / 1.055, 2.4) : e / 12.92, a = a > .04045 ? Math.pow((a + .055) / 1.055, 2.4) : a / 12.92, i = i > .04045 ? Math.pow((i + .055) / 1.055, 2.4) : i / 12.92; var n = .4124 * e + .3576 * a + .1805 * i, o = .2126 * e + .7152 * a + .0722 * i, r = .0193 * e + .1192 * a + .9505 * i; return [100 * n, 100 * o, 100 * r] } function u(t) { var e, a, i, n = d(t), o = n[0], r = n[1], l = n[2]; return o /= 95.047, r /= 100, l /= 108.883, o = o > .008856 ? Math.pow(o, 1 / 3) : 7.787 * o + 16 / 116, r = r > .008856 ? Math.pow(r, 1 / 3) : 7.787 * r + 16 / 116, l = l > .008856 ? Math.pow(l, 1 / 3) : 7.787 * l + 16 / 116, e = 116 * r - 16, a = 500 * (o - r), i = 200 * (r - l), [e, a, i] } function c(t) { return W(u(t)) } function h(t) { var e, a, i, n, o, r = t[0] / 360, l = t[1] / 100, s = t[2] / 100; if (0 == l) return o = 255 * s, [o, o, o]; a = s < .5 ? s * (1 + l) : s + l - s * l, e = 2 * s - a, n = [0, 0, 0]; for (var d = 0; d < 3; d++) i = r + 1 / 3 * -(d - 1), i < 0 && i++, i > 1 && i--, o = 6 * i < 1 ? e + 6 * (a - e) * i : 2 * i < 1 ? a : 3 * i < 2 ? e + (a - e) * (2 / 3 - i) * 6 : e, n[d] = 255 * o; return n } function f(t) { var e, a, i = t[0], n = t[1] / 100, o = t[2] / 100; return 0 === o ? [0, 0, 0] : (o *= 2, n *= o <= 1 ? o : 2 - o, a = (o + n) / 2, e = 2 * n / (o + n), [i, 100 * e, 100 * a]) } function p(t) { return o(h(t)) } function m(t) { return l(h(t)) } function v(t) { return s(h(t)) } function x(t) { var e = t[0] / 60, a = t[1] / 100, i = t[2] / 100, n = Math.floor(e) % 6, o = e - Math.floor(e), r = 255 * i * (1 - a), l = 255 * i * (1 - a * o), s = 255 * i * (1 - a * (1 - o)), i = 255 * i; switch (n) { case 0: return [i, s, r]; case 1: return [l, i, r]; case 2: return [r, i, s]; case 3: return [r, l, i]; case 4: return [s, r, i]; case 5: return [i, r, l] } } function y(t) { var e, a, i = t[0], n = t[1] / 100, o = t[2] / 100; return a = (2 - n) * o, e = n * o, e /= a <= 1 ? a : 2 - a, e = e || 0, a /= 2, [i, 100 * e, 100 * a] } function k(t) { return o(x(t)) } function S(t) { return l(x(t)) } function w(t) { return s(x(t)) } function C(t) { var e, a, i, n, o = t[0] / 360, l = t[1] / 100, s = t[2] / 100, d = l + s; switch (d > 1 && (l /= d, s /= d), e = Math.floor(6 * o), a = 1 - s, i = 6 * o - e, 0 != (1 & e) && (i = 1 - i), n = l + i * (a - l), e) { default: case 6: case 0: r = a, g = n, b = l; break; case 1: r = n, g = a, b = l; break; case 2: r = l, g = a, b = n; break; case 3: r = l, g = n, b = a; break; case 4: r = n, g = l, b = a; break; case 5: r = a, g = l, b = n } return [255 * r, 255 * g, 255 * b] } function M(t) { return i(C(t)) } function D(t) { return n(C(t)) } function A(t) { return l(C(t)) } function I(t) { return s(C(t)) } function F(t) { var e, a, i, n = t[0] / 100, o = t[1] / 100, r = t[2] / 100, l = t[3] / 100; return e = 1 - Math.min(1, n * (1 - l) + l), a = 1 - Math.min(1, o * (1 - l) + l), i = 1 - Math.min(1, r * (1 - l) + l), [255 * e, 255 * a, 255 * i] } function T(t) { return i(F(t)) } function P(t) { return n(F(t)) } function _(t) { return o(F(t)) } function R(t) { return s(F(t)) } function V(t) { var e, a, i, n = t[0] / 100, o = t[1] / 100, r = t[2] / 100; return e = 3.2406 * n + o * -1.5372 + r * -.4986, a = n * -.9689 + 1.8758 * o + .0415 * r, i = .0557 * n + o * -.204 + 1.057 * r, e = e > .0031308 ? 1.055 * Math.pow(e, 1 / 2.4) - .055 : e = 12.92 * e, a = a > .0031308 ? 1.055 * Math.pow(a, 1 / 2.4) - .055 : a = 12.92 * a, i = i > .0031308 ? 1.055 * Math.pow(i, 1 / 2.4) - .055 : i = 12.92 * i, e = Math.min(Math.max(0, e), 1), a = Math.min(Math.max(0, a), 1), i = Math.min(Math.max(0, i), 1), [255 * e, 255 * a, 255 * i] } function O(t) { var e, a, i, n = t[0], o = t[1], r = t[2]; return n /= 95.047, o /= 100, r /= 108.883, n = n > .008856 ? Math.pow(n, 1 / 3) : 7.787 * n + 16 / 116, o = o > .008856 ? Math.pow(o, 1 / 3) : 7.787 * o + 16 / 116, r = r > .008856 ? Math.pow(r, 1 / 3) : 7.787 * r + 16 / 116, e = 116 * o - 16, a = 500 * (n - o), i = 200 * (o - r), [e, a, i] } function L(t) { return W(O(t)) } function B(t) { var e, a, i, n, o = t[0], r = t[1], l = t[2]; return o <= 8 ? (a = 100 * o / 903.3, n = 7.787 * (a / 100) + 16 / 116) : (a = 100 * Math.pow((o + 16) / 116, 3), n = Math.pow(a / 100, 1 / 3)), e = e / 95.047 <= .008856 ? e = 95.047 * (r / 500 + n - 16 / 116) / 7.787 : 95.047 * Math.pow(r / 500 + n, 3), i = i / 108.883 <= .008859 ? i = 108.883 * (n - l / 200 - 16 / 116) / 7.787 : 108.883 * Math.pow(n - l / 200, 3), [e, a, i] } function W(t) { var e, a, i, n = t[0], o = t[1], r = t[2]; return e = Math.atan2(r, o), a = 360 * e / 2 / Math.PI, a < 0 && (a += 360), i = Math.sqrt(o * o + r * r), [n, i, a] } function z(t) { return V(B(t)) } function H(t) { var e, a, i, n = t[0], o = t[1], r = t[2]; return i = r / 360 * 2 * Math.PI, e = o * Math.cos(i), a = o * Math.sin(i), [n, e, a] } function N(t) { return B(H(t)) } function E(t) { return z(H(t)) } function U(t) { return G[t] } function q(t) { return i(U(t)) } function j(t) { return n(U(t)) } function Y(t) { return o(U(t)) } function J(t) { return l(U(t)) } function X(t) { return u(U(t)) } function Z(t) { return d(U(t)) } e.exports = { rgb2hsl: i, rgb2hsv: n, rgb2hwb: o, rgb2cmyk: l, rgb2keyword: s, rgb2xyz: d, rgb2lab: u, rgb2lch: c, hsl2rgb: h, hsl2hsv: f, hsl2hwb: p, hsl2cmyk: m, hsl2keyword: v, hsv2rgb: x, hsv2hsl: y, hsv2hwb: k, hsv2cmyk: S, hsv2keyword: w, hwb2rgb: C, hwb2hsl: M, hwb2hsv: D, hwb2cmyk: A, hwb2keyword: I, cmyk2rgb: F, cmyk2hsl: T, cmyk2hsv: P, cmyk2hwb: _, cmyk2keyword: R, keyword2rgb: U, keyword2hsl: q, keyword2hsv: j, keyword2hwb: Y, keyword2cmyk: J, keyword2lab: X, keyword2xyz: Z, xyz2rgb: V, xyz2lab: O, xyz2lch: L, lab2xyz: B, lab2rgb: z, lab2lch: W, lch2lab: H, lch2xyz: N, lch2rgb: E }; var G = { 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] }, Q = {}; for (var $ in G) Q[JSON.stringify(G[$])] = $ }, {}], 5: [function(t, e, a) { var i = t(4), n = function() { return new d }; for (var o in i) { n[o + "Raw"] = function(t) { return function(e) { return "number" == typeof e && (e = Array.prototype.slice.call(arguments)), i[t](e) } }(o); var r = /(\w+)2(\w+)/.exec(o), l = r[1], s = r[2]; n[l] = n[l] || {}, n[l][s] = n[o] = function(t) { return function(e) { "number" == typeof e && (e = Array.prototype.slice.call(arguments)); var a = i[t](e); if ("string" == typeof a || void 0 === a) return a; for (var n = 0; n < a.length; n++) a[n] = Math.round(a[n]); return a } }(o) } var d = function() { this.convs = {} }; d.prototype.routeSpace = function(t, e) { var a = e[0]; return void 0 === a ? this.getValues(t) : ("number" == typeof a && (a = Array.prototype.slice.call(e)), this.setValues(t, a)) }, d.prototype.setValues = function(t, e) { return this.space = t, this.convs = {}, this.convs[t] = e, this }, d.prototype.getValues = function(t) { var e = this.convs[t]; if (!e) { var a = this.space, i = this.convs[a]; e = n[a][t](i), this.convs[t] = e } return e }, ["rgb", "hsl", "hsv", "cmyk", "keyword"].forEach(function(t) { d.prototype[t] = function(e) { return this.routeSpace(t, arguments) } }), e.exports = n }, { 4: 4 }], 6: [function(t, e, a) { e.exports = { 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] } }, {}], 7: [function(t, e, a) { var i = t(26)(); t(25)(i), t(24)(i), t(21)(i), t(22)(i), t(23)(i), t(27)(i), t(31)(i), t(29)(i), t(30)(i), t(32)(i), t(28)(i), t(33)(i), t(34)(i), t(35)(i), t(36)(i), t(37)(i), t(40)(i), t(38)(i), t(39)(i), t(41)(i), t(42)(i), t(43)(i), t(15)(i), t(16)(i), t(17)(i), t(18)(i), t(19)(i), t(20)(i), t(8)(i), t(9)(i), t(10)(i), t(11)(i), t(12)(i), t(13)(i), t(14)(i), window.Chart = e.exports = i }, { 10: 10, 11: 11, 12: 12, 13: 13, 14: 14, 15: 15, 16: 16, 17: 17, 18: 18, 19: 19, 20: 20, 21: 21, 22: 22, 23: 23, 24: 24, 25: 25, 26: 26, 27: 27, 28: 28, 29: 29, 30: 30, 31: 31, 32: 32, 33: 33, 34: 34, 35: 35, 36: 36, 37: 37, 38: 38, 39: 39, 40: 40, 41: 41, 42: 42, 43: 43, 8: 8, 9: 9 }], 8: [function(t, e, a) { "use strict"; e.exports = function(t) { t.Bar = function(e, a) { return a.type = "bar", new t(e, a) } } }, {}], 9: [function(t, e, a) { "use strict"; e.exports = function(t) { t.Bubble = function(e, a) { return a.type = "bubble", new t(e, a) } } }, {}], 10: [function(t, e, a) { "use strict"; e.exports = function(t) { t.Doughnut = function(e, a) { return a.type = "doughnut", new t(e, a) } } }, {}], 11: [function(t, e, a) { "use strict"; e.exports = function(t) { t.Line = function(e, a) { return a.type = "line", new t(e, a) } } }, {}], 12: [function(t, e, a) { "use strict"; e.exports = function(t) { t.PolarArea = function(e, a) { return a.type = "polarArea", new t(e, a) } } }, {}], 13: [function(t, e, a) { "use strict"; e.exports = function(t) { t.Radar = function(e, a) { return a.options = t.helpers.configMerge({ aspectRatio: 1 }, a.options), a.type = "radar", new t(e, a) } } }, {}], 14: [function(t, e, a) { "use strict"; e.exports = function(t) { var e = { hover: { mode: "single" }, scales: { xAxes: [{ type: "linear", position: "bottom", id: "x-axis-1" }], yAxes: [{ type: "linear", position: "left", id: "y-axis-1" }] }, tooltips: { callbacks: { title: function(t, e) { return "" }, label: function(t, e) { return "(" + t.xLabel + ", " + t.yLabel + ")" } } } }; t.defaults.scatter = e, t.controllers.scatter = t.controllers.line, t.Scatter = function(e, a) { return a.type = "scatter", new t(e, a) } } }, {}], 15: [function(t, e, a) { "use strict"; e.exports = function(t) { var e = t.helpers; t.defaults.bar = { hover: { mode: "label" }, scales: { xAxes: [{ type: "category", categoryPercentage: .8, barPercentage: .9, gridLines: { offsetGridLines: !0 } }], yAxes: [{ type: "linear" }] } }, t.controllers.bar = t.DatasetController.extend({ dataElementType: t.elements.Rectangle, initialize: function(e, a) { t.DatasetController.prototype.initialize.call(this, e, a), this.getMeta().bar = !0 }, getBarCount: function() { var t = this, a = 0; return e.each(t.chart.data.datasets, function(e, i) { var n = t.chart.getDatasetMeta(i); n.bar && t.chart.isDatasetVisible(i) && ++a }, t), a }, update: function(t) { var a = this; e.each(a.getMeta().data, function(e, i) { a.updateElement(e, i, t) }, a) }, updateElement: function(t, a, i) { var n = this, o = n.getMeta(), r = n.getScaleForId(o.xAxisID), l = n.getScaleForId(o.yAxisID), s = l.getBasePixel(), d = n.chart.options.elements.rectangle, u = t.custom || {}, c = n.getDataset(); e.extend(t, { _xScale: r, _yScale: l, _datasetIndex: n.index, _index: a, _model: { x: n.calculateBarX(a, n.index), y: i ? s : n.calculateBarY(a, n.index), label: n.chart.data.labels[a], datasetLabel: c.label, base: i ? s : n.calculateBarBase(n.index, a), width: n.calculateBarWidth(a), backgroundColor: u.backgroundColor ? u.backgroundColor : e.getValueAtIndexOrDefault(c.backgroundColor, a, d.backgroundColor), borderSkipped: u.borderSkipped ? u.borderSkipped : d.borderSkipped, borderColor: u.borderColor ? u.borderColor : e.getValueAtIndexOrDefault(c.borderColor, a, d.borderColor), borderWidth: u.borderWidth ? u.borderWidth : e.getValueAtIndexOrDefault(c.borderWidth, a, d.borderWidth) } }), t.pivot() }, calculateBarBase: function(t, e) { var a = this, i = a.getMeta(), n = a.getScaleForId(i.yAxisID), o = 0; if (n.options.stacked) { var r = a.chart, l = r.data.datasets, s = l[t].data[e]; if (s < 0) for (var d = 0; d < t; d++) { var u = l[d], c = r.getDatasetMeta(d); c.bar && c.yAxisID === n.id && r.isDatasetVisible(d) && (o += u.data[e] < 0 ? u.data[e] : 0) } else for (var h = 0; h < t; h++) { var f = l[h], g = r.getDatasetMeta(h); g.bar && g.yAxisID === n.id && r.isDatasetVisible(h) && (o += f.data[e] > 0 ? f.data[e] : 0) } return n.getPixelForValue(o) } return n.getBasePixel() }, getRuler: function(t) { var e, a = this, i = a.getMeta(), n = a.getScaleForId(i.xAxisID), o = a.getBarCount(); e = "category" === n.options.type ? n.getPixelForTick(t + 1) - n.getPixelForTick(t) : n.width / n.ticks.length; var r = e * n.options.categoryPercentage, l = (e - e * n.options.categoryPercentage) / 2, s = r / o; if (n.ticks.length !== a.chart.data.labels.length) { var d = n.ticks.length / a.chart.data.labels.length; s *= d } var u = s * n.options.barPercentage, c = s - s * n.options.barPercentage; return { datasetCount: o, tickWidth: e, categoryWidth: r, categorySpacing: l, fullBarWidth: s, barWidth: u, barSpacing: c } }, calculateBarWidth: function(t) { var e = this.getScaleForId(this.getMeta().xAxisID), a = this.getRuler(t); return e.options.stacked ? a.categoryWidth : a.barWidth }, getBarIndex: function(t) { var e, a, i = 0; for (a = 0; a < t; ++a) e = this.chart.getDatasetMeta(a), e.bar && this.chart.isDatasetVisible(a) && ++i; return i }, calculateBarX: function(t, e) { var a = this, i = a.getMeta(), n = a.getScaleForId(i.xAxisID), o = a.getBarIndex(e), r = a.getRuler(t), l = n.getPixelForValue(null, t, e, a.chart.isCombo); return l -= a.chart.isCombo ? r.tickWidth / 2 : 0, n.options.stacked ? l + r.categoryWidth / 2 + r.categorySpacing : l + r.barWidth / 2 + r.categorySpacing + r.barWidth * o + r.barSpacing / 2 + r.barSpacing * o }, calculateBarY: function(t, e) { var a = this, i = a.getMeta(), n = a.getScaleForId(i.yAxisID), o = a.getDataset().data[t]; if (n.options.stacked) { for (var r = 0, l = 0, s = 0; s < e; s++) { var d = a.chart.data.datasets[s], u = a.chart.getDatasetMeta(s); u.bar && u.yAxisID === n.id && a.chart.isDatasetVisible(s) && (d.data[t] < 0 ? l += d.data[t] || 0 : r += d.data[t] || 0) } return o < 0 ? n.getPixelForValue(l + o) : n.getPixelForValue(r + o) } return n.getPixelForValue(o) }, draw: function(t) { var a = this, i = t || 1; e.each(a.getMeta().data, function(t, e) { var n = a.getDataset().data[e]; null === n || void 0 === n || isNaN(n) || t.transition(i).draw() }, a) }, setHoverStyle: function(t) { var a = this.chart.data.datasets[t._datasetIndex], i = t._index, n = t.custom || {}, o = t._model; o.backgroundColor = n.hoverBackgroundColor ? n.hoverBackgroundColor : e.getValueAtIndexOrDefault(a.hoverBackgroundColor, i, e.getHoverColor(o.backgroundColor)), o.borderColor = n.hoverBorderColor ? n.hoverBorderColor : e.getValueAtIndexOrDefault(a.hoverBorderColor, i, e.getHoverColor(o.borderColor)), o.borderWidth = n.hoverBorderWidth ? n.hoverBorderWidth : e.getValueAtIndexOrDefault(a.hoverBorderWidth, i, o.borderWidth) }, removeHoverStyle: function(t) { var a = this.chart.data.datasets[t._datasetIndex], i = t._index, n = t.custom || {}, o = t._model, r = this.chart.options.elements.rectangle; o.backgroundColor = n.backgroundColor ? n.backgroundColor : e.getValueAtIndexOrDefault(a.backgroundColor, i, r.backgroundColor), o.borderColor = n.borderColor ? n.borderColor : e.getValueAtIndexOrDefault(a.borderColor, i, r.borderColor), o.borderWidth = n.borderWidth ? n.borderWidth : e.getValueAtIndexOrDefault(a.borderWidth, i, r.borderWidth) } }), t.defaults.horizontalBar = { hover: { mode: "label" }, scales: { xAxes: [{ type: "linear", position: "bottom" }], yAxes: [{ position: "left", type: "category", categoryPercentage: .8, barPercentage: .9, gridLines: { offsetGridLines: !0 } }] }, elements: { rectangle: { borderSkipped: "left" } }, tooltips: { callbacks: { title: function(t, e) { var a = ""; return t.length > 0 && (t[0].yLabel ? a = t[0].yLabel : e.labels.length > 0 && t[0].index < e.labels.length && (a = e.labels[t[0].index])), a }, label: function(t, e) { var a = e.datasets[t.datasetIndex].label || ""; return a + ": " + t.xLabel } } } }, t.controllers.horizontalBar = t.controllers.bar.extend({ updateElement: function(t, a, i, n) { var o = this, r = o.getMeta(), l = o.getScaleForId(r.xAxisID), s = o.getScaleForId(r.yAxisID), d = l.getBasePixel(), u = t.custom || {}, c = o.getDataset(), h = o.chart.options.elements.rectangle; e.extend(t, { _xScale: l, _yScale: s, _datasetIndex: o.index, _index: a, _model: { x: i ? d : o.calculateBarX(a, o.index), y: o.calculateBarY(a, o.index), label: o.chart.data.labels[a], datasetLabel: c.label, base: i ? d : o.calculateBarBase(o.index, a), height: o.calculateBarHeight(a), backgroundColor: u.backgroundColor ? u.backgroundColor : e.getValueAtIndexOrDefault(c.backgroundColor, a, h.backgroundColor), borderSkipped: u.borderSkipped ? u.borderSkipped : h.borderSkipped, borderColor: u.borderColor ? u.borderColor : e.getValueAtIndexOrDefault(c.borderColor, a, h.borderColor), borderWidth: u.borderWidth ? u.borderWidth : e.getValueAtIndexOrDefault(c.borderWidth, a, h.borderWidth) }, draw: function() { function t(t) { return s[(u + t) % 4] } var e = this._chart.ctx, a = this._view, i = a.height / 2, n = a.y - i, o = a.y + i, r = a.base - (a.base - a.x), l = a.borderWidth / 2; a.borderWidth && (n += l, o -= l, r += l), e.beginPath(), e.fillStyle = a.backgroundColor, e.strokeStyle = a.borderColor, e.lineWidth = a.borderWidth; var s = [ [a.base, o], [a.base, n], [r, n], [r, o] ], d = ["bottom", "left", "top", "right"], u = d.indexOf(a.borderSkipped, 0); u === -1 && (u = 0), e.moveTo.apply(e, t(0)); for (var c = 1; c < 4; c++) e.lineTo.apply(e, t(c)); e.fill(), a.borderWidth && e.stroke() }, inRange: function(t, e) { var a = this._view, i = !1; return a && (i = a.x < a.base ? e >= a.y - a.height / 2 && e <= a.y + a.height / 2 && t >= a.x && t <= a.base : e >= a.y - a.height / 2 && e <= a.y + a.height / 2 && t >= a.base && t <= a.x), i } }), t.pivot() }, calculateBarBase: function(t, e) { var a = this, i = a.getMeta(), n = a.getScaleForId(i.xAxisID), o = 0; if (n.options.stacked) { var r = a.chart.data.datasets[t].data[e]; if (r < 0) for (var l = 0; l < t; l++) { var s = a.chart.data.datasets[l], d = a.chart.getDatasetMeta(l); d.bar && d.xAxisID === n.id && a.chart.isDatasetVisible(l) && (o += s.data[e] < 0 ? s.data[e] : 0) } else for (var u = 0; u < t; u++) { var c = a.chart.data.datasets[u], h = a.chart.getDatasetMeta(u); h.bar && h.xAxisID === n.id && a.chart.isDatasetVisible(u) && (o += c.data[e] > 0 ? c.data[e] : 0) } return n.getPixelForValue(o) } return n.getBasePixel() }, getRuler: function(t) { var e, a = this, i = a.getMeta(), n = a.getScaleForId(i.yAxisID), o = a.getBarCount(); e = "category" === n.options.type ? n.getPixelForTick(t + 1) - n.getPixelForTick(t) : n.width / n.ticks.length; var r = e * n.options.categoryPercentage, l = (e - e * n.options.categoryPercentage) / 2, s = r / o; if (n.ticks.length !== a.chart.data.labels.length) { var d = n.ticks.length / a.chart.data.labels.length; s *= d } var u = s * n.options.barPercentage, c = s - s * n.options.barPercentage; return { datasetCount: o, tickHeight: e, categoryHeight: r, categorySpacing: l, fullBarHeight: s, barHeight: u, barSpacing: c } }, calculateBarHeight: function(t) { var e = this, a = e.getScaleForId(e.getMeta().yAxisID), i = e.getRuler(t); return a.options.stacked ? i.categoryHeight : i.barHeight }, calculateBarX: function(t, e) { var a = this, i = a.getMeta(), n = a.getScaleForId(i.xAxisID), o = a.getDataset().data[t]; if (n.options.stacked) { for (var r = 0, l = 0, s = 0; s < e; s++) { var d = a.chart.data.datasets[s], u = a.chart.getDatasetMeta(s); u.bar && u.xAxisID === n.id && a.chart.isDatasetVisible(s) && (d.data[t] < 0 ? l += d.data[t] || 0 : r += d.data[t] || 0) } return o < 0 ? n.getPixelForValue(l + o) : n.getPixelForValue(r + o) } return n.getPixelForValue(o) }, calculateBarY: function(t, e) { var a = this, i = a.getMeta(), n = a.getScaleForId(i.yAxisID), o = a.getBarIndex(e), r = a.getRuler(t), l = n.getPixelForValue(null, t, e, a.chart.isCombo); return l -= a.chart.isCombo ? r.tickHeight / 2 : 0, n.options.stacked ? l + r.categoryHeight / 2 + r.categorySpacing : l + r.barHeight / 2 + r.categorySpacing + r.barHeight * o + r.barSpacing / 2 + r.barSpacing * o } }) } }, {}], 16: [function(t, e, a) { "use strict"; e.exports = function(t) { var e = t.helpers; t.defaults.bubble = { hover: { mode: "single" }, scales: { xAxes: [{ type: "linear", position: "bottom", id: "x-axis-0" }], yAxes: [{ type: "linear", position: "left", id: "y-axis-0" }] }, tooltips: { callbacks: { title: function(t, e) { return "" }, label: function(t, e) { var a = e.datasets[t.datasetIndex].label || "", i = e.datasets[t.datasetIndex].data[t.index]; return a + ": (" + i.x + ", " + i.y + ", " + i.r + ")" } } } }, t.controllers.bubble = t.DatasetController.extend({ dataElementType: t.elements.Point, update: function(t) { var a = this, i = a.getMeta(), n = i.data; e.each(n, function(e, i) { a.updateElement(e, i, t) }) }, updateElement: function(a, i, n) { var o = this, r = o.getMeta(), l = o.getScaleForId(r.xAxisID), s = o.getScaleForId(r.yAxisID), d = a.custom || {}, u = o.getDataset(), c = u.data[i], h = o.chart.options.elements.point, f = o.index; e.extend(a, { _xScale: l, _yScale: s, _datasetIndex: f, _index: i, _model: { x: n ? l.getPixelForDecimal(.5) : l.getPixelForValue(c, i, f, o.chart.isCombo), y: n ? s.getBasePixel() : s.getPixelForValue(c, i, f), radius: n ? 0 : d.radius ? d.radius : o.getRadius(c), hitRadius: d.hitRadius ? d.hitRadius : e.getValueAtIndexOrDefault(u.hitRadius, i, h.hitRadius) } }), t.DatasetController.prototype.removeHoverStyle.call(o, a, h); var g = a._model; g.skip = d.skip ? d.skip : isNaN(g.x) || isNaN(g.y), a.pivot() }, getRadius: function(t) { return t.r || this.chart.options.elements.point.radius }, setHoverStyle: function(a) { var i = this; t.DatasetController.prototype.setHoverStyle.call(i, a); var n = i.chart.data.datasets[a._datasetIndex], o = a._index, r = a.custom || {}, l = a._model; l.radius = r.hoverRadius ? r.hoverRadius : e.getValueAtIndexOrDefault(n.hoverRadius, o, i.chart.options.elements.point.hoverRadius) + i.getRadius(n.data[o]) }, removeHoverStyle: function(e) { var a = this; t.DatasetController.prototype.removeHoverStyle.call(a, e, a.chart.options.elements.point); var i = a.chart.data.datasets[e._datasetIndex].data[e._index], n = e.custom || {}, o = e._model; o.radius = n.radius ? n.radius : a.getRadius(i) } }) } }, {}], 17: [function(t, e, a) { "use strict"; e.exports = function(t) { var e = t.helpers, a = t.defaults; a.doughnut = { animation: { animateRotate: !0, animateScale: !1 }, aspectRatio: 1, hover: { mode: "single" }, legendCallback: function(t) { var e = []; e.push('
    '); var a = t.data, i = a.datasets, n = a.labels; if (i.length) for (var o = 0; o < i[0].data.length; ++o) e.push('
  • '), n[o] && e.push(n[o]), e.push("
  • "); return e.push("
"), e.join("") }, legend: { labels: { generateLabels: function(t) { var a = t.data; return a.labels.length && a.datasets.length ? a.labels.map(function(i, n) { var o = t.getDatasetMeta(0), r = a.datasets[0], l = o.data[n], s = l.custom || {}, d = e.getValueAtIndexOrDefault, u = t.options.elements.arc, c = s.backgroundColor ? s.backgroundColor : d(r.backgroundColor, n, u.backgroundColor), h = s.borderColor ? s.borderColor : d(r.borderColor, n, u.borderColor), f = s.borderWidth ? s.borderWidth : d(r.borderWidth, n, u.borderWidth); return { text: i, fillStyle: c, strokeStyle: h, lineWidth: f, hidden: isNaN(r.data[n]) || o.data[n].hidden, index: n } }) : [] } }, onClick: function(t, e) { var a, i, n, o = e.index, r = this.chart; for (a = 0, i = (r.data.datasets || []).length; a < i; ++a) n = r.getDatasetMeta(a), n.data[o].hidden = !n.data[o].hidden; r.update() } }, cutoutPercentage: 50, rotation: Math.PI * -.5, circumference: 2 * Math.PI, tooltips: { callbacks: { title: function() { return "" }, label: function(t, e) { return e.labels[t.index] + ": " + e.datasets[t.datasetIndex].data[t.index] } } } }, a.pie = e.clone(a.doughnut), e.extend(a.pie, { cutoutPercentage: 0 }), t.controllers.doughnut = t.controllers.pie = t.DatasetController.extend({ dataElementType: t.elements.Arc, linkScales: e.noop, getRingIndex: function(t) { for (var e = 0, a = 0; a < t; ++a) this.chart.isDatasetVisible(a) && ++e; return e }, update: function(t) { var a = this, i = a.chart, n = i.chartArea, o = i.options, r = o.elements.arc, l = n.right - n.left - r.borderWidth, s = n.bottom - n.top - r.borderWidth, d = Math.min(l, s), u = { x: 0, y: 0 }, c = a.getMeta(), h = o.cutoutPercentage, f = o.circumference; if (f < 2 * Math.PI) { var g = o.rotation % (2 * Math.PI); g += 2 * Math.PI * (g >= Math.PI ? -1 : g < -Math.PI ? 1 : 0); var p = g + f, m = { x: Math.cos(g), y: Math.sin(g) }, b = { x: Math.cos(p), y: Math.sin(p) }, v = g <= 0 && 0 <= p || g <= 2 * Math.PI && 2 * Math.PI <= p, x = g <= .5 * Math.PI && .5 * Math.PI <= p || g <= 2.5 * Math.PI && 2.5 * Math.PI <= p, y = g <= -Math.PI && -Math.PI <= p || g <= Math.PI && Math.PI <= p, k = g <= .5 * -Math.PI && .5 * -Math.PI <= p || g <= 1.5 * Math.PI && 1.5 * Math.PI <= p, S = h / 100, w = { x: y ? -1 : Math.min(m.x * (m.x < 0 ? 1 : S), b.x * (b.x < 0 ? 1 : S)), y: k ? -1 : Math.min(m.y * (m.y < 0 ? 1 : S), b.y * (b.y < 0 ? 1 : S)) }, C = { x: v ? 1 : Math.max(m.x * (m.x > 0 ? 1 : S), b.x * (b.x > 0 ? 1 : S)), y: x ? 1 : Math.max(m.y * (m.y > 0 ? 1 : S), b.y * (b.y > 0 ? 1 : S)) }, M = { width: .5 * (C.x - w.x), height: .5 * (C.y - w.y) }; d = Math.min(l / M.width, s / M.height), u = { x: (C.x + w.x) * -.5, y: (C.y + w.y) * -.5 } } i.outerRadius = Math.max(d / 2, 0), i.innerRadius = Math.max(h ? i.outerRadius / 100 * h : 1, 0), i.radiusLength = (i.outerRadius - i.innerRadius) / i.getVisibleDatasetCount(), i.offsetX = u.x * i.outerRadius, i.offsetY = u.y * i.outerRadius, c.total = a.calculateTotal(), a.outerRadius = i.outerRadius - i.radiusLength * a.getRingIndex(a.index), a.innerRadius = a.outerRadius - i.radiusLength, e.each(c.data, function(e, i) { a.updateElement(e, i, t) }) }, updateElement: function(t, a, i) { var n = this, o = n.chart, r = o.chartArea, l = o.options, s = l.animation, d = (l.elements.arc, (r.left + r.right) / 2), u = (r.top + r.bottom) / 2, c = l.rotation, h = l.rotation, f = n.getDataset(), g = i && s.animateRotate ? 0 : t.hidden ? 0 : n.calculateCircumference(f.data[a]) * (l.circumference / (2 * Math.PI)), p = i && s.animateScale ? 0 : n.innerRadius, m = i && s.animateScale ? 0 : n.outerRadius, b = (t.custom || {}, e.getValueAtIndexOrDefault); e.extend(t, { _datasetIndex: n.index, _index: a, _model: { x: d + o.offsetX, y: u + o.offsetY, startAngle: c, endAngle: h, circumference: g, outerRadius: m, innerRadius: p, label: b(f.label, a, o.data.labels[a]) } }); var v = t._model; this.removeHoverStyle(t), i && s.animateRotate || (0 === a ? v.startAngle = l.rotation : v.startAngle = n.getMeta().data[a - 1]._model.endAngle, v.endAngle = v.startAngle + v.circumference), t.pivot() }, removeHoverStyle: function(e) { t.DatasetController.prototype.removeHoverStyle.call(this, e, this.chart.options.elements.arc) }, calculateTotal: function() { var t, a = this.getDataset(), i = this.getMeta(), n = 0; return e.each(i.data, function(e, i) { t = a.data[i], isNaN(t) || e.hidden || (n += Math.abs(t)) }), n }, calculateCircumference: function(t) { var e = this.getMeta().total; return e > 0 && !isNaN(t) ? 2 * Math.PI * (t / e) : 0 } }) } }, {}], 18: [function(t, e, a) { "use strict"; e.exports = function(t) { function e(t, e) { return a.getValueOrDefault(t.showLine, e.showLines) } var a = t.helpers; t.defaults.line = { showLines: !0, hover: { mode: "label" }, scales: { xAxes: [{ type: "category", id: "x-axis-0" }], yAxes: [{ type: "linear", id: "y-axis-0" }] } }, t.controllers.line = t.DatasetController.extend({ datasetElementType: t.elements.Line, dataElementType: t.elements.Point, addElementAndReset: function(a) { var i = this, n = i.chart.options, o = i.getMeta(); t.DatasetController.prototype.addElementAndReset.call(i, a), e(i.getDataset(), n) && 0 !== o.dataset._model.tension && i.updateBezierControlPoints() }, update: function(t) { var i, n, o, r = this, l = r.getMeta(), s = l.dataset, d = l.data || [], u = r.chart.options, c = u.elements.line, h = r.getScaleForId(l.yAxisID), f = r.getDataset(), g = e(f, u); for (g && (o = s.custom || {}, void 0 !== f.tension && void 0 === f.lineTension && (f.lineTension = f.tension), s._scale = h, s._datasetIndex = r.index, s._children = d, s._model = { spanGaps: !!f.spanGaps && f.spanGaps, tension: o.tension ? o.tension : a.getValueOrDefault(f.lineTension, c.tension), backgroundColor: o.backgroundColor ? o.backgroundColor : f.backgroundColor || c.backgroundColor, borderWidth: o.borderWidth ? o.borderWidth : f.borderWidth || c.borderWidth, borderColor: o.borderColor ? o.borderColor : f.borderColor || c.borderColor, borderCapStyle: o.borderCapStyle ? o.borderCapStyle : f.borderCapStyle || c.borderCapStyle, borderDash: o.borderDash ? o.borderDash : f.borderDash || c.borderDash, borderDashOffset: o.borderDashOffset ? o.borderDashOffset : f.borderDashOffset || c.borderDashOffset, borderJoinStyle: o.borderJoinStyle ? o.borderJoinStyle : f.borderJoinStyle || c.borderJoinStyle, fill: o.fill ? o.fill : void 0 !== f.fill ? f.fill : c.fill, scaleTop: h.top, scaleBottom: h.bottom, scaleZero: h.getBasePixel() }, s.pivot()), i = 0, n = d.length; i < n; ++i) r.updateElement(d[i], i, t); for (g && 0 !== s._model.tension && r.updateBezierControlPoints(), i = 0, n = d.length; i < n; ++i) d[i].pivot() }, getPointBackgroundColor: function(t, e) { var i = this.chart.options.elements.point.backgroundColor, n = this.getDataset(), o = t.custom || {}; return o.backgroundColor ? i = o.backgroundColor : n.pointBackgroundColor ? i = a.getValueAtIndexOrDefault(n.pointBackgroundColor, e, i) : n.backgroundColor && (i = n.backgroundColor), i }, getPointBorderColor: function(t, e) { var i = this.chart.options.elements.point.borderColor, n = this.getDataset(), o = t.custom || {}; return o.borderColor ? i = o.borderColor : n.pointBorderColor ? i = a.getValueAtIndexOrDefault(n.pointBorderColor, e, i) : n.borderColor && (i = n.borderColor), i }, getPointBorderWidth: function(t, e) { var i = this.chart.options.elements.point.borderWidth, n = this.getDataset(), o = t.custom || {}; return o.borderWidth ? i = o.borderWidth : n.pointBorderWidth ? i = a.getValueAtIndexOrDefault(n.pointBorderWidth, e, i) : n.borderWidth && (i = n.borderWidth), i }, updateElement: function(t, e, i) { var n, o, r = this, l = r.getMeta(), s = t.custom || {}, d = r.getDataset(), u = r.index, c = d.data[e], h = r.getScaleForId(l.yAxisID), f = r.getScaleForId(l.xAxisID), g = r.chart.options.elements.point; void 0 !== d.radius && void 0 === d.pointRadius && (d.pointRadius = d.radius), void 0 !== d.hitRadius && void 0 === d.pointHitRadius && (d.pointHitRadius = d.hitRadius), n = f.getPixelForValue(c, e, u, r.chart.isCombo), o = i ? h.getBasePixel() : r.calculatePointY(c, e, u, r.chart.isCombo), t._xScale = f, t._yScale = h, t._datasetIndex = u, t._index = e, t._model = { x: n, y: o, skip: s.skip || isNaN(n) || isNaN(o), radius: s.radius || a.getValueAtIndexOrDefault(d.pointRadius, e, g.radius), pointStyle: s.pointStyle || a.getValueAtIndexOrDefault(d.pointStyle, e, g.pointStyle), backgroundColor: r.getPointBackgroundColor(t, e), borderColor: r.getPointBorderColor(t, e), borderWidth: r.getPointBorderWidth(t, e), tension: l.dataset._model ? l.dataset._model.tension : 0, hitRadius: s.hitRadius || a.getValueAtIndexOrDefault(d.pointHitRadius, e, g.hitRadius) } }, calculatePointY: function(t, e, a, i) { var n, o, r, l = this, s = l.chart, d = l.getMeta(), u = l.getScaleForId(d.yAxisID), c = 0, h = 0; if (u.options.stacked) { for (n = 0; n < a; n++) o = s.data.datasets[n], r = s.getDatasetMeta(n), "line" === r.type && s.isDatasetVisible(n) && (o.data[e] < 0 ? h += o.data[e] || 0 : c += o.data[e] || 0); return t < 0 ? u.getPixelForValue(h + t) : u.getPixelForValue(c + t) } return u.getPixelForValue(t) }, updateBezierControlPoints: function() { var t, e, i, n, o, r = this.getMeta(), l = (this.chart.chartArea, r.data || []); for (t = 0, e = l.length; t < e; ++t) i = l[t], n = i._model, o = a.splineCurve(a.previousItem(l, t)._model, n, a.nextItem(l, t)._model, r.dataset._model.tension), n.controlPointPreviousX = o.previous.x, n.controlPointPreviousY = o.previous.y, n.controlPointNextX = o.next.x, n.controlPointNextY = o.next.y }, draw: function(t) { var a, i, n = this, o = n.getMeta(), r = o.data || [], l = t || 1; for (a = 0, i = r.length; a < i; ++a) r[a].transition(l); for (e(n.getDataset(), n.chart.options) && o.dataset.transition(l).draw(), a = 0, i = r.length; a < i; ++a) r[a].draw() }, setHoverStyle: function(t) { var e = this.chart.data.datasets[t._datasetIndex], i = t._index, n = t.custom || {}, o = t._model; o.radius = n.hoverRadius || a.getValueAtIndexOrDefault(e.pointHoverRadius, i, this.chart.options.elements.point.hoverRadius), o.backgroundColor = n.hoverBackgroundColor || a.getValueAtIndexOrDefault(e.pointHoverBackgroundColor, i, a.getHoverColor(o.backgroundColor)), o.borderColor = n.hoverBorderColor || a.getValueAtIndexOrDefault(e.pointHoverBorderColor, i, a.getHoverColor(o.borderColor)), o.borderWidth = n.hoverBorderWidth || a.getValueAtIndexOrDefault(e.pointHoverBorderWidth, i, o.borderWidth) }, removeHoverStyle: function(t) { var e = this, i = e.chart.data.datasets[t._datasetIndex], n = t._index, o = t.custom || {}, r = t._model; void 0 !== i.radius && void 0 === i.pointRadius && (i.pointRadius = i.radius), r.radius = o.radius || a.getValueAtIndexOrDefault(i.pointRadius, n, e.chart.options.elements.point.radius), r.backgroundColor = e.getPointBackgroundColor(t, n), r.borderColor = e.getPointBorderColor(t, n), r.borderWidth = e.getPointBorderWidth(t, n) } }) } }, {}], 19: [function(t, e, a) { "use strict"; e.exports = function(t) { var e = t.helpers; t.defaults.polarArea = { scale: { type: "radialLinear", lineArc: !0 }, animation: { animateRotate: !0, animateScale: !0 }, aspectRatio: 1, legendCallback: function(t) { var e = []; e.push('
    '); var a = t.data, i = a.datasets, n = a.labels; if (i.length) for (var o = 0; o < i[0].data.length; ++o) e.push('
  • '), n[o] && e.push(n[o]), e.push("
  • "); return e.push("
"), e.join("") }, legend: { labels: { generateLabels: function(t) { var a = t.data; return a.labels.length && a.datasets.length ? a.labels.map(function(i, n) { var o = t.getDatasetMeta(0), r = a.datasets[0], l = o.data[n], s = l.custom || {}, d = e.getValueAtIndexOrDefault, u = t.options.elements.arc, c = s.backgroundColor ? s.backgroundColor : d(r.backgroundColor, n, u.backgroundColor), h = s.borderColor ? s.borderColor : d(r.borderColor, n, u.borderColor), f = s.borderWidth ? s.borderWidth : d(r.borderWidth, n, u.borderWidth); return { text: i, fillStyle: c, strokeStyle: h, lineWidth: f, hidden: isNaN(r.data[n]) || o.data[n].hidden, index: n } }) : [] } }, onClick: function(t, e) { var a, i, n, o = e.index, r = this.chart; for (a = 0, i = (r.data.datasets || []).length; a < i; ++a) n = r.getDatasetMeta(a), n.data[o].hidden = !n.data[o].hidden; r.update() } }, tooltips: { callbacks: { title: function() { return "" }, label: function(t, e) { return e.labels[t.index] + ": " + t.yLabel } } } }, t.controllers.polarArea = t.DatasetController.extend({ dataElementType: t.elements.Arc, linkScales: e.noop, update: function(t) { var a = this, i = a.chart, n = i.chartArea, o = a.getMeta(), r = i.options, l = r.elements.arc, s = Math.min(n.right - n.left, n.bottom - n.top); i.outerRadius = Math.max((s - l.borderWidth / 2) / 2, 0), i.innerRadius = Math.max(r.cutoutPercentage ? i.outerRadius / 100 * r.cutoutPercentage : 1, 0), i.radiusLength = (i.outerRadius - i.innerRadius) / i.getVisibleDatasetCount(), a.outerRadius = i.outerRadius - i.radiusLength * a.index, a.innerRadius = a.outerRadius - i.radiusLength, o.count = a.countVisibleElements(), e.each(o.data, function(e, i) { a.updateElement(e, i, t) }) }, updateElement: function(t, a, i) { for (var n = this, o = n.chart, r = o.chartArea, l = n.getDataset(), s = o.options, d = s.animation, u = (s.elements.arc, t.custom || {}, o.scale), c = e.getValueAtIndexOrDefault, h = o.data.labels, f = n.calculateCircumference(l.data[a]), g = (r.left + r.right) / 2, p = (r.top + r.bottom) / 2, m = 0, b = n.getMeta(), v = 0; v < a; ++v) isNaN(l.data[v]) || b.data[v].hidden || ++m; var x = -.5 * Math.PI, y = t.hidden ? 0 : u.getDistanceFromCenterForValue(l.data[a]), k = x + f * m, S = k + (t.hidden ? 0 : f), w = d.animateScale ? 0 : u.getDistanceFromCenterForValue(l.data[a]); e.extend(t, { _datasetIndex: n.index, _index: a, _scale: u, _model: { x: g, y: p, innerRadius: 0, outerRadius: i ? w : y, startAngle: i && d.animateRotate ? x : k, endAngle: i && d.animateRotate ? x : S, label: c(h, a, h[a]) } }), n.removeHoverStyle(t), t.pivot() }, removeHoverStyle: function(e) { t.DatasetController.prototype.removeHoverStyle.call(this, e, this.chart.options.elements.arc) }, countVisibleElements: function() { var t = this.getDataset(), a = this.getMeta(), i = 0; return e.each(a.data, function(e, a) { isNaN(t.data[a]) || e.hidden || i++ }), i }, calculateCircumference: function(t) { var e = this.getMeta().count; return e > 0 && !isNaN(t) ? 2 * Math.PI / e : 0 } }) } }, {}], 20: [function(t, e, a) { "use strict"; e.exports = function(t) { var e = t.helpers; t.defaults.radar = { scale: { type: "radialLinear" }, elements: { line: { tension: 0 } } }, t.controllers.radar = t.DatasetController.extend({ datasetElementType: t.elements.Line, dataElementType: t.elements.Point, linkScales: e.noop, addElementAndReset: function(e) { t.DatasetController.prototype.addElementAndReset.call(this, e), this.updateBezierControlPoints() }, update: function(t) { var a = this, i = a.getMeta(), n = i.dataset, o = i.data, r = n.custom || {}, l = a.getDataset(), s = a.chart.options.elements.line, d = a.chart.scale; void 0 !== l.tension && void 0 === l.lineTension && (l.lineTension = l.tension), e.extend(i.dataset, { _datasetIndex: a.index, _children: o, _loop: !0, _model: { tension: r.tension ? r.tension : e.getValueOrDefault(l.lineTension, s.tension), backgroundColor: r.backgroundColor ? r.backgroundColor : l.backgroundColor || s.backgroundColor, borderWidth: r.borderWidth ? r.borderWidth : l.borderWidth || s.borderWidth, borderColor: r.borderColor ? r.borderColor : l.borderColor || s.borderColor, fill: r.fill ? r.fill : void 0 !== l.fill ? l.fill : s.fill, borderCapStyle: r.borderCapStyle ? r.borderCapStyle : l.borderCapStyle || s.borderCapStyle, borderDash: r.borderDash ? r.borderDash : l.borderDash || s.borderDash, borderDashOffset: r.borderDashOffset ? r.borderDashOffset : l.borderDashOffset || s.borderDashOffset, borderJoinStyle: r.borderJoinStyle ? r.borderJoinStyle : l.borderJoinStyle || s.borderJoinStyle, scaleTop: d.top, scaleBottom: d.bottom, scaleZero: d.getBasePosition() } }), i.dataset.pivot(), e.each(o, function(e, i) { a.updateElement(e, i, t) }, a), a.updateBezierControlPoints() }, updateElement: function(t, a, i) { var n = this, o = t.custom || {}, r = n.getDataset(), l = n.chart.scale, s = n.chart.options.elements.point, d = l.getPointPositionForValue(a, r.data[a]); e.extend(t, { _datasetIndex: n.index, _index: a, _scale: l, _model: { x: i ? l.xCenter : d.x, y: i ? l.yCenter : d.y, tension: o.tension ? o.tension : e.getValueOrDefault(r.tension, n.chart.options.elements.line.tension), radius: o.radius ? o.radius : e.getValueAtIndexOrDefault(r.pointRadius, a, s.radius), backgroundColor: o.backgroundColor ? o.backgroundColor : e.getValueAtIndexOrDefault(r.pointBackgroundColor, a, s.backgroundColor), borderColor: o.borderColor ? o.borderColor : e.getValueAtIndexOrDefault(r.pointBorderColor, a, s.borderColor), borderWidth: o.borderWidth ? o.borderWidth : e.getValueAtIndexOrDefault(r.pointBorderWidth, a, s.borderWidth), pointStyle: o.pointStyle ? o.pointStyle : e.getValueAtIndexOrDefault(r.pointStyle, a, s.pointStyle), hitRadius: o.hitRadius ? o.hitRadius : e.getValueAtIndexOrDefault(r.hitRadius, a, s.hitRadius) } }), t._model.skip = o.skip ? o.skip : isNaN(t._model.x) || isNaN(t._model.y) }, updateBezierControlPoints: function() { var t = this.chart.chartArea, a = this.getMeta(); e.each(a.data, function(i, n) { var o = i._model, r = e.splineCurve(e.previousItem(a.data, n, !0)._model, o, e.nextItem(a.data, n, !0)._model, o.tension); o.controlPointPreviousX = Math.max(Math.min(r.previous.x, t.right), t.left), o.controlPointPreviousY = Math.max(Math.min(r.previous.y, t.bottom), t.top), o.controlPointNextX = Math.max(Math.min(r.next.x, t.right), t.left), o.controlPointNextY = Math.max(Math.min(r.next.y, t.bottom), t.top), i.pivot() }) }, draw: function(t) { var a = this.getMeta(), i = t || 1; e.each(a.data, function(t, e) { t.transition(i) }), a.dataset.transition(i).draw(), e.each(a.data, function(t) { t.draw() }) }, setHoverStyle: function(t) { var a = this.chart.data.datasets[t._datasetIndex], i = t.custom || {}, n = t._index, o = t._model; o.radius = i.hoverRadius ? i.hoverRadius : e.getValueAtIndexOrDefault(a.pointHoverRadius, n, this.chart.options.elements.point.hoverRadius), o.backgroundColor = i.hoverBackgroundColor ? i.hoverBackgroundColor : e.getValueAtIndexOrDefault(a.pointHoverBackgroundColor, n, e.getHoverColor(o.backgroundColor)), o.borderColor = i.hoverBorderColor ? i.hoverBorderColor : e.getValueAtIndexOrDefault(a.pointHoverBorderColor, n, e.getHoverColor(o.borderColor)), o.borderWidth = i.hoverBorderWidth ? i.hoverBorderWidth : e.getValueAtIndexOrDefault(a.pointHoverBorderWidth, n, o.borderWidth) }, removeHoverStyle: function(t) { var a = this.chart.data.datasets[t._datasetIndex], i = t.custom || {}, n = t._index, o = t._model, r = this.chart.options.elements.point; o.radius = i.radius ? i.radius : e.getValueAtIndexOrDefault(a.radius, n, r.radius), o.backgroundColor = i.backgroundColor ? i.backgroundColor : e.getValueAtIndexOrDefault(a.pointBackgroundColor, n, r.backgroundColor), o.borderColor = i.borderColor ? i.borderColor : e.getValueAtIndexOrDefault(a.pointBorderColor, n, r.borderColor), o.borderWidth = i.borderWidth ? i.borderWidth : e.getValueAtIndexOrDefault(a.pointBorderWidth, n, r.borderWidth) } }) } }, {}], 21: [function(t, e, a) { "use strict"; e.exports = function(t) { var e = t.helpers; t.defaults.global.animation = { duration: 1e3, easing: "easeOutQuart", onProgress: e.noop, onComplete: e.noop }, t.Animation = t.Element.extend({ currentStep: null, numSteps: 60, easing: "", render: null, onAnimationProgress: null, onAnimationComplete: null }), t.animationService = { frameDuration: 17, animations: [], dropFrames: 0, request: null, addAnimation: function(t, e, a, i) { var n = this; i || (t.animating = !0); for (var o = 0; o < n.animations.length; ++o) if (n.animations[o].chartInstance === t) return void(n.animations[o].animationObject = e); n.animations.push({ chartInstance: t, animationObject: e }), 1 === n.animations.length && n.requestAnimationFrame() }, cancelAnimation: function(t) { var a = e.findIndex(this.animations, function(e) { return e.chartInstance === t }); a !== -1 && (this.animations.splice(a, 1), t.animating = !1) }, requestAnimationFrame: function() { var t = this; null === t.request && (t.request = e.requestAnimFrame.call(window, function() { t.request = null, t.startDigest() })) }, startDigest: function() { var t = this, e = Date.now(), a = 0; t.dropFrames > 1 && (a = Math.floor(t.dropFrames), t.dropFrames = t.dropFrames % 1); for (var i = 0; i < t.animations.length;) null === t.animations[i].animationObject.currentStep && (t.animations[i].animationObject.currentStep = 0), t.animations[i].animationObject.currentStep += 1 + a, t.animations[i].animationObject.currentStep > t.animations[i].animationObject.numSteps && (t.animations[i].animationObject.currentStep = t.animations[i].animationObject.numSteps), t.animations[i].animationObject.render(t.animations[i].chartInstance, t.animations[i].animationObject), t.animations[i].animationObject.onAnimationProgress && t.animations[i].animationObject.onAnimationProgress.call && t.animations[i].animationObject.onAnimationProgress.call(t.animations[i].chartInstance, t.animations[i]), t.animations[i].animationObject.currentStep === t.animations[i].animationObject.numSteps ? (t.animations[i].animationObject.onAnimationComplete && t.animations[i].animationObject.onAnimationComplete.call && t.animations[i].animationObject.onAnimationComplete.call(t.animations[i].chartInstance, t.animations[i]), t.animations[i].chartInstance.animating = !1, t.animations.splice(i, 1)) : ++i; var n = Date.now(), o = (n - e) / t.frameDuration; t.dropFrames += o, t.animations.length > 0 && t.requestAnimationFrame() } } } }, {}], 22: [function(t, e, a) { "use strict"; e.exports = function(t) { var e = t.helpers; t.types = {}, t.instances = {}, t.controllers = {}, t.Controller = function(a) { return this.chart = a, this.config = a.config, this.options = this.config.options = e.configMerge(t.defaults.global, t.defaults[this.config.type], this.config.options || {}), this.id = e.uid(), Object.defineProperty(this, "data", { get: function() { return this.config.data } }), t.instances[this.id] = this, this.options.responsive && this.resize(!0), this.initialize(), this }, e.extend(t.Controller.prototype, { initialize: function() { var e = this; return t.plugins.notify("beforeInit", [e]), e.bindEvents(), e.ensureScalesHaveIDs(), e.buildOrUpdateControllers(), e.buildScales(), e.updateLayout(), e.resetElements(), e.initToolTip(), e.update(), t.plugins.notify("afterInit", [e]), e }, clear: function() { return e.clear(this.chart), this }, stop: function() { return t.animationService.cancelAnimation(this), this }, resize: function(a) { var i = this, n = i.chart, o = n.canvas, r = e.getMaximumWidth(o), l = n.aspectRatio, s = i.options.maintainAspectRatio && isNaN(l) === !1 && isFinite(l) && 0 !== l ? r / l : e.getMaximumHeight(o), d = n.width !== r || n.height !== s; if (!d) return i; o.width = n.width = r, o.height = n.height = s, e.retinaScale(n); var u = { width: r, height: s }; return t.plugins.notify("resize", [i, u]), i.options.onResize && i.options.onResize(i, u), a || (i.stop(), i.update(i.options.responsiveAnimationDuration)), i }, ensureScalesHaveIDs: function() { var t = this.options, a = t.scales || {}, i = t.scale; e.each(a.xAxes, function(t, e) { t.id = t.id || "x-axis-" + e }), e.each(a.yAxes, function(t, e) { t.id = t.id || "y-axis-" + e }), i && (i.id = i.id || "scale") }, buildScales: function() { var a = this, i = a.options, n = a.scales = {}, o = []; i.scales && (o = o.concat((i.scales.xAxes || []).map(function(t) { return { options: t, dtype: "category" } }), (i.scales.yAxes || []).map(function(t) { return { options: t, dtype: "linear" } }))), i.scale && o.push({ options: i.scale, dtype: "radialLinear", isDefault: !0 }), e.each(o, function(i, o) { var r = i.options, l = e.getValueOrDefault(r.type, i.dtype), s = t.scaleService.getScaleConstructor(l); if (s) { var d = new s({ id: r.id, options: r, ctx: a.chart.ctx, chart: a }); n[d.id] = d, i.isDefault && (a.scale = d) } }), t.scaleService.addScalesToLayout(this) }, updateLayout: function() { t.layoutService.update(this, this.chart.width, this.chart.height) }, buildOrUpdateControllers: function() { var a = this, i = [], n = []; if (e.each(a.data.datasets, function(e, o) { var r = a.getDatasetMeta(o); r.type || (r.type = e.type || a.config.type), i.push(r.type), r.controller ? r.controller.updateIndex(o) : (r.controller = new t.controllers[r.type](a, o), n.push(r.controller)) }, a), i.length > 1) for (var o = 1; o < i.length; o++) if (i[o] !== i[o - 1]) { a.isCombo = !0; break } return n }, resetElements: function() { var t = this; e.each(t.data.datasets, function(e, a) { t.getDatasetMeta(a).controller.reset() }, t) }, update: function(a, i) { var n = this; t.plugins.notify("beforeUpdate", [n]), n.tooltip._data = n.data; var o = n.buildOrUpdateControllers(); e.each(n.data.datasets, function(t, e) { n.getDatasetMeta(e).controller.buildOrUpdateElements() }, n), t.layoutService.update(n, n.chart.width, n.chart.height), t.plugins.notify("afterScaleUpdate", [n]), e.each(o, function(t) { t.reset() }), n.updateDatasets(), t.plugins.notify("afterUpdate", [n]), n.render(a, i) }, updateDatasets: function() { var e, a, i = this; if (t.plugins.notify("beforeDatasetsUpdate", [i])) { for (e = 0, a = i.data.datasets.length; e < a; ++e) i.getDatasetMeta(e).controller.update(); t.plugins.notify("afterDatasetsUpdate", [i]) } }, render: function(a, i) { var n = this; t.plugins.notify("beforeRender", [n]); var o = n.options.animation; if (o && ("undefined" != typeof a && 0 !== a || "undefined" == typeof a && 0 !== o.duration)) { var r = new t.Animation; r.numSteps = (a || o.duration) / 16.66, r.easing = o.easing, r.render = function(t, a) { var i = e.easingEffects[a.easing], n = a.currentStep / a.numSteps, o = i(n); t.draw(o, n, a.currentStep) }, r.onAnimationProgress = o.onProgress, r.onAnimationComplete = o.onComplete, t.animationService.addAnimation(n, r, a, i) } else n.draw(), o && o.onComplete && o.onComplete.call && o.onComplete.call(n); return n }, draw: function(a) { var i = this, n = a || 1; i.clear(), t.plugins.notify("beforeDraw", [i, n]), e.each(i.boxes, function(t) { t.draw(i.chartArea) }, i), i.scale && i.scale.draw(), t.plugins.notify("beforeDatasetsDraw", [i, n]), e.each(i.data.datasets, function(t, e) { i.isDatasetVisible(e) && i.getDatasetMeta(e).controller.draw(a) }, i, !0), t.plugins.notify("afterDatasetsDraw", [i, n]), i.tooltip.transition(n).draw(), t.plugins.notify("afterDraw", [i, n]) }, getElementAtEvent: function(t) { var a = this, i = e.getRelativePosition(t, a.chart), n = []; return e.each(a.data.datasets, function(t, o) { if (a.isDatasetVisible(o)) { var r = a.getDatasetMeta(o); e.each(r.data, function(t, e) { if (t.inRange(i.x, i.y)) return n.push(t), n }) } }), n }, getElementsAtEvent: function(t) { var a = this, i = e.getRelativePosition(t, a.chart), n = [], o = function() { if (a.data.datasets) for (var t = 0; t < a.data.datasets.length; t++) { var e = a.getDatasetMeta(t); if (a.isDatasetVisible(t)) for (var n = 0; n < e.data.length; n++) if (e.data[n].inRange(i.x, i.y)) return e.data[n] } }.call(a); return o ? (e.each(a.data.datasets, function(t, e) { if (a.isDatasetVisible(e)) { var i = a.getDatasetMeta(e); n.push(i.data[o._index]) } }, a), n) : n }, getElementsAtEventForMode: function(t, e) { var a = this; switch (e) { case "single": return a.getElementAtEvent(t); case "label": return a.getElementsAtEvent(t); case "dataset": return a.getDatasetAtEvent(t); default: return t } }, getDatasetAtEvent: function(t) { var e = this.getElementAtEvent(t); return e.length > 0 && (e = this.getDatasetMeta(e[0]._datasetIndex).data), e }, getDatasetMeta: function(t) { var e = this, a = e.data.datasets[t]; a._meta || (a._meta = {}); var i = a._meta[e.id]; return i || (i = a._meta[e.id] = { type: null, data: [], dataset: null, controller: null, hidden: null, xAxisID: null, yAxisID: null }), i }, getVisibleDatasetCount: function() { for (var t = 0, e = 0, a = this.data.datasets.length; e < a; ++e) this.isDatasetVisible(e) && t++; return t }, isDatasetVisible: function(t) { var e = this.getDatasetMeta(t); return "boolean" == typeof e.hidden ? !e.hidden : !this.data.datasets[t].hidden }, generateLegend: function() { return this.options.legendCallback(this) }, destroy: function() { var a = this; a.stop(), a.clear(), e.unbindEvents(a, a.events), e.removeResizeListener(a.chart.canvas.parentNode); var i = a.chart.canvas; i.width = a.chart.width, i.height = a.chart.height, void 0 !== a.chart.originalDevicePixelRatio && a.chart.ctx.scale(1 / a.chart.originalDevicePixelRatio, 1 / a.chart.originalDevicePixelRatio), i.style.width = a.chart.originalCanvasStyleWidth, i.style.height = a.chart.originalCanvasStyleHeight, t.plugins.notify("destroy", [a]), delete t.instances[a.id] }, toBase64Image: function() { return this.chart.canvas.toDataURL.apply(this.chart.canvas, arguments) }, initToolTip: function() { var e = this; e.tooltip = new t.Tooltip({ _chart: e.chart, _chartInstance: e, _data: e.data, _options: e.options.tooltips }, e) }, bindEvents: function() { var t = this; e.bindEvents(t, t.options.events, function(e) { t.eventHandler(e) }) }, updateHoverStyle: function(t, e, a) { var i, n, o, r = a ? "setHoverStyle" : "removeHoverStyle"; switch (e) { case "single": t = [t[0]]; break; case "label": case "dataset": break; default: return } for (n = 0, o = t.length; n < o; ++n) i = t[n], i && this.getDatasetMeta(i._datasetIndex).controller[r](i) }, eventHandler: function(t) { var a = this, i = a.tooltip, n = a.options || {}, o = n.hover, r = n.tooltips; return a.lastActive = a.lastActive || [], a.lastTooltipActive = a.lastTooltipActive || [], "mouseout" === t.type ? (a.active = [], a.tooltipActive = []) : (a.active = a.getElementsAtEventForMode(t, o.mode), a.tooltipActive = a.getElementsAtEventForMode(t, r.mode)), o.onHover && o.onHover.call(a, a.active), "mouseup" !== t.type && "click" !== t.type || (n.onClick && n.onClick.call(a, t, a.active), a.legend && a.legend.handleEvent && a.legend.handleEvent(t)), a.lastActive.length && a.updateHoverStyle(a.lastActive, o.mode, !1), a.active.length && o.mode && a.updateHoverStyle(a.active, o.mode, !0), (r.enabled || r.custom) && (i.initialize(), i._active = a.tooltipActive, i.update(!0)), i.pivot(), a.animating || e.arrayEquals(a.active, a.lastActive) && e.arrayEquals(a.tooltipActive, a.lastTooltipActive) || (a.stop(), (r.enabled || r.custom) && i.update(!0), a.render(o.animationDuration, !0)), a.lastActive = a.active, a.lastTooltipActive = a.tooltipActive, a } }) } }, {}], 23: [function(t, e, a) { "use strict"; e.exports = function(t) { var e = t.helpers, a = e.noop; t.DatasetController = function(t, e) { this.initialize.call(this, t, e) }, e.extend(t.DatasetController.prototype, { datasetElementType: null, dataElementType: null, initialize: function(t, e) { var a = this; a.chart = t, a.index = e, a.linkScales(), a.addElements() }, updateIndex: function(t) { this.index = t }, linkScales: function() { var t = this, e = t.getMeta(), a = t.getDataset(); null === e.xAxisID && (e.xAxisID = a.xAxisID || t.chart.options.scales.xAxes[0].id), null === e.yAxisID && (e.yAxisID = a.yAxisID || t.chart.options.scales.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] }, reset: function() { this.update(!0) }, createMetaDataset: function() { var t = this, e = t.datasetElementType; return e && new e({ _chart: t.chart.chart, _datasetIndex: t.index }) }, createMetaData: function(t) { var e = this, a = e.dataElementType; return a && new a({ _chart: e.chart.chart, _datasetIndex: e.index, _index: t }) }, addElements: function() { var t, e, a = this, i = a.getMeta(), n = a.getDataset().data || [], o = i.data; for (t = 0, e = n.length; t < e; ++t) o[t] = o[t] || a.createMetaData(i, t); i.dataset = i.dataset || a.createMetaDataset() }, addElementAndReset: function(t) { var e = this, a = e.createMetaData(t); e.getMeta().data.splice(t, 0, a), e.updateElement(a, t, !0) }, buildOrUpdateElements: function() { var t = this.getMeta(), e = t.data, a = this.getDataset().data.length, i = e.length; if (a < i) e.splice(a, i - a); else if (a > i) for (var n = i; n < a; ++n) this.addElementAndReset(n) }, update: a, draw: function(t) { var a = t || 1; e.each(this.getMeta().data, function(t, e) { t.transition(a).draw() }) }, removeHoverStyle: function(t, a) { var i = this.chart.data.datasets[t._datasetIndex], n = t._index, o = t.custom || {}, r = e.getValueAtIndexOrDefault, l = (e.color, t._model); l.backgroundColor = o.backgroundColor ? o.backgroundColor : r(i.backgroundColor, n, a.backgroundColor), l.borderColor = o.borderColor ? o.borderColor : r(i.borderColor, n, a.borderColor), l.borderWidth = o.borderWidth ? o.borderWidth : r(i.borderWidth, n, a.borderWidth) }, setHoverStyle: function(t) { var a = this.chart.data.datasets[t._datasetIndex], i = t._index, n = t.custom || {}, o = e.getValueAtIndexOrDefault, r = (e.color, e.getHoverColor), l = t._model; l.backgroundColor = n.hoverBackgroundColor ? n.hoverBackgroundColor : o(a.hoverBackgroundColor, i, r(l.backgroundColor)), l.borderColor = n.hoverBorderColor ? n.hoverBorderColor : o(a.hoverBorderColor, i, r(l.borderColor)), l.borderWidth = n.hoverBorderWidth ? n.hoverBorderWidth : o(a.hoverBorderWidth, i, l.borderWidth) } }), t.DatasetController.extend = e.inherits } }, {}], 24: [function(t, e, a) { "use strict"; e.exports = function(t) { var e = t.helpers; t.elements = {}, t.Element = function(t) { e.extend(this, t), this.initialize.apply(this, arguments) }, e.extend(t.Element.prototype, { initialize: function() { this.hidden = !1 }, pivot: function() { var t = this; return t._view || (t._view = e.clone(t._model)), t._start = e.clone(t._view), t }, transition: function(t) { var a = this; return a._view || (a._view = e.clone(a._model)), 1 === t ? (a._view = a._model, a._start = null, a) : (a._start || a.pivot(), e.each(a._model, function(i, n) { if ("_" === n[0]); else if (a._view.hasOwnProperty(n)) if (i === a._view[n]); else if ("string" == typeof i) try { var o = e.color(a._model[n]).mix(e.color(a._start[n]), t); a._view[n] = o.rgbString() } catch (r) { a._view[n] = i } else if ("number" == typeof i) { var l = void 0 !== a._start[n] && isNaN(a._start[n]) === !1 ? a._start[n] : 0; a._view[n] = (a._model[n] - l) * t + l } else a._view[n] = i; else "number" != typeof i || isNaN(a._view[n]) ? a._view[n] = i : a._view[n] = i * t }, a), a) }, tooltipPosition: function() { return { x: this._model.x, y: this._model.y } }, hasValue: function() { return e.isNumber(this._model.x) && e.isNumber(this._model.y) } }), t.Element.extend = e.inherits } }, {}], 25: [function(t, e, a) { "use strict"; var i = t(3); e.exports = function(t) { function e(t, e, a) { var i; return "string" == typeof t ? (i = parseInt(t, 10), t.indexOf("%") != -1 && (i = i / 100 * e.parentNode[a])) : i = t, i } function a(t) { return void 0 !== t && null !== t && "none" !== t } function n(t, i, n) { var o = document.defaultView, r = t.parentNode, l = o.getComputedStyle(t)[i], s = o.getComputedStyle(r)[i], d = a(l), u = a(s), c = Number.POSITIVE_INFINITY; return d || u ? Math.min(d ? e(l, t, n) : c, u ? e(s, r, n) : c) : "none" } var o = t.helpers = {}; o.each = function(t, e, a, i) { var n, r; if (o.isArray(t)) if (r = t.length, i) for (n = r - 1; n >= 0; n--) e.call(a, t[n], n); else for (n = 0; n < r; n++) e.call(a, t[n], n); else if ("object" == typeof t) { var l = Object.keys(t); for (r = l.length, n = 0; n < r; n++) e.call(a, t[l[n]], l[n]) } }, o.clone = function(t) { var e = {}; return o.each(t, function(t, a) { o.isArray(t) ? e[a] = t.slice(0) : "object" == typeof t && null !== t ? e[a] = o.clone(t) : e[a] = t }), e }, o.extend = function(t) { for (var e = function(e, a) { t[a] = e }, a = 1, i = arguments.length; a < i; a++) o.each(arguments[a], e); return t }, o.configMerge = function(e) { var a = o.clone(e); return o.each(Array.prototype.slice.call(arguments, 1), function(e) { o.each(e, function(e, i) { if ("scales" === i) a[i] = o.scaleMerge(a.hasOwnProperty(i) ? a[i] : {}, e); else if ("scale" === i) a[i] = o.configMerge(a.hasOwnProperty(i) ? a[i] : {}, t.scaleService.getScaleDefaults(e.type), e); else if (a.hasOwnProperty(i) && o.isArray(a[i]) && o.isArray(e)) { var n = a[i]; o.each(e, function(t, e) { e < n.length ? "object" == typeof n[e] && null !== n[e] && "object" == typeof t && null !== t ? n[e] = o.configMerge(n[e], t) : n[e] = t : n.push(t) }) } else a.hasOwnProperty(i) && "object" == typeof a[i] && null !== a[i] && "object" == typeof e ? a[i] = o.configMerge(a[i], e) : a[i] = e }) }), a }, o.scaleMerge = function(e, a) { var i = o.clone(e); return o.each(a, function(e, a) { "xAxes" === a || "yAxes" === a ? i.hasOwnProperty(a) ? o.each(e, function(e, n) { var r = o.getValueOrDefault(e.type, "xAxes" === a ? "category" : "linear"), l = t.scaleService.getScaleDefaults(r); n >= i[a].length || !i[a][n].type ? i[a].push(o.configMerge(l, e)) : e.type && e.type !== i[a][n].type ? i[a][n] = o.configMerge(i[a][n], l, e) : i[a][n] = o.configMerge(i[a][n], e) }) : (i[a] = [], o.each(e, function(e) { var n = o.getValueOrDefault(e.type, "xAxes" === a ? "category" : "linear"); i[a].push(o.configMerge(t.scaleService.getScaleDefaults(n), e)) })) : i.hasOwnProperty(a) && "object" == typeof i[a] && null !== i[a] && "object" == typeof e ? i[a] = o.configMerge(i[a], e) : i[a] = e }), i }, o.getValueAtIndexOrDefault = function(t, e, a) { return void 0 === t || null === t ? a : o.isArray(t) ? e < t.length ? t[e] : a : t }, o.getValueOrDefault = function(t, e) { return void 0 === t ? e : t }, o.indexOf = Array.prototype.indexOf ? function(t, e) { return t.indexOf(e) } : function(t, e) { for (var a = 0, i = t.length; a < i; ++a) if (t[a] === e) return a; return -1 }, o.where = function(t, e) { if (o.isArray(t) && Array.prototype.filter) return t.filter(e); var a = []; return o.each(t, function(t) { e(t) && a.push(t) }), a }, o.findIndex = Array.prototype.findIndex ? function(t, e, a) { return t.findIndex(e, a) } : function(t, e, a) { a = void 0 === a ? t : a; for (var i = 0, n = t.length; i < n; ++i) if (e.call(a, t[i], i, t)) return i; return -1 }, o.findNextWhere = function(t, e, a) { void 0 !== a && null !== a || (a = -1); for (var i = a + 1; i < t.length; i++) { var n = t[i]; if (e(n)) return n } }, o.findPreviousWhere = function(t, e, a) { void 0 !== a && null !== a || (a = t.length); for (var i = a - 1; i >= 0; i--) { var n = t[i]; if (e(n)) return n } }, o.inherits = function(t) { var e = this, a = t && t.hasOwnProperty("constructor") ? t.constructor : function() { return e.apply(this, arguments) }, i = function() { this.constructor = a }; return i.prototype = e.prototype, a.prototype = new i, a.extend = o.inherits, t && o.extend(a.prototype, t), a.__super__ = e.prototype, a }, o.noop = function() {}, o.uid = function() { var t = 0; return function() { return t++ } }(), o.isNumber = function(t) { return !isNaN(parseFloat(t)) && isFinite(t) }, o.almostEquals = function(t, e, a) { return Math.abs(t - e) < a }, o.max = function(t) { return t.reduce(function(t, e) { return isNaN(e) ? t : Math.max(t, e) }, Number.NEGATIVE_INFINITY) }, o.min = function(t) { return t.reduce(function(t, e) { return isNaN(e) ? t : Math.min(t, e) }, Number.POSITIVE_INFINITY) }, o.sign = Math.sign ? function(t) { return Math.sign(t) } : function(t) { return t = +t, 0 === t || isNaN(t) ? t : t > 0 ? 1 : -1 }, o.log10 = Math.log10 ? function(t) { return Math.log10(t) } : function(t) { return Math.log(t) / Math.LN10 }, o.toRadians = function(t) { return t * (Math.PI / 180) }, o.toDegrees = function(t) { return t * (180 / Math.PI) }, o.getAngleFromPoint = function(t, e) { var a = e.x - t.x, i = e.y - t.y, n = Math.sqrt(a * a + i * i), o = Math.atan2(i, a); return o < -.5 * Math.PI && (o += 2 * Math.PI), { angle: o, distance: n } }, o.aliasPixel = function(t) { return t % 2 === 0 ? 0 : .5 }, o.splineCurve = function(t, e, a, i) { var n = t.skip ? e : t, o = e, r = a.skip ? e : a, l = Math.sqrt(Math.pow(o.x - n.x, 2) + Math.pow(o.y - n.y, 2)), s = Math.sqrt(Math.pow(r.x - o.x, 2) + Math.pow(r.y - o.y, 2)), d = l / (l + s), u = s / (l + s); d = isNaN(d) ? 0 : d, u = isNaN(u) ? 0 : u; var c = i * d, h = i * u; return { previous: { x: o.x - c * (r.x - n.x), y: o.y - c * (r.y - n.y) }, next: { x: o.x + h * (r.x - n.x), y: o.y + h * (r.y - n.y) } } }, o.nextItem = function(t, e, a) { return a ? e >= t.length - 1 ? t[0] : t[e + 1] : e >= t.length - 1 ? t[t.length - 1] : t[e + 1] }, o.previousItem = function(t, e, a) { return a ? e <= 0 ? t[t.length - 1] : t[e - 1] : e <= 0 ? t[0] : t[e - 1] }, o.niceNum = function(t, e) { var a, i = Math.floor(o.log10(t)), n = t / Math.pow(10, i); return a = e ? n < 1.5 ? 1 : n < 3 ? 2 : n < 7 ? 5 : 10 : n <= 1 ? 1 : n <= 2 ? 2 : n <= 5 ? 5 : 10, a * Math.pow(10, i) }; var r = o.easingEffects = { linear: function(t) { return t }, easeInQuad: function(t) { return t * t }, easeOutQuad: function(t) { return -1 * t * (t - 2) }, easeInOutQuad: function(t) { return (t /= .5) < 1 ? .5 * t * t : -.5 * (--t * (t - 2) - 1) }, easeInCubic: function(t) { return t * t * t }, easeOutCubic: function(t) { return 1 * ((t = t / 1 - 1) * t * t + 1) }, easeInOutCubic: function(t) { return (t /= .5) < 1 ? .5 * t * t * t : .5 * ((t -= 2) * t * t + 2) }, easeInQuart: function(t) { return t * t * t * t }, easeOutQuart: function(t) { return -1 * ((t = t / 1 - 1) * t * t * t - 1) }, easeInOutQuart: function(t) { return (t /= .5) < 1 ? .5 * t * t * t * t : -.5 * ((t -= 2) * t * t * t - 2) }, easeInQuint: function(t) { return 1 * (t /= 1) * t * t * t * t }, easeOutQuint: function(t) { return 1 * ((t = t / 1 - 1) * t * t * t * t + 1) }, easeInOutQuint: function(t) { return (t /= .5) < 1 ? .5 * t * t * t * t * t : .5 * ((t -= 2) * t * t * t * t + 2) }, easeInSine: function(t) { return -1 * Math.cos(t / 1 * (Math.PI / 2)) + 1 }, easeOutSine: function(t) { return 1 * Math.sin(t / 1 * (Math.PI / 2)) }, easeInOutSine: function(t) { return -.5 * (Math.cos(Math.PI * t / 1) - 1) }, easeInExpo: function(t) { return 0 === t ? 1 : 1 * Math.pow(2, 10 * (t / 1 - 1)) }, easeOutExpo: function(t) { return 1 === t ? 1 : 1 * (-Math.pow(2, -10 * t / 1) + 1) }, easeInOutExpo: function(t) { return 0 === t ? 0 : 1 === t ? 1 : (t /= .5) < 1 ? .5 * Math.pow(2, 10 * (t - 1)) : .5 * (-Math.pow(2, -10 * --t) + 2) }, easeInCirc: function(t) { return t >= 1 ? t : -1 * (Math.sqrt(1 - (t /= 1) * t) - 1) }, easeOutCirc: function(t) { return 1 * Math.sqrt(1 - (t = t / 1 - 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, a = 0, i = 1; return 0 === t ? 0 : 1 === (t /= 1) ? 1 : (a || (a = .3), i < Math.abs(1) ? (i = 1, e = a / 4) : e = a / (2 * Math.PI) * Math.asin(1 / i), -(i * Math.pow(2, 10 * (t -= 1)) * Math.sin((1 * t - e) * (2 * Math.PI) / a))) }, easeOutElastic: function(t) { var e = 1.70158, a = 0, i = 1; return 0 === t ? 0 : 1 === (t /= 1) ? 1 : (a || (a = .3), i < Math.abs(1) ? (i = 1, e = a / 4) : e = a / (2 * Math.PI) * Math.asin(1 / i), i * Math.pow(2, -10 * t) * Math.sin((1 * t - e) * (2 * Math.PI) / a) + 1) }, easeInOutElastic: function(t) { var e = 1.70158, a = 0, i = 1; return 0 === t ? 0 : 2 === (t /= .5) ? 1 : (a || (a = 1 * (.3 * 1.5)), i < Math.abs(1) ? (i = 1, e = a / 4) : e = a / (2 * Math.PI) * Math.asin(1 / i), t < 1 ? -.5 * (i * Math.pow(2, 10 * (t -= 1)) * Math.sin((1 * t - e) * (2 * Math.PI) / a)) : i * Math.pow(2, -10 * (t -= 1)) * Math.sin((1 * t - e) * (2 * Math.PI) / a) * .5 + 1) }, easeInBack: function(t) { var e = 1.70158; return 1 * (t /= 1) * t * ((e + 1) * t - e) }, easeOutBack: function(t) { var e = 1.70158; return 1 * ((t = t / 1 - 1) * t * ((e + 1) * t + e) + 1) }, easeInOutBack: function(t) { var e = 1.70158; return (t /= .5) < 1 ? .5 * (t * t * (((e *= 1.525) + 1) * t - e)) : .5 * ((t -= 2) * t * (((e *= 1.525) + 1) * t + e) + 2) }, easeInBounce: function(t) { return 1 - r.easeOutBounce(1 - t) }, easeOutBounce: function(t) { return (t /= 1) < 1 / 2.75 ? 1 * (7.5625 * t * t) : t < 2 / 2.75 ? 1 * (7.5625 * (t -= 1.5 / 2.75) * t + .75) : t < 2.5 / 2.75 ? 1 * (7.5625 * (t -= 2.25 / 2.75) * t + .9375) : 1 * (7.5625 * (t -= 2.625 / 2.75) * t + .984375) }, easeInOutBounce: function(t) { return t < .5 ? .5 * r.easeInBounce(2 * t) : .5 * r.easeOutBounce(2 * t - 1) + .5 } }; o.requestAnimFrame = function() { return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function(t) { return window.setTimeout(t, 1e3 / 60) } }(), o.cancelAnimFrame = function() { return window.cancelAnimationFrame || window.webkitCancelAnimationFrame || window.mozCancelAnimationFrame || window.oCancelAnimationFrame || window.msCancelAnimationFrame || function(t) { return window.clearTimeout(t, 1e3 / 60) } }(), o.getRelativePosition = function(t, e) { var a, i, n = t.originalEvent || t, r = t.currentTarget || t.srcElement, l = r.getBoundingClientRect(), s = n.touches; s && s.length > 0 ? (a = s[0].clientX, i = s[0].clientY) : (a = n.clientX, i = n.clientY); var d = parseFloat(o.getStyle(r, "padding-left")), u = parseFloat(o.getStyle(r, "padding-top")), c = parseFloat(o.getStyle(r, "padding-right")), h = parseFloat(o.getStyle(r, "padding-bottom")), f = l.right - l.left - d - c, g = l.bottom - l.top - u - h; return a = Math.round((a - l.left - d) / f * r.width / e.currentDevicePixelRatio), i = Math.round((i - l.top - u) / g * r.height / e.currentDevicePixelRatio), { x: a, y: i } }, o.addEvent = function(t, e, a) { t.addEventListener ? t.addEventListener(e, a) : t.attachEvent ? t.attachEvent("on" + e, a) : t["on" + e] = a }, o.removeEvent = function(t, e, a) { t.removeEventListener ? t.removeEventListener(e, a, !1) : t.detachEvent ? t.detachEvent("on" + e, a) : t["on" + e] = o.noop }, o.bindEvents = function(t, e, a) { var i = t.events = t.events || {}; o.each(e, function(e) { i[e] = function() { a.apply(t, arguments) }, o.addEvent(t.chart.canvas, e, i[e]) }) }, o.unbindEvents = function(t, e) { var a = t.chart.canvas; o.each(e, function(t, e) { o.removeEvent(a, e, t) }) }, o.getConstraintWidth = function(t) { return n(t, "max-width", "clientWidth") }, o.getConstraintHeight = function(t) { return n(t, "max-height", "clientHeight") }, o.getMaximumWidth = function(t) { var e = t.parentNode, a = parseInt(o.getStyle(e, "padding-left")) + parseInt(o.getStyle(e, "padding-right")), i = e.clientWidth - a, n = o.getConstraintWidth(t); return isNaN(n) ? i : Math.min(i, n) }, o.getMaximumHeight = function(t) { var e = t.parentNode, a = parseInt(o.getStyle(e, "padding-top")) + parseInt(o.getStyle(e, "padding-bottom")), i = e.clientHeight - a, n = o.getConstraintHeight(t); return isNaN(n) ? i : Math.min(i, n) }, o.getStyle = function(t, e) { return t.currentStyle ? t.currentStyle[e] : document.defaultView.getComputedStyle(t, null).getPropertyValue(e) }, o.retinaScale = function(t) { var e = t.ctx, a = t.canvas, i = a.width, n = a.height, o = t.currentDevicePixelRatio = window.devicePixelRatio || 1; 1 !== o && (a.height = n * o, a.width = i * o, e.scale(o, o), t.originalDevicePixelRatio = t.originalDevicePixelRatio || o), a.style.width = i + "px", a.style.height = n + "px" }, o.clear = function(t) { t.ctx.clearRect(0, 0, t.width, t.height) }, o.fontString = function(t, e, a) { return e + " " + t + "px " + a }, o.longestText = function(t, e, a, i) { i = i || {}; var n = i.data = i.data || {}, r = i.garbageCollect = i.garbageCollect || []; i.font !== e && (n = i.data = {}, r = i.garbageCollect = [], i.font = e), t.font = e; var l = 0; o.each(a, function(e) { void 0 !== e && null !== e && o.isArray(e) !== !0 ? l = o.measureText(t, n, r, l, e) : o.isArray(e) && o.each(e, function(e) { void 0 === e || null === e || o.isArray(e) || (l = o.measureText(t, n, r, l, e)) }) }); var s = r.length / 2; if (s > a.length) { for (var d = 0; d < s; d++) delete n[r[d]]; r.splice(0, s) } return l }, o.measureText = function(t, e, a, i, n) { var o = e[n]; return o || (o = e[n] = t.measureText(n).width, a.push(n)), o > i && (i = o), i }, o.numberOfLabelLines = function(t) { var e = 1; return o.each(t, function(t) { o.isArray(t) && t.length > e && (e = t.length) }), e }, o.drawRoundedRectangle = function(t, e, a, i, n, o) { t.beginPath(), t.moveTo(e + o, a), t.lineTo(e + i - o, a), t.quadraticCurveTo(e + i, a, e + i, a + o), t.lineTo(e + i, a + n - o), t.quadraticCurveTo(e + i, a + n, e + i - o, a + n), t.lineTo(e + o, a + n), t.quadraticCurveTo(e, a + n, e, a + n - o), t.lineTo(e, a + o), t.quadraticCurveTo(e, a, e + o, a), t.closePath() }, o.color = function(e) { return i ? i(e instanceof CanvasGradient ? t.defaults.global.defaultColor : e) : (console.log("Color.js not found!"), e) }, o.addResizeListener = function(t, e) { var a = document.createElement("iframe"), i = "chartjs-hidden-iframe"; a.classlist ? a.classlist.add(i) : a.setAttribute("class", i); var n = a.style; n.width = "100%", n.display = "block", n.border = 0, n.height = 0, n.margin = 0, n.position = "absolute", n.left = 0, n.right = 0, n.top = 0, n.bottom = 0, t.insertBefore(a, t.firstChild), (a.contentWindow || a).onresize = function() { e && e() } }, o.removeResizeListener = function(t) { var e = t.querySelector(".chartjs-hidden-iframe"); e && e.parentNode.removeChild(e) }, o.isArray = Array.isArray ? function(t) { return Array.isArray(t) } : function(t) { return "[object Array]" === Object.prototype.toString.call(t) }, o.arrayEquals = function(t, e) { var a, i, n, r; if (!t || !e || t.length != e.length) return !1; for (a = 0, i = t.length; a < i; ++a) if (n = t[a], r = e[a], n instanceof Array && r instanceof Array) { if (!o.arrayEquals(n, r)) return !1 } else if (n != r) return !1; return !0 }, o.callCallback = function(t, e, a) { t && "function" == typeof t.call && t.apply(a, e) }, o.getHoverColor = function(t) { return t instanceof CanvasPattern ? t : o.color(t).saturate(.5).darken(.1).rgbString() } } }, { 3: 3 }], 26: [function(t, e, a) { "use strict"; e.exports = function() { var t = function(e, a) { var i = this, n = t.helpers; return i.config = a, e.length && e[0].getContext && (e = e[0]), e.getContext && (e = e.getContext("2d")), i.ctx = e, i.canvas = e.canvas, e.canvas.style.display = e.canvas.style.display || "block", i.width = e.canvas.width || parseInt(n.getStyle(e.canvas, "width"), 10) || n.getMaximumWidth(e.canvas), i.height = e.canvas.height || parseInt(n.getStyle(e.canvas, "height"), 10) || n.getMaximumHeight(e.canvas), i.aspectRatio = i.width / i.height, (isNaN(i.aspectRatio) || isFinite(i.aspectRatio) === !1) && (i.aspectRatio = void 0 !== a.aspectRatio ? a.aspectRatio : 2), i.originalCanvasStyleWidth = e.canvas.style.width, i.originalCanvasStyleHeight = e.canvas.style.height, n.retinaScale(i), a && (i.controller = new t.Controller(i)), n.addResizeListener(e.canvas.parentNode, function() { i.controller && i.controller.config.options.responsive && i.controller.resize() }), i.controller ? i.controller : i }; return t.defaults = { global: { responsive: !0, responsiveAnimationDuration: 0, maintainAspectRatio: !0, events: ["mousemove", "mouseout", "click", "touchstart", "touchmove"], hover: { onHover: null, mode: "single", animationDuration: 400 }, onClick: null, defaultColor: "rgba(0,0,0,0.1)", defaultFontColor: "#666", defaultFontFamily: "'Helvetica Neue', 'Helvetica', 'Arial', sans-serif", defaultFontSize: 12, defaultFontStyle: "normal", showLines: !0, elements: {}, legendCallback: function(t) { var e = []; e.push('
    '); for (var a = 0; a < t.data.datasets.length; a++) e.push('
  • '), t.data.datasets[a].label && e.push(t.data.datasets[a].label), e.push("
  • "); return e.push("
"), e.join("") } } }, t.Chart = t, t } }, {}], 27: [function(t, e, a) { "use strict"; e.exports = function(t) { var e = t.helpers; t.layoutService = { defaults: {}, addBox: function(t, e) { t.boxes || (t.boxes = []), t.boxes.push(e) }, removeBox: function(t, e) { t.boxes && t.boxes.splice(t.boxes.indexOf(e), 1) }, update: function(t, a, i) { function n(t) { var e, a = t.isHorizontal(); a ? (e = t.update(t.options.fullWidth ? p : k, y), S -= e.height) : (e = t.update(x, v), k -= e.width), w.push({ horizontal: a, minSize: e, box: t }) } function o(t) { var a = e.findNextWhere(w, function(e) { return e.box === t }); if (a) if (t.isHorizontal()) { var i = { left: C, right: M, top: 0, bottom: 0 }; t.update(t.options.fullWidth ? p : k, m / 2, i) } else t.update(a.minSize.width, S) } function r(t) { var a = e.findNextWhere(w, function(e) { return e.box === t }), i = { left: 0, right: 0, top: D, bottom: A }; a && t.update(a.minSize.width, S, i) } function l(t) { t.isHorizontal() ? (t.left = t.options.fullWidth ? s : C, t.right = t.options.fullWidth ? a - s : C + k, t.top = P, t.bottom = P + t.height, P = t.bottom) : (t.left = T, t.right = T + t.width, t.top = D, t.bottom = D + S, T = t.right) } if (t) { var s = 0, d = 0, u = e.where(t.boxes, function(t) { return "left" === t.options.position }), c = e.where(t.boxes, function(t) { return "right" === t.options.position }), h = e.where(t.boxes, function(t) { return "top" === t.options.position }), f = e.where(t.boxes, function(t) { return "bottom" === t.options.position }), g = e.where(t.boxes, function(t) { return "chartArea" === t.options.position }); h.sort(function(t, e) { return (e.options.fullWidth ? 1 : 0) - (t.options.fullWidth ? 1 : 0) }), f.sort(function(t, e) { return (t.options.fullWidth ? 1 : 0) - (e.options.fullWidth ? 1 : 0) }); var p = a - 2 * s, m = i - 2 * d, b = p / 2, v = m / 2, x = (a - b) / (u.length + c.length), y = (i - v) / (h.length + f.length), k = p, S = m, w = []; e.each(u.concat(c, h, f), n); var C = s, M = s, D = d, A = d; e.each(u.concat(c), o), e.each(u, function(t) { C += t.width }), e.each(c, function(t) { M += t.width }), e.each(h.concat(f), o), e.each(h, function(t) { D += t.height }), e.each(f, function(t) { A += t.height }), e.each(u.concat(c), r), C = s, M = s, D = d, A = d, e.each(u, function(t) { C += t.width }), e.each(c, function(t) { M += t.width }), e.each(h, function(t) { D += t.height }), e.each(f, function(t) { A += t.height }); var I = i - D - A, F = a - C - M; F === k && I === S || (e.each(u, function(t) { t.height = I }), e.each(c, function(t) { t.height = I }), e.each(h, function(t) { t.options.fullWidth || (t.width = F) }), e.each(f, function(t) { t.options.fullWidth || (t.width = F) }), S = I, k = F); var T = s, P = d; e.each(u.concat(h), l), T += k, P += S, e.each(c, l), e.each(f, l), t.chartArea = { left: C, top: D, right: C + k, bottom: D + S }, e.each(g, function(e) { e.left = t.chartArea.left, e.top = t.chartArea.top, e.right = t.chartArea.right, e.bottom = t.chartArea.bottom, e.update(k, S) }) } } } } }, {}], 28: [function(t, e, a) { "use strict"; e.exports = function(t) { var e = t.helpers, a = e.noop; t.defaults.global.legend = { display: !0, position: "top", fullWidth: !0, reverse: !1, onClick: function(t, e) { var a = e.datasetIndex, i = this.chart, n = i.getDatasetMeta(a); n.hidden = null === n.hidden ? !i.data.datasets[a].hidden : null, i.update() }, labels: { boxWidth: 40, padding: 10, generateLabels: function(t) { var a = t.data; return e.isArray(a.datasets) ? a.datasets.map(function(a, i) { return { text: a.label, fillStyle: e.isArray(a.backgroundColor) ? a.backgroundColor[0] : a.backgroundColor, hidden: !t.isDatasetVisible(i), lineCap: a.borderCapStyle, lineDash: a.borderDash, lineDashOffset: a.borderDashOffset, lineJoin: a.borderJoinStyle, lineWidth: a.borderWidth, strokeStyle: a.borderColor, datasetIndex: i } }, this) : [] } } }, t.Legend = t.Element.extend({ initialize: function(t) { e.extend(this, t), this.legendHitBoxes = [], this.doughnutMode = !1 }, beforeUpdate: a, update: function(t, e, a) { var i = this; return i.beforeUpdate(), i.maxWidth = t, i.maxHeight = e, i.margins = a, i.beforeSetDimensions(), i.setDimensions(), i.afterSetDimensions(), i.beforeBuildLabels(), i.buildLabels(), i.afterBuildLabels(), i.beforeFit(), i.fit(), i.afterFit(), i.afterUpdate(), i.minSize }, afterUpdate: a, beforeSetDimensions: a, 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: a, beforeBuildLabels: a, buildLabels: function() { var t = this; t.legendItems = t.options.labels.generateLabels.call(t, t.chart), t.options.reverse && t.legendItems.reverse() }, afterBuildLabels: a, beforeFit: a, fit: function() { var a = this, i = a.options, n = i.labels, o = i.display, r = a.ctx, l = t.defaults.global, s = e.getValueOrDefault, d = s(n.fontSize, l.defaultFontSize), u = s(n.fontStyle, l.defaultFontStyle), c = s(n.fontFamily, l.defaultFontFamily), h = e.fontString(d, u, c), f = a.legendHitBoxes = [], g = a.minSize, p = a.isHorizontal(); if (p ? (g.width = a.maxWidth, g.height = o ? 10 : 0) : (g.width = o ? 10 : 0, g.height = a.maxHeight), o) if (r.font = h, p) { var m = a.lineWidths = [0], b = a.legendItems.length ? d + n.padding : 0; r.textAlign = "left", r.textBaseline = "top", e.each(a.legendItems, function(t, e) { var i = n.boxWidth + d / 2 + r.measureText(t.text).width; m[m.length - 1] + i + n.padding >= a.width && (b += d + n.padding, m[m.length] = a.left), f[e] = { left: 0, top: 0, width: i, height: d }, m[m.length - 1] += i + n.padding }), g.height += b } else { var v = n.padding, x = a.columnWidths = [], y = n.padding, k = 0, S = 0, w = d + v; e.each(a.legendItems, function(t, e) { var a = n.boxWidth + d / 2 + r.measureText(t.text).width; S + w > g.height && (y += k + n.padding, x.push(k), k = 0, S = 0), k = Math.max(k, a), S += w, f[e] = { left: 0, top: 0, width: a, height: d } }), y += k, x.push(k), g.width += y } a.width = g.width, a.height = g.height }, afterFit: a, isHorizontal: function() { return "top" === this.options.position || "bottom" === this.options.position }, draw: function() { var a = this, i = a.options, n = i.labels, o = t.defaults.global, r = o.elements.line, l = a.width, s = (a.height, a.lineWidths); if (i.display) { var d, u = a.ctx, c = e.getValueOrDefault, h = c(n.fontColor, o.defaultFontColor), f = c(n.fontSize, o.defaultFontSize), g = c(n.fontStyle, o.defaultFontStyle), p = c(n.fontFamily, o.defaultFontFamily), m = e.fontString(f, g, p); u.textAlign = "left", u.textBaseline = "top", u.lineWidth = .5, u.strokeStyle = h, u.fillStyle = h, u.font = m; var b = n.boxWidth, v = a.legendHitBoxes, x = function(t, e, a) { u.save(), u.fillStyle = c(a.fillStyle, o.defaultColor), u.lineCap = c(a.lineCap, r.borderCapStyle), u.lineDashOffset = c(a.lineDashOffset, r.borderDashOffset), u.lineJoin = c(a.lineJoin, r.borderJoinStyle), u.lineWidth = c(a.lineWidth, r.borderWidth), u.strokeStyle = c(a.strokeStyle, o.defaultColor), u.setLineDash && u.setLineDash(c(a.lineDash, r.borderDash)), u.strokeRect(t, e, b, f), u.fillRect(t, e, b, f), u.restore() }, y = function(t, e, a, i) { u.fillText(a.text, b + f / 2 + t, e), a.hidden && (u.beginPath(), u.lineWidth = 2, u.moveTo(b + f / 2 + t, e + f / 2), u.lineTo(b + f / 2 + t + i, e + f / 2), u.stroke()) }, k = a.isHorizontal(); d = k ? { x: a.left + (l - s[0]) / 2, y: a.top + n.padding, line: 0 } : { x: a.left + n.padding, y: a.top, line: 0 }; var S = f + n.padding; e.each(a.legendItems, function(t, e) { var i = u.measureText(t.text).width, o = b + f / 2 + i, r = d.x, c = d.y; k ? r + o >= l && (c = d.y += f + n.padding, d.line++, r = d.x = a.left + (l - s[d.line]) / 2) : c + S > a.bottom && (r = d.x = r + a.columnWidths[d.line] + n.padding, c = d.y = a.top, d.line++), x(r, c, t), v[e].left = r, v[e].top = c, y(r, c, t, i), k ? d.x += o + n.padding : d.y += S }) } }, handleEvent: function(t) { var a = this, i = e.getRelativePosition(t, a.chart.chart), n = i.x, o = i.y, r = a.options; if (n >= a.left && n <= a.right && o >= a.top && o <= a.bottom) for (var l = a.legendHitBoxes, s = 0; s < l.length; ++s) { var d = l[s]; if (n >= d.left && n <= d.left + d.width && o >= d.top && o <= d.top + d.height) { r.onClick && r.onClick.call(a, t, a.legendItems[s]); break } } } }), t.plugins.register({ beforeInit: function(e) { var a = e.options, i = a.legend; i && (e.legend = new t.Legend({ ctx: e.chart.ctx, options: i, chart: e }), t.layoutService.addBox(e, e.legend)) } }) } }, {}], 29: [function(t, e, a) { "use strict"; e.exports = function(t) { var e = t.helpers.noop; t.plugins = { _plugins: [], register: function(t) { var e = this._plugins; [].concat(t).forEach(function(t) { e.indexOf(t) === -1 && e.push(t) }) }, unregister: function(t) { var e = this._plugins; [].concat(t).forEach(function(t) { var a = e.indexOf(t); a !== -1 && e.splice(a, 1) }) }, clear: function() { this._plugins = [] }, count: function() { return this._plugins.length }, getAll: function() { return this._plugins }, notify: function(t, e) { var a, i, n = this._plugins, o = n.length; for (a = 0; a < o; ++a) if (i = n[a], "function" == typeof i[t] && i[t].apply(i, e || []) === !1) return !1; return !0 } }, t.PluginBase = t.Element.extend({ beforeInit: e, afterInit: e, beforeUpdate: e, afterUpdate: e, beforeDraw: e, afterDraw: e, destroy: e }), t.pluginService = t.plugins } }, {}], 30: [function(t, e, a) { "use strict"; e.exports = function(t) { var e = t.helpers; t.defaults.scale = { display: !0, position: "left", gridLines: { display: !0, color: "rgba(0, 0, 0, 0.1)", lineWidth: 1, drawBorder: !0, drawOnChartArea: !0, drawTicks: !0, tickMarkLength: 10, zeroLineWidth: 1, zeroLineColor: "rgba(0,0,0,0.25)", offsetGridLines: !1 }, scaleLabel: { labelString: "", display: !1 }, ticks: { beginAtZero: !1, minRotation: 0, maxRotation: 50, mirror: !1, padding: 10, reverse: !1, display: !0, autoSkip: !0, autoSkipPadding: 0, labelOffset: 0, callback: function(t) { return e.isArray(t) ? t : "" + t } } }, t.Scale = t.Element.extend({ beforeUpdate: function() { e.callCallback(this.options.beforeUpdate, [this]) }, update: function(t, a, i) { var n = this; return n.beforeUpdate(), n.maxWidth = t, n.maxHeight = a, n.margins = e.extend({ left: 0, right: 0, top: 0, bottom: 0 }, i), n.beforeSetDimensions(), n.setDimensions(), n.afterSetDimensions(), n.beforeDataLimits(), n.determineDataLimits(), n.afterDataLimits(), n.beforeBuildTicks(), n.buildTicks(), n.afterBuildTicks(), n.beforeTickToLabelConversion(), n.convertTicksToLabels(), n.afterTickToLabelConversion(), n.beforeCalculateTickRotation(), n.calculateTickRotation(), n.afterCalculateTickRotation(), n.beforeFit(), n.fit(), n.afterFit(), n.afterUpdate(), n.minSize }, afterUpdate: function() { e.callCallback(this.options.afterUpdate, [this]) }, beforeSetDimensions: function() { e.callCallback(this.options.beforeSetDimensions, [this]) }, 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 }, afterSetDimensions: function() { e.callCallback(this.options.afterSetDimensions, [this]) }, beforeDataLimits: function() { e.callCallback(this.options.beforeDataLimits, [this]) }, determineDataLimits: e.noop, afterDataLimits: function() { e.callCallback(this.options.afterDataLimits, [this]) }, beforeBuildTicks: function() { e.callCallback(this.options.beforeBuildTicks, [this]) }, buildTicks: e.noop, afterBuildTicks: function() { e.callCallback(this.options.afterBuildTicks, [this]) }, beforeTickToLabelConversion: function() { e.callCallback(this.options.beforeTickToLabelConversion, [this]) }, convertTicksToLabels: function() { var t = this; t.ticks = t.ticks.map(function(e, a, i) { return t.options.ticks.userCallback ? t.options.ticks.userCallback(e, a, i) : t.options.ticks.callback(e, a, i) }, t) }, afterTickToLabelConversion: function() { e.callCallback(this.options.afterTickToLabelConversion, [this]) }, beforeCalculateTickRotation: function() { e.callCallback(this.options.beforeCalculateTickRotation, [this]) }, calculateTickRotation: function() { var a = this, i = a.ctx, n = t.defaults.global, o = a.options.ticks, r = e.getValueOrDefault(o.fontSize, n.defaultFontSize), l = e.getValueOrDefault(o.fontStyle, n.defaultFontStyle), s = e.getValueOrDefault(o.fontFamily, n.defaultFontFamily), d = e.fontString(r, l, s); i.font = d; var u, c = i.measureText(a.ticks[0]).width, h = i.measureText(a.ticks[a.ticks.length - 1]).width; if (a.labelRotation = o.minRotation || 0, a.paddingRight = 0, a.paddingLeft = 0, a.options.display && a.isHorizontal()) { a.paddingRight = h / 2 + 3, a.paddingLeft = c / 2 + 3, a.longestTextCache || (a.longestTextCache = {}); for (var f, g, p = e.longestText(i, d, a.ticks, a.longestTextCache), m = p, b = a.getPixelForTick(1) - a.getPixelForTick(0) - 6; m > b && a.labelRotation < o.maxRotation;) { if (f = Math.cos(e.toRadians(a.labelRotation)), g = Math.sin(e.toRadians(a.labelRotation)), u = f * c, u + r / 2 > a.yLabelWidth && (a.paddingLeft = u + r / 2), a.paddingRight = r / 2, g * p > a.maxHeight) { a.labelRotation--; break } a.labelRotation++, m = f * p } } a.margins && (a.paddingLeft = Math.max(a.paddingLeft - a.margins.left, 0), a.paddingRight = Math.max(a.paddingRight - a.margins.right, 0)) }, afterCalculateTickRotation: function() { e.callCallback(this.options.afterCalculateTickRotation, [this]) }, beforeFit: function() { e.callCallback(this.options.beforeFit, [this]) }, fit: function() { var a = this, i = a.minSize = { width: 0, height: 0 }, n = a.options, o = t.defaults.global, r = n.ticks, l = n.scaleLabel, s = n.display, d = a.isHorizontal(), u = e.getValueOrDefault(r.fontSize, o.defaultFontSize), c = e.getValueOrDefault(r.fontStyle, o.defaultFontStyle), h = e.getValueOrDefault(r.fontFamily, o.defaultFontFamily), f = e.fontString(u, c, h), g = e.getValueOrDefault(l.fontSize, o.defaultFontSize), p = e.getValueOrDefault(l.fontStyle, o.defaultFontStyle), m = e.getValueOrDefault(l.fontFamily, o.defaultFontFamily), b = (e.fontString(g, p, m), n.gridLines.tickMarkLength); if (d ? i.width = a.isFullWidth() ? a.maxWidth - a.margins.left - a.margins.right : a.maxWidth : i.width = s ? b : 0, d ? i.height = s ? b : 0 : i.height = a.maxHeight, l.display && s && (d ? i.height += 1.5 * g : i.width += 1.5 * g), r.display && s) { a.longestTextCache || (a.longestTextCache = {}); var v = e.longestText(a.ctx, f, a.ticks, a.longestTextCache), x = e.numberOfLabelLines(a.ticks), y = .5 * u; if (d) { a.longestLabelWidth = v; var k = Math.sin(e.toRadians(a.labelRotation)) * a.longestLabelWidth + u * x + y * x; i.height = Math.min(a.maxHeight, i.height + k), a.ctx.font = f; var S = a.ctx.measureText(a.ticks[0]).width, w = a.ctx.measureText(a.ticks[a.ticks.length - 1]).width, C = Math.cos(e.toRadians(a.labelRotation)), M = Math.sin(e.toRadians(a.labelRotation)); a.paddingLeft = 0 !== a.labelRotation ? C * S + 3 : S / 2 + 3, a.paddingRight = 0 !== a.labelRotation ? M * (u / 2) + 3 : w / 2 + 3 } else { var D = a.maxWidth - i.width, A = r.mirror; A ? v = 0 : v += a.options.ticks.padding, v < D ? i.width += v : i.width = a.maxWidth, a.paddingTop = u / 2, a.paddingBottom = u / 2 } } a.margins && (a.paddingLeft = Math.max(a.paddingLeft - a.margins.left, 0), a.paddingTop = Math.max(a.paddingTop - a.margins.top, 0), a.paddingRight = Math.max(a.paddingRight - a.margins.right, 0), a.paddingBottom = Math.max(a.paddingBottom - a.margins.bottom, 0)), a.width = i.width, a.height = i.height }, afterFit: function() { e.callCallback(this.options.afterFit, [this]) }, isHorizontal: function() { return "top" === this.options.position || "bottom" === this.options.position }, isFullWidth: function() { return this.options.fullWidth }, getRightValue: function a(t) { return null === t || "undefined" == typeof t ? NaN : "number" == typeof t && isNaN(t) ? NaN : "object" == typeof t ? t instanceof Date || t.isValid ? t : a(this.isHorizontal() ? t.x : t.y) : t }, getLabelForIndex: e.noop, getPixelForValue: e.noop, getValueForPixel: e.noop, getPixelForTick: function(t, e) { var a = this; if (a.isHorizontal()) { var i = a.width - (a.paddingLeft + a.paddingRight), n = i / Math.max(a.ticks.length - (a.options.gridLines.offsetGridLines ? 0 : 1), 1), o = n * t + a.paddingLeft; e && (o += n / 2); var r = a.left + Math.round(o); return r += a.isFullWidth() ? a.margins.left : 0 } var l = a.height - (a.paddingTop + a.paddingBottom); return a.top + t * (l / (a.ticks.length - 1)) }, getPixelForDecimal: function(t) { var e = this; if (e.isHorizontal()) { var a = e.width - (e.paddingLeft + e.paddingRight), i = a * t + e.paddingLeft, n = e.left + Math.round(i); return n += e.isFullWidth() ? e.margins.left : 0 } return e.top + t * e.height }, getBasePixel: function() { var t = this, e = t.min, a = t.max; return t.getPixelForValue(t.beginAtZero ? 0 : e < 0 && a < 0 ? a : e > 0 && a > 0 ? e : 0) }, draw: function(a) { var i = this, n = i.options; if (n.display) { var o, r, l = i.ctx, s = t.defaults.global, d = n.ticks, u = n.gridLines, c = n.scaleLabel, h = 0 !== i.labelRotation, f = d.autoSkip, g = i.isHorizontal(); d.maxTicksLimit && (r = d.maxTicksLimit); var p = e.getValueOrDefault(d.fontColor, s.defaultFontColor), m = e.getValueOrDefault(d.fontSize, s.defaultFontSize), b = e.getValueOrDefault(d.fontStyle, s.defaultFontStyle), v = e.getValueOrDefault(d.fontFamily, s.defaultFontFamily), x = e.fontString(m, b, v), y = u.tickMarkLength, k = e.getValueOrDefault(c.fontColor, s.defaultFontColor), S = e.getValueOrDefault(c.fontSize, s.defaultFontSize), w = e.getValueOrDefault(c.fontStyle, s.defaultFontStyle), C = e.getValueOrDefault(c.fontFamily, s.defaultFontFamily), M = e.fontString(S, w, C), D = e.toRadians(i.labelRotation), A = Math.cos(D), I = (Math.sin(D), i.longestLabelWidth * A); l.fillStyle = p; var F = []; if (g) { if (o = !1, h && (I /= 2), (I + d.autoSkipPadding) * i.ticks.length > i.width - (i.paddingLeft + i.paddingRight) && (o = 1 + Math.floor((I + d.autoSkipPadding) * i.ticks.length / (i.width - (i.paddingLeft + i.paddingRight)))), r && i.ticks.length > r) for (; !o || i.ticks.length / (o || 1) > r;) o || (o = 1), o += 1; f || (o = !1) } var T = "right" === n.position ? i.left : i.right - y, P = "right" === n.position ? i.left + y : i.right, _ = "bottom" === n.position ? i.top : i.bottom - y, R = "bottom" === n.position ? i.top + y : i.bottom; if (e.each(i.ticks, function(t, r) { if (void 0 !== t && null !== t) { var l = i.ticks.length === r + 1, s = o > 1 && r % o > 0 || r % o === 0 && r + o >= i.ticks.length; if ((!s || l) && void 0 !== t && null !== t) { var c, f; r === ("undefined" != typeof i.zeroLineIndex ? i.zeroLineIndex : 0) ? (c = u.zeroLineWidth, f = u.zeroLineColor) : (c = e.getValueAtIndexOrDefault(u.lineWidth, r), f = e.getValueAtIndexOrDefault(u.color, r)); var p, m, b, v, x, k, S, w, C, M, A, I = "middle"; if (g) { h || (I = "top" === n.position ? "bottom" : "top"), A = h ? "right" : "center"; var V = i.getPixelForTick(r) + e.aliasPixel(c); C = i.getPixelForTick(r, u.offsetGridLines) + d.labelOffset, M = h ? i.top + 12 : "top" === n.position ? i.bottom - y : i.top + y, p = b = x = S = V, m = _, v = R, k = a.top, w = a.bottom } else { "left" === n.position ? d.mirror ? (C = i.right + d.padding, A = "left") : (C = i.right - d.padding, A = "right") : d.mirror ? (C = i.left - d.padding, A = "right") : (C = i.left + d.padding, A = "left"); var O = i.getPixelForTick(r); O += e.aliasPixel(c), M = i.getPixelForTick(r, u.offsetGridLines), p = T, b = P, x = a.left, S = a.right, m = v = k = w = O } F.push({ tx1: p, ty1: m, tx2: b, ty2: v, x1: x, y1: k, x2: S, y2: w, labelX: C, labelY: M, glWidth: c, glColor: f, rotation: -1 * D, label: t, textBaseline: I, textAlign: A }) } } }), e.each(F, function(t) { if (u.display && (l.lineWidth = t.glWidth, l.strokeStyle = t.glColor, l.beginPath(), u.drawTicks && (l.moveTo(t.tx1, t.ty1), l.lineTo(t.tx2, t.ty2)), u.drawOnChartArea && (l.moveTo(t.x1, t.y1), l.lineTo(t.x2, t.y2)), l.stroke()), d.display) { l.save(), l.translate(t.labelX, t.labelY), l.rotate(t.rotation), l.font = x, l.textBaseline = t.textBaseline, l.textAlign = t.textAlign; var a = t.label; if (e.isArray(a)) for (var i = 0, n = 0; i < a.length; ++i) l.fillText("" + a[i], 0, n), n += 1.5 * m; else l.fillText(a, 0, 0); l.restore() } }), c.display) { var V, O, L = 0; if (g) V = i.left + (i.right - i.left) / 2, O = "bottom" === n.position ? i.bottom - S / 2 : i.top + S / 2; else { var B = "left" === n.position; V = B ? i.left + S / 2 : i.right - S / 2, O = i.top + (i.bottom - i.top) / 2, L = B ? -.5 * Math.PI : .5 * Math.PI } l.save(), l.translate(V, O), l.rotate(L), l.textAlign = "center", l.textBaseline = "middle", l.fillStyle = k, l.font = M, l.fillText(c.labelString, 0, 0), l.restore() } if (u.drawBorder) { l.lineWidth = e.getValueAtIndexOrDefault(u.lineWidth, 0), l.strokeStyle = e.getValueAtIndexOrDefault(u.color, 0); var W = i.left, z = i.right, H = i.top, N = i.bottom, E = e.aliasPixel(l.lineWidth); g ? (H = N = "top" === n.position ? i.bottom : i.top, H += E, N += E) : (W = z = "left" === n.position ? i.right : i.left, W += E, z += E), l.beginPath(), l.moveTo(W, H), l.lineTo(z, N), l.stroke() } } } }) } }, {}], 31: [function(t, e, a) { "use strict"; e.exports = function(t) { var e = t.helpers; t.scaleService = { constructors: {}, defaults: {}, registerScaleType: function(t, a, i) { this.constructors[t] = a, this.defaults[t] = e.clone(i) }, getScaleConstructor: function(t) { return this.constructors.hasOwnProperty(t) ? this.constructors[t] : void 0 }, getScaleDefaults: function(a) { return this.defaults.hasOwnProperty(a) ? e.scaleMerge(t.defaults.scale, this.defaults[a]) : {} }, updateScaleDefaults: function(t, a) { var i = this.defaults; i.hasOwnProperty(t) && (i[t] = e.extend(i[t], a)) }, addScalesToLayout: function(a) { e.each(a.scales, function(e) { t.layoutService.addBox(a, e) }) } } } }, {}], 32: [function(t, e, a) { "use strict"; e.exports = function(t) { var e = t.helpers; t.defaults.global.title = { display: !1, position: "top", fullWidth: !0, fontStyle: "bold", padding: 10, text: "" }; var a = e.noop; t.Title = t.Element.extend({ initialize: function(a) { var i = this; e.extend(i, a), i.options = e.configMerge(t.defaults.global.title, a.options), i.legendHitBoxes = [] }, beforeUpdate: function() { var a = this.chart.options; a && a.title && (this.options = e.configMerge(t.defaults.global.title, a.title)) }, update: function(t, e, a) { var i = this; return i.beforeUpdate(), i.maxWidth = t, i.maxHeight = e, i.margins = a, i.beforeSetDimensions(), i.setDimensions(), i.afterSetDimensions(), i.beforeBuildLabels(), i.buildLabels(), i.afterBuildLabels(), i.beforeFit(), i.fit(), i.afterFit(), i.afterUpdate(), i.minSize }, afterUpdate: a, beforeSetDimensions: a, 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: a, beforeBuildLabels: a, buildLabels: a, afterBuildLabels: a, beforeFit: a, fit: function() { var a = this, i = (a.ctx, e.getValueOrDefault), n = a.options, o = t.defaults.global, r = n.display, l = i(n.fontSize, o.defaultFontSize), s = a.minSize; a.isHorizontal() ? (s.width = a.maxWidth, s.height = r ? l + 2 * n.padding : 0) : (s.width = r ? l + 2 * n.padding : 0, s.height = a.maxHeight), a.width = s.width, a.height = s.height }, afterFit: a, isHorizontal: function() { var t = this.options.position; return "top" === t || "bottom" === t }, draw: function() { var a = this, i = a.ctx, n = e.getValueOrDefault, o = a.options, r = t.defaults.global; if (o.display) { var l, s, d = n(o.fontSize, r.defaultFontSize), u = n(o.fontStyle, r.defaultFontStyle), c = n(o.fontFamily, r.defaultFontFamily), h = e.fontString(d, u, c), f = 0, g = a.top, p = a.left, m = a.bottom, b = a.right; i.fillStyle = n(o.fontColor, r.defaultFontColor), i.font = h, a.isHorizontal() ? (l = p + (b - p) / 2, s = g + (m - g) / 2) : (l = "left" === o.position ? p + d / 2 : b - d / 2, s = g + (m - g) / 2, f = Math.PI * ("left" === o.position ? -.5 : .5)), i.save(), i.translate(l, s), i.rotate(f), i.textAlign = "center", i.textBaseline = "middle", i.fillText(o.text, 0, 0), i.restore() } } }), t.plugins.register({ beforeInit: function(e) { var a = e.options, i = a.title; i && (e.titleBlock = new t.Title({ ctx: e.chart.ctx, options: i, chart: e }), t.layoutService.addBox(e, e.titleBlock)) } }) } }, {}], 33: [function(t, e, a) { "use strict"; e.exports = function(t) { function e(t, e) { return e && (n.isArray(e) ? Array.prototype.push.apply(t, e) : t.push(e)), t } function a(t) { if (!t.length) return !1; var e, a, i = [], n = []; for (e = 0, a = t.length; e < a; ++e) { var o = t[e]; if (o && o.hasValue()) { var r = o.tooltipPosition(); i.push(r.x), n.push(r.y) } } var l = 0, s = 0; for (e = 0, a - i.length; e < a; ++e) l += i[e], s += n[e]; return { x: Math.round(l / i.length), y: Math.round(s / i.length) } } function i(t) { var e = t._xScale, a = t._yScale || t._scale, i = t._index, n = t._datasetIndex; return { xLabel: e ? e.getLabelForIndex(i, n) : "", yLabel: a ? a.getLabelForIndex(i, n) : "", index: i, datasetIndex: n } } var n = t.helpers; t.defaults.global.tooltips = { enabled: !0, custom: null, mode: "single", backgroundColor: "rgba(0,0,0,0.8)", titleFontStyle: "bold", titleSpacing: 2, titleMarginBottom: 6, titleFontColor: "#fff", titleAlign: "left", bodySpacing: 2, bodyFontColor: "#fff", bodyAlign: "left", footerFontStyle: "bold", footerSpacing: 2, footerMarginTop: 6, footerFontColor: "#fff", footerAlign: "left", yPadding: 6, xPadding: 6, yAlign: "center", xAlign: "center", caretSize: 5, cornerRadius: 6, multiKeyBackground: "#fff", callbacks: { beforeTitle: n.noop, title: function(t, e) { var a = "", i = e.labels, n = i ? i.length : 0; if (t.length > 0) { var o = t[0]; o.xLabel ? a = o.xLabel : n > 0 && o.index < n && (a = i[o.index]) } return a }, afterTitle: n.noop, beforeBody: n.noop, beforeLabel: n.noop, label: function(t, e) { var a = e.datasets[t.datasetIndex].label || ""; return a + ": " + t.yLabel }, labelColor: function(t, e) { var a = e.getDatasetMeta(t.datasetIndex), i = a.data[t.index], n = i._view; return { borderColor: n.borderColor, backgroundColor: n.backgroundColor } }, afterLabel: n.noop, afterBody: n.noop, beforeFooter: n.noop, footer: n.noop, afterFooter: n.noop } }, t.Tooltip = t.Element.extend({ initialize: function() { var e = this, a = t.defaults.global, i = e._options, o = n.getValueOrDefault; n.extend(e, { _model: { xPadding: i.xPadding, yPadding: i.yPadding, xAlign: i.yAlign, yAlign: i.xAlign, bodyFontColor: i.bodyFontColor, _bodyFontFamily: o(i.bodyFontFamily, a.defaultFontFamily), _bodyFontStyle: o(i.bodyFontStyle, a.defaultFontStyle), _bodyAlign: i.bodyAlign, bodyFontSize: o(i.bodyFontSize, a.defaultFontSize), bodySpacing: i.bodySpacing, titleFontColor: i.titleFontColor, _titleFontFamily: o(i.titleFontFamily, a.defaultFontFamily), _titleFontStyle: o(i.titleFontStyle, a.defaultFontStyle), titleFontSize: o(i.titleFontSize, a.defaultFontSize), _titleAlign: i.titleAlign, titleSpacing: i.titleSpacing, titleMarginBottom: i.titleMarginBottom, footerFontColor: i.footerFontColor, _footerFontFamily: o(i.footerFontFamily, a.defaultFontFamily), _footerFontStyle: o(i.footerFontStyle, a.defaultFontStyle), footerFontSize: o(i.footerFontSize, a.defaultFontSize), _footerAlign: i.footerAlign, footerSpacing: i.footerSpacing, footerMarginTop: i.footerMarginTop, caretSize: i.caretSize, cornerRadius: i.cornerRadius, backgroundColor: i.backgroundColor, opacity: 0, legendColorBackground: i.multiKeyBackground } }) }, getTitle: function() { var t = this, a = t._options, i = a.callbacks, n = i.beforeTitle.apply(t, arguments), o = i.title.apply(t, arguments), r = i.afterTitle.apply(t, arguments), l = []; return l = e(l, n), l = e(l, o), l = e(l, r) }, getBeforeBody: function() { var t = this._options.callbacks.beforeBody.apply(this, arguments); return n.isArray(t) ? t : void 0 !== t ? [t] : [] }, getBody: function(t, a) { var i = this, o = i._options.callbacks, r = []; return n.each(t, function(t) { var n = { before: [], lines: [], after: [] }; e(n.before, o.beforeLabel.call(i, t, a)), e(n.lines, o.label.call(i, t, a)), e(n.after, o.afterLabel.call(i, t, a)), r.push(n) }), r }, getAfterBody: function() { var t = this._options.callbacks.afterBody.apply(this, arguments); return n.isArray(t) ? t : void 0 !== t ? [t] : [] }, getFooter: function() { var t = this, a = t._options.callbacks, i = a.beforeFooter.apply(t, arguments), n = a.footer.apply(t, arguments), o = a.afterFooter.apply(t, arguments), r = []; return r = e(r, i), r = e(r, n), r = e(r, o) }, update: function(t) { var e, o, r = this, l = r._options, s = r._model, d = r._active, u = r._data, c = r._chartInstance; if (d.length) { s.opacity = 1; var h = [], f = a(d), g = []; for (e = 0, o = d.length; e < o; ++e) g.push(i(d[e])); l.itemSort && (g = g.sort(l.itemSort)), d.length > 1 && n.each(g, function(t) { h.push(l.callbacks.labelColor.call(r, t, c)) }), n.extend(s, { title: r.getTitle(g, u), beforeBody: r.getBeforeBody(g, u), body: r.getBody(g, u), afterBody: r.getAfterBody(g, u), footer: r.getFooter(g, u), x: Math.round(f.x), y: Math.round(f.y), caretPadding: n.getValueOrDefault(f.padding, 2), labelColors: h }); var p = r.getTooltipSize(s); r.determineAlignment(p), n.extend(s, r.getBackgroundPoint(s, p)) } else r._model.opacity = 0; return t && l.custom && l.custom.call(r, s), r }, getTooltipSize: function(t) { var e = this._chart.ctx, a = { height: 2 * t.yPadding, width: 0 }, i = t.body, o = i.reduce(function(t, e) { return t + e.before.length + e.lines.length + e.after.length }, 0); o += t.beforeBody.length + t.afterBody.length; var r = t.title.length, l = t.footer.length, s = t.titleFontSize, d = t.bodyFontSize, u = t.footerFontSize; a.height += r * s, a.height += (r - 1) * t.titleSpacing, a.height += r ? t.titleMarginBottom : 0, a.height += o * d, a.height += o ? (o - 1) * t.bodySpacing : 0, a.height += l ? t.footerMarginTop : 0, a.height += l * u, a.height += l ? (l - 1) * t.footerSpacing : 0; var c = 0, h = function(t) { a.width = Math.max(a.width, e.measureText(t).width + c) }; return e.font = n.fontString(s, t._titleFontStyle, t._titleFontFamily), n.each(t.title, h), e.font = n.fontString(d, t._bodyFontStyle, t._bodyFontFamily), n.each(t.beforeBody.concat(t.afterBody), h), c = i.length > 1 ? d + 2 : 0, n.each(i, function(t) { n.each(t.before, h), n.each(t.lines, h), n.each(t.after, h) }), c = 0, e.font = n.fontString(u, t._footerFontStyle, t._footerFontFamily), n.each(t.footer, h), a.width += 2 * t.xPadding, a }, determineAlignment: function(t) { var e = this, a = e._model, i = e._chart, n = e._chartInstance.chartArea; a.y < t.height ? a.yAlign = "top" : a.y > i.height - t.height && (a.yAlign = "bottom"); var o, r, l, s, d, u = (n.left + n.right) / 2, c = (n.top + n.bottom) / 2; "center" === a.yAlign ? (o = function(t) { return t <= u }, r = function(t) { return t > u }) : (o = function(e) { return e <= t.width / 2 }, r = function(e) { return e >= i.width - t.width / 2 }), l = function(e) { return e + t.width > i.width }, s = function(e) { return e - t.width < 0 }, d = function(t) { return t <= c ? "top" : "bottom" }, o(a.x) ? (a.xAlign = "left", l(a.x) && (a.xAlign = "center", a.yAlign = d(a.y))) : r(a.x) && (a.xAlign = "right", s(a.x) && (a.xAlign = "center", a.yAlign = d(a.y))) }, getBackgroundPoint: function(t, e) { var a = { x: t.x, y: t.y }, i = t.caretSize, n = t.caretPadding, o = t.cornerRadius, r = t.xAlign, l = t.yAlign, s = i + n, d = o + n; return "right" === r ? a.x -= e.width : "center" === r && (a.x -= e.width / 2), "top" === l ? a.y += s : "bottom" === l ? a.y -= e.height + s : a.y -= e.height / 2, "center" === l ? "left" === r ? a.x += s : "right" === r && (a.x -= s) : "left" === r ? a.x -= d : "right" === r && (a.x += d), a }, drawCaret: function(t, e, a, i) { var o, r, l, s, d, u, c = this._view, h = this._chart.ctx, f = c.caretSize, g = c.cornerRadius, p = c.xAlign, m = c.yAlign, b = t.x, v = t.y, x = e.width, y = e.height; "center" === m ? ("left" === p ? (o = b, r = o - f, l = o) : (o = b + x, r = o + f, l = o), d = v + y / 2, s = d - f, u = d + f) : ("left" === p ? (o = b + g, r = o + f, l = r + f) : "right" === p ? (o = b + x - g, r = o - f, l = r - f) : (r = b + x / 2, o = r - f, l = r + f), "top" === m ? (s = v, d = s - f, u = s) : (s = v + y, d = s + f, u = s)); var k = n.color(c.backgroundColor); h.fillStyle = k.alpha(a * k.alpha()).rgbString(), h.beginPath(), h.moveTo(o, s), h.lineTo(r, d), h.lineTo(l, u), h.closePath(), h.fill() }, drawTitle: function(t, e, a, i) { var o = e.title; if (o.length) { a.textAlign = e._titleAlign, a.textBaseline = "top"; var r = e.titleFontSize, l = e.titleSpacing, s = n.color(e.titleFontColor); a.fillStyle = s.alpha(i * s.alpha()).rgbString(), a.font = n.fontString(r, e._titleFontStyle, e._titleFontFamily); var d, u; for (d = 0, u = o.length; d < u; ++d) a.fillText(o[d], t.x, t.y), t.y += r + l, d + 1 === o.length && (t.y += e.titleMarginBottom - l) } }, drawBody: function(t, e, a, i) { var o = e.bodyFontSize, r = e.bodySpacing, l = e.body; a.textAlign = e._bodyAlign, a.textBaseline = "top"; var s = n.color(e.bodyFontColor), d = s.alpha(i * s.alpha()).rgbString(); a.fillStyle = d, a.font = n.fontString(o, e._bodyFontStyle, e._bodyFontFamily); var u = 0, c = function(e) { a.fillText(e, t.x + u, t.y), t.y += o + r }; n.each(e.beforeBody, c); var h = l.length > 1; u = h ? o + 2 : 0, n.each(l, function(r, l) { n.each(r.before, c), n.each(r.lines, function(r) { h && (a.fillStyle = n.color(e.legendColorBackground).alpha(i).rgbaString(), a.fillRect(t.x, t.y, o, o), a.strokeStyle = n.color(e.labelColors[l].borderColor).alpha(i).rgbaString(), a.strokeRect(t.x, t.y, o, o), a.fillStyle = n.color(e.labelColors[l].backgroundColor).alpha(i).rgbaString(), a.fillRect(t.x + 1, t.y + 1, o - 2, o - 2), a.fillStyle = d), c(r) }), n.each(r.after, c) }), u = 0, n.each(e.afterBody, c), t.y -= r }, drawFooter: function(t, e, a, i) { var o = e.footer; if (o.length) { t.y += e.footerMarginTop, a.textAlign = e._footerAlign, a.textBaseline = "top"; var r = n.color(e.footerFontColor); a.fillStyle = r.alpha(i * r.alpha()).rgbString(), a.font = n.fontString(e.footerFontSize, e._footerFontStyle, e._footerFontFamily), n.each(o, function(i) { a.fillText(i, t.x, t.y), t.y += e.footerFontSize + e.footerSpacing }) } }, draw: function() { var t = this._chart.ctx, e = this._view; if (0 !== e.opacity) { var a = this.getTooltipSize(e), i = { x: e.x, y: e.y }, o = Math.abs(e.opacity < .001) ? 0 : e.opacity; if (this._options.enabled) { var r = n.color(e.backgroundColor); t.fillStyle = r.alpha(o * r.alpha()).rgbString(), n.drawRoundedRectangle(t, i.x, i.y, a.width, a.height, e.cornerRadius), t.fill(), this.drawCaret(i, a, o, e.caretPadding), i.x += e.xPadding, i.y += e.yPadding, this.drawTitle(i, e, t, o), this.drawBody(i, e, t, o), this.drawFooter(i, e, t, o) } } } }) } }, {}], 34: [function(t, e, a) { "use strict"; e.exports = function(t, e) { var a = t.helpers, i = t.defaults.global; i.elements.arc = { backgroundColor: i.defaultColor, borderColor: "#fff", borderWidth: 2 }, t.elements.Arc = t.Element.extend({ inLabelRange: function(t) { var e = this._view; return !!e && Math.pow(t - e.x, 2) < Math.pow(e.radius + e.hoverRadius, 2) }, inRange: function(t, e) { var i = this._view; if (i) { for (var n = a.getAngleFromPoint(i, { x: t, y: e }), o = n.angle, r = n.distance, l = i.startAngle, s = i.endAngle; s < l;) s += 2 * Math.PI; for (; o > s;) o -= 2 * Math.PI; for (; o < l;) o += 2 * Math.PI; var d = o >= l && o <= s, u = r >= i.innerRadius && r <= i.outerRadius; return d && u } return !1 }, tooltipPosition: function() { var t = this._view, e = t.startAngle + (t.endAngle - t.startAngle) / 2, a = (t.outerRadius - t.innerRadius) / 2 + t.innerRadius; return { x: t.x + Math.cos(e) * a, y: t.y + Math.sin(e) * a } }, draw: function() { var t = this._chart.ctx, e = this._view, a = e.startAngle, i = e.endAngle; t.beginPath(), t.arc(e.x, e.y, e.outerRadius, a, i), t.arc(e.x, e.y, e.innerRadius, i, a, !0), t.closePath(), t.strokeStyle = e.borderColor, t.lineWidth = e.borderWidth, t.fillStyle = e.backgroundColor, t.fill(), t.lineJoin = "bevel", e.borderWidth && t.stroke() } }) } }, {}], 35: [function(t, e, a) { "use strict"; e.exports = function(t) { var e = t.helpers, a = t.defaults.global; t.defaults.global.elements.line = { tension: .4, backgroundColor: a.defaultColor, borderWidth: 3, borderColor: a.defaultColor, borderCapStyle: "butt", borderDash: [], borderDashOffset: 0, borderJoinStyle: "miter", fill: !0 }, t.elements.Line = t.Element.extend({ lineToNextPoint: function(t, e, a, i, n) { var o = this, r = o._chart.ctx, l = !!o._view && o._view.spanGaps; e._view.skip && !l ? i.call(o, t, e, a) : t._view.skip && !l ? n.call(o, t, e, a) : 0 === e._view.tension ? r.lineTo(e._view.x, e._view.y) : r.bezierCurveTo(t._view.controlPointNextX, t._view.controlPointNextY, e._view.controlPointPreviousX, e._view.controlPointPreviousY, e._view.x, e._view.y) }, draw: function() { function t(t) { r._view.skip || l._view.skip ? t && o.lineTo(i._view.scaleZero.x, i._view.scaleZero.y) : o.bezierCurveTo(l._view.controlPointNextX, l._view.controlPointNextY, r._view.controlPointPreviousX, r._view.controlPointPreviousY, r._view.x, r._view.y) } var i = this, n = i._view, o = i._chart.ctx, r = i._children[0], l = i._children[i._children.length - 1]; o.save(), i._children.length > 0 && n.fill && (o.beginPath(), e.each(i._children, function(t, a) { var r = e.previousItem(i._children, a), l = e.nextItem(i._children, a); 0 === a ? (i._loop ? o.moveTo(n.scaleZero.x, n.scaleZero.y) : o.moveTo(t._view.x, n.scaleZero), t._view.skip ? i._loop || o.moveTo(l._view.x, i._view.scaleZero) : o.lineTo(t._view.x, t._view.y)) : i.lineToNextPoint(r, t, l, function(t, e, a) { i._loop ? o.lineTo(i._view.scaleZero.x, i._view.scaleZero.y) : (o.lineTo(t._view.x, i._view.scaleZero), o.moveTo(a._view.x, i._view.scaleZero)) }, function(t, e) { o.lineTo(e._view.x, e._view.y) }) }, i), i._loop ? t(!0) : (o.lineTo(i._children[i._children.length - 1]._view.x, n.scaleZero), o.lineTo(i._children[0]._view.x, n.scaleZero)), o.fillStyle = n.backgroundColor || a.defaultColor, o.closePath(), o.fill()); var s = a.elements.line; o.lineCap = n.borderCapStyle || s.borderCapStyle, o.setLineDash && o.setLineDash(n.borderDash || s.borderDash), o.lineDashOffset = n.borderDashOffset || s.borderDashOffset, o.lineJoin = n.borderJoinStyle || s.borderJoinStyle, o.lineWidth = n.borderWidth || s.borderWidth, o.strokeStyle = n.borderColor || a.defaultColor, o.beginPath(), e.each(i._children, function(t, a) { var n = e.previousItem(i._children, a), r = e.nextItem(i._children, a); 0 === a ? o.moveTo(t._view.x, t._view.y) : i.lineToNextPoint(n, t, r, function(t, e, a) { o.moveTo(a._view.x, a._view.y) }, function(t, e) { o.moveTo(e._view.x, e._view.y) }) }, i), i._loop && i._children.length > 0 && t(), o.stroke(), o.restore() } }) } }, {}], 36: [function(t, e, a) { "use strict"; e.exports = function(t) { var e = t.helpers, a = t.defaults.global, i = a.defaultColor; a.elements.point = { radius: 3, pointStyle: "circle", backgroundColor: i, borderWidth: 1, borderColor: i, hitRadius: 1, hoverRadius: 4, hoverBorderWidth: 1 }, t.elements.Point = t.Element.extend({ inRange: function(t, e) { var a = this._view; return !!a && Math.pow(t - a.x, 2) + Math.pow(e - a.y, 2) < Math.pow(a.hitRadius + a.radius, 2) }, inLabelRange: function(t) { var e = this._view; return !!e && Math.pow(t - e.x, 2) < Math.pow(e.radius + e.hitRadius, 2) }, tooltipPosition: function() { var t = this._view; return { x: t.x, y: t.y, padding: t.radius + t.borderWidth } }, draw: function() { var t, n, o, r, l, s, d = this._view, u = this._chart.ctx, c = d.pointStyle, h = d.radius, f = d.x, g = d.y; if (!d.skip) { if ("object" == typeof c && (t = c.toString(), "[object HTMLImageElement]" === t || "[object HTMLCanvasElement]" === t)) return void u.drawImage(c, f - c.width / 2, g - c.height / 2); if (!(isNaN(h) || h <= 0)) { switch (u.strokeStyle = d.borderColor || i, u.lineWidth = e.getValueOrDefault(d.borderWidth, a.elements.point.borderWidth), u.fillStyle = d.backgroundColor || i, c) { default: u.beginPath(), u.arc(f, g, h, 0, 2 * Math.PI), u.closePath(), u.fill(); break; case "triangle": u.beginPath(), n = 3 * h / Math.sqrt(3), l = n * Math.sqrt(3) / 2, u.moveTo(f - n / 2, g + l / 3), u.lineTo(f + n / 2, g + l / 3), u.lineTo(f, g - 2 * l / 3), u.closePath(), u.fill(); break; case "rect": s = 1 / Math.SQRT2 * h, u.fillRect(f - s, g - s, 2 * s, 2 * s), u.strokeRect(f - s, g - s, 2 * s, 2 * s); break; case "rectRot": s = 1 / Math.SQRT2 * h, u.beginPath(), u.moveTo(f - s, g), u.lineTo(f, g + s), u.lineTo(f + s, g), u.lineTo(f, g - s), u.closePath(), u.fill(); break; case "cross": u.beginPath(), u.moveTo(f, g + h), u.lineTo(f, g - h), u.moveTo(f - h, g), u.lineTo(f + h, g), u.closePath(); break; case "crossRot": u.beginPath(), o = Math.cos(Math.PI / 4) * h, r = Math.sin(Math.PI / 4) * h, u.moveTo(f - o, g - r), u.lineTo(f + o, g + r), u.moveTo(f - o, g + r), u.lineTo(f + o, g - r), u.closePath(); break; case "star": u.beginPath(), u.moveTo(f, g + h), u.lineTo(f, g - h), u.moveTo(f - h, g), u.lineTo(f + h, g), o = Math.cos(Math.PI / 4) * h, r = Math.sin(Math.PI / 4) * h, u.moveTo(f - o, g - r), u.lineTo(f + o, g + r), u.moveTo(f - o, g + r), u.lineTo(f + o, g - r), u.closePath(); break; case "line": u.beginPath(), u.moveTo(f - h, g), u.lineTo(f + h, g), u.closePath(); break; case "dash": u.beginPath(), u.moveTo(f, g), u.lineTo(f + h, g), u.closePath() } u.stroke() } } } }) } }, {}], 37: [function(t, e, a) { "use strict"; e.exports = function(t) { var e = (t.helpers, t.defaults.global); e.elements.rectangle = { backgroundColor: e.defaultColor, borderWidth: 0, borderColor: e.defaultColor, borderSkipped: "bottom" }, t.elements.Rectangle = t.Element.extend({ draw: function() { function t(t) { return s[(u + t) % 4] } var e = this._chart.ctx, a = this._view, i = a.width / 2, n = a.x - i, o = a.x + i, r = a.base - (a.base - a.y), l = a.borderWidth / 2; a.borderWidth && (n += l, o -= l, r += l), e.beginPath(), e.fillStyle = a.backgroundColor, e.strokeStyle = a.borderColor, e.lineWidth = a.borderWidth; var s = [ [n, a.base], [n, r], [o, r], [o, a.base] ], d = ["bottom", "left", "top", "right"], u = d.indexOf(a.borderSkipped, 0); u === -1 && (u = 0), e.moveTo.apply(e, t(0)); for (var c = 1; c < 4; c++) e.lineTo.apply(e, t(c)); e.fill(), a.borderWidth && e.stroke() }, height: function() { var t = this._view; return t.base - t.y }, inRange: function(t, e) { var a = this._view; return !!a && (a.y < a.base ? t >= a.x - a.width / 2 && t <= a.x + a.width / 2 && e >= a.y && e <= a.base : t >= a.x - a.width / 2 && t <= a.x + a.width / 2 && e >= a.base && e <= a.y) }, inLabelRange: function(t) { var e = this._view; return !!e && (t >= e.x - e.width / 2 && t <= e.x + e.width / 2) }, tooltipPosition: function() { var t = this._view; return { x: t.x, y: t.y } } }) } }, {}], 38: [function(t, e, a) { "use strict"; e.exports = function(t) { var e = t.helpers, a = { position: "bottom" }, i = t.Scale.extend({ determineDataLimits: function() { var t = this; t.minIndex = 0, t.maxIndex = t.chart.data.labels.length - 1; var a; void 0 !== t.options.ticks.min && (a = e.indexOf(t.chart.data.labels, t.options.ticks.min), t.minIndex = a !== -1 ? a : t.minIndex), void 0 !== t.options.ticks.max && (a = e.indexOf(t.chart.data.labels, t.options.ticks.max), t.maxIndex = a !== -1 ? a : t.maxIndex), t.min = t.chart.data.labels[t.minIndex], t.max = t.chart.data.labels[t.maxIndex] }, buildTicks: function(t) { var e = this; e.ticks = 0 === e.minIndex && e.maxIndex === e.chart.data.labels.length - 1 ? e.chart.data.labels : e.chart.data.labels.slice(e.minIndex, e.maxIndex + 1) }, getLabelForIndex: function(t, e) { return this.ticks[t] }, getPixelForValue: function(t, e, a, i) { var n = this, o = Math.max(n.maxIndex + 1 - n.minIndex - (n.options.gridLines.offsetGridLines ? 0 : 1), 1); if (n.isHorizontal()) { var r = n.width - (n.paddingLeft + n.paddingRight), l = r / o, s = l * (e - n.minIndex) + n.paddingLeft; return n.options.gridLines.offsetGridLines && i && (s += l / 2), n.left + Math.round(s) } var d = n.height - (n.paddingTop + n.paddingBottom), u = d / o, c = u * (e - n.minIndex) + n.paddingTop; return n.options.gridLines.offsetGridLines && i && (c += u / 2), n.top + Math.round(c) }, getPixelForTick: function(t, e) { return this.getPixelForValue(this.ticks[t], t + this.minIndex, null, e) }, getValueForPixel: function(t) { var e, a = this, i = Math.max(a.ticks.length - (a.options.gridLines.offsetGridLines ? 0 : 1), 1), n = a.isHorizontal(), o = n ? a.width - (a.paddingLeft + a.paddingRight) : a.height - (a.paddingTop + a.paddingBottom), r = o / i; return a.options.gridLines.offsetGridLines && (t -= r / 2), t -= n ? a.paddingLeft : a.paddingTop, e = t <= 0 ? 0 : Math.round(t / r) } }); t.scaleService.registerScaleType("category", i, a) } }, {}], 39: [function(t, e, a) { "use strict"; e.exports = function(t) { var e = t.helpers, a = { position: "left", ticks: { callback: function(t, a, i) { var n = i.length > 3 ? i[2] - i[1] : i[1] - i[0]; Math.abs(n) > 1 && t !== Math.floor(t) && (n = t - Math.floor(t)); var o = e.log10(Math.abs(n)), r = ""; if (0 !== t) { var l = -1 * Math.floor(o); l = Math.max(Math.min(l, 20), 0), r = t.toFixed(l) } else r = "0"; return r } } }, i = t.LinearScaleBase.extend({ determineDataLimits: function() { function t(t) { return l ? t.xAxisID === a.id : t.yAxisID === a.id } var a = this, i = a.options, n = (i.ticks, a.chart), o = n.data, r = o.datasets, l = a.isHorizontal(); if (a.min = null, a.max = null, i.stacked) { var s = {}, d = !1, u = !1; e.each(r, function(o, r) { var l = n.getDatasetMeta(r); void 0 === s[l.type] && (s[l.type] = { positiveValues: [], negativeValues: [] }); var c = s[l.type].positiveValues, h = s[l.type].negativeValues; n.isDatasetVisible(r) && t(l) && e.each(o.data, function(t, e) { var n = +a.getRightValue(t); isNaN(n) || l.data[e].hidden || (c[e] = c[e] || 0, h[e] = h[e] || 0, i.relativePoints ? c[e] = 100 : n < 0 ? (u = !0, h[e] += n) : (d = !0, c[e] += n)) }) }), e.each(s, function(t) { var i = t.positiveValues.concat(t.negativeValues), n = e.min(i), o = e.max(i); a.min = null === a.min ? n : Math.min(a.min, n), a.max = null === a.max ? o : Math.max(a.max, o) }) } else e.each(r, function(i, o) { var r = n.getDatasetMeta(o); n.isDatasetVisible(o) && t(r) && e.each(i.data, function(t, e) { var i = +a.getRightValue(t); isNaN(i) || r.data[e].hidden || (null === a.min ? a.min = i : i < a.min && (a.min = i), null === a.max ? a.max = i : i > a.max && (a.max = i)) }) }); this.handleTickRangeOptions() }, getTickLimit: function() { var a, i = this, n = i.options.ticks; if (i.isHorizontal()) a = Math.min(n.maxTicksLimit ? n.maxTicksLimit : 11, Math.ceil(i.width / 50)); else { var o = e.getValueOrDefault(n.fontSize, t.defaults.global.defaultFontSize); a = Math.min(n.maxTicksLimit ? n.maxTicksLimit : 11, Math.ceil(i.height / (2 * o))) } return a }, handleDirectionalChanges: function() { this.isHorizontal() || this.ticks.reverse() }, getLabelForIndex: function(t, e) { return +this.getRightValue(this.chart.data.datasets[e].data[t]) }, getPixelForValue: function(t, e, a, i) { var n, o, r = this, l = r.paddingLeft, s = r.paddingBottom, d = r.start, u = +r.getRightValue(t), c = r.end - d; return r.isHorizontal() ? (o = r.width - (l + r.paddingRight), n = r.left + o / c * (u - d), Math.round(n + l)) : (o = r.height - (r.paddingTop + s), n = r.bottom - s - o / c * (u - d), Math.round(n)) }, getValueForPixel: function(t) { var e = this, a = e.isHorizontal(), i = e.paddingLeft, n = e.paddingBottom, o = a ? e.width - (i + e.paddingRight) : e.height - (e.paddingTop + n), r = (a ? t - e.left - i : e.bottom - n - t) / o; return e.start + (e.end - e.start) * r }, getPixelForTick: function(t, e) { return this.getPixelForValue(this.ticksAsNumbers[t], null, null, e) } }); t.scaleService.registerScaleType("linear", i, a) } }, {}], 40: [function(t, e, a) { "use strict"; e.exports = function(t) { var e = t.helpers, a = e.noop; t.LinearScaleBase = t.Scale.extend({ handleTickRangeOptions: function() { var t = this, a = t.options, i = a.ticks; if (i.beginAtZero) { var n = e.sign(t.min), o = e.sign(t.max); n < 0 && o < 0 ? t.max = 0 : n > 0 && o > 0 && (t.min = 0) } void 0 !== i.min ? t.min = i.min : void 0 !== i.suggestedMin && (t.min = Math.min(t.min, i.suggestedMin)), void 0 !== i.max ? t.max = i.max : void 0 !== i.suggestedMax && (t.max = Math.max(t.max, i.suggestedMax)), t.min === t.max && (t.max++, i.beginAtZero || t.min--) }, getTickLimit: a, handleDirectionalChanges: a, buildTicks: function() { var t = this, a = t.options, i = a.ticks, n = e.getValueOrDefault, o = (t.isHorizontal(), t.ticks = []), r = t.getTickLimit(); r = Math.max(2, r); var l, s = i.fixedStepSize && i.fixedStepSize > 0 || i.stepSize && i.stepSize > 0; if (s) l = n(i.fixedStepSize, i.stepSize); else { var d = e.niceNum(t.max - t.min, !1); l = e.niceNum(d / (r - 1), !0) } var u = Math.floor(t.min / l) * l, c = Math.ceil(t.max / l) * l, h = (c - u) / l; h = e.almostEquals(h, Math.round(h), l / 1e3) ? Math.round(h) : Math.ceil(h), o.push(void 0 !== i.min ? i.min : u); for (var f = 1; f < h; ++f) o.push(u + f * l); o.push(void 0 !== i.max ? i.max : c), t.handleDirectionalChanges(), t.max = e.max(o), t.min = e.min(o), i.reverse ? (o.reverse(), t.start = t.max, t.end = t.min) : (t.start = t.min, t.end = t.max) }, convertTicksToLabels: function() { var e = this; e.ticksAsNumbers = e.ticks.slice(), e.zeroLineIndex = e.ticks.indexOf(0), t.Scale.prototype.convertTicksToLabels.call(e) } }) } }, {}], 41: [function(t, e, a) { "use strict"; e.exports = function(t) { var e = t.helpers, a = { position: "left", ticks: { callback: function(t, a, i) { var n = t / Math.pow(10, Math.floor(e.log10(t))); return 1 === n || 2 === n || 5 === n || 0 === a || a === i.length - 1 ? t.toExponential() : "" } } }, i = t.Scale.extend({ determineDataLimits: function() { function t(t) { return d ? t.xAxisID === a.id : t.yAxisID === a.id } var a = this, i = a.options, n = i.ticks, o = a.chart, r = o.data, l = r.datasets, s = e.getValueOrDefault, d = a.isHorizontal(); if (a.min = null, a.max = null, i.stacked) { var u = {}; e.each(l, function(n, r) { var l = o.getDatasetMeta(r); o.isDatasetVisible(r) && t(l) && (void 0 === u[l.type] && (u[l.type] = []), e.each(n.data, function(t, e) { var n = u[l.type], o = +a.getRightValue(t); isNaN(o) || l.data[e].hidden || (n[e] = n[e] || 0, i.relativePoints ? n[e] = 100 : n[e] += o) })) }), e.each(u, function(t) { var i = e.min(t), n = e.max(t); a.min = null === a.min ? i : Math.min(a.min, i), a.max = null === a.max ? n : Math.max(a.max, n) }) } else e.each(l, function(i, n) { var r = o.getDatasetMeta(n); o.isDatasetVisible(n) && t(r) && e.each(i.data, function(t, e) { var i = +a.getRightValue(t); isNaN(i) || r.data[e].hidden || (null === a.min ? a.min = i : i < a.min && (a.min = i), null === a.max ? a.max = i : i > a.max && (a.max = i)) }) }); a.min = s(n.min, a.min), a.max = s(n.max, a.max), a.min === a.max && (0 !== a.min && null !== a.min ? (a.min = Math.pow(10, Math.floor(e.log10(a.min)) - 1), a.max = Math.pow(10, Math.floor(e.log10(a.max)) + 1)) : (a.min = 1, a.max = 10)) }, buildTicks: function() { for (var t = this, a = t.options, i = a.ticks, n = e.getValueOrDefault, o = t.ticks = [], r = n(i.min, Math.pow(10, Math.floor(e.log10(t.min)))); r < t.max;) { o.push(r); var l = Math.floor(e.log10(r)), s = Math.floor(r / Math.pow(10, l)) + 1; 10 === s && (s = 1, ++l), r = s * Math.pow(10, l) } var d = n(i.max, r); o.push(d), t.isHorizontal() || o.reverse(), t.max = e.max(o), t.min = e.min(o), i.reverse ? (o.reverse(), t.start = t.max, t.end = t.min) : (t.start = t.min, t.end = t.max) }, convertTicksToLabels: function() { this.tickValues = this.ticks.slice(), t.Scale.prototype.convertTicksToLabels.call(this) }, getLabelForIndex: function(t, e) { return +this.getRightValue(this.chart.data.datasets[e].data[t]) }, getPixelForTick: function(t, e) { return this.getPixelForValue(this.tickValues[t], null, null, e) }, getPixelForValue: function(t, a, i, n) { var o, r, l = this, s = l.start, d = +l.getRightValue(t), u = e.log10(l.end) - e.log10(s), c = l.paddingTop, h = l.paddingBottom, f = l.paddingLeft; return l.isHorizontal() ? 0 === d ? r = l.left + f : (o = l.width - (f + l.paddingRight), r = l.left + o / u * (e.log10(d) - e.log10(s)), r += f) : 0 === d ? r = l.top + c : (o = l.height - (c + h), r = l.bottom - h - o / u * (e.log10(d) - e.log10(s))), r }, getValueForPixel: function(t) { var a, i, n = this, o = e.log10(n.end) - e.log10(n.start); return n.isHorizontal() ? (i = n.width - (n.paddingLeft + n.paddingRight), a = n.start * Math.pow(10, (t - n.left - n.paddingLeft) * o / i)) : (i = n.height - (n.paddingTop + n.paddingBottom), a = Math.pow(10, (n.bottom - n.paddingBottom - t) * o / i) / n.start), a } }); t.scaleService.registerScaleType("logarithmic", i, a) } }, {}], 42: [function(t, e, a) { "use strict"; e.exports = function(t) { var e = t.helpers, a = t.defaults.global, i = { display: !0, animate: !0, lineArc: !1, position: "chartArea", angleLines: { display: !0, color: "rgba(0, 0, 0, 0.1)", lineWidth: 1 }, ticks: { showLabelBackdrop: !0, backdropColor: "rgba(255,255,255,0.75)", backdropPaddingY: 2, backdropPaddingX: 2 }, pointLabels: { fontSize: 10, callback: function(t) { return t } } }, n = t.LinearScaleBase.extend({ getValueCount: function() { return this.chart.data.labels.length }, setDimensions: function() { var t = this, i = t.options, n = i.ticks; t.width = t.maxWidth, t.height = t.maxHeight, t.xCenter = Math.round(t.width / 2), t.yCenter = Math.round(t.height / 2); var o = e.min([t.height, t.width]), r = e.getValueOrDefault(n.fontSize, a.defaultFontSize); t.drawingArea = i.display ? o / 2 - (r / 2 + n.backdropPaddingY) : o / 2 }, determineDataLimits: function() { var t = this, a = t.chart; t.min = null, t.max = null, e.each(a.data.datasets, function(i, n) { if (a.isDatasetVisible(n)) { var o = a.getDatasetMeta(n); e.each(i.data, function(e, a) { var i = +t.getRightValue(e); isNaN(i) || o.data[a].hidden || (null === t.min ? t.min = i : i < t.min && (t.min = i), null === t.max ? t.max = i : i > t.max && (t.max = i)) }) } }), t.handleTickRangeOptions() }, getTickLimit: function() { var t = this.options.ticks, i = e.getValueOrDefault(t.fontSize, a.defaultFontSize); return Math.min(t.maxTicksLimit ? t.maxTicksLimit : 11, Math.ceil(this.drawingArea / (1.5 * i))) }, convertTicksToLabels: function() { var e = this; t.LinearScaleBase.prototype.convertTicksToLabels.call(e), e.pointLabels = e.chart.data.labels.map(e.options.pointLabels.callback, e) }, getLabelForIndex: function(t, e) { return +this.getRightValue(this.chart.data.datasets[e].data[t]) }, fit: function() { var t, i, n, o, r, l, s, d, u, c, h, f, g = this.options.pointLabels, p = e.getValueOrDefault(g.fontSize, a.defaultFontSize), m = e.getValueOrDefault(g.fontStyle, a.defaultFontStyle), b = e.getValueOrDefault(g.fontFamily, a.defaultFontFamily), v = e.fontString(p, m, b), x = e.min([this.height / 2 - p - 5, this.width / 2]), y = this.width, k = 0; for (this.ctx.font = v, i = 0; i < this.getValueCount(); i++) t = this.getPointPosition(i, x), n = this.ctx.measureText(this.pointLabels[i] ? this.pointLabels[i] : "").width + 5, 0 === i || i === this.getValueCount() / 2 ? (o = n / 2, t.x + o > y && (y = t.x + o, r = i), t.x - o < k && (k = t.x - o, s = i)) : i < this.getValueCount() / 2 ? t.x + n > y && (y = t.x + n, r = i) : i > this.getValueCount() / 2 && t.x - n < k && (k = t.x - n, s = i); u = k, c = Math.ceil(y - this.width), l = this.getIndexAngle(r), d = this.getIndexAngle(s), h = c / Math.sin(l + Math.PI / 2), f = u / Math.sin(d + Math.PI / 2), h = e.isNumber(h) ? h : 0, f = e.isNumber(f) ? f : 0, this.drawingArea = Math.round(x - (f + h) / 2), this.setCenterPoint(f, h) }, setCenterPoint: function(t, e) { var a = this, i = a.width - e - a.drawingArea, n = t + a.drawingArea; a.xCenter = Math.round((n + i) / 2 + a.left), a.yCenter = Math.round(a.height / 2 + a.top) }, getIndexAngle: function(t) { var e = 2 * Math.PI / this.getValueCount(); return t * e - Math.PI / 2 }, getDistanceFromCenterForValue: function(t) { var e = this; if (null === t) return 0; var a = e.drawingArea / (e.max - e.min); return e.options.reverse ? (e.max - t) * a : (t - e.min) * a }, getPointPosition: function(t, e) { var a = this, i = a.getIndexAngle(t); return { x: Math.round(Math.cos(i) * e) + a.xCenter, y: Math.round(Math.sin(i) * e) + a.yCenter } }, getPointPositionForValue: function(t, e) { return this.getPointPosition(t, this.getDistanceFromCenterForValue(e)) }, getBasePosition: function() { var t = this, e = t.min, a = t.max; return t.getPointPositionForValue(0, t.beginAtZero ? 0 : e < 0 && a < 0 ? a : e > 0 && a > 0 ? e : 0) }, draw: function() { var t = this, i = t.options, n = i.gridLines, o = i.ticks, r = i.angleLines, l = i.pointLabels, s = e.getValueOrDefault; if (i.display) { var d = t.ctx, u = s(o.fontSize, a.defaultFontSize), c = s(o.fontStyle, a.defaultFontStyle), h = s(o.fontFamily, a.defaultFontFamily), f = e.fontString(u, c, h); if (e.each(t.ticks, function(r, l) { if (l > 0 || i.reverse) { var c = t.getDistanceFromCenterForValue(t.ticksAsNumbers[l]), h = t.yCenter - c; if (n.display && 0 !== l) if (d.strokeStyle = e.getValueAtIndexOrDefault(n.color, l - 1), d.lineWidth = e.getValueAtIndexOrDefault(n.lineWidth, l - 1), i.lineArc) d.beginPath(), d.arc(t.xCenter, t.yCenter, c, 0, 2 * Math.PI), d.closePath(), d.stroke(); else { d.beginPath(); for (var g = 0; g < t.getValueCount(); g++) { var p = t.getPointPosition(g, c); 0 === g ? d.moveTo(p.x, p.y) : d.lineTo(p.x, p.y) } d.closePath(), d.stroke() } if (o.display) { var m = s(o.fontColor, a.defaultFontColor); if (d.font = f, o.showLabelBackdrop) { var b = d.measureText(r).width; d.fillStyle = o.backdropColor, d.fillRect(t.xCenter - b / 2 - o.backdropPaddingX, h - u / 2 - o.backdropPaddingY, b + 2 * o.backdropPaddingX, u + 2 * o.backdropPaddingY) } d.textAlign = "center", d.textBaseline = "middle", d.fillStyle = m, d.fillText(r, t.xCenter, h) } } }), !i.lineArc) { d.lineWidth = r.lineWidth, d.strokeStyle = r.color; for (var g = t.getDistanceFromCenterForValue(i.reverse ? t.min : t.max), p = s(l.fontSize, a.defaultFontSize), m = s(l.fontStyle, a.defaultFontStyle), b = s(l.fontFamily, a.defaultFontFamily), v = e.fontString(p, m, b), x = t.getValueCount() - 1; x >= 0; x--) { if (r.display) { var y = t.getPointPosition(x, g); d.beginPath(), d.moveTo(t.xCenter, t.yCenter), d.lineTo(y.x, y.y), d.stroke(), d.closePath() } var k = t.getPointPosition(x, g + 5), S = s(l.fontColor, a.defaultFontColor); d.font = v, d.fillStyle = S; var w = t.pointLabels, C = w.length, M = w.length / 2, D = M / 2, A = x < D || x > C - D, I = x === D || x === C - D; 0 === x ? d.textAlign = "center" : x === M ? d.textAlign = "center" : x < M ? d.textAlign = "left" : d.textAlign = "right", I ? d.textBaseline = "middle" : A ? d.textBaseline = "bottom" : d.textBaseline = "top", d.fillText(w[x] ? w[x] : "", k.x, k.y) } } } } }); t.scaleService.registerScaleType("radialLinear", n, i) } }, {}], 43: [function(t, e, a) { "use strict"; var i = t(1); i = "function" == typeof i ? i : window.moment, e.exports = function(t) { var e = t.helpers, a = { units: [{ name: "millisecond", steps: [1, 2, 5, 10, 20, 50, 100, 250, 500] }, { name: "second", steps: [1, 2, 5, 10, 30] }, { name: "minute", steps: [1, 2, 5, 10, 30] }, { name: "hour", steps: [1, 2, 3, 6, 12] }, { name: "day", steps: [1, 2, 5] }, { name: "week", maxStep: 4 }, { name: "month", maxStep: 3 }, { name: "quarter", maxStep: 4 }, { name: "year", maxStep: !1 }] }, n = { position: "bottom", time: { parser: !1, format: !1, unit: !1, round: !1, displayFormat: !1, isoWeekday: !1, displayFormats: { millisecond: "h:mm:ss.SSS a", second: "h:mm:ss a", minute: "h:mm:ss a", hour: "MMM D, hA", day: "ll", week: "ll", month: "MMM YYYY", quarter: "[Q]Q - YYYY", year: "YYYY" } }, ticks: { autoSkip: !1 } }, o = t.Scale.extend({ initialize: function() { if (!i) throw new Error("Chart.js - Moment.js could not be found! You must include it before Chart.js to use the time scale. Download at https://momentjs.com"); t.Scale.prototype.initialize.call(this) }, getLabelMoment: function(t, e) { return this.labelMoments[t][e] }, getMomentStartOf: function(t) { var e = this; return "week" === e.options.time.unit && e.options.time.isoWeekday !== !1 ? t.clone().startOf("isoWeek").isoWeekday(e.options.time.isoWeekday) : t.clone().startOf(e.tickUnit) }, determineDataLimits: function() { var t = this; t.labelMoments = []; var a = []; t.chart.data.labels && t.chart.data.labels.length > 0 ? (e.each(t.chart.data.labels, function(e, i) { var n = t.parseTime(e); n.isValid() && (t.options.time.round && n.startOf(t.options.time.round), a.push(n)) }, t), t.firstTick = i.min.call(t, a), t.lastTick = i.max.call(t, a)) : (t.firstTick = null, t.lastTick = null), e.each(t.chart.data.datasets, function(n, o) { var r = [], l = t.chart.isDatasetVisible(o); "object" == typeof n.data[0] && null !== n.data[0] ? e.each(n.data, function(e, a) { var n = t.parseTime(t.getRightValue(e)); n.isValid() && (t.options.time.round && n.startOf(t.options.time.round), r.push(n), l && (t.firstTick = null !== t.firstTick ? i.min(t.firstTick, n) : n, t.lastTick = null !== t.lastTick ? i.max(t.lastTick, n) : n)) }, t) : r = a, t.labelMoments.push(r) }, t), t.options.time.min && (t.firstTick = t.parseTime(t.options.time.min)), t.options.time.max && (t.lastTick = t.parseTime(t.options.time.max)), t.firstTick = (t.firstTick || i()).clone(), t.lastTick = (t.lastTick || i()).clone() }, buildTicks: function(i) { var n = this; n.ctx.save(); var o = e.getValueOrDefault(n.options.ticks.fontSize, t.defaults.global.defaultFontSize), r = e.getValueOrDefault(n.options.ticks.fontStyle, t.defaults.global.defaultFontStyle), l = e.getValueOrDefault(n.options.ticks.fontFamily, t.defaults.global.defaultFontFamily), s = e.fontString(o, r, l); if (n.ctx.font = s, n.ticks = [], n.unitScale = 1, n.scaleSizeInUnits = 0, n.options.time.unit) n.tickUnit = n.options.time.unit || "day", n.displayFormat = n.options.time.displayFormats[n.tickUnit], n.scaleSizeInUnits = n.lastTick.diff(n.firstTick, n.tickUnit, !0), n.unitScale = e.getValueOrDefault(n.options.time.unitStepSize, 1); else { var d = n.isHorizontal() ? n.width - (n.paddingLeft + n.paddingRight) : n.height - (n.paddingTop + n.paddingBottom), u = n.tickFormatFunction(n.firstTick, 0, []), c = n.ctx.measureText(u).width, h = Math.cos(e.toRadians(n.options.ticks.maxRotation)), f = Math.sin(e.toRadians(n.options.ticks.maxRotation)); c = c * h + o * f; var g = d / c; n.tickUnit = "millisecond", n.scaleSizeInUnits = n.lastTick.diff(n.firstTick, n.tickUnit, !0), n.displayFormat = n.options.time.displayFormats[n.tickUnit]; for (var p = 0, m = a.units[p]; p < a.units.length;) { if (n.unitScale = 1, e.isArray(m.steps) && Math.ceil(n.scaleSizeInUnits / g) < e.max(m.steps)) { for (var b = 0; b < m.steps.length; ++b) if (m.steps[b] >= Math.ceil(n.scaleSizeInUnits / g)) { n.unitScale = e.getValueOrDefault(n.options.time.unitStepSize, m.steps[b]); break } break } if (m.maxStep === !1 || Math.ceil(n.scaleSizeInUnits / g) < m.maxStep) { n.unitScale = e.getValueOrDefault(n.options.time.unitStepSize, Math.ceil(n.scaleSizeInUnits / g)); break }++p, m = a.units[p], n.tickUnit = m.name; var v = n.firstTick.diff(n.getMomentStartOf(n.firstTick), n.tickUnit, !0), x = n.getMomentStartOf(n.lastTick.clone().add(1, n.tickUnit)).diff(n.lastTick, n.tickUnit, !0); n.scaleSizeInUnits = n.lastTick.diff(n.firstTick, n.tickUnit, !0) + v + x, n.displayFormat = n.options.time.displayFormats[m.name] } } var y; if (n.options.time.min ? y = n.getMomentStartOf(n.firstTick) : (n.firstTick = n.getMomentStartOf(n.firstTick), y = n.firstTick), !n.options.time.max) { var k = n.getMomentStartOf(n.lastTick); 0 !== k.diff(n.lastTick, n.tickUnit, !0) && (n.lastTick = n.getMomentStartOf(n.lastTick.add(1, n.tickUnit))) } n.smallestLabelSeparation = n.width, e.each(n.chart.data.datasets, function(t, e) { for (var a = 1; a < n.labelMoments[e].length; a++) n.smallestLabelSeparation = Math.min(n.smallestLabelSeparation, n.labelMoments[e][a].diff(n.labelMoments[e][a - 1], n.tickUnit, !0)) }, n), n.options.time.displayFormat && (n.displayFormat = n.options.time.displayFormat), n.ticks.push(n.firstTick.clone()); for (var S = 1; S <= n.scaleSizeInUnits; ++S) { var w = y.clone().add(S, n.tickUnit); if (n.options.time.max && w.diff(n.lastTick, n.tickUnit, !0) >= 0) break; S % n.unitScale === 0 && n.ticks.push(w) } var C = n.ticks[n.ticks.length - 1].diff(n.lastTick, n.tickUnit); 0 === C && 0 !== n.scaleSizeInUnits || (n.options.time.max ? (n.ticks.push(n.lastTick.clone()), n.scaleSizeInUnits = n.lastTick.diff(n.ticks[0], n.tickUnit, !0)) : (n.ticks.push(n.lastTick.clone()), n.scaleSizeInUnits = n.lastTick.diff(n.firstTick, n.tickUnit, !0))), n.ctx.restore() }, getLabelForIndex: function(t, e) { var a = this, i = a.chart.data.labels && t < a.chart.data.labels.length ? a.chart.data.labels[t] : ""; return "object" == typeof a.chart.data.datasets[e].data[0] && (i = a.getRightValue(a.chart.data.datasets[e].data[t])), a.options.time.tooltipFormat && (i = a.parseTime(i).format(a.options.time.tooltipFormat)), i }, tickFormatFunction: function(t, a, i) { var n = t.format(this.displayFormat), o = this.options.ticks, r = e.getValueOrDefault(o.callback, o.userCallback); return r ? r(n, a, i) : n }, convertTicksToLabels: function() { var t = this; t.tickMoments = t.ticks, t.ticks = t.ticks.map(t.tickFormatFunction, t) }, getPixelForValue: function(t, e, a, i) { var n = this, o = t && t.isValid && t.isValid() ? t : n.getLabelMoment(a, e); if (o) { var r = o.diff(n.firstTick, n.tickUnit, !0), l = r / n.scaleSizeInUnits; if (n.isHorizontal()) { var s = n.width - (n.paddingLeft + n.paddingRight), d = (s / Math.max(n.ticks.length - 1, 1), s * l + n.paddingLeft); return n.left + Math.round(d) } var u = n.height - (n.paddingTop + n.paddingBottom), c = (u / Math.max(n.ticks.length - 1, 1), u * l + n.paddingTop); return n.top + Math.round(c) } }, getPixelForTick: function(t, e) { return this.getPixelForValue(this.tickMoments[t], null, null, e) }, getValueForPixel: function(t) { var e = this, a = e.isHorizontal() ? e.width - (e.paddingLeft + e.paddingRight) : e.height - (e.paddingTop + e.paddingBottom), n = (t - (e.isHorizontal() ? e.left + e.paddingLeft : e.top + e.paddingTop)) / a; return n *= e.scaleSizeInUnits, e.firstTick.clone().add(i.duration(n, e.tickUnit).asSeconds(), "seconds") }, parseTime: function(t) { var e = this; return "string" == typeof e.options.time.parser ? i(t, e.options.time.parser) : "function" == typeof e.options.time.parser ? e.options.time.parser(t) : "function" == typeof t.getMonth || "number" == typeof t ? i(t) : t.isValid && t.isValid() ? t : "string" != typeof e.options.time.format && e.options.time.format.call ? (console.warn("options.time.format is deprecated and replaced by options.time.parser. See http://nnnick.github.io/Chart.js/docs-v2/#scales-time-scale"), e.options.time.format(t)) : i(t, e.options.time.format) } }); t.scaleService.registerScaleType("time", o, n) } }, { 1: 1 }] }, {}, [7])(7) });PKj<\yyassets/js/vendor/select2.jsnuW+A/*! * Select2 4.0.3 * https://select2.github.io * * Released under the MIT license * https://github.com/select2/select2/blob/master/LICENSE.md */ (function (factory) { if (typeof define === 'function' && define.amd) { // AMD. Register as an anonymous module. define(['jquery'], factory); } else if (typeof exports === 'object') { // Node/CommonJS factory(require('jquery')); } else { // Browser globals factory(jQuery); } }(function (jQuery) { // This is needed so we can catch the AMD loader configuration and use it // The inner file should be wrapped (by `banner.start.js`) in a function that // returns the AMD loader references. var S2 = (function () { // Restore the Select2 AMD loader so it can be used // Needed mostly in the language files, where the loader is not inserted if (jQuery && jQuery.fn && jQuery.fn.select2 && jQuery.fn.select2.amd) { var S2 = jQuery.fn.select2.amd; } var S2;(function () { if (!S2 || !S2.requirejs) { if (!S2) { S2 = {}; } else { require = S2; } /** * @license almond 0.3.1 Copyright (c) 2011-2014, The Dojo Foundation All Rights Reserved. * Available via the MIT or new BSD license. * see: http://github.com/jrburke/almond for details */ //Going sloppy to avoid 'use strict' string cost, but strict practices should //be followed. /*jslint sloppy: true */ /*global setTimeout: false */ var requirejs, require, define; (function (undef) { var main, req, makeMap, handlers, defined = {}, waiting = {}, config = {}, defining = {}, hasOwn = Object.prototype.hasOwnProperty, aps = [].slice, jsSuffixRegExp = /\.js$/; function hasProp(obj, prop) { return hasOwn.call(obj, prop); } /** * Given a relative module name, like ./something, normalize it to * a real name that can be mapped to a path. * @param {String} name the relative name * @param {String} baseName a real name that the name arg is relative * to. * @returns {String} normalized name */ function normalize(name, baseName) { var nameParts, nameSegment, mapValue, foundMap, lastIndex, foundI, foundStarMap, starI, i, j, part, baseParts = baseName && baseName.split("/"), map = config.map, starMap = (map && map['*']) || {}; //Adjust any relative paths. if (name && name.charAt(0) === ".") { //If have a base name, try to normalize against it, //otherwise, assume it is a top-level require that will //be relative to baseUrl in the end. if (baseName) { name = name.split('/'); lastIndex = name.length - 1; // Node .js allowance: if (config.nodeIdCompat && jsSuffixRegExp.test(name[lastIndex])) { name[lastIndex] = name[lastIndex].replace(jsSuffixRegExp, ''); } //Lop off the last part of baseParts, so that . matches the //"directory" and not name of the baseName's module. For instance, //baseName of "one/two/three", maps to "one/two/three.js", but we //want the directory, "one/two" for this normalization. name = baseParts.slice(0, baseParts.length - 1).concat(name); //start trimDots for (i = 0; i < name.length; i += 1) { part = name[i]; if (part === ".") { name.splice(i, 1); i -= 1; } else if (part === "..") { if (i === 1 && (name[2] === '..' || name[0] === '..')) { //End of the line. Keep at least one non-dot //path segment at the front so it can be mapped //correctly to disk. Otherwise, there is likely //no path mapping for a path starting with '..'. //This can still fail, but catches the most reasonable //uses of .. break; } else if (i > 0) { name.splice(i - 1, 2); i -= 2; } } } //end trimDots name = name.join("/"); } else if (name.indexOf('./') === 0) { // No baseName, so this is ID is resolved relative // to baseUrl, pull off the leading dot. name = name.substring(2); } } //Apply map config if available. if ((baseParts || starMap) && map) { nameParts = name.split('/'); for (i = nameParts.length; i > 0; i -= 1) { nameSegment = nameParts.slice(0, i).join("/"); if (baseParts) { //Find the longest baseName segment match in the config. //So, do joins on the biggest to smallest lengths of baseParts. for (j = baseParts.length; j > 0; j -= 1) { mapValue = map[baseParts.slice(0, j).join('/')]; //baseName segment has config, find if it has one for //this name. if (mapValue) { mapValue = mapValue[nameSegment]; if (mapValue) { //Match, update name to the new value. foundMap = mapValue; foundI = i; break; } } } } if (foundMap) { break; } //Check for a star map match, but just hold on to it, //if there is a shorter segment match later in a matching //config, then favor over this star map. if (!foundStarMap && starMap && starMap[nameSegment]) { foundStarMap = starMap[nameSegment]; starI = i; } } if (!foundMap && foundStarMap) { foundMap = foundStarMap; foundI = starI; } if (foundMap) { nameParts.splice(0, foundI, foundMap); name = nameParts.join('/'); } } return name; } function makeRequire(relName, forceSync) { return function () { //A version of a require function that passes a moduleName //value for items that may need to //look up paths relative to the moduleName var args = aps.call(arguments, 0); //If first arg is not require('string'), and there is only //one arg, it is the array form without a callback. Insert //a null so that the following concat is correct. if (typeof args[0] !== 'string' && args.length === 1) { args.push(null); } return req.apply(undef, args.concat([relName, forceSync])); }; } function makeNormalize(relName) { return function (name) { return normalize(name, relName); }; } function makeLoad(depName) { return function (value) { defined[depName] = value; }; } function callDep(name) { if (hasProp(waiting, name)) { var args = waiting[name]; delete waiting[name]; defining[name] = true; main.apply(undef, args); } if (!hasProp(defined, name) && !hasProp(defining, name)) { throw new Error('No ' + name); } return defined[name]; } //Turns a plugin!resource to [plugin, resource] //with the plugin being undefined if the name //did not have a plugin prefix. function splitPrefix(name) { var prefix, index = name ? name.indexOf('!') : -1; if (index > -1) { prefix = name.substring(0, index); name = name.substring(index + 1, name.length); } return [prefix, name]; } /** * Makes a name map, normalizing the name, and using a plugin * for normalization if necessary. Grabs a ref to plugin * too, as an optimization. */ makeMap = function (name, relName) { var plugin, parts = splitPrefix(name), prefix = parts[0]; name = parts[1]; if (prefix) { prefix = normalize(prefix, relName); plugin = callDep(prefix); } //Normalize according if (prefix) { if (plugin && plugin.normalize) { name = plugin.normalize(name, makeNormalize(relName)); } else { name = normalize(name, relName); } } else { name = normalize(name, relName); parts = splitPrefix(name); prefix = parts[0]; name = parts[1]; if (prefix) { plugin = callDep(prefix); } } //Using ridiculous property names for space reasons return { f: prefix ? prefix + '!' + name : name, //fullName n: name, pr: prefix, p: plugin }; }; function makeConfig(name) { return function () { return (config && config.config && config.config[name]) || {}; }; } handlers = { require: function (name) { return makeRequire(name); }, exports: function (name) { var e = defined[name]; if (typeof e !== 'undefined') { return e; } else { return (defined[name] = {}); } }, module: function (name) { return { id: name, uri: '', exports: defined[name], config: makeConfig(name) }; } }; main = function (name, deps, callback, relName) { var cjsModule, depName, ret, map, i, args = [], callbackType = typeof callback, usingExports; //Use name if no relName relName = relName || name; //Call the callback to define the module, if necessary. if (callbackType === 'undefined' || callbackType === 'function') { //Pull out the defined dependencies and pass the ordered //values to the callback. //Default to [require, exports, module] if no deps deps = !deps.length && callback.length ? ['require', 'exports', 'module'] : deps; for (i = 0; i < deps.length; i += 1) { map = makeMap(deps[i], relName); depName = map.f; //Fast path CommonJS standard dependencies. if (depName === "require") { args[i] = handlers.require(name); } else if (depName === "exports") { //CommonJS module spec 1.1 args[i] = handlers.exports(name); usingExports = true; } else if (depName === "module") { //CommonJS module spec 1.1 cjsModule = args[i] = handlers.module(name); } else if (hasProp(defined, depName) || hasProp(waiting, depName) || hasProp(defining, depName)) { args[i] = callDep(depName); } else if (map.p) { map.p.load(map.n, makeRequire(relName, true), makeLoad(depName), {}); args[i] = defined[depName]; } else { throw new Error(name + ' missing ' + depName); } } ret = callback ? callback.apply(defined[name], args) : undefined; if (name) { //If setting exports via "module" is in play, //favor that over return value and exports. After that, //favor a non-undefined return value over exports use. if (cjsModule && cjsModule.exports !== undef && cjsModule.exports !== defined[name]) { defined[name] = cjsModule.exports; } else if (ret !== undef || !usingExports) { //Use the return value from the function. defined[name] = ret; } } } else if (name) { //May just be an object definition for the module. Only //worry about defining if have a module name. defined[name] = callback; } }; requirejs = require = req = function (deps, callback, relName, forceSync, alt) { if (typeof deps === "string") { if (handlers[deps]) { //callback in this case is really relName return handlers[deps](callback); } //Just return the module wanted. In this scenario, the //deps arg is the module name, and second arg (if passed) //is just the relName. //Normalize module name, if it contains . or .. return callDep(makeMap(deps, callback).f); } else if (!deps.splice) { //deps is a config object, not an array. config = deps; if (config.deps) { req(config.deps, config.callback); } if (!callback) { return; } if (callback.splice) { //callback is an array, which means it is a dependency list. //Adjust args if there are dependencies deps = callback; callback = relName; relName = null; } else { deps = undef; } } //Support require(['a']) callback = callback || function () {}; //If relName is a function, it is an errback handler, //so remove it. if (typeof relName === 'function') { relName = forceSync; forceSync = alt; } //Simulate async callback; if (forceSync) { main(undef, deps, callback, relName); } else { //Using a non-zero value because of concern for what old browsers //do, and latest browsers "upgrade" to 4 if lower value is used: //http://www.whatwg.org/specs/web-apps/current-work/multipage/timers.html#dom-windowtimers-settimeout: //If want a value immediately, use require('id') instead -- something //that works in almond on the global level, but not guaranteed and //unlikely to work in other AMD implementations. setTimeout(function () { main(undef, deps, callback, relName); }, 4); } return req; }; /** * Just drops the config on the floor, but returns req in case * the config return value is used. */ req.config = function (cfg) { return req(cfg); }; /** * Expose module registry for debugging and tooling */ requirejs._defined = defined; define = function (name, deps, callback) { if (typeof name !== 'string') { throw new Error('See almond README: incorrect module build, no module name'); } //This module may not have dependencies if (!deps.splice) { //deps is not an array, so probably means //an object literal or factory function for //the value. Adjust args. callback = deps; deps = []; } if (!hasProp(defined, name) && !hasProp(waiting, name)) { waiting[name] = [name, deps, callback]; } }; define.amd = { jQuery: true }; }()); S2.requirejs = requirejs;S2.require = require;S2.define = define; } }()); S2.define("almond", function(){}); /* global jQuery:false, $:false */ S2.define('jquery',[],function () { var _$ = jQuery || $; if (_$ == null && console && console.error) { console.error( 'Select2: An instance of jQuery or a jQuery-compatible library was not ' + 'found. Make sure that you are including jQuery before Select2 on your ' + 'web page.' ); } return _$; }); S2.define('select2/utils',[ 'jquery' ], function ($) { var Utils = {}; Utils.Extend = function (ChildClass, SuperClass) { var __hasProp = {}.hasOwnProperty; function BaseConstructor () { this.constructor = ChildClass; } for (var key in SuperClass) { if (__hasProp.call(SuperClass, key)) { ChildClass[key] = SuperClass[key]; } } BaseConstructor.prototype = SuperClass.prototype; ChildClass.prototype = new BaseConstructor(); ChildClass.__super__ = SuperClass.prototype; return ChildClass; }; function getMethods (theClass) { var proto = theClass.prototype; var methods = []; for (var methodName in proto) { var m = proto[methodName]; if (typeof m !== 'function') { continue; } if (methodName === 'constructor') { continue; } methods.push(methodName); } return methods; } Utils.Decorate = function (SuperClass, DecoratorClass) { var decoratedMethods = getMethods(DecoratorClass); var superMethods = getMethods(SuperClass); function DecoratedClass () { var unshift = Array.prototype.unshift; var argCount = DecoratorClass.prototype.constructor.length; var calledConstructor = SuperClass.prototype.constructor; if (argCount > 0) { unshift.call(arguments, SuperClass.prototype.constructor); calledConstructor = DecoratorClass.prototype.constructor; } calledConstructor.apply(this, arguments); } DecoratorClass.displayName = SuperClass.displayName; function ctr () { this.constructor = DecoratedClass; } DecoratedClass.prototype = new ctr(); for (var m = 0; m < superMethods.length; m++) { var superMethod = superMethods[m]; DecoratedClass.prototype[superMethod] = SuperClass.prototype[superMethod]; } var calledMethod = function (methodName) { // Stub out the original method if it's not decorating an actual method var originalMethod = function () {}; if (methodName in DecoratedClass.prototype) { originalMethod = DecoratedClass.prototype[methodName]; } var decoratedMethod = DecoratorClass.prototype[methodName]; return function () { var unshift = Array.prototype.unshift; unshift.call(arguments, originalMethod); return decoratedMethod.apply(this, arguments); }; }; for (var d = 0; d < decoratedMethods.length; d++) { var decoratedMethod = decoratedMethods[d]; DecoratedClass.prototype[decoratedMethod] = calledMethod(decoratedMethod); } return DecoratedClass; }; var Observable = function () { this.listeners = {}; }; Observable.prototype.on = function (event, callback) { this.listeners = this.listeners || {}; if (event in this.listeners) { this.listeners[event].push(callback); } else { this.listeners[event] = [callback]; } }; Observable.prototype.trigger = function (event) { var slice = Array.prototype.slice; var params = slice.call(arguments, 1); this.listeners = this.listeners || {}; // Params should always come in as an array if (params == null) { params = []; } // If there are no arguments to the event, use a temporary object if (params.length === 0) { params.push({}); } // Set the `_type` of the first object to the event params[0]._type = event; if (event in this.listeners) { this.invoke(this.listeners[event], slice.call(arguments, 1)); } if ('*' in this.listeners) { this.invoke(this.listeners['*'], arguments); } }; Observable.prototype.invoke = function (listeners, params) { for (var i = 0, len = listeners.length; i < len; i++) { listeners[i].apply(this, params); } }; Utils.Observable = Observable; Utils.generateChars = function (length) { var chars = ''; for (var i = 0; i < length; i++) { var randomChar = Math.floor(Math.random() * 36); chars += randomChar.toString(36); } return chars; }; Utils.bind = function (func, context) { return function () { func.apply(context, arguments); }; }; Utils._convertData = function (data) { for (var originalKey in data) { var keys = originalKey.split('-'); var dataLevel = data; if (keys.length === 1) { continue; } for (var k = 0; k < keys.length; k++) { var key = keys[k]; // Lowercase the first letter // By default, dash-separated becomes camelCase key = key.substring(0, 1).toLowerCase() + key.substring(1); if (!(key in dataLevel)) { dataLevel[key] = {}; } if (k == keys.length - 1) { dataLevel[key] = data[originalKey]; } dataLevel = dataLevel[key]; } delete data[originalKey]; } return data; }; Utils.hasScroll = function (index, el) { // Adapted from the function created by @ShadowScripter // and adapted by @BillBarry on the Stack Exchange Code Review website. // The original code can be found at // http://codereview.stackexchange.com/q/13338 // and was designed to be used with the Sizzle selector engine. var $el = $(el); var overflowX = el.style.overflowX; var overflowY = el.style.overflowY; //Check both x and y declarations if (overflowX === overflowY && (overflowY === 'hidden' || overflowY === 'visible')) { return false; } if (overflowX === 'scroll' || overflowY === 'scroll') { return true; } return ($el.innerHeight() < el.scrollHeight || $el.innerWidth() < el.scrollWidth); }; Utils.escapeMarkup = function (markup) { var replaceMap = { '\\': '\', '&': '&', '<': '<', '>': '>', '"': '"', '\'': ''', '/': '/' }; // Do not try to escape the markup if it's not a string if (typeof markup !== 'string') { return markup; } return String(markup).replace(/[&<>"'\/\\]/g, function (match) { return replaceMap[match]; }); }; // Append an array of jQuery nodes to a given element. Utils.appendMany = function ($element, $nodes) { // jQuery 1.7.x does not support $.fn.append() with an array // Fall back to a jQuery object collection using $.fn.add() if ($.fn.jquery.substr(0, 3) === '1.7') { var $jqNodes = $(); $.map($nodes, function (node) { $jqNodes = $jqNodes.add(node); }); $nodes = $jqNodes; } $element.append($nodes); }; return Utils; }); S2.define('select2/results',[ 'jquery', './utils' ], function ($, Utils) { function Results ($element, options, dataAdapter) { this.$element = $element; this.data = dataAdapter; this.options = options; Results.__super__.constructor.call(this); } Utils.Extend(Results, Utils.Observable); Results.prototype.render = function () { var $results = $( '
    ' ); if (this.options.get('multiple')) { $results.attr('aria-multiselectable', 'true'); } this.$results = $results; return $results; }; Results.prototype.clear = function () { this.$results.empty(); }; Results.prototype.displayMessage = function (params) { var escapeMarkup = this.options.get('escapeMarkup'); this.clear(); this.hideLoading(); var $message = $( '
  • ' ); var message = this.options.get('translations').get(params.message); $message.append( escapeMarkup( message(params.args) ) ); $message[0].className += ' select2-results__message'; this.$results.append($message); }; Results.prototype.hideMessages = function () { this.$results.find('.select2-results__message').remove(); }; Results.prototype.append = function (data) { this.hideLoading(); var $options = []; if (data.results == null || data.results.length === 0) { if (this.$results.children().length === 0) { this.trigger('results:message', { message: 'noResults' }); } return; } data.results = this.sort(data.results); for (var d = 0; d < data.results.length; d++) { var item = data.results[d]; var $option = this.option(item); $options.push($option); } this.$results.append($options); }; Results.prototype.position = function ($results, $dropdown) { var $resultsContainer = $dropdown.find('.select2-results'); $resultsContainer.append($results); }; Results.prototype.sort = function (data) { var sorter = this.options.get('sorter'); return sorter(data); }; Results.prototype.highlightFirstItem = function () { var $options = this.$results .find('.select2-results__option[aria-selected]'); var $selected = $options.filter('[aria-selected=true]'); // Check if there are any selected options if ($selected.length > 0) { // If there are selected options, highlight the first $selected.first().trigger('mouseenter'); } else { // If there are no selected options, highlight the first option // in the dropdown $options.first().trigger('mouseenter'); } this.ensureHighlightVisible(); }; Results.prototype.setClasses = function () { var self = this; this.data.current(function (selected) { var selectedIds = $.map(selected, function (s) { return s.id.toString(); }); var $options = self.$results .find('.select2-results__option[aria-selected]'); $options.each(function () { var $option = $(this); var item = $.data(this, 'data'); // id needs to be converted to a string when comparing var id = '' + item.id; if ((item.element != null && item.element.selected) || (item.element == null && $.inArray(id, selectedIds) > -1)) { $option.attr('aria-selected', 'true'); } else { $option.attr('aria-selected', 'false'); } }); }); }; Results.prototype.showLoading = function (params) { this.hideLoading(); var loadingMore = this.options.get('translations').get('searching'); var loading = { disabled: true, loading: true, text: loadingMore(params) }; var $loading = this.option(loading); $loading.className += ' loading-results'; this.$results.prepend($loading); }; Results.prototype.hideLoading = function () { this.$results.find('.loading-results').remove(); }; Results.prototype.option = function (data) { var option = document.createElement('li'); option.className = 'select2-results__option'; var attrs = { 'role': 'treeitem', 'aria-selected': 'false' }; if (data.disabled) { delete attrs['aria-selected']; attrs['aria-disabled'] = 'true'; } if (data.id == null) { delete attrs['aria-selected']; } if (data._resultId != null) { option.id = data._resultId; } if (data.title) { option.title = data.title; } if (data.children) { attrs.role = 'group'; attrs['aria-label'] = data.text; delete attrs['aria-selected']; } for (var attr in attrs) { var val = attrs[attr]; option.setAttribute(attr, val); } if (data.children) { var $option = $(option); var label = document.createElement('strong'); label.className = 'select2-results__group'; var $label = $(label); this.template(data, label); var $children = []; for (var c = 0; c < data.children.length; c++) { var child = data.children[c]; var $child = this.option(child); $children.push($child); } var $childrenContainer = $('
      ', { 'class': 'select2-results__options select2-results__options--nested' }); $childrenContainer.append($children); $option.append(label); $option.append($childrenContainer); } else { this.template(data, option); } $.data(option, 'data', data); return option; }; Results.prototype.bind = function (container, $container) { var self = this; var id = container.id + '-results'; this.$results.attr('id', id); container.on('results:all', function (params) { self.clear(); self.append(params.data); if (container.isOpen()) { self.setClasses(); self.highlightFirstItem(); } }); container.on('results:append', function (params) { self.append(params.data); if (container.isOpen()) { self.setClasses(); } }); container.on('query', function (params) { self.hideMessages(); self.showLoading(params); }); container.on('select', function () { if (!container.isOpen()) { return; } self.setClasses(); self.highlightFirstItem(); }); container.on('unselect', function () { if (!container.isOpen()) { return; } self.setClasses(); self.highlightFirstItem(); }); container.on('open', function () { // When the dropdown is open, aria-expended="true" self.$results.attr('aria-expanded', 'true'); self.$results.attr('aria-hidden', 'false'); self.setClasses(); self.ensureHighlightVisible(); }); container.on('close', function () { // When the dropdown is closed, aria-expended="false" self.$results.attr('aria-expanded', 'false'); self.$results.attr('aria-hidden', 'true'); self.$results.removeAttr('aria-activedescendant'); }); container.on('results:toggle', function () { var $highlighted = self.getHighlightedResults(); if ($highlighted.length === 0) { return; } $highlighted.trigger('mouseup'); }); container.on('results:select', function () { var $highlighted = self.getHighlightedResults(); if ($highlighted.length === 0) { return; } var data = $highlighted.data('data'); if ($highlighted.attr('aria-selected') == 'true') { self.trigger('close', {}); } else { self.trigger('select', { data: data }); } }); container.on('results:previous', function () { var $highlighted = self.getHighlightedResults(); var $options = self.$results.find('[aria-selected]'); var currentIndex = $options.index($highlighted); // If we are already at te top, don't move further if (currentIndex === 0) { return; } var nextIndex = currentIndex - 1; // If none are highlighted, highlight the first if ($highlighted.length === 0) { nextIndex = 0; } var $next = $options.eq(nextIndex); $next.trigger('mouseenter'); var currentOffset = self.$results.offset().top; var nextTop = $next.offset().top; var nextOffset = self.$results.scrollTop() + (nextTop - currentOffset); if (nextIndex === 0) { self.$results.scrollTop(0); } else if (nextTop - currentOffset < 0) { self.$results.scrollTop(nextOffset); } }); container.on('results:next', function () { var $highlighted = self.getHighlightedResults(); var $options = self.$results.find('[aria-selected]'); var currentIndex = $options.index($highlighted); var nextIndex = currentIndex + 1; // If we are at the last option, stay there if (nextIndex >= $options.length) { return; } var $next = $options.eq(nextIndex); $next.trigger('mouseenter'); var currentOffset = self.$results.offset().top + self.$results.outerHeight(false); var nextBottom = $next.offset().top + $next.outerHeight(false); var nextOffset = self.$results.scrollTop() + nextBottom - currentOffset; if (nextIndex === 0) { self.$results.scrollTop(0); } else if (nextBottom > currentOffset) { self.$results.scrollTop(nextOffset); } }); container.on('results:focus', function (params) { params.element.addClass('select2-results__option--highlighted'); }); container.on('results:message', function (params) { self.displayMessage(params); }); if ($.fn.mousewheel) { this.$results.on('mousewheel', function (e) { var top = self.$results.scrollTop(); var bottom = self.$results.get(0).scrollHeight - top + e.deltaY; var isAtTop = e.deltaY > 0 && top - e.deltaY <= 0; var isAtBottom = e.deltaY < 0 && bottom <= self.$results.height(); if (isAtTop) { self.$results.scrollTop(0); e.preventDefault(); e.stopPropagation(); } else if (isAtBottom) { self.$results.scrollTop( self.$results.get(0).scrollHeight - self.$results.height() ); e.preventDefault(); e.stopPropagation(); } }); } this.$results.on('mouseup', '.select2-results__option[aria-selected]', function (evt) { var $this = $(this); var data = $this.data('data'); if ($this.attr('aria-selected') === 'true') { if (self.options.get('multiple')) { self.trigger('unselect', { originalEvent: evt, data: data }); } else { self.trigger('close', {}); } return; } self.trigger('select', { originalEvent: evt, data: data }); }); this.$results.on('mouseenter', '.select2-results__option[aria-selected]', function (evt) { var data = $(this).data('data'); self.getHighlightedResults() .removeClass('select2-results__option--highlighted'); self.trigger('results:focus', { data: data, element: $(this) }); }); }; Results.prototype.getHighlightedResults = function () { var $highlighted = this.$results .find('.select2-results__option--highlighted'); return $highlighted; }; Results.prototype.destroy = function () { this.$results.remove(); }; Results.prototype.ensureHighlightVisible = function () { var $highlighted = this.getHighlightedResults(); if ($highlighted.length === 0) { return; } var $options = this.$results.find('[aria-selected]'); var currentIndex = $options.index($highlighted); var currentOffset = this.$results.offset().top; var nextTop = $highlighted.offset().top; var nextOffset = this.$results.scrollTop() + (nextTop - currentOffset); var offsetDelta = nextTop - currentOffset; nextOffset -= $highlighted.outerHeight(false) * 2; if (currentIndex <= 2) { this.$results.scrollTop(0); } else if (offsetDelta > this.$results.outerHeight() || offsetDelta < 0) { this.$results.scrollTop(nextOffset); } }; Results.prototype.template = function (result, container) { var template = this.options.get('templateResult'); var escapeMarkup = this.options.get('escapeMarkup'); var content = template(result, container); if (content == null) { container.style.display = 'none'; } else if (typeof content === 'string') { container.innerHTML = escapeMarkup(content); } else { $(container).append(content); } }; return Results; }); S2.define('select2/keys',[ ], function () { var KEYS = { BACKSPACE: 8, TAB: 9, ENTER: 13, SHIFT: 16, CTRL: 17, ALT: 18, ESC: 27, SPACE: 32, PAGE_UP: 33, PAGE_DOWN: 34, END: 35, HOME: 36, LEFT: 37, UP: 38, RIGHT: 39, DOWN: 40, DELETE: 46 }; return KEYS; }); S2.define('select2/selection/base',[ 'jquery', '../utils', '../keys' ], function ($, Utils, KEYS) { function BaseSelection ($element, options) { this.$element = $element; this.options = options; BaseSelection.__super__.constructor.call(this); } Utils.Extend(BaseSelection, Utils.Observable); BaseSelection.prototype.render = function () { var $selection = $( '' ); this._tabindex = 0; if (this.$element.data('old-tabindex') != null) { this._tabindex = this.$element.data('old-tabindex'); } else if (this.$element.attr('tabindex') != null) { this._tabindex = this.$element.attr('tabindex'); } $selection.attr('title', this.$element.attr('title')); $selection.attr('tabindex', this._tabindex); this.$selection = $selection; return $selection; }; BaseSelection.prototype.bind = function (container, $container) { var self = this; var id = container.id + '-container'; var resultsId = container.id + '-results'; this.container = container; this.$selection.on('focus', function (evt) { self.trigger('focus', evt); }); this.$selection.on('blur', function (evt) { self._handleBlur(evt); }); this.$selection.on('keydown', function (evt) { self.trigger('keypress', evt); if (evt.which === KEYS.SPACE) { evt.preventDefault(); } }); container.on('results:focus', function (params) { self.$selection.attr('aria-activedescendant', params.data._resultId); }); container.on('selection:update', function (params) { self.update(params.data); }); container.on('open', function () { // When the dropdown is open, aria-expanded="true" self.$selection.attr('aria-expanded', 'true'); self.$selection.attr('aria-owns', resultsId); self._attachCloseHandler(container); }); container.on('close', function () { // When the dropdown is closed, aria-expanded="false" self.$selection.attr('aria-expanded', 'false'); self.$selection.removeAttr('aria-activedescendant'); self.$selection.removeAttr('aria-owns'); self.$selection.focus(); self._detachCloseHandler(container); }); container.on('enable', function () { self.$selection.attr('tabindex', self._tabindex); }); container.on('disable', function () { self.$selection.attr('tabindex', '-1'); }); }; BaseSelection.prototype._handleBlur = function (evt) { var self = this; // This needs to be delayed as the active element is the body when the tab // key is pressed, possibly along with others. window.setTimeout(function () { // Don't trigger `blur` if the focus is still in the selection if ( (document.activeElement == self.$selection[0]) || ($.contains(self.$selection[0], document.activeElement)) ) { return; } self.trigger('blur', evt); }, 1); }; BaseSelection.prototype._attachCloseHandler = function (container) { var self = this; $(document.body).on('mousedown.select2.' + container.id, function (e) { var $target = $(e.target); var $select = $target.closest('.select2'); var $all = $('.select2.select2-container--open'); $all.each(function () { var $this = $(this); if (this == $select[0]) { return; } var $element = $this.data('element'); $element.select2('close'); }); }); }; BaseSelection.prototype._detachCloseHandler = function (container) { $(document.body).off('mousedown.select2.' + container.id); }; BaseSelection.prototype.position = function ($selection, $container) { var $selectionContainer = $container.find('.selection'); $selectionContainer.append($selection); }; BaseSelection.prototype.destroy = function () { this._detachCloseHandler(this.container); }; BaseSelection.prototype.update = function (data) { throw new Error('The `update` method must be defined in child classes.'); }; return BaseSelection; }); S2.define('select2/selection/single',[ 'jquery', './base', '../utils', '../keys' ], function ($, BaseSelection, Utils, KEYS) { function SingleSelection () { SingleSelection.__super__.constructor.apply(this, arguments); } Utils.Extend(SingleSelection, BaseSelection); SingleSelection.prototype.render = function () { var $selection = SingleSelection.__super__.render.call(this); $selection.addClass('select2-selection--single'); $selection.html( '' + '' + '' + '' ); return $selection; }; SingleSelection.prototype.bind = function (container, $container) { var self = this; SingleSelection.__super__.bind.apply(this, arguments); var id = container.id + '-container'; this.$selection.find('.select2-selection__rendered').attr('id', id); this.$selection.attr('aria-labelledby', id); this.$selection.on('mousedown', function (evt) { // Only respond to left clicks if (evt.which !== 1) { return; } self.trigger('toggle', { originalEvent: evt }); }); this.$selection.on('focus', function (evt) { // User focuses on the container }); this.$selection.on('blur', function (evt) { // User exits the container }); container.on('focus', function (evt) { if (!container.isOpen()) { self.$selection.focus(); } }); container.on('selection:update', function (params) { self.update(params.data); }); }; SingleSelection.prototype.clear = function () { this.$selection.find('.select2-selection__rendered').empty(); }; SingleSelection.prototype.display = function (data, container) { var template = this.options.get('templateSelection'); var escapeMarkup = this.options.get('escapeMarkup'); return escapeMarkup(template(data, container)); }; SingleSelection.prototype.selectionContainer = function () { return $(''); }; SingleSelection.prototype.update = function (data) { if (data.length === 0) { this.clear(); return; } var selection = data[0]; var $rendered = this.$selection.find('.select2-selection__rendered'); var formatted = this.display(selection, $rendered); $rendered.empty().append(formatted); $rendered.prop('title', selection.title || selection.text); }; return SingleSelection; }); S2.define('select2/selection/multiple',[ 'jquery', './base', '../utils' ], function ($, BaseSelection, Utils) { function MultipleSelection ($element, options) { MultipleSelection.__super__.constructor.apply(this, arguments); } Utils.Extend(MultipleSelection, BaseSelection); MultipleSelection.prototype.render = function () { var $selection = MultipleSelection.__super__.render.call(this); $selection.addClass('select2-selection--multiple'); $selection.html( '
        ' ); return $selection; }; MultipleSelection.prototype.bind = function (container, $container) { var self = this; MultipleSelection.__super__.bind.apply(this, arguments); this.$selection.on('click', function (evt) { self.trigger('toggle', { originalEvent: evt }); }); this.$selection.on( 'click', '.select2-selection__choice__remove', function (evt) { // Ignore the event if it is disabled if (self.options.get('disabled')) { return; } var $remove = $(this); var $selection = $remove.parent(); var data = $selection.data('data'); self.trigger('unselect', { originalEvent: evt, data: data }); } ); }; MultipleSelection.prototype.clear = function () { this.$selection.find('.select2-selection__rendered').empty(); }; MultipleSelection.prototype.display = function (data, container) { var template = this.options.get('templateSelection'); var escapeMarkup = this.options.get('escapeMarkup'); return escapeMarkup(template(data, container)); }; MultipleSelection.prototype.selectionContainer = function () { var $container = $( '
      • ' + '' + '×' + '' + '
      • ' ); return $container; }; MultipleSelection.prototype.update = function (data) { this.clear(); if (data.length === 0) { return; } var $selections = []; for (var d = 0; d < data.length; d++) { var selection = data[d]; var $selection = this.selectionContainer(); var formatted = this.display(selection, $selection); $selection.append(formatted); $selection.prop('title', selection.title || selection.text); $selection.data('data', selection); $selections.push($selection); } var $rendered = this.$selection.find('.select2-selection__rendered'); Utils.appendMany($rendered, $selections); }; return MultipleSelection; }); S2.define('select2/selection/placeholder',[ '../utils' ], function (Utils) { function Placeholder (decorated, $element, options) { this.placeholder = this.normalizePlaceholder(options.get('placeholder')); decorated.call(this, $element, options); } Placeholder.prototype.normalizePlaceholder = function (_, placeholder) { if (typeof placeholder === 'string') { placeholder = { id: '', text: placeholder }; } return placeholder; }; Placeholder.prototype.createPlaceholder = function (decorated, placeholder) { var $placeholder = this.selectionContainer(); $placeholder.html(this.display(placeholder)); $placeholder.addClass('select2-selection__placeholder') .removeClass('select2-selection__choice'); return $placeholder; }; Placeholder.prototype.update = function (decorated, data) { var singlePlaceholder = ( data.length == 1 && data[0].id != this.placeholder.id ); var multipleSelections = data.length > 1; if (multipleSelections || singlePlaceholder) { return decorated.call(this, data); } this.clear(); var $placeholder = this.createPlaceholder(this.placeholder); this.$selection.find('.select2-selection__rendered').append($placeholder); }; return Placeholder; }); S2.define('select2/selection/allowClear',[ 'jquery', '../keys' ], function ($, KEYS) { function AllowClear () { } AllowClear.prototype.bind = function (decorated, container, $container) { var self = this; decorated.call(this, container, $container); if (this.placeholder == null) { if (this.options.get('debug') && window.console && console.error) { console.error( 'Select2: The `allowClear` option should be used in combination ' + 'with the `placeholder` option.' ); } } this.$selection.on('mousedown', '.select2-selection__clear', function (evt) { self._handleClear(evt); }); container.on('keypress', function (evt) { self._handleKeyboardClear(evt, container); }); }; AllowClear.prototype._handleClear = function (_, evt) { // Ignore the event if it is disabled if (this.options.get('disabled')) { return; } var $clear = this.$selection.find('.select2-selection__clear'); // Ignore the event if nothing has been selected if ($clear.length === 0) { return; } evt.stopPropagation(); var data = $clear.data('data'); for (var d = 0; d < data.length; d++) { var unselectData = { data: data[d] }; // Trigger the `unselect` event, so people can prevent it from being // cleared. this.trigger('unselect', unselectData); // If the event was prevented, don't clear it out. if (unselectData.prevented) { return; } } this.$element.val(this.placeholder.id).trigger('change'); this.trigger('toggle', {}); }; AllowClear.prototype._handleKeyboardClear = function (_, evt, container) { if (container.isOpen()) { return; } if (evt.which == KEYS.DELETE || evt.which == KEYS.BACKSPACE) { this._handleClear(evt); } }; AllowClear.prototype.update = function (decorated, data) { decorated.call(this, data); if (this.$selection.find('.select2-selection__placeholder').length > 0 || data.length === 0) { return; } var $remove = $( '' + '×' + '' ); $remove.data('data', data); this.$selection.find('.select2-selection__rendered').prepend($remove); }; return AllowClear; }); S2.define('select2/selection/search',[ 'jquery', '../utils', '../keys' ], function ($, Utils, KEYS) { function Search (decorated, $element, options) { decorated.call(this, $element, options); } Search.prototype.render = function (decorated) { var $search = $( '' ); this.$searchContainer = $search; this.$search = $search.find('input'); var $rendered = decorated.call(this); this._transferTabIndex(); return $rendered; }; Search.prototype.bind = function (decorated, container, $container) { var self = this; decorated.call(this, container, $container); container.on('open', function () { self.$search.trigger('focus'); }); container.on('close', function () { self.$search.val(''); self.$search.removeAttr('aria-activedescendant'); self.$search.trigger('focus'); }); container.on('enable', function () { self.$search.prop('disabled', false); self._transferTabIndex(); }); container.on('disable', function () { self.$search.prop('disabled', true); }); container.on('focus', function (evt) { self.$search.trigger('focus'); }); container.on('results:focus', function (params) { self.$search.attr('aria-activedescendant', params.id); }); this.$selection.on('focusin', '.select2-search--inline', function (evt) { self.trigger('focus', evt); }); this.$selection.on('focusout', '.select2-search--inline', function (evt) { self._handleBlur(evt); }); this.$selection.on('keydown', '.select2-search--inline', function (evt) { evt.stopPropagation(); self.trigger('keypress', evt); self._keyUpPrevented = evt.isDefaultPrevented(); var key = evt.which; if (key === KEYS.BACKSPACE && self.$search.val() === '') { var $previousChoice = self.$searchContainer .prev('.select2-selection__choice'); if ($previousChoice.length > 0) { var item = $previousChoice.data('data'); self.searchRemoveChoice(item); evt.preventDefault(); } } }); // Try to detect the IE version should the `documentMode` property that // is stored on the document. This is only implemented in IE and is // slightly cleaner than doing a user agent check. // This property is not available in Edge, but Edge also doesn't have // this bug. var msie = document.documentMode; var disableInputEvents = msie && msie <= 11; // Workaround for browsers which do not support the `input` event // This will prevent double-triggering of events for browsers which support // both the `keyup` and `input` events. this.$selection.on( 'input.searchcheck', '.select2-search--inline', function (evt) { // IE will trigger the `input` event when a placeholder is used on a // search box. To get around this issue, we are forced to ignore all // `input` events in IE and keep using `keyup`. if (disableInputEvents) { self.$selection.off('input.search input.searchcheck'); return; } // Unbind the duplicated `keyup` event self.$selection.off('keyup.search'); } ); this.$selection.on( 'keyup.search input.search', '.select2-search--inline', function (evt) { // IE will trigger the `input` event when a placeholder is used on a // search box. To get around this issue, we are forced to ignore all // `input` events in IE and keep using `keyup`. if (disableInputEvents && evt.type === 'input') { self.$selection.off('input.search input.searchcheck'); return; } var key = evt.which; // We can freely ignore events from modifier keys if (key == KEYS.SHIFT || key == KEYS.CTRL || key == KEYS.ALT) { return; } // Tabbing will be handled during the `keydown` phase if (key == KEYS.TAB) { return; } self.handleSearch(evt); } ); }; /** * This method will transfer the tabindex attribute from the rendered * selection to the search box. This allows for the search box to be used as * the primary focus instead of the selection container. * * @private */ Search.prototype._transferTabIndex = function (decorated) { this.$search.attr('tabindex', this.$selection.attr('tabindex')); this.$selection.attr('tabindex', '-1'); }; Search.prototype.createPlaceholder = function (decorated, placeholder) { this.$search.attr('placeholder', placeholder.text); }; Search.prototype.update = function (decorated, data) { var searchHadFocus = this.$search[0] == document.activeElement; this.$search.attr('placeholder', ''); decorated.call(this, data); this.$selection.find('.select2-selection__rendered') .append(this.$searchContainer); this.resizeSearch(); if (searchHadFocus) { this.$search.focus(); } }; Search.prototype.handleSearch = function () { this.resizeSearch(); if (!this._keyUpPrevented) { var input = this.$search.val(); this.trigger('query', { term: input }); } this._keyUpPrevented = false; }; Search.prototype.searchRemoveChoice = function (decorated, item) { this.trigger('unselect', { data: item }); this.$search.val(item.text); this.handleSearch(); }; Search.prototype.resizeSearch = function () { this.$search.css('width', '25px'); var width = ''; if (this.$search.attr('placeholder') !== '') { width = this.$selection.find('.select2-selection__rendered').innerWidth(); } else { var minimumWidth = this.$search.val().length + 1; width = (minimumWidth * 0.75) + 'em'; } this.$search.css('width', width); }; return Search; }); S2.define('select2/selection/eventRelay',[ 'jquery' ], function ($) { function EventRelay () { } EventRelay.prototype.bind = function (decorated, container, $container) { var self = this; var relayEvents = [ 'open', 'opening', 'close', 'closing', 'select', 'selecting', 'unselect', 'unselecting' ]; var preventableEvents = ['opening', 'closing', 'selecting', 'unselecting']; decorated.call(this, container, $container); container.on('*', function (name, params) { // Ignore events that should not be relayed if ($.inArray(name, relayEvents) === -1) { return; } // The parameters should always be an object params = params || {}; // Generate the jQuery event for the Select2 event var evt = $.Event('select2:' + name, { params: params }); self.$element.trigger(evt); // Only handle preventable events if it was one if ($.inArray(name, preventableEvents) === -1) { return; } params.prevented = evt.isDefaultPrevented(); }); }; return EventRelay; }); S2.define('select2/translation',[ 'jquery', 'require' ], function ($, require) { function Translation (dict) { this.dict = dict || {}; } Translation.prototype.all = function () { return this.dict; }; Translation.prototype.get = function (key) { return this.dict[key]; }; Translation.prototype.extend = function (translation) { this.dict = $.extend({}, translation.all(), this.dict); }; // Static functions Translation._cache = {}; Translation.loadPath = function (path) { if (!(path in Translation._cache)) { var translations = require(path); Translation._cache[path] = translations; } return new Translation(Translation._cache[path]); }; return Translation; }); S2.define('select2/diacritics',[ ], function () { var diacritics = { '\u24B6': 'A', '\uFF21': 'A', '\u00C0': 'A', '\u00C1': 'A', '\u00C2': 'A', '\u1EA6': 'A', '\u1EA4': 'A', '\u1EAA': 'A', '\u1EA8': 'A', '\u00C3': 'A', '\u0100': 'A', '\u0102': 'A', '\u1EB0': 'A', '\u1EAE': 'A', '\u1EB4': 'A', '\u1EB2': 'A', '\u0226': 'A', '\u01E0': 'A', '\u00C4': 'A', '\u01DE': 'A', '\u1EA2': 'A', '\u00C5': 'A', '\u01FA': 'A', '\u01CD': 'A', '\u0200': 'A', '\u0202': 'A', '\u1EA0': 'A', '\u1EAC': 'A', '\u1EB6': 'A', '\u1E00': 'A', '\u0104': 'A', '\u023A': 'A', '\u2C6F': 'A', '\uA732': 'AA', '\u00C6': 'AE', '\u01FC': 'AE', '\u01E2': 'AE', '\uA734': 'AO', '\uA736': 'AU', '\uA738': 'AV', '\uA73A': 'AV', '\uA73C': 'AY', '\u24B7': 'B', '\uFF22': 'B', '\u1E02': 'B', '\u1E04': 'B', '\u1E06': 'B', '\u0243': 'B', '\u0182': 'B', '\u0181': 'B', '\u24B8': 'C', '\uFF23': 'C', '\u0106': 'C', '\u0108': 'C', '\u010A': 'C', '\u010C': 'C', '\u00C7': 'C', '\u1E08': 'C', '\u0187': 'C', '\u023B': 'C', '\uA73E': 'C', '\u24B9': 'D', '\uFF24': 'D', '\u1E0A': 'D', '\u010E': 'D', '\u1E0C': 'D', '\u1E10': 'D', '\u1E12': 'D', '\u1E0E': 'D', '\u0110': 'D', '\u018B': 'D', '\u018A': 'D', '\u0189': 'D', '\uA779': 'D', '\u01F1': 'DZ', '\u01C4': 'DZ', '\u01F2': 'Dz', '\u01C5': 'Dz', '\u24BA': 'E', '\uFF25': 'E', '\u00C8': 'E', '\u00C9': 'E', '\u00CA': 'E', '\u1EC0': 'E', '\u1EBE': 'E', '\u1EC4': 'E', '\u1EC2': 'E', '\u1EBC': 'E', '\u0112': 'E', '\u1E14': 'E', '\u1E16': 'E', '\u0114': 'E', '\u0116': 'E', '\u00CB': 'E', '\u1EBA': 'E', '\u011A': 'E', '\u0204': 'E', '\u0206': 'E', '\u1EB8': 'E', '\u1EC6': 'E', '\u0228': 'E', '\u1E1C': 'E', '\u0118': 'E', '\u1E18': 'E', '\u1E1A': 'E', '\u0190': 'E', '\u018E': 'E', '\u24BB': 'F', '\uFF26': 'F', '\u1E1E': 'F', '\u0191': 'F', '\uA77B': 'F', '\u24BC': 'G', '\uFF27': 'G', '\u01F4': 'G', '\u011C': 'G', '\u1E20': 'G', '\u011E': 'G', '\u0120': 'G', '\u01E6': 'G', '\u0122': 'G', '\u01E4': 'G', '\u0193': 'G', '\uA7A0': 'G', '\uA77D': 'G', '\uA77E': 'G', '\u24BD': 'H', '\uFF28': 'H', '\u0124': 'H', '\u1E22': 'H', '\u1E26': 'H', '\u021E': 'H', '\u1E24': 'H', '\u1E28': 'H', '\u1E2A': 'H', '\u0126': 'H', '\u2C67': 'H', '\u2C75': 'H', '\uA78D': 'H', '\u24BE': 'I', '\uFF29': 'I', '\u00CC': 'I', '\u00CD': 'I', '\u00CE': 'I', '\u0128': 'I', '\u012A': 'I', '\u012C': 'I', '\u0130': 'I', '\u00CF': 'I', '\u1E2E': 'I', '\u1EC8': 'I', '\u01CF': 'I', '\u0208': 'I', '\u020A': 'I', '\u1ECA': 'I', '\u012E': 'I', '\u1E2C': 'I', '\u0197': 'I', '\u24BF': 'J', '\uFF2A': 'J', '\u0134': 'J', '\u0248': 'J', '\u24C0': 'K', '\uFF2B': 'K', '\u1E30': 'K', '\u01E8': 'K', '\u1E32': 'K', '\u0136': 'K', '\u1E34': 'K', '\u0198': 'K', '\u2C69': 'K', '\uA740': 'K', '\uA742': 'K', '\uA744': 'K', '\uA7A2': 'K', '\u24C1': 'L', '\uFF2C': 'L', '\u013F': 'L', '\u0139': 'L', '\u013D': 'L', '\u1E36': 'L', '\u1E38': 'L', '\u013B': 'L', '\u1E3C': 'L', '\u1E3A': 'L', '\u0141': 'L', '\u023D': 'L', '\u2C62': 'L', '\u2C60': 'L', '\uA748': 'L', '\uA746': 'L', '\uA780': 'L', '\u01C7': 'LJ', '\u01C8': 'Lj', '\u24C2': 'M', '\uFF2D': 'M', '\u1E3E': 'M', '\u1E40': 'M', '\u1E42': 'M', '\u2C6E': 'M', '\u019C': 'M', '\u24C3': 'N', '\uFF2E': 'N', '\u01F8': 'N', '\u0143': 'N', '\u00D1': 'N', '\u1E44': 'N', '\u0147': 'N', '\u1E46': 'N', '\u0145': 'N', '\u1E4A': 'N', '\u1E48': 'N', '\u0220': 'N', '\u019D': 'N', '\uA790': 'N', '\uA7A4': 'N', '\u01CA': 'NJ', '\u01CB': 'Nj', '\u24C4': 'O', '\uFF2F': 'O', '\u00D2': 'O', '\u00D3': 'O', '\u00D4': 'O', '\u1ED2': 'O', '\u1ED0': 'O', '\u1ED6': 'O', '\u1ED4': 'O', '\u00D5': 'O', '\u1E4C': 'O', '\u022C': 'O', '\u1E4E': 'O', '\u014C': 'O', '\u1E50': 'O', '\u1E52': 'O', '\u014E': 'O', '\u022E': 'O', '\u0230': 'O', '\u00D6': 'O', '\u022A': 'O', '\u1ECE': 'O', '\u0150': 'O', '\u01D1': 'O', '\u020C': 'O', '\u020E': 'O', '\u01A0': 'O', '\u1EDC': 'O', '\u1EDA': 'O', '\u1EE0': 'O', '\u1EDE': 'O', '\u1EE2': 'O', '\u1ECC': 'O', '\u1ED8': 'O', '\u01EA': 'O', '\u01EC': 'O', '\u00D8': 'O', '\u01FE': 'O', '\u0186': 'O', '\u019F': 'O', '\uA74A': 'O', '\uA74C': 'O', '\u01A2': 'OI', '\uA74E': 'OO', '\u0222': 'OU', '\u24C5': 'P', '\uFF30': 'P', '\u1E54': 'P', '\u1E56': 'P', '\u01A4': 'P', '\u2C63': 'P', '\uA750': 'P', '\uA752': 'P', '\uA754': 'P', '\u24C6': 'Q', '\uFF31': 'Q', '\uA756': 'Q', '\uA758': 'Q', '\u024A': 'Q', '\u24C7': 'R', '\uFF32': 'R', '\u0154': 'R', '\u1E58': 'R', '\u0158': 'R', '\u0210': 'R', '\u0212': 'R', '\u1E5A': 'R', '\u1E5C': 'R', '\u0156': 'R', '\u1E5E': 'R', '\u024C': 'R', '\u2C64': 'R', '\uA75A': 'R', '\uA7A6': 'R', '\uA782': 'R', '\u24C8': 'S', '\uFF33': 'S', '\u1E9E': 'S', '\u015A': 'S', '\u1E64': 'S', '\u015C': 'S', '\u1E60': 'S', '\u0160': 'S', '\u1E66': 'S', '\u1E62': 'S', '\u1E68': 'S', '\u0218': 'S', '\u015E': 'S', '\u2C7E': 'S', '\uA7A8': 'S', '\uA784': 'S', '\u24C9': 'T', '\uFF34': 'T', '\u1E6A': 'T', '\u0164': 'T', '\u1E6C': 'T', '\u021A': 'T', '\u0162': 'T', '\u1E70': 'T', '\u1E6E': 'T', '\u0166': 'T', '\u01AC': 'T', '\u01AE': 'T', '\u023E': 'T', '\uA786': 'T', '\uA728': 'TZ', '\u24CA': 'U', '\uFF35': 'U', '\u00D9': 'U', '\u00DA': 'U', '\u00DB': 'U', '\u0168': 'U', '\u1E78': 'U', '\u016A': 'U', '\u1E7A': 'U', '\u016C': 'U', '\u00DC': 'U', '\u01DB': 'U', '\u01D7': 'U', '\u01D5': 'U', '\u01D9': 'U', '\u1EE6': 'U', '\u016E': 'U', '\u0170': 'U', '\u01D3': 'U', '\u0214': 'U', '\u0216': 'U', '\u01AF': 'U', '\u1EEA': 'U', '\u1EE8': 'U', '\u1EEE': 'U', '\u1EEC': 'U', '\u1EF0': 'U', '\u1EE4': 'U', '\u1E72': 'U', '\u0172': 'U', '\u1E76': 'U', '\u1E74': 'U', '\u0244': 'U', '\u24CB': 'V', '\uFF36': 'V', '\u1E7C': 'V', '\u1E7E': 'V', '\u01B2': 'V', '\uA75E': 'V', '\u0245': 'V', '\uA760': 'VY', '\u24CC': 'W', '\uFF37': 'W', '\u1E80': 'W', '\u1E82': 'W', '\u0174': 'W', '\u1E86': 'W', '\u1E84': 'W', '\u1E88': 'W', '\u2C72': 'W', '\u24CD': 'X', '\uFF38': 'X', '\u1E8A': 'X', '\u1E8C': 'X', '\u24CE': 'Y', '\uFF39': 'Y', '\u1EF2': 'Y', '\u00DD': 'Y', '\u0176': 'Y', '\u1EF8': 'Y', '\u0232': 'Y', '\u1E8E': 'Y', '\u0178': 'Y', '\u1EF6': 'Y', '\u1EF4': 'Y', '\u01B3': 'Y', '\u024E': 'Y', '\u1EFE': 'Y', '\u24CF': 'Z', '\uFF3A': 'Z', '\u0179': 'Z', '\u1E90': 'Z', '\u017B': 'Z', '\u017D': 'Z', '\u1E92': 'Z', '\u1E94': 'Z', '\u01B5': 'Z', '\u0224': 'Z', '\u2C7F': 'Z', '\u2C6B': 'Z', '\uA762': 'Z', '\u24D0': 'a', '\uFF41': 'a', '\u1E9A': 'a', '\u00E0': 'a', '\u00E1': 'a', '\u00E2': 'a', '\u1EA7': 'a', '\u1EA5': 'a', '\u1EAB': 'a', '\u1EA9': 'a', '\u00E3': 'a', '\u0101': 'a', '\u0103': 'a', '\u1EB1': 'a', '\u1EAF': 'a', '\u1EB5': 'a', '\u1EB3': 'a', '\u0227': 'a', '\u01E1': 'a', '\u00E4': 'a', '\u01DF': 'a', '\u1EA3': 'a', '\u00E5': 'a', '\u01FB': 'a', '\u01CE': 'a', '\u0201': 'a', '\u0203': 'a', '\u1EA1': 'a', '\u1EAD': 'a', '\u1EB7': 'a', '\u1E01': 'a', '\u0105': 'a', '\u2C65': 'a', '\u0250': 'a', '\uA733': 'aa', '\u00E6': 'ae', '\u01FD': 'ae', '\u01E3': 'ae', '\uA735': 'ao', '\uA737': 'au', '\uA739': 'av', '\uA73B': 'av', '\uA73D': 'ay', '\u24D1': 'b', '\uFF42': 'b', '\u1E03': 'b', '\u1E05': 'b', '\u1E07': 'b', '\u0180': 'b', '\u0183': 'b', '\u0253': 'b', '\u24D2': 'c', '\uFF43': 'c', '\u0107': 'c', '\u0109': 'c', '\u010B': 'c', '\u010D': 'c', '\u00E7': 'c', '\u1E09': 'c', '\u0188': 'c', '\u023C': 'c', '\uA73F': 'c', '\u2184': 'c', '\u24D3': 'd', '\uFF44': 'd', '\u1E0B': 'd', '\u010F': 'd', '\u1E0D': 'd', '\u1E11': 'd', '\u1E13': 'd', '\u1E0F': 'd', '\u0111': 'd', '\u018C': 'd', '\u0256': 'd', '\u0257': 'd', '\uA77A': 'd', '\u01F3': 'dz', '\u01C6': 'dz', '\u24D4': 'e', '\uFF45': 'e', '\u00E8': 'e', '\u00E9': 'e', '\u00EA': 'e', '\u1EC1': 'e', '\u1EBF': 'e', '\u1EC5': 'e', '\u1EC3': 'e', '\u1EBD': 'e', '\u0113': 'e', '\u1E15': 'e', '\u1E17': 'e', '\u0115': 'e', '\u0117': 'e', '\u00EB': 'e', '\u1EBB': 'e', '\u011B': 'e', '\u0205': 'e', '\u0207': 'e', '\u1EB9': 'e', '\u1EC7': 'e', '\u0229': 'e', '\u1E1D': 'e', '\u0119': 'e', '\u1E19': 'e', '\u1E1B': 'e', '\u0247': 'e', '\u025B': 'e', '\u01DD': 'e', '\u24D5': 'f', '\uFF46': 'f', '\u1E1F': 'f', '\u0192': 'f', '\uA77C': 'f', '\u24D6': 'g', '\uFF47': 'g', '\u01F5': 'g', '\u011D': 'g', '\u1E21': 'g', '\u011F': 'g', '\u0121': 'g', '\u01E7': 'g', '\u0123': 'g', '\u01E5': 'g', '\u0260': 'g', '\uA7A1': 'g', '\u1D79': 'g', '\uA77F': 'g', '\u24D7': 'h', '\uFF48': 'h', '\u0125': 'h', '\u1E23': 'h', '\u1E27': 'h', '\u021F': 'h', '\u1E25': 'h', '\u1E29': 'h', '\u1E2B': 'h', '\u1E96': 'h', '\u0127': 'h', '\u2C68': 'h', '\u2C76': 'h', '\u0265': 'h', '\u0195': 'hv', '\u24D8': 'i', '\uFF49': 'i', '\u00EC': 'i', '\u00ED': 'i', '\u00EE': 'i', '\u0129': 'i', '\u012B': 'i', '\u012D': 'i', '\u00EF': 'i', '\u1E2F': 'i', '\u1EC9': 'i', '\u01D0': 'i', '\u0209': 'i', '\u020B': 'i', '\u1ECB': 'i', '\u012F': 'i', '\u1E2D': 'i', '\u0268': 'i', '\u0131': 'i', '\u24D9': 'j', '\uFF4A': 'j', '\u0135': 'j', '\u01F0': 'j', '\u0249': 'j', '\u24DA': 'k', '\uFF4B': 'k', '\u1E31': 'k', '\u01E9': 'k', '\u1E33': 'k', '\u0137': 'k', '\u1E35': 'k', '\u0199': 'k', '\u2C6A': 'k', '\uA741': 'k', '\uA743': 'k', '\uA745': 'k', '\uA7A3': 'k', '\u24DB': 'l', '\uFF4C': 'l', '\u0140': 'l', '\u013A': 'l', '\u013E': 'l', '\u1E37': 'l', '\u1E39': 'l', '\u013C': 'l', '\u1E3D': 'l', '\u1E3B': 'l', '\u017F': 'l', '\u0142': 'l', '\u019A': 'l', '\u026B': 'l', '\u2C61': 'l', '\uA749': 'l', '\uA781': 'l', '\uA747': 'l', '\u01C9': 'lj', '\u24DC': 'm', '\uFF4D': 'm', '\u1E3F': 'm', '\u1E41': 'm', '\u1E43': 'm', '\u0271': 'm', '\u026F': 'm', '\u24DD': 'n', '\uFF4E': 'n', '\u01F9': 'n', '\u0144': 'n', '\u00F1': 'n', '\u1E45': 'n', '\u0148': 'n', '\u1E47': 'n', '\u0146': 'n', '\u1E4B': 'n', '\u1E49': 'n', '\u019E': 'n', '\u0272': 'n', '\u0149': 'n', '\uA791': 'n', '\uA7A5': 'n', '\u01CC': 'nj', '\u24DE': 'o', '\uFF4F': 'o', '\u00F2': 'o', '\u00F3': 'o', '\u00F4': 'o', '\u1ED3': 'o', '\u1ED1': 'o', '\u1ED7': 'o', '\u1ED5': 'o', '\u00F5': 'o', '\u1E4D': 'o', '\u022D': 'o', '\u1E4F': 'o', '\u014D': 'o', '\u1E51': 'o', '\u1E53': 'o', '\u014F': 'o', '\u022F': 'o', '\u0231': 'o', '\u00F6': 'o', '\u022B': 'o', '\u1ECF': 'o', '\u0151': 'o', '\u01D2': 'o', '\u020D': 'o', '\u020F': 'o', '\u01A1': 'o', '\u1EDD': 'o', '\u1EDB': 'o', '\u1EE1': 'o', '\u1EDF': 'o', '\u1EE3': 'o', '\u1ECD': 'o', '\u1ED9': 'o', '\u01EB': 'o', '\u01ED': 'o', '\u00F8': 'o', '\u01FF': 'o', '\u0254': 'o', '\uA74B': 'o', '\uA74D': 'o', '\u0275': 'o', '\u01A3': 'oi', '\u0223': 'ou', '\uA74F': 'oo', '\u24DF': 'p', '\uFF50': 'p', '\u1E55': 'p', '\u1E57': 'p', '\u01A5': 'p', '\u1D7D': 'p', '\uA751': 'p', '\uA753': 'p', '\uA755': 'p', '\u24E0': 'q', '\uFF51': 'q', '\u024B': 'q', '\uA757': 'q', '\uA759': 'q', '\u24E1': 'r', '\uFF52': 'r', '\u0155': 'r', '\u1E59': 'r', '\u0159': 'r', '\u0211': 'r', '\u0213': 'r', '\u1E5B': 'r', '\u1E5D': 'r', '\u0157': 'r', '\u1E5F': 'r', '\u024D': 'r', '\u027D': 'r', '\uA75B': 'r', '\uA7A7': 'r', '\uA783': 'r', '\u24E2': 's', '\uFF53': 's', '\u00DF': 's', '\u015B': 's', '\u1E65': 's', '\u015D': 's', '\u1E61': 's', '\u0161': 's', '\u1E67': 's', '\u1E63': 's', '\u1E69': 's', '\u0219': 's', '\u015F': 's', '\u023F': 's', '\uA7A9': 's', '\uA785': 's', '\u1E9B': 's', '\u24E3': 't', '\uFF54': 't', '\u1E6B': 't', '\u1E97': 't', '\u0165': 't', '\u1E6D': 't', '\u021B': 't', '\u0163': 't', '\u1E71': 't', '\u1E6F': 't', '\u0167': 't', '\u01AD': 't', '\u0288': 't', '\u2C66': 't', '\uA787': 't', '\uA729': 'tz', '\u24E4': 'u', '\uFF55': 'u', '\u00F9': 'u', '\u00FA': 'u', '\u00FB': 'u', '\u0169': 'u', '\u1E79': 'u', '\u016B': 'u', '\u1E7B': 'u', '\u016D': 'u', '\u00FC': 'u', '\u01DC': 'u', '\u01D8': 'u', '\u01D6': 'u', '\u01DA': 'u', '\u1EE7': 'u', '\u016F': 'u', '\u0171': 'u', '\u01D4': 'u', '\u0215': 'u', '\u0217': 'u', '\u01B0': 'u', '\u1EEB': 'u', '\u1EE9': 'u', '\u1EEF': 'u', '\u1EED': 'u', '\u1EF1': 'u', '\u1EE5': 'u', '\u1E73': 'u', '\u0173': 'u', '\u1E77': 'u', '\u1E75': 'u', '\u0289': 'u', '\u24E5': 'v', '\uFF56': 'v', '\u1E7D': 'v', '\u1E7F': 'v', '\u028B': 'v', '\uA75F': 'v', '\u028C': 'v', '\uA761': 'vy', '\u24E6': 'w', '\uFF57': 'w', '\u1E81': 'w', '\u1E83': 'w', '\u0175': 'w', '\u1E87': 'w', '\u1E85': 'w', '\u1E98': 'w', '\u1E89': 'w', '\u2C73': 'w', '\u24E7': 'x', '\uFF58': 'x', '\u1E8B': 'x', '\u1E8D': 'x', '\u24E8': 'y', '\uFF59': 'y', '\u1EF3': 'y', '\u00FD': 'y', '\u0177': 'y', '\u1EF9': 'y', '\u0233': 'y', '\u1E8F': 'y', '\u00FF': 'y', '\u1EF7': 'y', '\u1E99': 'y', '\u1EF5': 'y', '\u01B4': 'y', '\u024F': 'y', '\u1EFF': 'y', '\u24E9': 'z', '\uFF5A': 'z', '\u017A': 'z', '\u1E91': 'z', '\u017C': 'z', '\u017E': 'z', '\u1E93': 'z', '\u1E95': 'z', '\u01B6': 'z', '\u0225': 'z', '\u0240': 'z', '\u2C6C': 'z', '\uA763': 'z', '\u0386': '\u0391', '\u0388': '\u0395', '\u0389': '\u0397', '\u038A': '\u0399', '\u03AA': '\u0399', '\u038C': '\u039F', '\u038E': '\u03A5', '\u03AB': '\u03A5', '\u038F': '\u03A9', '\u03AC': '\u03B1', '\u03AD': '\u03B5', '\u03AE': '\u03B7', '\u03AF': '\u03B9', '\u03CA': '\u03B9', '\u0390': '\u03B9', '\u03CC': '\u03BF', '\u03CD': '\u03C5', '\u03CB': '\u03C5', '\u03B0': '\u03C5', '\u03C9': '\u03C9', '\u03C2': '\u03C3' }; return diacritics; }); S2.define('select2/data/base',[ '../utils' ], function (Utils) { function BaseAdapter ($element, options) { BaseAdapter.__super__.constructor.call(this); } Utils.Extend(BaseAdapter, Utils.Observable); BaseAdapter.prototype.current = function (callback) { throw new Error('The `current` method must be defined in child classes.'); }; BaseAdapter.prototype.query = function (params, callback) { throw new Error('The `query` method must be defined in child classes.'); }; BaseAdapter.prototype.bind = function (container, $container) { // Can be implemented in subclasses }; BaseAdapter.prototype.destroy = function () { // Can be implemented in subclasses }; BaseAdapter.prototype.generateResultId = function (container, data) { var id = container.id + '-result-'; id += Utils.generateChars(4); if (data.id != null) { id += '-' + data.id.toString(); } else { id += '-' + Utils.generateChars(4); } return id; }; return BaseAdapter; }); S2.define('select2/data/select',[ './base', '../utils', 'jquery' ], function (BaseAdapter, Utils, $) { function SelectAdapter ($element, options) { this.$element = $element; this.options = options; SelectAdapter.__super__.constructor.call(this); } Utils.Extend(SelectAdapter, BaseAdapter); SelectAdapter.prototype.current = function (callback) { var data = []; var self = this; this.$element.find(':selected').each(function () { var $option = $(this); var option = self.item($option); data.push(option); }); callback(data); }; SelectAdapter.prototype.select = function (data) { var self = this; data.selected = true; // If data.element is a DOM node, use it instead if ($(data.element).is('option')) { data.element.selected = true; this.$element.trigger('change'); return; } if (this.$element.prop('multiple')) { this.current(function (currentData) { var val = []; data = [data]; data.push.apply(data, currentData); for (var d = 0; d < data.length; d++) { var id = data[d].id; if ($.inArray(id, val) === -1) { val.push(id); } } self.$element.val(val); self.$element.trigger('change'); }); } else { var val = data.id; this.$element.val(val); this.$element.trigger('change'); } }; SelectAdapter.prototype.unselect = function (data) { var self = this; if (!this.$element.prop('multiple')) { return; } data.selected = false; if ($(data.element).is('option')) { data.element.selected = false; this.$element.trigger('change'); return; } this.current(function (currentData) { var val = []; for (var d = 0; d < currentData.length; d++) { var id = currentData[d].id; if (id !== data.id && $.inArray(id, val) === -1) { val.push(id); } } self.$element.val(val); self.$element.trigger('change'); }); }; SelectAdapter.prototype.bind = function (container, $container) { var self = this; this.container = container; container.on('select', function (params) { self.select(params.data); }); container.on('unselect', function (params) { self.unselect(params.data); }); }; SelectAdapter.prototype.destroy = function () { // Remove anything added to child elements this.$element.find('*').each(function () { // Remove any custom data set by Select2 $.removeData(this, 'data'); }); }; SelectAdapter.prototype.query = function (params, callback) { var data = []; var self = this; var $options = this.$element.children(); $options.each(function () { var $option = $(this); if (!$option.is('option') && !$option.is('optgroup')) { return; } var option = self.item($option); var matches = self.matches(params, option); if (matches !== null) { data.push(matches); } }); callback({ results: data }); }; SelectAdapter.prototype.addOptions = function ($options) { Utils.appendMany(this.$element, $options); }; SelectAdapter.prototype.option = function (data) { var option; if (data.children) { option = document.createElement('optgroup'); option.label = data.text; } else { option = document.createElement('option'); if (option.textContent !== undefined) { option.textContent = data.text; } else { option.innerText = data.text; } } if (data.id) { option.value = data.id; } if (data.disabled) { option.disabled = true; } if (data.selected) { option.selected = true; } if (data.title) { option.title = data.title; } var $option = $(option); var normalizedData = this._normalizeItem(data); normalizedData.element = option; // Override the option's data with the combined data $.data(option, 'data', normalizedData); return $option; }; SelectAdapter.prototype.item = function ($option) { var data = {}; data = $.data($option[0], 'data'); if (data != null) { return data; } if ($option.is('option')) { data = { id: $option.val(), text: $option.text(), disabled: $option.prop('disabled'), selected: $option.prop('selected'), title: $option.prop('title') }; } else if ($option.is('optgroup')) { data = { text: $option.prop('label'), children: [], title: $option.prop('title') }; var $children = $option.children('option'); var children = []; for (var c = 0; c < $children.length; c++) { var $child = $($children[c]); var child = this.item($child); children.push(child); } data.children = children; } data = this._normalizeItem(data); data.element = $option[0]; $.data($option[0], 'data', data); return data; }; SelectAdapter.prototype._normalizeItem = function (item) { if (!$.isPlainObject(item)) { item = { id: item, text: item }; } item = $.extend({}, { text: '' }, item); var defaults = { selected: false, disabled: false }; if (item.id != null) { item.id = item.id.toString(); } if (item.text != null) { item.text = item.text.toString(); } if (item._resultId == null && item.id && this.container != null) { item._resultId = this.generateResultId(this.container, item); } return $.extend({}, defaults, item); }; SelectAdapter.prototype.matches = function (params, data) { var matcher = this.options.get('matcher'); return matcher(params, data); }; return SelectAdapter; }); S2.define('select2/data/array',[ './select', '../utils', 'jquery' ], function (SelectAdapter, Utils, $) { function ArrayAdapter ($element, options) { var data = options.get('data') || []; ArrayAdapter.__super__.constructor.call(this, $element, options); this.addOptions(this.convertToOptions(data)); } Utils.Extend(ArrayAdapter, SelectAdapter); ArrayAdapter.prototype.select = function (data) { var $option = this.$element.find('option').filter(function (i, elm) { return elm.value == data.id.toString(); }); if ($option.length === 0) { $option = this.option(data); this.addOptions($option); } ArrayAdapter.__super__.select.call(this, data); }; ArrayAdapter.prototype.convertToOptions = function (data) { var self = this; var $existing = this.$element.find('option'); var existingIds = $existing.map(function () { return self.item($(this)).id; }).get(); var $options = []; // Filter out all items except for the one passed in the argument function onlyItem (item) { return function () { return $(this).val() == item.id; }; } for (var d = 0; d < data.length; d++) { var item = this._normalizeItem(data[d]); // Skip items which were pre-loaded, only merge the data if ($.inArray(item.id, existingIds) >= 0) { var $existingOption = $existing.filter(onlyItem(item)); var existingData = this.item($existingOption); var newData = $.extend(true, {}, item, existingData); var $newOption = this.option(newData); $existingOption.replaceWith($newOption); continue; } var $option = this.option(item); if (item.children) { var $children = this.convertToOptions(item.children); Utils.appendMany($option, $children); } $options.push($option); } return $options; }; return ArrayAdapter; }); S2.define('select2/data/ajax',[ './array', '../utils', 'jquery' ], function (ArrayAdapter, Utils, $) { function AjaxAdapter ($element, options) { this.ajaxOptions = this._applyDefaults(options.get('ajax')); if (this.ajaxOptions.processResults != null) { this.processResults = this.ajaxOptions.processResults; } AjaxAdapter.__super__.constructor.call(this, $element, options); } Utils.Extend(AjaxAdapter, ArrayAdapter); AjaxAdapter.prototype._applyDefaults = function (options) { var defaults = { data: function (params) { return $.extend({}, params, { q: params.term }); }, transport: function (params, success, failure) { var $request = $.ajax(params); $request.then(success); $request.fail(failure); return $request; } }; return $.extend({}, defaults, options, true); }; AjaxAdapter.prototype.processResults = function (results) { return results; }; AjaxAdapter.prototype.query = function (params, callback) { var matches = []; var self = this; if (this._request != null) { // JSONP requests cannot always be aborted if ($.isFunction(this._request.abort)) { this._request.abort(); } this._request = null; } var options = $.extend({ type: 'GET' }, this.ajaxOptions); if (typeof options.url === 'function') { options.url = options.url.call(this.$element, params); } if (typeof options.data === 'function') { options.data = options.data.call(this.$element, params); } function request () { var $request = options.transport(options, function (data) { var results = self.processResults(data, params); if (self.options.get('debug') && window.console && console.error) { // Check to make sure that the response included a `results` key. if (!results || !results.results || !$.isArray(results.results)) { console.error( 'Select2: The AJAX results did not return an array in the ' + '`results` key of the response.' ); } } callback(results); }, function () { // Attempt to detect if a request was aborted // Only works if the transport exposes a status property if ($request.status && $request.status === '0') { return; } self.trigger('results:message', { message: 'errorLoading' }); }); self._request = $request; } if (this.ajaxOptions.delay && params.term != null) { if (this._queryTimeout) { window.clearTimeout(this._queryTimeout); } this._queryTimeout = window.setTimeout(request, this.ajaxOptions.delay); } else { request(); } }; return AjaxAdapter; }); S2.define('select2/data/tags',[ 'jquery' ], function ($) { function Tags (decorated, $element, options) { var tags = options.get('tags'); var createTag = options.get('createTag'); if (createTag !== undefined) { this.createTag = createTag; } var insertTag = options.get('insertTag'); if (insertTag !== undefined) { this.insertTag = insertTag; } decorated.call(this, $element, options); if ($.isArray(tags)) { for (var t = 0; t < tags.length; t++) { var tag = tags[t]; var item = this._normalizeItem(tag); var $option = this.option(item); this.$element.append($option); } } } Tags.prototype.query = function (decorated, params, callback) { var self = this; this._removeOldTags(); if (params.term == null || params.page != null) { decorated.call(this, params, callback); return; } function wrapper (obj, child) { var data = obj.results; for (var i = 0; i < data.length; i++) { var option = data[i]; var checkChildren = ( option.children != null && !wrapper({ results: option.children }, true) ); var checkText = option.text === params.term; if (checkText || checkChildren) { if (child) { return false; } obj.data = data; callback(obj); return; } } if (child) { return true; } var tag = self.createTag(params); if (tag != null) { var $option = self.option(tag); $option.attr('data-select2-tag', true); self.addOptions([$option]); self.insertTag(data, tag); } obj.results = data; callback(obj); } decorated.call(this, params, wrapper); }; Tags.prototype.createTag = function (decorated, params) { var term = $.trim(params.term); if (term === '') { return null; } return { id: term, text: term }; }; Tags.prototype.insertTag = function (_, data, tag) { data.unshift(tag); }; Tags.prototype._removeOldTags = function (_) { var tag = this._lastTag; var $options = this.$element.find('option[data-select2-tag]'); $options.each(function () { if (this.selected) { return; } $(this).remove(); }); }; return Tags; }); S2.define('select2/data/tokenizer',[ 'jquery' ], function ($) { function Tokenizer (decorated, $element, options) { var tokenizer = options.get('tokenizer'); if (tokenizer !== undefined) { this.tokenizer = tokenizer; } decorated.call(this, $element, options); } Tokenizer.prototype.bind = function (decorated, container, $container) { decorated.call(this, container, $container); this.$search = container.dropdown.$search || container.selection.$search || $container.find('.select2-search__field'); }; Tokenizer.prototype.query = function (decorated, params, callback) { var self = this; function createAndSelect (data) { // Normalize the data object so we can use it for checks var item = self._normalizeItem(data); // Check if the data object already exists as a tag // Select it if it doesn't var $existingOptions = self.$element.find('option').filter(function () { return $(this).val() === item.id; }); // If an existing option wasn't found for it, create the option if (!$existingOptions.length) { var $option = self.option(item); $option.attr('data-select2-tag', true); self._removeOldTags(); self.addOptions([$option]); } // Select the item, now that we know there is an option for it select(item); } function select (data) { self.trigger('select', { data: data }); } params.term = params.term || ''; var tokenData = this.tokenizer(params, this.options, createAndSelect); if (tokenData.term !== params.term) { // Replace the search term if we have the search box if (this.$search.length) { this.$search.val(tokenData.term); this.$search.focus(); } params.term = tokenData.term; } decorated.call(this, params, callback); }; Tokenizer.prototype.tokenizer = function (_, params, options, callback) { var separators = options.get('tokenSeparators') || []; var term = params.term; var i = 0; var createTag = this.createTag || function (params) { return { id: params.term, text: params.term }; }; while (i < term.length) { var termChar = term[i]; if ($.inArray(termChar, separators) === -1) { i++; continue; } var part = term.substr(0, i); var partParams = $.extend({}, params, { term: part }); var data = createTag(partParams); if (data == null) { i++; continue; } callback(data); // Reset the term to not include the tokenized portion term = term.substr(i + 1) || ''; i = 0; } return { term: term }; }; return Tokenizer; }); S2.define('select2/data/minimumInputLength',[ ], function () { function MinimumInputLength (decorated, $e, options) { this.minimumInputLength = options.get('minimumInputLength'); decorated.call(this, $e, options); } MinimumInputLength.prototype.query = function (decorated, params, callback) { params.term = params.term || ''; if (params.term.length < this.minimumInputLength) { this.trigger('results:message', { message: 'inputTooShort', args: { minimum: this.minimumInputLength, input: params.term, params: params } }); return; } decorated.call(this, params, callback); }; return MinimumInputLength; }); S2.define('select2/data/maximumInputLength',[ ], function () { function MaximumInputLength (decorated, $e, options) { this.maximumInputLength = options.get('maximumInputLength'); decorated.call(this, $e, options); } MaximumInputLength.prototype.query = function (decorated, params, callback) { params.term = params.term || ''; if (this.maximumInputLength > 0 && params.term.length > this.maximumInputLength) { this.trigger('results:message', { message: 'inputTooLong', args: { maximum: this.maximumInputLength, input: params.term, params: params } }); return; } decorated.call(this, params, callback); }; return MaximumInputLength; }); S2.define('select2/data/maximumSelectionLength',[ ], function (){ function MaximumSelectionLength (decorated, $e, options) { this.maximumSelectionLength = options.get('maximumSelectionLength'); decorated.call(this, $e, options); } MaximumSelectionLength.prototype.query = function (decorated, params, callback) { var self = this; this.current(function (currentData) { var count = currentData != null ? currentData.length : 0; if (self.maximumSelectionLength > 0 && count >= self.maximumSelectionLength) { self.trigger('results:message', { message: 'maximumSelected', args: { maximum: self.maximumSelectionLength } }); return; } decorated.call(self, params, callback); }); }; return MaximumSelectionLength; }); S2.define('select2/dropdown',[ 'jquery', './utils' ], function ($, Utils) { function Dropdown ($element, options) { this.$element = $element; this.options = options; Dropdown.__super__.constructor.call(this); } Utils.Extend(Dropdown, Utils.Observable); Dropdown.prototype.render = function () { var $dropdown = $( '' + '' + '' ); $dropdown.attr('dir', this.options.get('dir')); this.$dropdown = $dropdown; return $dropdown; }; Dropdown.prototype.bind = function () { // Should be implemented in subclasses }; Dropdown.prototype.position = function ($dropdown, $container) { // Should be implmented in subclasses }; Dropdown.prototype.destroy = function () { // Remove the dropdown from the DOM this.$dropdown.remove(); }; return Dropdown; }); S2.define('select2/dropdown/search',[ 'jquery', '../utils' ], function ($, Utils) { function Search () { } Search.prototype.render = function (decorated) { var $rendered = decorated.call(this); var $search = $( '' + '' + '' ); this.$searchContainer = $search; this.$search = $search.find('input'); $rendered.prepend($search); return $rendered; }; Search.prototype.bind = function (decorated, container, $container) { var self = this; decorated.call(this, container, $container); this.$search.on('keydown', function (evt) { self.trigger('keypress', evt); self._keyUpPrevented = evt.isDefaultPrevented(); }); // Workaround for browsers which do not support the `input` event // This will prevent double-triggering of events for browsers which support // both the `keyup` and `input` events. this.$search.on('input', function (evt) { // Unbind the duplicated `keyup` event $(this).off('keyup'); }); this.$search.on('keyup input', function (evt) { self.handleSearch(evt); }); container.on('open', function () { self.$search.attr('tabindex', 0); self.$search.focus(); window.setTimeout(function () { self.$search.focus(); }, 0); }); container.on('close', function () { self.$search.attr('tabindex', -1); self.$search.val(''); }); container.on('focus', function () { if (container.isOpen()) { self.$search.focus(); } }); container.on('results:all', function (params) { if (params.query.term == null || params.query.term === '') { var showSearch = self.showSearch(params); if (showSearch) { self.$searchContainer.removeClass('select2-search--hide'); } else { self.$searchContainer.addClass('select2-search--hide'); } } }); }; Search.prototype.handleSearch = function (evt) { if (!this._keyUpPrevented) { var input = this.$search.val(); this.trigger('query', { term: input }); } this._keyUpPrevented = false; }; Search.prototype.showSearch = function (_, params) { return true; }; return Search; }); S2.define('select2/dropdown/hidePlaceholder',[ ], function () { function HidePlaceholder (decorated, $element, options, dataAdapter) { this.placeholder = this.normalizePlaceholder(options.get('placeholder')); decorated.call(this, $element, options, dataAdapter); } HidePlaceholder.prototype.append = function (decorated, data) { data.results = this.removePlaceholder(data.results); decorated.call(this, data); }; HidePlaceholder.prototype.normalizePlaceholder = function (_, placeholder) { if (typeof placeholder === 'string') { placeholder = { id: '', text: placeholder }; } return placeholder; }; HidePlaceholder.prototype.removePlaceholder = function (_, data) { var modifiedData = data.slice(0); for (var d = data.length - 1; d >= 0; d--) { var item = data[d]; if (this.placeholder.id === item.id) { modifiedData.splice(d, 1); } } return modifiedData; }; return HidePlaceholder; }); S2.define('select2/dropdown/infiniteScroll',[ 'jquery' ], function ($) { function InfiniteScroll (decorated, $element, options, dataAdapter) { this.lastParams = {}; decorated.call(this, $element, options, dataAdapter); this.$loadingMore = this.createLoadingMore(); this.loading = false; } InfiniteScroll.prototype.append = function (decorated, data) { this.$loadingMore.remove(); this.loading = false; decorated.call(this, data); if (this.showLoadingMore(data)) { this.$results.append(this.$loadingMore); } }; InfiniteScroll.prototype.bind = function (decorated, container, $container) { var self = this; decorated.call(this, container, $container); container.on('query', function (params) { self.lastParams = params; self.loading = true; }); container.on('query:append', function (params) { self.lastParams = params; self.loading = true; }); this.$results.on('scroll', function () { var isLoadMoreVisible = $.contains( document.documentElement, self.$loadingMore[0] ); if (self.loading || !isLoadMoreVisible) { return; } var currentOffset = self.$results.offset().top + self.$results.outerHeight(false); var loadingMoreOffset = self.$loadingMore.offset().top + self.$loadingMore.outerHeight(false); if (currentOffset + 50 >= loadingMoreOffset) { self.loadMore(); } }); }; InfiniteScroll.prototype.loadMore = function () { this.loading = true; var params = $.extend({}, {page: 1}, this.lastParams); params.page++; this.trigger('query:append', params); }; InfiniteScroll.prototype.showLoadingMore = function (_, data) { return data.pagination && data.pagination.more; }; InfiniteScroll.prototype.createLoadingMore = function () { var $option = $( '
      • ' ); var message = this.options.get('translations').get('loadingMore'); $option.html(message(this.lastParams)); return $option; }; return InfiniteScroll; }); S2.define('select2/dropdown/attachBody',[ 'jquery', '../utils' ], function ($, Utils) { function AttachBody (decorated, $element, options) { this.$dropdownParent = options.get('dropdownParent') || $(document.body); decorated.call(this, $element, options); } AttachBody.prototype.bind = function (decorated, container, $container) { var self = this; var setupResultsEvents = false; decorated.call(this, container, $container); container.on('open', function () { self._showDropdown(); self._attachPositioningHandler(container); if (!setupResultsEvents) { setupResultsEvents = true; container.on('results:all', function () { self._positionDropdown(); self._resizeDropdown(); }); container.on('results:append', function () { self._positionDropdown(); self._resizeDropdown(); }); } }); container.on('close', function () { self._hideDropdown(); self._detachPositioningHandler(container); }); this.$dropdownContainer.on('mousedown', function (evt) { evt.stopPropagation(); }); }; AttachBody.prototype.destroy = function (decorated) { decorated.call(this); this.$dropdownContainer.remove(); }; AttachBody.prototype.position = function (decorated, $dropdown, $container) { // Clone all of the container classes $dropdown.attr('class', $container.attr('class')); $dropdown.removeClass('select2'); $dropdown.addClass('select2-container--open'); $dropdown.css({ position: 'absolute', top: -999999 }); this.$container = $container; }; AttachBody.prototype.render = function (decorated) { var $container = $(''); var $dropdown = decorated.call(this); $container.append($dropdown); this.$dropdownContainer = $container; return $container; }; AttachBody.prototype._hideDropdown = function (decorated) { this.$dropdownContainer.detach(); }; AttachBody.prototype._attachPositioningHandler = function (decorated, container) { var self = this; var scrollEvent = 'scroll.select2.' + container.id; var resizeEvent = 'resize.select2.' + container.id; var orientationEvent = 'orientationchange.select2.' + container.id; var $watchers = this.$container.parents().filter(Utils.hasScroll); $watchers.each(function () { $(this).data('select2-scroll-position', { x: $(this).scrollLeft(), y: $(this).scrollTop() }); }); $watchers.on(scrollEvent, function (ev) { var position = $(this).data('select2-scroll-position'); $(this).scrollTop(position.y); }); $(window).on(scrollEvent + ' ' + resizeEvent + ' ' + orientationEvent, function (e) { self._positionDropdown(); self._resizeDropdown(); }); }; AttachBody.prototype._detachPositioningHandler = function (decorated, container) { var scrollEvent = 'scroll.select2.' + container.id; var resizeEvent = 'resize.select2.' + container.id; var orientationEvent = 'orientationchange.select2.' + container.id; var $watchers = this.$container.parents().filter(Utils.hasScroll); $watchers.off(scrollEvent); $(window).off(scrollEvent + ' ' + resizeEvent + ' ' + orientationEvent); }; AttachBody.prototype._positionDropdown = function () { var $window = $(window); var isCurrentlyAbove = this.$dropdown.hasClass('select2-dropdown--above'); var isCurrentlyBelow = this.$dropdown.hasClass('select2-dropdown--below'); var newDirection = null; var offset = this.$container.offset(); offset.bottom = offset.top + this.$container.outerHeight(false); var container = { height: this.$container.outerHeight(false) }; container.top = offset.top; container.bottom = offset.top + container.height; var dropdown = { height: this.$dropdown.outerHeight(false) }; var viewport = { top: $window.scrollTop(), bottom: $window.scrollTop() + $window.height() }; var enoughRoomAbove = viewport.top < (offset.top - dropdown.height); var enoughRoomBelow = viewport.bottom > (offset.bottom + dropdown.height); var css = { left: offset.left, top: container.bottom }; // Determine what the parent element is to use for calciulating the offset var $offsetParent = this.$dropdownParent; // For statically positoned elements, we need to get the element // that is determining the offset if ($offsetParent.css('position') === 'static') { $offsetParent = $offsetParent.offsetParent(); } var parentOffset = $offsetParent.offset(); css.top -= parentOffset.top; css.left -= parentOffset.left; if (!isCurrentlyAbove && !isCurrentlyBelow) { newDirection = 'below'; } if (!enoughRoomBelow && enoughRoomAbove && !isCurrentlyAbove) { newDirection = 'above'; } else if (!enoughRoomAbove && enoughRoomBelow && isCurrentlyAbove) { newDirection = 'below'; } if (newDirection == 'above' || (isCurrentlyAbove && newDirection !== 'below')) { css.top = container.top - parentOffset.top - dropdown.height; } if (newDirection != null) { this.$dropdown .removeClass('select2-dropdown--below select2-dropdown--above') .addClass('select2-dropdown--' + newDirection); this.$container .removeClass('select2-container--below select2-container--above') .addClass('select2-container--' + newDirection); } this.$dropdownContainer.css(css); }; AttachBody.prototype._resizeDropdown = function () { var css = { width: this.$container.outerWidth(false) + 'px' }; if (this.options.get('dropdownAutoWidth')) { css.minWidth = css.width; css.position = 'relative'; css.width = 'auto'; } this.$dropdown.css(css); }; AttachBody.prototype._showDropdown = function (decorated) { this.$dropdownContainer.appendTo(this.$dropdownParent); this._positionDropdown(); this._resizeDropdown(); }; return AttachBody; }); S2.define('select2/dropdown/minimumResultsForSearch',[ ], function () { function countResults (data) { var count = 0; for (var d = 0; d < data.length; d++) { var item = data[d]; if (item.children) { count += countResults(item.children); } else { count++; } } return count; } function MinimumResultsForSearch (decorated, $element, options, dataAdapter) { this.minimumResultsForSearch = options.get('minimumResultsForSearch'); if (this.minimumResultsForSearch < 0) { this.minimumResultsForSearch = Infinity; } decorated.call(this, $element, options, dataAdapter); } MinimumResultsForSearch.prototype.showSearch = function (decorated, params) { if (countResults(params.data.results) < this.minimumResultsForSearch) { return false; } return decorated.call(this, params); }; return MinimumResultsForSearch; }); S2.define('select2/dropdown/selectOnClose',[ ], function () { function SelectOnClose () { } SelectOnClose.prototype.bind = function (decorated, container, $container) { var self = this; decorated.call(this, container, $container); container.on('close', function (params) { self._handleSelectOnClose(params); }); }; SelectOnClose.prototype._handleSelectOnClose = function (_, params) { if (params && params.originalSelect2Event != null) { var event = params.originalSelect2Event; // Don't select an item if the close event was triggered from a select or // unselect event if (event._type === 'select' || event._type === 'unselect') { return; } } var $highlightedResults = this.getHighlightedResults(); // Only select highlighted results if ($highlightedResults.length < 1) { return; } var data = $highlightedResults.data('data'); // Don't re-select already selected resulte if ( (data.element != null && data.element.selected) || (data.element == null && data.selected) ) { return; } this.trigger('select', { data: data }); }; return SelectOnClose; }); S2.define('select2/dropdown/closeOnSelect',[ ], function () { function CloseOnSelect () { } CloseOnSelect.prototype.bind = function (decorated, container, $container) { var self = this; decorated.call(this, container, $container); container.on('select', function (evt) { self._selectTriggered(evt); }); container.on('unselect', function (evt) { self._selectTriggered(evt); }); }; CloseOnSelect.prototype._selectTriggered = function (_, evt) { var originalEvent = evt.originalEvent; // Don't close if the control key is being held if (originalEvent && originalEvent.ctrlKey) { return; } this.trigger('close', { originalEvent: originalEvent, originalSelect2Event: evt }); }; return CloseOnSelect; }); S2.define('select2/i18n/en',[],function () { // English return { errorLoading: function () { return 'The results could not be loaded.'; }, inputTooLong: function (args) { var overChars = args.input.length - args.maximum; var message = 'Please delete ' + overChars + ' character'; if (overChars != 1) { message += 's'; } return message; }, inputTooShort: function (args) { var remainingChars = args.minimum - args.input.length; var message = 'Please enter ' + remainingChars + ' or more characters'; return message; }, loadingMore: function () { return 'Loading more results…'; }, maximumSelected: function (args) { var message = 'You can only select ' + args.maximum + ' item'; if (args.maximum != 1) { message += 's'; } return message; }, noResults: function () { return 'No results found'; }, searching: function () { return 'Searching…'; } }; }); S2.define('select2/defaults',[ 'jquery', 'require', './results', './selection/single', './selection/multiple', './selection/placeholder', './selection/allowClear', './selection/search', './selection/eventRelay', './utils', './translation', './diacritics', './data/select', './data/array', './data/ajax', './data/tags', './data/tokenizer', './data/minimumInputLength', './data/maximumInputLength', './data/maximumSelectionLength', './dropdown', './dropdown/search', './dropdown/hidePlaceholder', './dropdown/infiniteScroll', './dropdown/attachBody', './dropdown/minimumResultsForSearch', './dropdown/selectOnClose', './dropdown/closeOnSelect', './i18n/en' ], function ($, require, ResultsList, SingleSelection, MultipleSelection, Placeholder, AllowClear, SelectionSearch, EventRelay, Utils, Translation, DIACRITICS, SelectData, ArrayData, AjaxData, Tags, Tokenizer, MinimumInputLength, MaximumInputLength, MaximumSelectionLength, Dropdown, DropdownSearch, HidePlaceholder, InfiniteScroll, AttachBody, MinimumResultsForSearch, SelectOnClose, CloseOnSelect, EnglishTranslation) { function Defaults () { this.reset(); } Defaults.prototype.apply = function (options) { options = $.extend(true, {}, this.defaults, options); if (options.dataAdapter == null) { if (options.ajax != null) { options.dataAdapter = AjaxData; } else if (options.data != null) { options.dataAdapter = ArrayData; } else { options.dataAdapter = SelectData; } if (options.minimumInputLength > 0) { options.dataAdapter = Utils.Decorate( options.dataAdapter, MinimumInputLength ); } if (options.maximumInputLength > 0) { options.dataAdapter = Utils.Decorate( options.dataAdapter, MaximumInputLength ); } if (options.maximumSelectionLength > 0) { options.dataAdapter = Utils.Decorate( options.dataAdapter, MaximumSelectionLength ); } if (options.tags) { options.dataAdapter = Utils.Decorate(options.dataAdapter, Tags); } if (options.tokenSeparators != null || options.tokenizer != null) { options.dataAdapter = Utils.Decorate( options.dataAdapter, Tokenizer ); } if (options.query != null) { var Query = require(options.amdBase + 'compat/query'); options.dataAdapter = Utils.Decorate( options.dataAdapter, Query ); } if (options.initSelection != null) { var InitSelection = require(options.amdBase + 'compat/initSelection'); options.dataAdapter = Utils.Decorate( options.dataAdapter, InitSelection ); } } if (options.resultsAdapter == null) { options.resultsAdapter = ResultsList; if (options.ajax != null) { options.resultsAdapter = Utils.Decorate( options.resultsAdapter, InfiniteScroll ); } if (options.placeholder != null) { options.resultsAdapter = Utils.Decorate( options.resultsAdapter, HidePlaceholder ); } if (options.selectOnClose) { options.resultsAdapter = Utils.Decorate( options.resultsAdapter, SelectOnClose ); } } if (options.dropdownAdapter == null) { if (options.multiple) { options.dropdownAdapter = Dropdown; } else { var SearchableDropdown = Utils.Decorate(Dropdown, DropdownSearch); options.dropdownAdapter = SearchableDropdown; } if (options.minimumResultsForSearch !== 0) { options.dropdownAdapter = Utils.Decorate( options.dropdownAdapter, MinimumResultsForSearch ); } if (options.closeOnSelect) { options.dropdownAdapter = Utils.Decorate( options.dropdownAdapter, CloseOnSelect ); } if ( options.dropdownCssClass != null || options.dropdownCss != null || options.adaptDropdownCssClass != null ) { var DropdownCSS = require(options.amdBase + 'compat/dropdownCss'); options.dropdownAdapter = Utils.Decorate( options.dropdownAdapter, DropdownCSS ); } options.dropdownAdapter = Utils.Decorate( options.dropdownAdapter, AttachBody ); } if (options.selectionAdapter == null) { if (options.multiple) { options.selectionAdapter = MultipleSelection; } else { options.selectionAdapter = SingleSelection; } // Add the placeholder mixin if a placeholder was specified if (options.placeholder != null) { options.selectionAdapter = Utils.Decorate( options.selectionAdapter, Placeholder ); } if (options.allowClear) { options.selectionAdapter = Utils.Decorate( options.selectionAdapter, AllowClear ); } if (options.multiple) { options.selectionAdapter = Utils.Decorate( options.selectionAdapter, SelectionSearch ); } if ( options.containerCssClass != null || options.containerCss != null || options.adaptContainerCssClass != null ) { var ContainerCSS = require(options.amdBase + 'compat/containerCss'); options.selectionAdapter = Utils.Decorate( options.selectionAdapter, ContainerCSS ); } options.selectionAdapter = Utils.Decorate( options.selectionAdapter, EventRelay ); } if (typeof options.language === 'string') { // Check if the language is specified with a region if (options.language.indexOf('-') > 0) { // Extract the region information if it is included var languageParts = options.language.split('-'); var baseLanguage = languageParts[0]; options.language = [options.language, baseLanguage]; } else { options.language = [options.language]; } } if ($.isArray(options.language)) { var languages = new Translation(); options.language.push('en'); var languageNames = options.language; for (var l = 0; l < languageNames.length; l++) { var name = languageNames[l]; var language = {}; try { // Try to load it with the original name language = Translation.loadPath(name); } catch (e) { try { // If we couldn't load it, check if it wasn't the full path name = this.defaults.amdLanguageBase + name; language = Translation.loadPath(name); } catch (ex) { // The translation could not be loaded at all. Sometimes this is // because of a configuration problem, other times this can be // because of how Select2 helps load all possible translation files. if (options.debug && window.console && console.warn) { console.warn( 'Select2: The language file for "' + name + '" could not be ' + 'automatically loaded. A fallback will be used instead.' ); } continue; } } languages.extend(language); } options.translations = languages; } else { var baseTranslation = Translation.loadPath( this.defaults.amdLanguageBase + 'en' ); var customTranslation = new Translation(options.language); customTranslation.extend(baseTranslation); options.translations = customTranslation; } return options; }; Defaults.prototype.reset = function () { function stripDiacritics (text) { // Used 'uni range + named function' from http://jsperf.com/diacritics/18 function match(a) { return DIACRITICS[a] || a; } return text.replace(/[^\u0000-\u007E]/g, match); } function matcher (params, data) { // Always return the object if there is nothing to compare if ($.trim(params.term) === '') { return data; } // Do a recursive check for options with children if (data.children && data.children.length > 0) { // Clone the data object if there are children // This is required as we modify the object to remove any non-matches var match = $.extend(true, {}, data); // Check each child of the option for (var c = data.children.length - 1; c >= 0; c--) { var child = data.children[c]; var matches = matcher(params, child); // If there wasn't a match, remove the object in the array if (matches == null) { match.children.splice(c, 1); } } // If any children matched, return the new object if (match.children.length > 0) { return match; } // If there were no matching children, check just the plain object return matcher(params, match); } var original = stripDiacritics(data.text).toUpperCase(); var term = stripDiacritics(params.term).toUpperCase(); // Check if the text contains the term if (original.indexOf(term) > -1) { return data; } // If it doesn't contain the term, don't return anything return null; } this.defaults = { amdBase: './', amdLanguageBase: './i18n/', closeOnSelect: true, debug: false, dropdownAutoWidth: false, escapeMarkup: Utils.escapeMarkup, language: EnglishTranslation, matcher: matcher, minimumInputLength: 0, maximumInputLength: 0, maximumSelectionLength: 0, minimumResultsForSearch: 0, selectOnClose: false, sorter: function (data) { return data; }, templateResult: function (result) { return result.text; }, templateSelection: function (selection) { return selection.text; }, theme: 'default', width: 'resolve' }; }; Defaults.prototype.set = function (key, value) { var camelKey = $.camelCase(key); var data = {}; data[camelKey] = value; var convertedData = Utils._convertData(data); $.extend(this.defaults, convertedData); }; var defaults = new Defaults(); return defaults; }); S2.define('select2/options',[ 'require', 'jquery', './defaults', './utils' ], function (require, $, Defaults, Utils) { function Options (options, $element) { this.options = options; if ($element != null) { this.fromElement($element); } this.options = Defaults.apply(this.options); if ($element && $element.is('input')) { var InputCompat = require(this.get('amdBase') + 'compat/inputData'); this.options.dataAdapter = Utils.Decorate( this.options.dataAdapter, InputCompat ); } } Options.prototype.fromElement = function ($e) { var excludedData = ['select2']; if (this.options.multiple == null) { this.options.multiple = $e.prop('multiple'); } if (this.options.disabled == null) { this.options.disabled = $e.prop('disabled'); } if (this.options.language == null) { if ($e.prop('lang')) { this.options.language = $e.prop('lang').toLowerCase(); } else if ($e.closest('[lang]').prop('lang')) { this.options.language = $e.closest('[lang]').prop('lang'); } } if (this.options.dir == null) { if ($e.prop('dir')) { this.options.dir = $e.prop('dir'); } else if ($e.closest('[dir]').prop('dir')) { this.options.dir = $e.closest('[dir]').prop('dir'); } else { this.options.dir = 'ltr'; } } $e.prop('disabled', this.options.disabled); $e.prop('multiple', this.options.multiple); if ($e.data('select2Tags')) { if (this.options.debug && window.console && console.warn) { console.warn( 'Select2: The `data-select2-tags` attribute has been changed to ' + 'use the `data-data` and `data-tags="true"` attributes and will be ' + 'removed in future versions of Select2.' ); } $e.data('data', $e.data('select2Tags')); $e.data('tags', true); } if ($e.data('ajaxUrl')) { if (this.options.debug && window.console && console.warn) { console.warn( 'Select2: The `data-ajax-url` attribute has been changed to ' + '`data-ajax--url` and support for the old attribute will be removed' + ' in future versions of Select2.' ); } $e.attr('ajax--url', $e.data('ajaxUrl')); $e.data('ajax--url', $e.data('ajaxUrl')); } var dataset = {}; // Prefer the element's `dataset` attribute if it exists // jQuery 1.x does not correctly handle data attributes with multiple dashes if ($.fn.jquery && $.fn.jquery.substr(0, 2) == '1.' && $e[0].dataset) { dataset = $.extend(true, {}, $e[0].dataset, $e.data()); } else { dataset = $e.data(); } var data = $.extend(true, {}, dataset); data = Utils._convertData(data); for (var key in data) { if ($.inArray(key, excludedData) > -1) { continue; } if ($.isPlainObject(this.options[key])) { $.extend(this.options[key], data[key]); } else { this.options[key] = data[key]; } } return this; }; Options.prototype.get = function (key) { return this.options[key]; }; Options.prototype.set = function (key, val) { this.options[key] = val; }; return Options; }); S2.define('select2/core',[ 'jquery', './options', './utils', './keys' ], function ($, Options, Utils, KEYS) { var Select2 = function ($element, options) { if ($element.data('select2') != null) { $element.data('select2').destroy(); } this.$element = $element; this.id = this._generateId($element); options = options || {}; this.options = new Options(options, $element); Select2.__super__.constructor.call(this); // Set up the tabindex var tabindex = $element.attr('tabindex') || 0; $element.data('old-tabindex', tabindex); $element.attr('tabindex', '-1'); // Set up containers and adapters var DataAdapter = this.options.get('dataAdapter'); this.dataAdapter = new DataAdapter($element, this.options); var $container = this.render(); this._placeContainer($container); var SelectionAdapter = this.options.get('selectionAdapter'); this.selection = new SelectionAdapter($element, this.options); this.$selection = this.selection.render(); this.selection.position(this.$selection, $container); var DropdownAdapter = this.options.get('dropdownAdapter'); this.dropdown = new DropdownAdapter($element, this.options); this.$dropdown = this.dropdown.render(); this.dropdown.position(this.$dropdown, $container); var ResultsAdapter = this.options.get('resultsAdapter'); this.results = new ResultsAdapter($element, this.options, this.dataAdapter); this.$results = this.results.render(); this.results.position(this.$results, this.$dropdown); // Bind events var self = this; // Bind the container to all of the adapters this._bindAdapters(); // Register any DOM event handlers this._registerDomEvents(); // Register any internal event handlers this._registerDataEvents(); this._registerSelectionEvents(); this._registerDropdownEvents(); this._registerResultsEvents(); this._registerEvents(); // Set the initial state this.dataAdapter.current(function (initialData) { self.trigger('selection:update', { data: initialData }); }); // Hide the original select $element.addClass('select2-hidden-accessible'); $element.attr('aria-hidden', 'true'); // Synchronize any monitored attributes this._syncAttributes(); $element.data('select2', this); }; Utils.Extend(Select2, Utils.Observable); Select2.prototype._generateId = function ($element) { var id = ''; if ($element.attr('id') != null) { id = $element.attr('id'); } else if ($element.attr('name') != null) { id = $element.attr('name') + '-' + Utils.generateChars(2); } else { id = Utils.generateChars(4); } id = id.replace(/(:|\.|\[|\]|,)/g, ''); id = 'select2-' + id; return id; }; Select2.prototype._placeContainer = function ($container) { $container.insertAfter(this.$element); var width = this._resolveWidth(this.$element, this.options.get('width')); if (width != null) { $container.css('width', width); } }; Select2.prototype._resolveWidth = function ($element, method) { var WIDTH = /^width:(([-+]?([0-9]*\.)?[0-9]+)(px|em|ex|%|in|cm|mm|pt|pc))/i; if (method == 'resolve') { var styleWidth = this._resolveWidth($element, 'style'); if (styleWidth != null) { return styleWidth; } return this._resolveWidth($element, 'element'); } if (method == 'element') { var elementWidth = $element.outerWidth(false); if (elementWidth <= 0) { return 'auto'; } return elementWidth + 'px'; } if (method == 'style') { var style = $element.attr('style'); if (typeof(style) !== 'string') { return null; } var attrs = style.split(';'); for (var i = 0, l = attrs.length; i < l; i = i + 1) { var attr = attrs[i].replace(/\s/g, ''); var matches = attr.match(WIDTH); if (matches !== null && matches.length >= 1) { return matches[1]; } } return null; } return method; }; Select2.prototype._bindAdapters = function () { this.dataAdapter.bind(this, this.$container); this.selection.bind(this, this.$container); this.dropdown.bind(this, this.$container); this.results.bind(this, this.$container); }; Select2.prototype._registerDomEvents = function () { var self = this; this.$element.on('change.select2', function () { self.dataAdapter.current(function (data) { self.trigger('selection:update', { data: data }); }); }); this.$element.on('focus.select2', function (evt) { self.trigger('focus', evt); }); this._syncA = Utils.bind(this._syncAttributes, this); this._syncS = Utils.bind(this._syncSubtree, this); if (this.$element[0].attachEvent) { this.$element[0].attachEvent('onpropertychange', this._syncA); } var observer = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver ; if (observer != null) { this._observer = new observer(function (mutations) { $.each(mutations, self._syncA); $.each(mutations, self._syncS); }); this._observer.observe(this.$element[0], { attributes: true, childList: true, subtree: false }); } else if (this.$element[0].addEventListener) { this.$element[0].addEventListener( 'DOMAttrModified', self._syncA, false ); this.$element[0].addEventListener( 'DOMNodeInserted', self._syncS, false ); this.$element[0].addEventListener( 'DOMNodeRemoved', self._syncS, false ); } }; Select2.prototype._registerDataEvents = function () { var self = this; this.dataAdapter.on('*', function (name, params) { self.trigger(name, params); }); }; Select2.prototype._registerSelectionEvents = function () { var self = this; var nonRelayEvents = ['toggle', 'focus']; this.selection.on('toggle', function () { self.toggleDropdown(); }); this.selection.on('focus', function (params) { self.focus(params); }); this.selection.on('*', function (name, params) { if ($.inArray(name, nonRelayEvents) !== -1) { return; } self.trigger(name, params); }); }; Select2.prototype._registerDropdownEvents = function () { var self = this; this.dropdown.on('*', function (name, params) { self.trigger(name, params); }); }; Select2.prototype._registerResultsEvents = function () { var self = this; this.results.on('*', function (name, params) { self.trigger(name, params); }); }; Select2.prototype._registerEvents = function () { var self = this; this.on('open', function () { self.$container.addClass('select2-container--open'); }); this.on('close', function () { self.$container.removeClass('select2-container--open'); }); this.on('enable', function () { self.$container.removeClass('select2-container--disabled'); }); this.on('disable', function () { self.$container.addClass('select2-container--disabled'); }); this.on('blur', function () { self.$container.removeClass('select2-container--focus'); }); this.on('query', function (params) { if (!self.isOpen()) { self.trigger('open', {}); } this.dataAdapter.query(params, function (data) { self.trigger('results:all', { data: data, query: params }); }); }); this.on('query:append', function (params) { this.dataAdapter.query(params, function (data) { self.trigger('results:append', { data: data, query: params }); }); }); this.on('keypress', function (evt) { var key = evt.which; if (self.isOpen()) { if (key === KEYS.ESC || key === KEYS.TAB || (key === KEYS.UP && evt.altKey)) { self.close(); evt.preventDefault(); } else if (key === KEYS.ENTER) { self.trigger('results:select', {}); evt.preventDefault(); } else if ((key === KEYS.SPACE && evt.ctrlKey)) { self.trigger('results:toggle', {}); evt.preventDefault(); } else if (key === KEYS.UP) { self.trigger('results:previous', {}); evt.preventDefault(); } else if (key === KEYS.DOWN) { self.trigger('results:next', {}); evt.preventDefault(); } } else { if (key === KEYS.ENTER || key === KEYS.SPACE || (key === KEYS.DOWN && evt.altKey)) { self.open(); evt.preventDefault(); } } }); }; Select2.prototype._syncAttributes = function () { this.options.set('disabled', this.$element.prop('disabled')); if (this.options.get('disabled')) { if (this.isOpen()) { this.close(); } this.trigger('disable', {}); } else { this.trigger('enable', {}); } }; Select2.prototype._syncSubtree = function (evt, mutations) { var changed = false; var self = this; // Ignore any mutation events raised for elements that aren't options or // optgroups. This handles the case when the select element is destroyed if ( evt && evt.target && ( evt.target.nodeName !== 'OPTION' && evt.target.nodeName !== 'OPTGROUP' ) ) { return; } if (!mutations) { // If mutation events aren't supported, then we can only assume that the // change affected the selections changed = true; } else if (mutations.addedNodes && mutations.addedNodes.length > 0) { for (var n = 0; n < mutations.addedNodes.length; n++) { var node = mutations.addedNodes[n]; if (node.selected) { changed = true; } } } else if (mutations.removedNodes && mutations.removedNodes.length > 0) { changed = true; } // Only re-pull the data if we think there is a change if (changed) { this.dataAdapter.current(function (currentData) { self.trigger('selection:update', { data: currentData }); }); } }; /** * Override the trigger method to automatically trigger pre-events when * there are events that can be prevented. */ Select2.prototype.trigger = function (name, args) { var actualTrigger = Select2.__super__.trigger; var preTriggerMap = { 'open': 'opening', 'close': 'closing', 'select': 'selecting', 'unselect': 'unselecting' }; if (args === undefined) { args = {}; } if (name in preTriggerMap) { var preTriggerName = preTriggerMap[name]; var preTriggerArgs = { prevented: false, name: name, args: args }; actualTrigger.call(this, preTriggerName, preTriggerArgs); if (preTriggerArgs.prevented) { args.prevented = true; return; } } actualTrigger.call(this, name, args); }; Select2.prototype.toggleDropdown = function () { if (this.options.get('disabled')) { return; } if (this.isOpen()) { this.close(); } else { this.open(); } }; Select2.prototype.open = function () { if (this.isOpen()) { return; } this.trigger('query', {}); }; Select2.prototype.close = function () { if (!this.isOpen()) { return; } this.trigger('close', {}); }; Select2.prototype.isOpen = function () { return this.$container.hasClass('select2-container--open'); }; Select2.prototype.hasFocus = function () { return this.$container.hasClass('select2-container--focus'); }; Select2.prototype.focus = function (data) { // No need to re-trigger focus events if we are already focused if (this.hasFocus()) { return; } this.$container.addClass('select2-container--focus'); this.trigger('focus', {}); }; Select2.prototype.enable = function (args) { if (this.options.get('debug') && window.console && console.warn) { console.warn( 'Select2: The `select2("enable")` method has been deprecated and will' + ' be removed in later Select2 versions. Use $element.prop("disabled")' + ' instead.' ); } if (args == null || args.length === 0) { args = [true]; } var disabled = !args[0]; this.$element.prop('disabled', disabled); }; Select2.prototype.data = function () { if (this.options.get('debug') && arguments.length > 0 && window.console && console.warn) { console.warn( 'Select2: Data can no longer be set using `select2("data")`. You ' + 'should consider setting the value instead using `$element.val()`.' ); } var data = []; this.dataAdapter.current(function (currentData) { data = currentData; }); return data; }; Select2.prototype.val = function (args) { if (this.options.get('debug') && window.console && console.warn) { console.warn( 'Select2: The `select2("val")` method has been deprecated and will be' + ' removed in later Select2 versions. Use $element.val() instead.' ); } if (args == null || args.length === 0) { return this.$element.val(); } var newVal = args[0]; if ($.isArray(newVal)) { newVal = $.map(newVal, function (obj) { return obj.toString(); }); } this.$element.val(newVal).trigger('change'); }; Select2.prototype.destroy = function () { this.$container.remove(); if (this.$element[0].detachEvent) { this.$element[0].detachEvent('onpropertychange', this._syncA); } if (this._observer != null) { this._observer.disconnect(); this._observer = null; } else if (this.$element[0].removeEventListener) { this.$element[0] .removeEventListener('DOMAttrModified', this._syncA, false); this.$element[0] .removeEventListener('DOMNodeInserted', this._syncS, false); this.$element[0] .removeEventListener('DOMNodeRemoved', this._syncS, false); } this._syncA = null; this._syncS = null; this.$element.off('.select2'); this.$element.attr('tabindex', this.$element.data('old-tabindex')); this.$element.removeClass('select2-hidden-accessible'); this.$element.attr('aria-hidden', 'false'); this.$element.removeData('select2'); this.dataAdapter.destroy(); this.selection.destroy(); this.dropdown.destroy(); this.results.destroy(); this.dataAdapter = null; this.selection = null; this.dropdown = null; this.results = null; }; Select2.prototype.render = function () { var $container = $( '' + '' + '' + '' ); $container.attr('dir', this.options.get('dir')); this.$container = $container; this.$container.addClass('select2-container--' + this.options.get('theme')); $container.data('element', this.$element); return $container; }; return Select2; }); S2.define('select2/compat/utils',[ 'jquery' ], function ($) { function syncCssClasses ($dest, $src, adapter) { var classes, replacements = [], adapted; classes = $.trim($dest.attr('class')); if (classes) { classes = '' + classes; // for IE which returns object $(classes.split(/\s+/)).each(function () { // Save all Select2 classes if (this.indexOf('select2-') === 0) { replacements.push(this); } }); } classes = $.trim($src.attr('class')); if (classes) { classes = '' + classes; // for IE which returns object $(classes.split(/\s+/)).each(function () { // Only adapt non-Select2 classes if (this.indexOf('select2-') !== 0) { adapted = adapter(this); if (adapted != null) { replacements.push(adapted); } } }); } $dest.attr('class', replacements.join(' ')); } return { syncCssClasses: syncCssClasses }; }); S2.define('select2/compat/containerCss',[ 'jquery', './utils' ], function ($, CompatUtils) { // No-op CSS adapter that discards all classes by default function _containerAdapter (clazz) { return null; } function ContainerCSS () { } ContainerCSS.prototype.render = function (decorated) { var $container = decorated.call(this); var containerCssClass = this.options.get('containerCssClass') || ''; if ($.isFunction(containerCssClass)) { containerCssClass = containerCssClass(this.$element); } var containerCssAdapter = this.options.get('adaptContainerCssClass'); containerCssAdapter = containerCssAdapter || _containerAdapter; if (containerCssClass.indexOf(':all:') !== -1) { containerCssClass = containerCssClass.replace(':all:', ''); var _cssAdapter = containerCssAdapter; containerCssAdapter = function (clazz) { var adapted = _cssAdapter(clazz); if (adapted != null) { // Append the old one along with the adapted one return adapted + ' ' + clazz; } return clazz; }; } var containerCss = this.options.get('containerCss') || {}; if ($.isFunction(containerCss)) { containerCss = containerCss(this.$element); } CompatUtils.syncCssClasses($container, this.$element, containerCssAdapter); $container.css(containerCss); $container.addClass(containerCssClass); return $container; }; return ContainerCSS; }); S2.define('select2/compat/dropdownCss',[ 'jquery', './utils' ], function ($, CompatUtils) { // No-op CSS adapter that discards all classes by default function _dropdownAdapter (clazz) { return null; } function DropdownCSS () { } DropdownCSS.prototype.render = function (decorated) { var $dropdown = decorated.call(this); var dropdownCssClass = this.options.get('dropdownCssClass') || ''; if ($.isFunction(dropdownCssClass)) { dropdownCssClass = dropdownCssClass(this.$element); } var dropdownCssAdapter = this.options.get('adaptDropdownCssClass'); dropdownCssAdapter = dropdownCssAdapter || _dropdownAdapter; if (dropdownCssClass.indexOf(':all:') !== -1) { dropdownCssClass = dropdownCssClass.replace(':all:', ''); var _cssAdapter = dropdownCssAdapter; dropdownCssAdapter = function (clazz) { var adapted = _cssAdapter(clazz); if (adapted != null) { // Append the old one along with the adapted one return adapted + ' ' + clazz; } return clazz; }; } var dropdownCss = this.options.get('dropdownCss') || {}; if ($.isFunction(dropdownCss)) { dropdownCss = dropdownCss(this.$element); } CompatUtils.syncCssClasses($dropdown, this.$element, dropdownCssAdapter); $dropdown.css(dropdownCss); $dropdown.addClass(dropdownCssClass); return $dropdown; }; return DropdownCSS; }); S2.define('select2/compat/initSelection',[ 'jquery' ], function ($) { function InitSelection (decorated, $element, options) { if (options.get('debug') && window.console && console.warn) { console.warn( 'Select2: The `initSelection` option has been deprecated in favor' + ' of a custom data adapter that overrides the `current` method. ' + 'This method is now called multiple times instead of a single ' + 'time when the instance is initialized. Support will be removed ' + 'for the `initSelection` option in future versions of Select2' ); } this.initSelection = options.get('initSelection'); this._isInitialized = false; decorated.call(this, $element, options); } InitSelection.prototype.current = function (decorated, callback) { var self = this; if (this._isInitialized) { decorated.call(this, callback); return; } this.initSelection.call(null, this.$element, function (data) { self._isInitialized = true; if (!$.isArray(data)) { data = [data]; } callback(data); }); }; return InitSelection; }); S2.define('select2/compat/inputData',[ 'jquery' ], function ($) { function InputData (decorated, $element, options) { this._currentData = []; this._valueSeparator = options.get('valueSeparator') || ','; if ($element.prop('type') === 'hidden') { if (options.get('debug') && console && console.warn) { console.warn( 'Select2: Using a hidden input with Select2 is no longer ' + 'supported and may stop working in the future. It is recommended ' + 'to use a `